diff --git a/.travis.yml b/.travis.yml index 6aa3f6338c..02876d6572 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ env: - BUILD_TYPE=make # build using Makefile - BUILD_TYPE=complete # build manually and regenerate figures, grammar, and cross-references - BUILD_TYPE=check-whitespace # check for whitespace at the ends of lines - - BUILD_TYPE=check-newlines # check for blank lines at the ends of files + - BUILD_TYPE=check-newlines # check for blank lines at the ends of files - BUILD_TYPE=check-macro-use # check for proper macro use script: @@ -26,7 +26,8 @@ script: - pushd source - if [ "$BUILD_TYPE" = "latexmk" ]; then docker exec -it texlive-basic bash -c "cd /$TRAVIS_REPO_SLUG/source && latexmk -pdf std -silent"; - ! grep -Fe "Overfull \\hbox" std.log; + ! grep -Fe "Overfull \\hbox" std.log && + ! grep "LaTeX Warning..There were undefined references" std.log; fi - if [ "$BUILD_TYPE" = "make" ]; then docker exec -it texlive-basic bash -c "cd /$TRAVIS_REPO_SLUG/source && make -j2"; diff --git a/papers/n4762.pdf b/papers/n4762.pdf new file mode 100644 index 0000000000..4b0f08275e Binary files /dev/null and b/papers/n4762.pdf differ diff --git a/papers/n4764.html b/papers/n4764.html new file mode 100644 index 0000000000..97f0d1a0dd --- /dev/null +++ b/papers/n4764.html @@ -0,0 +1,1350 @@ +N4764 +

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

+ +

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

+ +

Acknowledgements

+ +

Special thanks to Casey Carter for supplying a pull request to merge +P0898R3 (LWG motion 28), +and working with us on editorial cleanups within the +12 pages of added text.

+ +

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

+ +

New papers

+ + + +

Motions incorporated into working draft

+ +

Core working group motions

+ +

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

+ + + +

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

+ + + +

CWG motion 3: P0806R2 "Deprecate implicit capture of this via [=]"

+ +

CWG motion 4: P1042R1 "__VA_OPT__ wording clarifications"

+ +

CWG motion 5: P0929R2 "Checking for abstract class types" applied, resolving 2 core issues:

+ + + +

CWG motion 6: P0732R2 "Class types in non-type template parameters"

+ +

CWG motion 7 was not approved

+ +

CWG motion 8: P1025R1 "Update the reference to the Unicode standard"

+ +

CWG motion 9: P0528R3 "The curious case of padding bits, featuring atomic compare-and-exchange"

+ +

CWG motion 10: P0722R3 "Efficient sized delete for variable sized classes"

+ +

CWG motion 11: P1064R0 "Allowing virtual function calls in constant expressions"

+ +

CWG motion 12: P1008R1 "Prohibit aggregates with user-declared constructors"

+ +

CWG motion 13: P1120R0 "Consistency improvements for <=> and other comparison operators"

+ +

CWG motion 14: P0542R5 "Contract-based programming" see below

+ +

CWG motion 15: P0941R2 "Feature-test macros" see below

+ +

CWG motion 16: P0892R2 "explicit(bool)"

+ +

Library working group motions

+ +

LWG motions 1-5 apply to the Parallelism TS

+ +

LWG motions 6 and 7 apply to the Reflection TS

+ +

LWG motions 8 and 9 apply to the Coroutines TS

+ +

LWG motion 10 applies to the Networking TS

+ +

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

+ + + +

LWG motion 12: Library issue resolution for 1 issue applied:

+ + + +

LWG motion 13: P0476R2 "Bit-casting object representations"

+ +

LWG motion 14: P0788R3 "Standard library specification in a concepts and contracts world"

+ +

LWG motion 15 was not approved

+ +

LWG motion 16: P0458R2 "Checking for existence of an element in associative containers"

+ +

LWG motion 17: P0759R1 "fpos requirements"

+ +

LWG motion 18: P1023R0 "constexpr comparison operators for std::array"

+ +

LWG motion 19: P0769R2 "Add shift to <algorithm>"

+ +

LWG motion 20: P0887R1 "The identity metafunction"

+ +

LWG motion 21: P0879R0 "constexpr for swap and swap-related functions" applied, resolving 1 issue:

+ + + +

LWG motion 22: P0758R1 "Implicit conversion traits and utility functions"

+ +

LWG motion 23: P0556R3 "Integral power-of-2 operations"

+ +

LWG motion 24: P0019R8 "atomic_ref"

+ +

LWG motion 25: P0935R0 "Eradicating unnecessarily explicit default constructors from the standard library"

+ +

LWG motion 26: P0646R1 "Improving the return value of erase-like algorithms"

+ +

LWG motion 27: P0619R4 "Reviewing deprecated facilities of C++17 for C++20" see below

+ +

LWG motion 28: P0898R3 "Standard library concepts" see below

+ +

Notable editorial changes

+ +

CWG motion 14

+ +

Subclause structure and paragraph order of [dcl.attr.contracts] was reworked. +Several normatively-redundant statements were converted to notes or removed.

+ +

CWG motion 15

+ +

Multiple papers moved at this meeting included suggested feature-test macros. +However, these were not presented as editing instructions, because we did not +have feature-test macros in the standard wording yet. After consultation with +CWG and LWG, the following feature test macros have been added in addition to +those listed in CWG motion 15 (all with value 201806L):

+ + + +

CWG motions 16 and 12

+ +

CWG motion 16 would have us change wording that was deleted by CWG motion 12. +The requested change in CWG motion 16 (from teletype "explicit" to body font "explicit") +was ignored.

+ +

LWG motion 11: issue 2139

+ +

The underlying text has changed between the drafting of the resolution to this +issue and its application. We believe every requested edit has been applied; +however, an additional use of "user-defined type" has been added to +[namespace.std] that should likely also have been covered by this wording. +It has not been changed.

+ +

LWG motions 13 and 23

+ +

These motions both introduce a <bit> header, but the organizational structure +suggested by motion 23 doesn't make sense for the functionality +added by motion 13. +The wording of motion 23 has been rearranged to fit into +the structure established by motion 13.

+ +

LWG motions 16

+ +

Added the new contains member function for associative containers to the list +of member function templates that do not participate in overload resolution +unless the comparator is transparent, after consultation with LWG.

+ +

LWG motions 19 and 21

+ +

LWG motion 19 adds a shift_right algorithm to <algorithm> +as a non-constexpr function template.

+ +

LWG motion 21 instructs that we mark +all non-parallel algorithms in <algorithm> +as constexpr. +Naturally, however, +its proposed wording change does not list the shift_right algorithm. +After consultation with LWG, shift_right has been marked constexpr +to satisfy the intent of LWG motion 21.

+ +

LWG motion 27

+ +

Synopses for +<ccomplex>, +<cstdalign>, +<cstdbool>, and +<ctgmath> +were not removed; +instead, they have been repurposed as synopses for +<complex.h>, +<stdalign.h>, +<stdbool.h>, and +<tgmath.h>. +(The latter used to be defined in terms of the former, +but can no longer be specified in that way.) +Also introduced a synopsis for <iso646.h>.

+ +

LWG motion 28

+ +

Clause labels shortened and simplified throughout.

+ +

The single-item clauses [concept.movable], [concept.copyable], +[concept.semiregular], and [concept.regular] have been merged into their +parent, [concepts.object].

+ +

The single-item clauses [concept.signed.int] and [concept.unsigned.int] +have been merged into their parent, [concept.integral].

+ +

Legacy concept names changed from Cpp98Something to Cpp17Something. Many of +these concepts did not exist in C++98 (which in any case was revoked and +replaced by C++03).

+ +

Reworked "uniform random bit generator" requirements to describe them in terms +of the UniformRandomBitGenerator concept.

+ +

Removed "there need be no subsumption relationship" wording that is already +implied by the core language rules for concepts.

+ +

Editorial paper P1076R1 "Clause reorganization"

+ +

The claue reorganization described in P1076R1 and discussed at the WG21 +Rapperswil meeting has been applied to the working draft, with the following +modifications:

+ +

[class.copy] was left containing only two paragraphs of text, neither of which +had any normative impact. It has been removed.

+ +

The top-level subclauses of [algorithms] have been reordered to make the +description of the <numeric> header fit better into its structure.

+ +

Several paragraphs of [class] describing various properties of classes have +been moved into a new subclause [class.prop] "Properties of clases".

+ +

Removal of single-item subclauses

+ +

The single-item subclauses +[move.iter.op=] and +[move.iter.op.const] +have been merged into [move.iter.cons].

+ +

The single-item subclauses +[move.iter.op.star], +[move.iter.op.ref], and +[move.iter.op.index] +have been merged into [move.iter.elem].

+ +

The single-item subclauses +[move.iter.op.+], +[move.iter.op.-], +[move.iter.op.incr], +[move.iter.op.+=], +[move.iter.op.decr], and +[move.iter.op.-=] +have been merged into [move.iter.nav].

+ +

The now-empty [move.iter.ops] has been removed.

+ +

Minor editorial fixes

+ +

A log of editorial fixes made to the working draft since N4750 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 afe115acc28e33e48e2ece9f850820d6faa51757
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jul 6 10:47:19 2018 +0200
+
+    [class] Introduce a subheading 'Properties of classes'.
+
+commit d3f80a4a994a66cc8148a6031d29182aad4f16f6
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jul 7 00:49:56 2018 +0200
+
+    [namespace.udecl] Demote normative duplication to notes (#1976)
+
+    The effects of using-declarations naming member functions
+    are discussed in other parts of the standard.
+    The effects of initializing with an inherited constructor are
+    discussed elsewhere, too.
+
+commit 9459c137f138f903d670e6689b3963f0a3f7d083
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jul 6 10:40:09 2018 +0200
+
+    [time.point,time.duration] Remove class name repeated in subheadings (#2249)
+
+commit 56c599f71e8a9cfe77233e5dcd77ccfe72d81af8
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jul 5 20:22:47 2018 -0700
+
+    [algorithm.syn] Reorder after [algorithms.requirements] and
+    [algorithms.parallel], which apply to both <algorithm> and <numeric>.
+
+commit 8806777151719da531aae976c46f98c485bf0580
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jul 4 08:39:53 2018 +0200
+
+    [algorithms] Integrate requirements from [numeric.ops].
+
+commit e8d3d7029c5be1494016bc03e0004d0e9eeaa8cd
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jul 4 08:25:30 2018 +0200
+
+    Remove [class.copy] and adjust cross-references pointing there.
+
+    The normative statements that used to be contained in
+    [class.copy] were redundant with [dcl.init] and [over.ass].
+
+commit 006fb15de62c93b6e3de3d32648f276c9ec70181
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jul 4 00:29:28 2018 +0200
+
+    [class.derived,class.access,special] Move into [class], as appropriate.
+
+    P1076R1: Editorial clause reorganization
+
+commit 3c580cd204fde95a21de1830ace75d14d429f845
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jul 4 00:07:05 2018 +0200
+
+    [dcl.decl] Move into [dcl.dcl] as appropriate.
+
+    P1076R1: Editorial clause reorganization
+
+commit 40907944b775e4da980b69565dcbaa4bd494d347
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jul 4 00:00:51 2018 +0200
+
+    [namespace.udecl] Move one level up
+
+    P1076R1: Editorial clause reorganization
+
+commit f87c7fd1d9a258d043b7b22fb13ce6bdf6931a28
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jul 3 23:54:36 2018 +0200
+
+    [numeric.ops] Move into [algorithms], after [alg.sorting]
+
+    P1076R1: Editorial clause reorganization
+
+commit 40719643c5f237aecf0136a001cce1d85ceaaf59
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jul 3 23:48:00 2018 +0200
+
+    [localization] Move to before [input.output]
+
+    P1076R1: Editorial clause reorganization
+
+commit a41eef0a98e9727ca85ff12c99b27209969a62b8
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jul 3 23:37:46 2018 +0200
+
+    [time.general] Add summary table
+
+commit 63603768789149c9b46bac7e810ddfb618e8eefe
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jul 3 23:30:45 2018 +0200
+
+    [time] Promote to a top-level clause.
+
+    P1076R1: Editorial clause reorganization
+
+commit 006a9380cfe9e00bcee9b03884b3b4bf57bf6fa2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jul 3 23:22:05 2018 +0200
+
+    [conv] Move as a subclause into [expr], immediately before [expr.arith.conv]
+
+    P1076R1: Editorial clause reorganization
+
+commit 70adb738f6edbc0697d1f26c72040d6b3a971421
+Author: Hubert Tong <hubert-reinterpretcast@users.noreply.github.com>
+Date:   Thu Jul 5 16:22:22 2018 -0400
+
+    [intro.defs] Use https in hyperlink URL; see Directives, Part 2:2018 (#2248)
+
+commit 3fe46c716367d6e367b4c5acff344bce3f2a5cd2
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Fri May 11 11:53:45 2018 +0100
+
+    [class] Reformat paragraph defining standard-layout class
+
+    Move the note before the definition of M(X).
+    Use a nested list for the definition of M(X).
+    Move the example to a new paragraph.
+
+commit 0cac48775c1b1db4038cc0e456ccef81d5dd5fdc
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Mon Jul 2 17:13:53 2018 -0400
+
+    [concepts.{lang,compare,callable}.general] Replace "section" with "subclause".
+
+commit 9db2f62e966224e8e749913871771dd4ac886c78
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 15 09:08:21 2018 +0200
+
+    [basic.start,except] Harmonize references to std::terminate
+
+commit 3846e6ba6592099145655420e3b88c6c874cd5fc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 1 10:05:58 2018 +0200
+
+    [over.match.viable] Fix cross-reference to satisfaction of constraints
+
+commit 61e272c36350786e8b3fa1662efb0a8b9484cdd5
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 14 11:08:25 2018 +0200
+
+    [dcl.init.ref] Avoid use of 'underlying type' for references
+
+commit c56870954b48305df89133a80e6ab8a21a0a90e9
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Mon Jul 2 17:10:38 2018 -0400
+
+    [temp.constr.constr], [iterator.requirements.general], [re.results.size] Replace "section" with "subclause"
+
+commit f3b625826ae894613c9ec47bd4e1874fc46e71d4
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Mon Jul 2 17:05:50 2018 -0400
+
+    [concepts.object] Dissolve single-item subclauses. (#2240)
+
+    The following subclause headings have been removed:
+
+      [concept.movable]
+      [concept.copyable]
+      [concept.semiregular]
+      [concept.regular]
+
+    The content for these former subclauses now resides in the parent subclause, [concepts.object].
+
+commit 75c9148c3d810a825765aef9f04f9689f678f7bf
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Sat Jun 16 15:57:32 2018 -0400
+
+    [re.general] Refer to table as done in the other clauses
+
+commit 2fdaf88fcffd65ea2ccc4e032e288c74ac94bb7d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jul 2 11:52:45 2018 -0700
+
+    [basic.lookup.unqual] Finesse "class definition" footnote to avoid
+    saying that a class definition is one of two components of the
+    definition of a class.
+
+commit 4d757ab4026f2b1af37ea1f3c6fb8fbd4c83f0dc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sat Jun 30 00:23:57 2018 +0200
+
+    [class.mem] Define complete-class context
+
+    and use it, instead of having separate redundant lists
+    in [basic.scope.class] and [basic.lookup.unqual].
+
+commit ade8b020efbfa8fd220d1ed7f230850f2849d593
+Author: S. B. Tam <cpplearner@outlook.com>
+Date:   Tue Jul 3 02:32:45 2018 +0800
+
+    [expr.prim.id.{un,}qual] A structured binding name is an lvalue (#2234)
+
+    Fix wording here to match corresponding wording in [dcl.struct.bind].
+
+commit 809a034ac0428dc71d3b07bb15c39a1131d2e3f8
+Author: Michael Adams <mdadams@ece.uvic.ca>
+Date:   Mon Jul 2 11:30:48 2018 -0700
+
+    [class.copy.elision] Fix typo that accidentally makes example ill-formed
+
+commit 61b25c662399e7ebd126ee6771126aa29fed407e
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Sat Jun 30 05:27:09 2018 -0400
+
+    [{i,o}{string,f}stream.cons] Remove unmatched parenthesis (#2233)
+
+commit 0420f57904322da8adc32890687dc914d5c06edc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Jun 19 11:23:54 2018 +0200
+
+    [dcl.attr.contract] Introduce subheadings and reorder paragraphs to fit
+
+commit 492e6a79cd4b36488c248771b73b46ba54ec27a6
+Author: Johel Ernesto Guerrero Peña <johelegp@gmail.com>
+Date:   Wed Jun 27 21:18:27 2018 -0400
+
+    [variant.get] Consistently place comma after "otherwise"
+
+commit 5326a0d1311682568eccd19b1f8c2512091a2a53
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 28 12:42:25 2018 +0200
+
+    [input.iterators,fs.rec.dir.itr.members] Disambiguate phrasing for previous value of iterators
+
+commit 2f5d2cbcd69c0cb63bad481f44d32082dd68ea6c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 28 23:54:24 2018 +0200
+
+    [depr.locale.stdcvt.req] Add normative references for encoding forms
+
+commit 69d7e1ffeed2187c1986f727882e65890c6dfa0f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 29 00:08:44 2018 +0200
+
+    [optional] Move requirements from header synopsis to class template
+
+commit 6116910802836c517ecde9237b6ffabcdafc26cf
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 29 00:15:09 2018 +0200
+
+    [basic.fundamental] Add definition of 'fundamental type'
+
+commit b65061ee7d81079e72b2467ac9307ba9a24aaf00
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 29 13:41:11 2018 +0200
+
+    [expr.prim.lambda,depr.capture.this] Replace 'lambda expression'
+
+    with the grammar term 'lambda-expression'.
+    Also remove the unused definition of 'local lambda expression'.
+
+commit 354fa005c1b8ad55ddd1bca31bf4f8bef67db46e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri May 25 10:37:36 2018 +0200
+
+    [dcl.init,over.match.ctor] Clarify copy-initialization for empty arguments.
+
+    Also turn the enumeration of direct-initialization cases into
+    a bulleted list, referring to grammar non-terminals.
+
+commit 69259f9d29a571233908c4f9be5afc9b98e9a2e3
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri May 25 01:14:17 2018 +0200
+
+    Drop redundant 'expression'
+
+    when calling out a value category.
+
+commit 09f1354234154602dee9a0afc12f0b160bf455ea
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jun 29 13:59:12 2018 -0700
+
+    [dcl.attr.contract] Fix mention of odr-use of a parameter value to talk
+    about odr-use of the parameter instead; values can't be odr-used.
+
+    As agreed on the core reflector.
+
+commit 45fa09c5e38057571284c3eda52aa479afa0f3cb
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 29 17:38:17 2018 +0200
+
+    [temp.dep] Fix typo 'An expressions...' (#2181)
+
+commit 50a00f2776122a1328d29332f45e3ec20ee6d0fb
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 29 00:53:00 2018 +0200
+
+    [lex] Cite ISO/IEC 10646 correctly (#2226)
+
+commit 6f6a5dd6de12968f447940049d7fbf447e0ccf9f
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue May 8 13:29:32 2018 +0200
+
+    [atomics.types.operations] Avoid inappropriate use of 'underlying type'
+
+commit 35e17ec6e2f702be4c31fd99c058404223a865da
+Author: Casey Carter <Casey@Carter.net>
+Date:   Thu Jun 28 12:28:20 2018 -0700
+
+    [algorithm.syn] Relocate the "partitions" algorithms (#2219)
+
+    Move the synopsis for the "partitions" algorithms between the "binary_search" family and the "merge" family, to agree with the order of the detailed specifications as reordered by #1245.
+
+commit 03e97ca6af73a842d38d40977a2630b0c978eade
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Apr 19 23:12:20 2018 +0200
+
+    [temp.arg.explicit,temp.mem] Clarify note about explicit template arguments
+
+    for conversion function templates and constructor templates.
+
+commit cdad8c27d822e5aec90b86a6e72e6f093d204924
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Apr 3 23:33:29 2018 +0200
+
+    [move.iterators] Dissolve single-item subclauses.
+
+commit 1f9524d9b2a2ec95e7b48ec82ff9782e2b79d413
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Wed Jun 27 22:42:53 2018 +0100
+
+    [support.limits.general] Fix typo: '<forwardlist>' should be '<forward_list>'
+
+commit e0d78d373e975ccbc7cd59d5b7292c48f920b959
+Author: Alisdair Meredith <public@alisdairm.net>
+Date:   Wed Jun 27 17:33:20 2018 -0400
+
+    [span.overview] Fix reverse_iterator for span (#2112)
+
+    There is a common convention to omit 'std::' when not strictly needed,
+    other than for 'std::move' and 'std::forward'.  A third case is for
+    'reverse_iterator' and 'const_reverse_iterator' type aliases inside a
+    class definition, as the leading 'reverse_iterator' type alias hides
+    the 'std' version from the 'const_reverse_iterator' definition, and
+    subsequently fails to compile.  This patch restore the class definition
+    to a safely copy/pastable state.
+
+    An additional review indicated this convention has been applied correctly
+    for every othert potential occurrence in the library.
+
+commit 33e8e2b3c5c2ae9e53ed656f7e3dfe874e55ede3
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Jun 27 14:32:34 2018 -0700
+
+    [output.iterators] Strike useless sentence from note (#2083)
+
+    There's no such thing as an "insert pointer," and the rest of this sentence isn't much better.
+
+commit fe3f46b976c8c19336f0007625fe3e487827ca55
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Wed Jun 27 12:12:45 2018 -0700
+
+    Harmonize phrasings of "this destructor is trivial". (#2191)
+
+    Inspired by P0602 https://lichray.github.io/trivially_variant.html
+    Zhihao suggested that we harmonize "trivially destructible"
+    wording across the rest of the Standard.
+
+commit 14809d0b4b27395ea407734d00d0f6dc9c7b0c05
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jun 27 21:04:50 2018 +0200
+
+    [expr.spaceship] Fix typo for std::strong_equality::nonequal (#2216)
+
+commit 2954bfccb653504279f101cf1d8c7f9fb96947ff
+Author: Sergey Zubkov <cubbi@cubbi.com>
+Date:   Wed Jun 27 15:03:49 2018 -0400
+
+    [diff.cpp17.depr] Fix typo from P0619R4 (#2217)
+
+    In the paper, "raw_memory_iterator" was meant to say "raw_storage_iterator".
+
+commit 264839261e3d0b0cb66415f2c1755d1f84d2cb3d
+Author: timsong-cpp <rs2740@gmail.com>
+Date:   Wed Jun 27 06:51:41 2018 -0400
+
+    [istreambuf.iterator.proxy] correct title and remove default template argument (#2078)
+
+    This is a class, not a class template. Also, the default template argument is 1) redundant and 2) ill-formed for violating [temp.param]p12.
+
+commit e6794e6f167db93a519564d5fc986309d194e140
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jun 27 12:49:39 2018 +0200
+
+    [syserr] Remove class name repeated in subheadings (#2093)
+
+commit f0e7cdd3392e91b427764abf1c9c30058a457143
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jun 27 12:49:12 2018 +0200
+
+    [smartptr] Remove class name repeated in subheadings (#2092)
+
+commit a92cdcb6ca8aa43e49a54d22f8760e9ca9cbaad7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jun 27 12:48:03 2018 +0200
+
+    [vector.cons] vector(const Allocator&) should be noexcept (#2182)
+
+    This fixes an oversight in the wording of
+    "N4258: Cleaning‐up noexcept in the Library",
+    which updated the overview, but not the description.
+
+commit f4a6f328137fa59bf3aa319eb4ccb743b2205dfc
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jun 26 19:06:44 2018 -0700
+
+    [alg.sorting] Fix grammar.
+
+commit de4ddf0a8fa164c7b451b6bb500c492681a7738c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jun 26 20:00:54 2018 -0700
+
+    [cpp.cond], [cpp.predefined], [support.limits.general] Add feature-test
+    macros from 2018-06 motions:
+
+    __has_cpp_attribute(assert)
+    __has_cpp_attribute(ensures)
+    __has_cpp_attribute(expects)
+    __cpp_explicit_bool
+    __cpp_nontype_template_parameter_class
+    __cpp_lib_atomic_ref
+    __cpp_lib_bit_cast
+    __cpp_lib_concepts
+    __cpp_lib_constexpr_swap_algorithms
+    __cpp_lib_list_remove_return_type
+
+    ... all with value 201806L.
+
+commit 1984951deba6caeb117300b198e349b0e9bf841c
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jun 26 18:24:56 2018 -0700
+
+    [meta.type.trans] Strike redundant and confusing note on type member of
+    basic_common_reference, and replace it with a clarifying description of
+    the primary template.
+
+commit a5a086fada4312ee1794a5d2cb65a7ce5ac284d4
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jun 26 17:51:24 2018 -0700
+
+    [meta.trans.other] Replace "(possibly cv) void" with just "cv void".
+
+    These two formulations mean the same thing.
+
+commit cc393db472ef7e89fa4e8bc8bcce6e44979efd5e
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jun 26 17:43:51 2018 -0700
+
+    [concept.strictweakorder] Fix grammar in note.
+
+commit 01f681dd376ec6285fae0253d21745999fd9557f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jun 26 14:50:39 2018 -0700
+
+    [concept.equalitycomparable] Remove note that the equality-preserving
+    nature of == implies that == is reflexive. This turns out to not quite
+    be justified by the normative rules.
+
+commit fbc2eef266332b8dea52718640ceca7cde9d6c1f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jun 25 18:25:06 2018 -0700
+
+    [concept.boolean] Reword satisfaction rules for Boolean to make them not
+    appear to depend on the "given" lvalues b1 and b2.
+
+commit d324da9c1ea4702dfb2d595390114d872f29089e
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jun 25 18:15:28 2018 -0700
+
+    [concept.destructible] Fix meaningless phrase "potentially-throwing,
+    even if non-throwing".
+
+    By definition, non-throwing is the opposite of potentially-throwing for
+    an exception-specification ([except.spec]p1).
+
+commit 4ac1f96f51c998846ce97e81c793484a52318357
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jun 25 17:34:27 2018 -0700
+
+    [concepts.equality] Add missing paragraph numbers, reorder implicit
+    expression variations in example for clarity and to fix overfull hbox.
+
+commit 60ae4bf7daae6802fefef5a5f32c1d2248a51334
+Author: Casey Carter <Casey@Carter.net>
+Date:   Fri Jun 22 20:28:23 2018 -0700
+
+    [concepts] There need be no "there need be no subsumption relationship"
+
+    ... the core language rules already imply it.
+
+commit 11b6f1844a7b43a232d55442f4af7f9ce20faa45
+Author: Casey Carter <Casey@Carter.net>
+Date:   Fri Jun 22 21:14:00 2018 -0700
+
+    [structure.requirements] Add paragraph explaining the typographical convention for requirement names
+
+commit bfaea046b5176152a86514a886a5b7ab66e4dffe
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Jun 20 09:39:06 2018 -0700
+
+    [rand.req.urng] Rework URBG requirements for clarity and simplicitly
+
+    ... by removing the redundance between the new concept and the "old" requirements.
+
+    Also fixup the reference in [rand.req.eng] to properly refer [rand.req.urng] instead of the requirements table. The table has been removed, and the reference should have been to the subclause in the first place to clearly incorporate the requirements outside of the table.
+
+commit def89125ccf441d2178e6159d6b9448f17045f6a
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Jun 20 11:21:43 2018 -0700
+
+    [meta.trans.other] Remove basic_common_reference requirement with no normative effect.
+
+    We already say that only T and U can be specialized. We do not need to
+    also say that TQual and UQual cannot be. Also clarify that users may
+    *partially* specialize basic_common_reference.
+
+commit 528d382ca9b350c3aece9a57e23a2560b7ba0651
+Author: Casey Carter <Casey@Carter.net>
+Date:   Tue Jun 19 16:31:00 2018 -0700
+
+    [meta.trans.other] Make style of common_type and common_reference consistent
+
+    ...by tagging the specification of common_reference with "Note C" and basic_common_reference "Note D".
+
+    Also remove the allowance to specialize basic_common_reference "if at least one template parameter in the specialization depends on a program-defined type"; it's redundant with "...pursuant to [namespace.std]". (This is consistent with `common_type`'s wording.)
+
+commit 2aa8b236c8afe09272fba8d0767fbc6552b301b5
+Author: Casey Carter <Casey@Carter.net>
+Date:   Tue Jun 19 16:06:03 2018 -0700
+
+    [structure.requirements] Rephrase para 8 for clarity
+
+commit d9c710c4f13c95d65f96d503bd45f11628fdf68a
+Author: Casey Carter <Casey@Carter.net>
+Date:   Mon Jun 18 06:55:44 2018 -0700
+
+    [concepts.general][library.general] Concepts constrain template arguments, not parameters
+
+commit a818d5bfb084da10818b830d210d8bb4312912e4
+Author: Casey Carter <Casey@Carter.net>
+Date:   Thu Jun 21 09:38:44 2018 -0700
+
+    [concepts.swappable] Correct example
+
+commit db9aee9ca04a192f32cd630cf3682d30c62a0bf7
+Author: Casey Carter <Casey@Carter.net>
+Date:   Tue Jun 19 15:34:43 2018 -0700
+
+    [customization.point.object][meta.trans.other] Replace "user-defined" added by P0898R3 with "program-defined"
+
+    ...to be consistent with the intent of LWG2139
+
+commit 03f3764a071dfe30ef1137435a88ea036ca65c1f
+Author: Casey Carter <Casey@Carter.net>
+Date:   Wed Jun 20 15:16:51 2018 -0700
+
+    [definitions] Redefine expression-equivalent per ISO directives
+
+    To be replaceable in context, and add a clarifying example.
+
+commit d119277cb8864be440a6e0445211c232e87f91a7
+Author: Casey Carter <Casey@Carter.net>
+Date:   Thu Jun 21 09:18:24 2018 -0700
+
+    [concepts] Rephrase ocurrences of "must"
+
+commit 16b35d651de53654321b584eba2c6c4e126eb7d8
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jun 22 18:08:26 2018 -0700
+
+    [depr.c.headers] Undo P0619R4's removal of synopses for <ccomplex>,
+    <cstdalign>, <cstdbool>, and <ctgmath>.
+
+    Instead, repurpose these to be synopses for <complex.h>, <stdalign.h>,
+    <stdbool.h>, and <tgmath.h>, and move them into [depr.c.headers].
+    Also introduce a synopsis for <iso646.h>.
+
+    This avoids three of these five headers being specified as equivalent to
+    a non-existent <cfoo> header, and the other two missing a synopsis.
+
+commit cf0749742b9318143505f9ffe2d4dabb5420d727
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jun 22 17:17:41 2018 -0700
+
+    [diff.cpp17.library] Fix description of how to adjust code for the
+    removal of <ccomplex> and <ctgmath>.
+
+commit fa04176c01dd10105eec6590407b2c76384f5c52
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jun 22 17:06:40 2018 -0700
+
+    [diff.cpp17.library] Fix list of new headers compared to C++17.
+
+commit 9e80b6c69467fb2fb146637e1f0fca8b7495250f
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jun 22 16:59:45 2018 -0700
+
+    [diff.cpp17.except] Fix Rationale to be a rationale.
+
+    "This was retained for one additional C++ standard to ease transition"
+    is not a rationale for removing the feature now.
+
+commit 043ee628bc8accbe7f1ac4dc2210e88186bc95a4
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jun 22 16:41:51 2018 -0700
+
+    [diff.cpp17.except] Add a note that there is no longer a way to write
+    code that is non-throwing in both C++20 and C++03.
+
+commit fd244b515387efde9fb08ffe183985a38e93d184
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jun 22 16:29:19 2018 -0700
+
+    [diff.cpp03.language.support] Remove change described in p1, which is no
+    longer a possible change.
+
+    It is not possible to write a global replacement operator new or
+    operator delete in C++20 with code that is also valid C++03, because
+
+    a) operator new must be declared 'throw(std::bad_alloc)' in C++03 and
+       must be declared with no exception specification in C++11 onwards,
+    and
+    b) operator delete must be declared 'throw()' in C++03 and must be
+       declared 'noexcept' in C++20 onwards.
+
+    Therefore there is no code that is valid in C++03 and C++20 and changes
+    meaning due to the change identified in this section.
+
+    Instead, expand [diff.cpp03.language.support]p2 to explain that the
+    affected programs are simply not valid in C++20.
+
+commit 3e80cd4c07563639a8ca55d41d704701ae6d0eb4
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Fri Jun 22 16:07:09 2018 -0700
+
+    [complex.special] Reorder defaulted complex copy constructor to
+    emphasize relationship between it and the converting constructors.
+
+commit 74539419429281072e1f8b787a0ce0dc2bb067db
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu Jun 21 20:09:23 2018 -0700
+
+    [atomics.ref] Reword introductory sentences to avoid overfull hbox.
+
+commit 3c21cfcfa1091a406d4b384e4677f0fa0e8ea75c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Mon Jun 11 19:10:53 2018 +0200
+
+    [alg.shift] Avoid undefined iterator arithmetic on ForwardIterator.
+    Avoid using the undefined concept BidirectionalIterator.
+
+commit 949892305c88abd7c2ecb15a77bde3222366733d
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Jun 11 23:43:22 2018 +0100
+
+    [structure.specifications] remove "implementation-defined" from example
+    mentioning [[expects]] and add cross-reference to [[expects]] attribute.
+
+commit 23c6b62f321d463792c54db38a89b335dc232f3e
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Jun 11 23:41:37 2018 +0100
+
+    [structure.specifications] replace "paragraph" with "element"
+
+commit 4aa23529058e5f17f74e663ff189a1548812e009
+Author: Jonathan Wakely <cxx@kayari.org>
+Date:   Mon Jun 11 23:37:31 2018 +0100
+
+    [res.on.required] replace "paragraph" with "element"
+
+commit 3b24b2dc75bd5b80d2c5fc1cb3fdb62ac3852d8d
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jun 19 17:13:17 2018 -0700
+
+    [diff.cpp17] Correct description of explicit(bool) compatibility.
+
+    Parenthesized names for explicit constructors and conversion functions
+    are still valid if the name doesn't immediately follow the explicit
+    keyword. Add an example using explicit(true) as a hint indicating how
+    to get the same effect.
+
+    Change affected subclauses from [dcl.fct] to the somewhat-more-precise
+    [class.ctor] and [class.conv.fct].
+
+commit 001a2011d172cce2784857a492e2c37e25ade7e9
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jun 18 18:19:39 2018 -0700
+
+    [dcl.attr.contract] Fix typeface of std::terminate in comment.
+
+commit 913c83a98735709462a49613f8993bca4042ed70
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 17 09:18:08 2018 +0200
+
+    [dcl.attr.contract] Move according to alphabetical sorting of headings
+
+commit 463ab8dc3726514b2adf8dcf6816262f58688da3
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 15 11:01:23 2018 +0200
+
+    [except.terminate] Clarify evaluation of a contract
+
+commit f2f60fd4c3f9810ae815a408e1fd3ac1462482c7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 15 10:53:18 2018 +0200
+
+    [temp.explicit] Remove redundant rules for contracts
+
+    given that [dcl.attr.grammar] already prohibits
+    attribute-specifier-seqs for an explicit instantiation.
+
+commit a7a0e115dbf5f149936a04f57b9dd3174c9efa6a
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 15 10:51:04 2018 +0200
+
+    [class.virtual] Fix comment in example
+
+commit ca0d62cc3d8c397d843fe1e1ae4a80f8fa389587
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 15 10:42:25 2018 +0200
+
+    [dcl.attr.contract] Fix sentence defining violation handler
+
+commit 0cd3f3dc072d736b4e8572311918bdccbb91e1f7
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 15 10:33:54 2018 +0200
+
+    [dcl.attr.contract] Clarify evaluation of non-checked contracts
+
+commit 2930dc55b0c5573aad90c22e1909f98bb9bec4c2
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 15 10:18:18 2018 +0200
+
+    [dcl.attr.contract] Permit modifications of temporaries within the predicate.
+
+commit 87c3c20540b99708b02ce3dfc6a792a3fea454aa
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 15 10:17:19 2018 +0200
+
+    [dcl.attr.contract] Clarify that assertions may apply to a null statement
+
+commit 072f42df7b298c3677b2a1e8f1a4687d1e005ffc
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 15 10:10:53 2018 +0200
+
+    [dcl.attr.contract] Clarify rules on std::contract_violation
+
+commit 77579d2f9527552820dfc667867589da12adceda
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 15 10:08:09 2018 +0200
+
+    [dcl.attr.contract] Predicates of a contract are potentially evaluated,
+
+    as per the definition in [basic.def.odr], so turn the
+    redundant normative statement into a note.
+
+commit da24c5df270fc17a82b6767aef5baee94fba4a45
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Fri Jun 15 09:43:43 2018 +0200
+
+    [basic.def.odr] Rephrase ODR rule for contracts
+
+commit 0fc2af6bbe05e16feb03e8f24651ea12e8a6997c
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 10 22:53:26 2018 +0200
+
+    [dcl.attr.contract] Reorder paragraphs for more coherence.
+
+    Also move rules on virtual functions to [class.virtual].
+    Rephase assertion checking along pre/postcondition checking.
+
+commit 42019fd86775859393e7e5edc7e8d4c2e64c8019
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 10 22:24:18 2018 +0200
+
+    [basic.def.odr] Rephrase build level and continuation mode requirements
+
+commit ac603143816388fa8fa12a8fb0802130b6643884
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 10 22:17:23 2018 +0200
+
+    [dcl.attr.contract] Rephrase comments in examples
+
+commit 19d07dec4cbe5ae86eb6231eb833d166c5939faf
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 10 22:14:46 2018 +0200
+
+    [except.terminate] Add contract violation with continuation mode off
+
+commit f28517ab52f7bf80879a7883fe08bb97020f80da
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Sun Jun 10 21:17:50 2018 +0200
+
+    [dcl.attr.contract] Avoid duplication of 'renaming' in enumeration
+
+commit a8b8e534a7a5235157333f6a9f64c339e48e0e86
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Mon Jun 11 15:56:16 2018 -0700
+
+    [basic.stc.dynamic.deallocation] Remove confusing note.
+
+    This note is only correct due to subtleties of later wording
+    (particularly that a destroying operator delete cannot be a function
+    template). Correcting it results in it simply duplicating existing
+    normative rules and not adding anything. So remove it instead.
+
+commit e4f579e421dac17ff36f98b2211d143991de7850
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jun 13 09:16:17 2018 +0200
+
+    [temp.arg.nontype] Fix example involving string literal
+
+    P0732R2 contained some changes to this section that were missing
+    explicit markup; apply those changes too. Also fix missing definition of
+    operator<=> in class type used as type of non-type template parameter.
+
+commit 5cca3b5015491a6c8b5d1d63f651073940d1145e
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jun 13 08:34:52 2018 +0200
+
+    [dcl.fct] Move function definition rule to [dcl.fct.def.general]
+
+    This is the rule that requires complete non-abstract
+    types function parameter or return types.
+
+commit b39b44b32394384edcc8f7f682274fbffd22f067
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Wed Jun 13 08:28:26 2018 +0200
+
+    [temp.deduct] Forming an array of abstract class type is not deduction failure
+
+commit ba6cd4c525371eb98c60a025da21e5ca813b4a94
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Jun 14 21:48:23 2018 +0100
+
+    [cpp.subst] Reword paragraph to simplify the logical structure and avoid ambiguous references.
+
+commit 4ce05424a8774e13b9958eb9cb9165da5b19edb0
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jun 12 16:27:40 2018 -0700
+
+    [depr.capture.this] Reorder so the order of Annex D matches the order of the main text
+
+commit 628a32db863ac10fe0fb4c45d6975a50f5497acf
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Tue Jun 12 16:26:37 2018 -0700
+
+    [depr.capture.this] Replace "can" with "may".
+
+    This wording is describing permission, not capability, so should use "may".
+
+commit 5274b2ee4c558d39012a34d104be0d2139115c00
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Fri Jun 15 14:31:14 2018 +0100
+
+    [temp.deduct] Fixes from editorial review of CWG2293:
+
+    * Use "not valid" rather than "invalid", since only "valid" has been defined.
+    * Add an "otherwise" to improve flow.
+
+commit 0e771884acfdcb1dc693ef654f34cf717986f803
+Author: Jonathan Wakely <github@kayari.org>
+Date:   Fri Jun 8 08:23:25 2018 +0100
+
+    [time.zone.db.remote] replace "this section" with "this subclause" (#2103)
+
+commit b9c5272c78fb312883cb548219b7fd2cb44280c7
+Author: Thomas Köppe <tkoeppe@google.com>
+Date:   Thu Jun 7 23:24:37 2018 +0200
+
+    [cfenv.syn] Add "optional" markers for macros from the C library that are optional (as defined by C)
+
+commit aa77121b3aa9bc566b8d2e428cd21a28493ce57e
+Author: Alberto Barbati <2210776+iaanus@users.noreply.github.com>
+Date:   Thu Jun 7 21:39:51 2018 +0200
+
+    [dcl.attr.likelihood] Fix error in example
+
+commit fbee1d521da91a798d81ecc09f110a0946239630
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Thu Jun 7 21:36:42 2018 +0200
+
+    [views.general] Remove redundant introduction for span. (#2062)
+
+commit 069a179a0d54cad4b3d00f00eae532c827786894
+Author: Jens Maurer <Jens.Maurer@gmx.net>
+Date:   Tue Mar 27 14:41:13 2018 +0200
+
+    [cmp.syn] Rename to [compare.syn] to match the header name
+
+commit 8a0060d0dcda8c63a2c432016bd038c75a8de9a1
+Author: Marc Mutz <marc.mutz@kdab.com>
+Date:   Thu Jun 7 03:34:12 2018 +0200
+
+    [list.modifiers, forward.list.modifiers] Add missing 'to' in 'referred [to] by' (#2100)
+
+commit 57de3af9d24037d60d996b255c1ded8ee65387d2
+Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
+Date:   Wed May 30 00:18:13 2018 -0700
+
+    [comparisons] Fix a typo in the note for `std::less`. (#2089)
+
+commit 61b6c21f218e3cbb9d15426975f1a26d8b72a7fe
+Author: Richard Smith <richard@metafoo.co.uk>
+Date:   Thu May 10 14:40:22 2018 -0700
+
+    [class.expl.init] Fix example to account for guaranteed copy omission.
+
diff --git a/papers/n4764.md b/papers/n4764.md new file mode 100644 index 0000000000..d4b7fddd1a --- /dev/null +++ b/papers/n4764.md @@ -0,0 +1,1210 @@ +# N4764 Editors' Report -- Programming Languages -- C++ + +2018-07-07 +Richard Smith (editor) (Google Inc) +Thomas Köppe (co-editor) (Google DeepMind) +Jens Maurer (co-editor) +Dawn Perchik (co-editor) (Bright Side Computing, LLC) +`` + +## Acknowledgements + +Special thanks to Casey Carter for supplying a pull request to merge +[P0898R3](http://wg21.link/p0898r3) (LWG motion 28), +and working with us on editorial cleanups within the +12 pages of added text. + +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 + + * [N4762](http://wg21.link/n4762) is the current working draft for C++20. It replaces [N4750](http://wg21.link/n4750). + * N4764 is this Editors' Report. + +## Motions incorporated into working draft + +### Core working group motions + +CWG motion 1: [Core issue resolutions](http://wg21.link/p1113r0) for 6 issues in "ready" status applied: + + * [2254](http://wg21.link/cwg2254) Standard-layout classes and bit-fields + * [2293](http://wg21.link/cwg2293) Requirements for *simple-template-id* used as a *class-name* + * [2294](http://wg21.link/cwg2294) Dependent `auto` static data members + * [2321](http://wg21.link/cwg2321) Conditional operator and cv-qualified class prvalues + * [2322](http://wg21.link/cwg2322) Substitution failure and lexical order + * [2339](http://wg21.link/cwg2339) Underspecified template arguments in structured bindings + +CWG motion 2: [Core issue resolutions](http://wg21.link/p1114r0) for 6 issues in "tentatively ready" status applied: + + * [2233](http://wg21.link/cwg2233) Function parameter packs following default arguments + * [2249](http://wg21.link/cwg2249) *identifier*s and *id-expression*s + * [2285](http://wg21.link/cwg2285) Issues with structured bindings + * [2351](http://wg21.link/cwg2351) `void{}` + * [2356](http://wg21.link/cwg2356) Base class copy and move constructors should not be inherited + * [2359](http://wg21.link/cwg2359) Unintended copy initialization with designated initializers **(not a DR)** + +CWG motion 3: [P0806R2 "Deprecate implicit capture of `this` via `[=]`"](http://wg21.link/p0806r2) + +CWG motion 4: [P1042R1 "`__VA_OPT__` wording clarifications"](http://wg21.link/p1042r1) + +CWG motion 5: [P0929R2 "Checking for abstract class types"](http://wg21.link/p0929r2) applied, resolving 2 core issues: + + * [1640](http://wg21.link/cwg1640) Array of abstract instance of class template + * [1646](http://wg21.link/cwg1646) *decltype-specifier*s, abstract classes, and deduction failure + +CWG motion 6: [P0732R2 "Class types in non-type template parameters"](http://wg21.link/p0732r2) + +CWG motion 7 was not approved + +CWG motion 8: [P1025R1 "Update the reference to the Unicode standard"](http://wg21.link/p1025r1) + +CWG motion 9: [P0528R3 "The curious case of padding bits, featuring atomic compare-and-exchange"](http://wg21.link/p0528r3) + +CWG motion 10: [P0722R3 "Efficient sized delete for variable sized classes"](http://wg21.link/p0722r3) + +CWG motion 11: [P1064R0 "Allowing virtual function calls in constant expressions"](http://wg21.link/p1064r0) + +CWG motion 12: [P1008R1 "Prohibit aggregates with user-declared constructors"](http://wg21.link/p1008r1) + +CWG motion 13: [P1120R0 "Consistency improvements for `<=>` and other comparison operators"](http://wg21.link/p1120r0) + +CWG motion 14: [P0542R5 "Contract-based programming"](http://wg21.link/p0542r5) **see below** + +CWG motion 15: [P0941R2 "Feature-test macros"](http://wg21.link/p0941r2) **see below** + +CWG motion 16: [P0892R2 "`explicit(bool)`"](http://wg21.link/p0892r2) + +### Library working group motions + +LWG motions 1-5 apply to the Parallelism TS + +LWG motions 6 and 7 apply to the Reflection TS + +LWG motions 8 and 9 apply to the Coroutines TS + +LWG motion 10 applies to the Networking TS + +LWG motion 11: [Library issue resolutions](http://wg21.link/p1082r0) for 14 issues in "Ready" and "Tentatively Ready" status applied: + + * [2139](http://wg21.link/lwg2139) What is a user-defined type? **see below** + * [2970](http://wg21.link/lwg2970) Return type of `std::visit` misspecified + * [3058](http://wg21.link/lwg3058) Parallel `adjacent_difference` shouldn't require creating temporaries + * [3062](http://wg21.link/lwg3062) Unnecessary `decay_t` in `is_execution_policy_v` should be `remove_cvref_t` + * [3067](http://wg21.link/lwg3067) `recursive_directory_iterator::pop` must invalidate + * [3074](http://wg21.link/lwg3074) Non-member functions for `valarray` should only deduce from the `valarray` + * [3076](http://wg21.link/lwg3076) `basic_string` CTAD ambiguity + * [3079](http://wg21.link/lwg3079) [LWG 2935](http://wg21.link/lwg2935) forgot to fix the `existing_p` overloads of `create_directory` + * [3080](http://wg21.link/lwg3080) Floating point `from_chars` pattern specification breaks round-tripping + * [3083](http://wg21.link/lwg3083) What should `ios::iword(-1)` do? + * [3094](http://wg21.link/lwg3094) [time.duration.io]p4 makes surprising claims about encoding + * [3100](http://wg21.link/lwg3100) Unnecessary and confusing "empty span" wording + * [3102](http://wg21.link/lwg3102) Clarify `span` `iterator` and `const_iterator` behavior + * [3104](http://wg21.link/lwg3104) Fixing `duration` division + * Resolution of [3071](http://wg21.link/lwg3071) (`read_until` still refers to + "input sequence") from P1082R0 was not part of this motion, as it applies to + the Networking TS. + +LWG motion 12: [Library issue resolution](http://wg21.link/p0475r1) for 1 issue applied: + + * [2511](http://wg21.link/lwg2511) Guaranteed copy elision for piecewise construction + +LWG motion 13: [P0476R2 "Bit-casting object representations"](http://wg21.link/p0476r2) + +LWG motion 14: [P0788R3 "Standard library specification in a concepts and contracts world"](http://wg21.link/p0788r3) + +LWG motion 15 was not approved + +LWG motion 16: [P0458R2 "Checking for existence of an element in associative containers"](http://wg21.link/p0458r2) + +LWG motion 17: [P0759R1 "`fpos` requirements"](http://wg21.link/p0759r1) + +LWG motion 18: [P1023R0 "`constexpr` comparison operators for `std::array`"](http://wg21.link/p1023r0) + +LWG motion 19: [P0769R2 "Add `shift` to ``"](http://wg21.link/p0769r2) + +LWG motion 20: [P0887R1 "The `identity` metafunction"](http://wg21.link/p0887r1) + +LWG motion 21: [P0879R0 "`constexpr` for `swap` and `swap`-related functions"](http://wg21.link/p0879r0) applied, resolving 1 issue: + + * [2800](http://wg21.link/lwg2800) `constexpr` `swap` + +LWG motion 22: [P0758R1 "Implicit conversion traits and utility functions"](http://wg21.link/p0758r1) + +LWG motion 23: [P0556R3 "Integral power-of-2 operations"](http://wg21.link/p0556r3) + +LWG motion 24: [P0019R8 "`atomic_ref`"](http://wg21.link/p0019r8) + +LWG motion 25: [P0935R0 "Eradicating unnecessarily explicit default constructors from the standard library"](http://wg21.link/p0935r0) + +LWG motion 26: [P0646R1 "Improving the return value of `erase`-like algorithms"](http://wg21.link/p0646r1) + +LWG motion 27: [P0619R4 "Reviewing deprecated facilities of C++17 for C++20"](http://wg21.link/p0619r4) **see below** + +LWG motion 28: [P0898R3 "Standard library concepts"](http://wg21.link/p0898r3) **see below** + +## Notable editorial changes + +### CWG motion 14 + +Subclause structure and paragraph order of [dcl.attr.contracts] was reworked. +Several normatively-redundant statements were converted to notes or removed. + +### CWG motion 15 + +Multiple papers moved at this meeting included suggested feature-test macros. +However, these were not presented as editing instructions, because we did not +have feature-test macros in the standard wording yet. After consultation with +CWG and LWG, the following feature test macros have been added in addition to +those listed in CWG motion 15 (all with value `201806L`): + + * `__has_cpp_attribute(assert)` + * `__has_cpp_attribute(ensures)` + * `__has_cpp_attribute(expects)` + * `__cpp_explicit_bool` + * `__cpp_nontype_template_parameter_class` + * `__cpp_lib_atomic_ref` + * `__cpp_lib_bit_cast` + * `__cpp_lib_concepts` + * `__cpp_lib_constexpr_swap_algorithms` + * `__cpp_lib_list_remove_return_type` + +### CWG motions 16 and 12 + +CWG motion 16 would have us change wording that was deleted by CWG motion 12. +The requested change in CWG motion 16 (from teletype "`explicit`" to body font "explicit") +was ignored. + +### LWG motion 11: issue 2139 + +The underlying text has changed between the drafting of the resolution to this +issue and its application. We believe every requested edit has been applied; +however, an additional use of "user-defined type" has been added to +[namespace.std] that should likely also have been covered by this wording. +It has *not* been changed. + +### LWG motions 13 and 23 + +These motions both introduce a `` header, but the organizational structure +suggested by motion 23 doesn't make sense for the functionality +added by motion 13. +The wording of motion 23 has been rearranged to fit into +the structure established by motion 13. + +### LWG motions 16 + +Added the new `contains` member function for associative containers to the list +of member function templates that do not participate in overload resolution +unless the comparator is transparent, after consultation with LWG. + +### LWG motions 19 and 21 + +LWG motion 19 adds a `shift_right` algorithm to `` +as a non-`constexpr` function template. + +LWG motion 21 instructs that we mark +all non-parallel algorithms in `` +as `constexpr`. +Naturally, however, +its proposed wording change does not list the `shift_right` algorithm. +After consultation with LWG, `shift_right` has been marked `constexpr` +to satisfy the intent of LWG motion 21. + +### LWG motion 27 + +Synopses for +``, +``, +``, and +`` +were not removed; +instead, they have been repurposed as synopses for +``, +``, +``, and +``. +(The latter used to be defined in terms of the former, +but can no longer be specified in that way.) +Also introduced a synopsis for ``. + +### LWG motion 28 + +Clause labels shortened and simplified throughout. + +The single-item clauses [concept.movable], [concept.copyable], +[concept.semiregular], and [concept.regular] have been merged into their +parent, [concepts.object]. + +The single-item clauses [concept.signed.int] and [concept.unsigned.int] +have been merged into their parent, [concept.integral]. + +Legacy concept names changed from *Cpp98Something* to *Cpp17Something*. Many of +these concepts did not exist in C++98 (which in any case was revoked and +replaced by C++03). + +Reworked "uniform random bit generator" requirements to describe them in terms +of the `UniformRandomBitGenerator` concept. + +Removed "there need be no subsumption relationship" wording that is already +implied by the core language rules for concepts. + +### Editorial paper [P1076R1 "Clause reorganization"](http://wg21.likn/p1076r1) + +The claue reorganization described in P1076R1 and discussed at the WG21 +Rapperswil meeting has been applied to the working draft, with the following +modifications: + +[class.copy] was left containing only two paragraphs of text, neither of which +had any normative impact. It has been removed. + +The top-level subclauses of [algorithms] have been reordered to make the +description of the `` header fit better into its structure. + +Several paragraphs of [class] describing various properties of classes have +been moved into a new subclause [class.prop] "Properties of clases". + +### Removal of single-item subclauses + +The single-item subclauses +[move.iter.op=] and +[move.iter.op.const] +have been merged into [move.iter.cons]. + +The single-item subclauses +[move.iter.op.star], +[move.iter.op.ref], and +[move.iter.op.index] +have been merged into [move.iter.elem]. + +The single-item subclauses +[move.iter.op.+], +[move.iter.op.-], +[move.iter.op.incr], +[move.iter.op.+=], +[move.iter.op.decr], and +[move.iter.op.-=] +have been merged into [move.iter.nav]. + +The now-empty [move.iter.ops] has been removed. + +## Minor editorial fixes + +A log of editorial fixes made to the working draft since N4750 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/n4750...n4762). + + commit afe115acc28e33e48e2ece9f850820d6faa51757 + Author: Jens Maurer + Date: Fri Jul 6 10:47:19 2018 +0200 + + [class] Introduce a subheading 'Properties of classes'. + + commit d3f80a4a994a66cc8148a6031d29182aad4f16f6 + Author: Jens Maurer + Date: Sat Jul 7 00:49:56 2018 +0200 + + [namespace.udecl] Demote normative duplication to notes (#1976) + + The effects of using-declarations naming member functions + are discussed in other parts of the standard. + The effects of initializing with an inherited constructor are + discussed elsewhere, too. + + commit 9459c137f138f903d670e6689b3963f0a3f7d083 + Author: Jens Maurer + Date: Fri Jul 6 10:40:09 2018 +0200 + + [time.point,time.duration] Remove class name repeated in subheadings (#2249) + + commit 56c599f71e8a9cfe77233e5dcd77ccfe72d81af8 + Author: Richard Smith + Date: Thu Jul 5 20:22:47 2018 -0700 + + [algorithm.syn] Reorder after [algorithms.requirements] and + [algorithms.parallel], which apply to both and . + + commit 8806777151719da531aae976c46f98c485bf0580 + Author: Jens Maurer + Date: Wed Jul 4 08:39:53 2018 +0200 + + [algorithms] Integrate requirements from [numeric.ops]. + + commit e8d3d7029c5be1494016bc03e0004d0e9eeaa8cd + Author: Jens Maurer + Date: Wed Jul 4 08:25:30 2018 +0200 + + Remove [class.copy] and adjust cross-references pointing there. + + The normative statements that used to be contained in + [class.copy] were redundant with [dcl.init] and [over.ass]. + + commit 006fb15de62c93b6e3de3d32648f276c9ec70181 + Author: Jens Maurer + Date: Wed Jul 4 00:29:28 2018 +0200 + + [class.derived,class.access,special] Move into [class], as appropriate. + + P1076R1: Editorial clause reorganization + + commit 3c580cd204fde95a21de1830ace75d14d429f845 + Author: Jens Maurer + Date: Wed Jul 4 00:07:05 2018 +0200 + + [dcl.decl] Move into [dcl.dcl] as appropriate. + + P1076R1: Editorial clause reorganization + + commit 40907944b775e4da980b69565dcbaa4bd494d347 + Author: Jens Maurer + Date: Wed Jul 4 00:00:51 2018 +0200 + + [namespace.udecl] Move one level up + + P1076R1: Editorial clause reorganization + + commit f87c7fd1d9a258d043b7b22fb13ce6bdf6931a28 + Author: Jens Maurer + Date: Tue Jul 3 23:54:36 2018 +0200 + + [numeric.ops] Move into [algorithms], after [alg.sorting] + + P1076R1: Editorial clause reorganization + + commit 40719643c5f237aecf0136a001cce1d85ceaaf59 + Author: Jens Maurer + Date: Tue Jul 3 23:48:00 2018 +0200 + + [localization] Move to before [input.output] + + P1076R1: Editorial clause reorganization + + commit a41eef0a98e9727ca85ff12c99b27209969a62b8 + Author: Jens Maurer + Date: Tue Jul 3 23:37:46 2018 +0200 + + [time.general] Add summary table + + commit 63603768789149c9b46bac7e810ddfb618e8eefe + Author: Jens Maurer + Date: Tue Jul 3 23:30:45 2018 +0200 + + [time] Promote to a top-level clause. + + P1076R1: Editorial clause reorganization + + commit 006a9380cfe9e00bcee9b03884b3b4bf57bf6fa2 + Author: Jens Maurer + Date: Tue Jul 3 23:22:05 2018 +0200 + + [conv] Move as a subclause into [expr], immediately before [expr.arith.conv] + + P1076R1: Editorial clause reorganization + + commit 70adb738f6edbc0697d1f26c72040d6b3a971421 + Author: Hubert Tong + Date: Thu Jul 5 16:22:22 2018 -0400 + + [intro.defs] Use https in hyperlink URL; see Directives, Part 2:2018 (#2248) + + commit 3fe46c716367d6e367b4c5acff344bce3f2a5cd2 + Author: Jonathan Wakely + Date: Fri May 11 11:53:45 2018 +0100 + + [class] Reformat paragraph defining standard-layout class + + Move the note before the definition of M(X). + Use a nested list for the definition of M(X). + Move the example to a new paragraph. + + commit 0cac48775c1b1db4038cc0e456ccef81d5dd5fdc + Author: timsong-cpp + Date: Mon Jul 2 17:13:53 2018 -0400 + + [concepts.{lang,compare,callable}.general] Replace "section" with "subclause". + + commit 9db2f62e966224e8e749913871771dd4ac886c78 + Author: Jens Maurer + Date: Fri Jun 15 09:08:21 2018 +0200 + + [basic.start,except] Harmonize references to std::terminate + + commit 3846e6ba6592099145655420e3b88c6c874cd5fc + Author: Jens Maurer + Date: Fri Jun 1 10:05:58 2018 +0200 + + [over.match.viable] Fix cross-reference to satisfaction of constraints + + commit 61e272c36350786e8b3fa1662efb0a8b9484cdd5 + Author: Jens Maurer + Date: Thu Jun 14 11:08:25 2018 +0200 + + [dcl.init.ref] Avoid use of 'underlying type' for references + + commit c56870954b48305df89133a80e6ab8a21a0a90e9 + Author: Johel Ernesto Guerrero Peña + Date: Mon Jul 2 17:10:38 2018 -0400 + + [temp.constr.constr], [iterator.requirements.general], [re.results.size] Replace "section" with "subclause" + + commit f3b625826ae894613c9ec47bd4e1874fc46e71d4 + Author: timsong-cpp + Date: Mon Jul 2 17:05:50 2018 -0400 + + [concepts.object] Dissolve single-item subclauses. (#2240) + + The following subclause headings have been removed: + + [concept.movable] + [concept.copyable] + [concept.semiregular] + [concept.regular] + + The content for these former subclauses now resides in the parent subclause, [concepts.object]. + + commit 75c9148c3d810a825765aef9f04f9689f678f7bf + Author: Johel Ernesto Guerrero Peña + Date: Sat Jun 16 15:57:32 2018 -0400 + + [re.general] Refer to table as done in the other clauses + + commit 2fdaf88fcffd65ea2ccc4e032e288c74ac94bb7d + Author: Richard Smith + Date: Mon Jul 2 11:52:45 2018 -0700 + + [basic.lookup.unqual] Finesse "class definition" footnote to avoid + saying that a class definition is one of two components of the + definition of a class. + + commit 4d757ab4026f2b1af37ea1f3c6fb8fbd4c83f0dc + Author: Jens Maurer + Date: Sat Jun 30 00:23:57 2018 +0200 + + [class.mem] Define complete-class context + + and use it, instead of having separate redundant lists + in [basic.scope.class] and [basic.lookup.unqual]. + + commit ade8b020efbfa8fd220d1ed7f230850f2849d593 + Author: S. B. Tam + Date: Tue Jul 3 02:32:45 2018 +0800 + + [expr.prim.id.{un,}qual] A structured binding name is an lvalue (#2234) + + Fix wording here to match corresponding wording in [dcl.struct.bind]. + + commit 809a034ac0428dc71d3b07bb15c39a1131d2e3f8 + Author: Michael Adams + Date: Mon Jul 2 11:30:48 2018 -0700 + + [class.copy.elision] Fix typo that accidentally makes example ill-formed + + commit 61b25c662399e7ebd126ee6771126aa29fed407e + Author: timsong-cpp + Date: Sat Jun 30 05:27:09 2018 -0400 + + [{i,o}{string,f}stream.cons] Remove unmatched parenthesis (#2233) + + commit 0420f57904322da8adc32890687dc914d5c06edc + Author: Jens Maurer + Date: Tue Jun 19 11:23:54 2018 +0200 + + [dcl.attr.contract] Introduce subheadings and reorder paragraphs to fit + + commit 492e6a79cd4b36488c248771b73b46ba54ec27a6 + Author: Johel Ernesto Guerrero Peña + Date: Wed Jun 27 21:18:27 2018 -0400 + + [variant.get] Consistently place comma after "otherwise" + + commit 5326a0d1311682568eccd19b1f8c2512091a2a53 + Author: Jens Maurer + Date: Thu Jun 28 12:42:25 2018 +0200 + + [input.iterators,fs.rec.dir.itr.members] Disambiguate phrasing for previous value of iterators + + commit 2f5d2cbcd69c0cb63bad481f44d32082dd68ea6c + Author: Jens Maurer + Date: Thu Jun 28 23:54:24 2018 +0200 + + [depr.locale.stdcvt.req] Add normative references for encoding forms + + commit 69d7e1ffeed2187c1986f727882e65890c6dfa0f + Author: Jens Maurer + Date: Fri Jun 29 00:08:44 2018 +0200 + + [optional] Move requirements from header synopsis to class template + + commit 6116910802836c517ecde9237b6ffabcdafc26cf + Author: Jens Maurer + Date: Fri Jun 29 00:15:09 2018 +0200 + + [basic.fundamental] Add definition of 'fundamental type' + + commit b65061ee7d81079e72b2467ac9307ba9a24aaf00 + Author: Jens Maurer + Date: Fri Jun 29 13:41:11 2018 +0200 + + [expr.prim.lambda,depr.capture.this] Replace 'lambda expression' + + with the grammar term 'lambda-expression'. + Also remove the unused definition of 'local lambda expression'. + + commit 354fa005c1b8ad55ddd1bca31bf4f8bef67db46e + Author: Jens Maurer + Date: Fri May 25 10:37:36 2018 +0200 + + [dcl.init,over.match.ctor] Clarify copy-initialization for empty arguments. + + Also turn the enumeration of direct-initialization cases into + a bulleted list, referring to grammar non-terminals. + + commit 69259f9d29a571233908c4f9be5afc9b98e9a2e3 + Author: Jens Maurer + Date: Fri May 25 01:14:17 2018 +0200 + + Drop redundant 'expression' + + when calling out a value category. + + commit 09f1354234154602dee9a0afc12f0b160bf455ea + Author: Richard Smith + Date: Fri Jun 29 13:59:12 2018 -0700 + + [dcl.attr.contract] Fix mention of odr-use of a parameter value to talk + about odr-use of the parameter instead; values can't be odr-used. + + As agreed on the core reflector. + + commit 45fa09c5e38057571284c3eda52aa479afa0f3cb + Author: Jens Maurer + Date: Fri Jun 29 17:38:17 2018 +0200 + + [temp.dep] Fix typo 'An expressions...' (#2181) + + commit 50a00f2776122a1328d29332f45e3ec20ee6d0fb + Author: Jens Maurer + Date: Fri Jun 29 00:53:00 2018 +0200 + + [lex] Cite ISO/IEC 10646 correctly (#2226) + + commit 6f6a5dd6de12968f447940049d7fbf447e0ccf9f + Author: Jens Maurer + Date: Tue May 8 13:29:32 2018 +0200 + + [atomics.types.operations] Avoid inappropriate use of 'underlying type' + + commit 35e17ec6e2f702be4c31fd99c058404223a865da + Author: Casey Carter + Date: Thu Jun 28 12:28:20 2018 -0700 + + [algorithm.syn] Relocate the "partitions" algorithms (#2219) + + Move the synopsis for the "partitions" algorithms between the "binary_search" family and the "merge" family, to agree with the order of the detailed specifications as reordered by #1245. + + commit 03e97ca6af73a842d38d40977a2630b0c978eade + Author: Jens Maurer + Date: Thu Apr 19 23:12:20 2018 +0200 + + [temp.arg.explicit,temp.mem] Clarify note about explicit template arguments + + for conversion function templates and constructor templates. + + commit cdad8c27d822e5aec90b86a6e72e6f093d204924 + Author: Jens Maurer + Date: Tue Apr 3 23:33:29 2018 +0200 + + [move.iterators] Dissolve single-item subclauses. + + commit 1f9524d9b2a2ec95e7b48ec82ff9782e2b79d413 + Author: Thomas Köppe + Date: Wed Jun 27 22:42:53 2018 +0100 + + [support.limits.general] Fix typo: '' should be '' + + commit e0d78d373e975ccbc7cd59d5b7292c48f920b959 + Author: Alisdair Meredith + Date: Wed Jun 27 17:33:20 2018 -0400 + + [span.overview] Fix reverse_iterator for span (#2112) + + There is a common convention to omit 'std::' when not strictly needed, + other than for 'std::move' and 'std::forward'. A third case is for + 'reverse_iterator' and 'const_reverse_iterator' type aliases inside a + class definition, as the leading 'reverse_iterator' type alias hides + the 'std' version from the 'const_reverse_iterator' definition, and + subsequently fails to compile. This patch restore the class definition + to a safely copy/pastable state. + + An additional review indicated this convention has been applied correctly + for every othert potential occurrence in the library. + + commit 33e8e2b3c5c2ae9e53ed656f7e3dfe874e55ede3 + Author: Casey Carter + Date: Wed Jun 27 14:32:34 2018 -0700 + + [output.iterators] Strike useless sentence from note (#2083) + + There's no such thing as an "insert pointer," and the rest of this sentence isn't much better. + + commit fe3f46b976c8c19336f0007625fe3e487827ca55 + Author: Arthur O'Dwyer + Date: Wed Jun 27 12:12:45 2018 -0700 + + Harmonize phrasings of "this destructor is trivial". (#2191) + + Inspired by P0602 https://lichray.github.io/trivially_variant.html + Zhihao suggested that we harmonize "trivially destructible" + wording across the rest of the Standard. + + commit 14809d0b4b27395ea407734d00d0f6dc9c7b0c05 + Author: Jens Maurer + Date: Wed Jun 27 21:04:50 2018 +0200 + + [expr.spaceship] Fix typo for std::strong_equality::nonequal (#2216) + + commit 2954bfccb653504279f101cf1d8c7f9fb96947ff + Author: Sergey Zubkov + Date: Wed Jun 27 15:03:49 2018 -0400 + + [diff.cpp17.depr] Fix typo from P0619R4 (#2217) + + In the paper, "raw_memory_iterator" was meant to say "raw_storage_iterator". + + commit 264839261e3d0b0cb66415f2c1755d1f84d2cb3d + Author: timsong-cpp + Date: Wed Jun 27 06:51:41 2018 -0400 + + [istreambuf.iterator.proxy] correct title and remove default template argument (#2078) + + This is a class, not a class template. Also, the default template argument is 1) redundant and 2) ill-formed for violating [temp.param]p12. + + commit e6794e6f167db93a519564d5fc986309d194e140 + Author: Jens Maurer + Date: Wed Jun 27 12:49:39 2018 +0200 + + [syserr] Remove class name repeated in subheadings (#2093) + + commit f0e7cdd3392e91b427764abf1c9c30058a457143 + Author: Jens Maurer + Date: Wed Jun 27 12:49:12 2018 +0200 + + [smartptr] Remove class name repeated in subheadings (#2092) + + commit a92cdcb6ca8aa43e49a54d22f8760e9ca9cbaad7 + Author: Jens Maurer + Date: Wed Jun 27 12:48:03 2018 +0200 + + [vector.cons] vector(const Allocator&) should be noexcept (#2182) + + This fixes an oversight in the wording of + "N4258: Cleaning‐up noexcept in the Library", + which updated the overview, but not the description. + + commit f4a6f328137fa59bf3aa319eb4ccb743b2205dfc + Author: Richard Smith + Date: Tue Jun 26 19:06:44 2018 -0700 + + [alg.sorting] Fix grammar. + + commit de4ddf0a8fa164c7b451b6bb500c492681a7738c + Author: Richard Smith + Date: Tue Jun 26 20:00:54 2018 -0700 + + [cpp.cond], [cpp.predefined], [support.limits.general] Add feature-test + macros from 2018-06 motions: + + __has_cpp_attribute(assert) + __has_cpp_attribute(ensures) + __has_cpp_attribute(expects) + __cpp_explicit_bool + __cpp_nontype_template_parameter_class + __cpp_lib_atomic_ref + __cpp_lib_bit_cast + __cpp_lib_concepts + __cpp_lib_constexpr_swap_algorithms + __cpp_lib_list_remove_return_type + + ... all with value 201806L. + + commit 1984951deba6caeb117300b198e349b0e9bf841c + Author: Richard Smith + Date: Tue Jun 26 18:24:56 2018 -0700 + + [meta.type.trans] Strike redundant and confusing note on type member of + basic_common_reference, and replace it with a clarifying description of + the primary template. + + commit a5a086fada4312ee1794a5d2cb65a7ce5ac284d4 + Author: Richard Smith + Date: Tue Jun 26 17:51:24 2018 -0700 + + [meta.trans.other] Replace "(possibly cv) void" with just "cv void". + + These two formulations mean the same thing. + + commit cc393db472ef7e89fa4e8bc8bcce6e44979efd5e + Author: Richard Smith + Date: Tue Jun 26 17:43:51 2018 -0700 + + [concept.strictweakorder] Fix grammar in note. + + commit 01f681dd376ec6285fae0253d21745999fd9557f + Author: Richard Smith + Date: Tue Jun 26 14:50:39 2018 -0700 + + [concept.equalitycomparable] Remove note that the equality-preserving + nature of == implies that == is reflexive. This turns out to not quite + be justified by the normative rules. + + commit fbc2eef266332b8dea52718640ceca7cde9d6c1f + Author: Richard Smith + Date: Mon Jun 25 18:25:06 2018 -0700 + + [concept.boolean] Reword satisfaction rules for Boolean to make them not + appear to depend on the "given" lvalues b1 and b2. + + commit d324da9c1ea4702dfb2d595390114d872f29089e + Author: Richard Smith + Date: Mon Jun 25 18:15:28 2018 -0700 + + [concept.destructible] Fix meaningless phrase "potentially-throwing, + even if non-throwing". + + By definition, non-throwing is the opposite of potentially-throwing for + an exception-specification ([except.spec]p1). + + commit 4ac1f96f51c998846ce97e81c793484a52318357 + Author: Richard Smith + Date: Mon Jun 25 17:34:27 2018 -0700 + + [concepts.equality] Add missing paragraph numbers, reorder implicit + expression variations in example for clarity and to fix overfull hbox. + + commit 60ae4bf7daae6802fefef5a5f32c1d2248a51334 + Author: Casey Carter + Date: Fri Jun 22 20:28:23 2018 -0700 + + [concepts] There need be no "there need be no subsumption relationship" + + ... the core language rules already imply it. + + commit 11b6f1844a7b43a232d55442f4af7f9ce20faa45 + Author: Casey Carter + Date: Fri Jun 22 21:14:00 2018 -0700 + + [structure.requirements] Add paragraph explaining the typographical convention for requirement names + + commit bfaea046b5176152a86514a886a5b7ab66e4dffe + Author: Casey Carter + Date: Wed Jun 20 09:39:06 2018 -0700 + + [rand.req.urng] Rework URBG requirements for clarity and simplicitly + + ... by removing the redundance between the new concept and the "old" requirements. + + Also fixup the reference in [rand.req.eng] to properly refer [rand.req.urng] instead of the requirements table. The table has been removed, and the reference should have been to the subclause in the first place to clearly incorporate the requirements outside of the table. + + commit def89125ccf441d2178e6159d6b9448f17045f6a + Author: Casey Carter + Date: Wed Jun 20 11:21:43 2018 -0700 + + [meta.trans.other] Remove basic_common_reference requirement with no normative effect. + + We already say that only T and U can be specialized. We do not need to + also say that TQual and UQual cannot be. Also clarify that users may + *partially* specialize basic_common_reference. + + commit 528d382ca9b350c3aece9a57e23a2560b7ba0651 + Author: Casey Carter + Date: Tue Jun 19 16:31:00 2018 -0700 + + [meta.trans.other] Make style of common_type and common_reference consistent + + ...by tagging the specification of common_reference with "Note C" and basic_common_reference "Note D". + + Also remove the allowance to specialize basic_common_reference "if at least one template parameter in the specialization depends on a program-defined type"; it's redundant with "...pursuant to [namespace.std]". (This is consistent with `common_type`'s wording.) + + commit 2aa8b236c8afe09272fba8d0767fbc6552b301b5 + Author: Casey Carter + Date: Tue Jun 19 16:06:03 2018 -0700 + + [structure.requirements] Rephrase para 8 for clarity + + commit d9c710c4f13c95d65f96d503bd45f11628fdf68a + Author: Casey Carter + Date: Mon Jun 18 06:55:44 2018 -0700 + + [concepts.general][library.general] Concepts constrain template arguments, not parameters + + commit a818d5bfb084da10818b830d210d8bb4312912e4 + Author: Casey Carter + Date: Thu Jun 21 09:38:44 2018 -0700 + + [concepts.swappable] Correct example + + commit db9aee9ca04a192f32cd630cf3682d30c62a0bf7 + Author: Casey Carter + Date: Tue Jun 19 15:34:43 2018 -0700 + + [customization.point.object][meta.trans.other] Replace "user-defined" added by P0898R3 with "program-defined" + + ...to be consistent with the intent of LWG2139 + + commit 03f3764a071dfe30ef1137435a88ea036ca65c1f + Author: Casey Carter + Date: Wed Jun 20 15:16:51 2018 -0700 + + [definitions] Redefine expression-equivalent per ISO directives + + To be replaceable in context, and add a clarifying example. + + commit d119277cb8864be440a6e0445211c232e87f91a7 + Author: Casey Carter + Date: Thu Jun 21 09:18:24 2018 -0700 + + [concepts] Rephrase ocurrences of "must" + + commit 16b35d651de53654321b584eba2c6c4e126eb7d8 + Author: Richard Smith + Date: Fri Jun 22 18:08:26 2018 -0700 + + [depr.c.headers] Undo P0619R4's removal of synopses for , + , , and . + + Instead, repurpose these to be synopses for , , + , and , and move them into [depr.c.headers]. + Also introduce a synopsis for . + + This avoids three of these five headers being specified as equivalent to + a non-existent header, and the other two missing a synopsis. + + commit cf0749742b9318143505f9ffe2d4dabb5420d727 + Author: Richard Smith + Date: Fri Jun 22 17:17:41 2018 -0700 + + [diff.cpp17.library] Fix description of how to adjust code for the + removal of and . + + commit fa04176c01dd10105eec6590407b2c76384f5c52 + Author: Richard Smith + Date: Fri Jun 22 17:06:40 2018 -0700 + + [diff.cpp17.library] Fix list of new headers compared to C++17. + + commit 9e80b6c69467fb2fb146637e1f0fca8b7495250f + Author: Richard Smith + Date: Fri Jun 22 16:59:45 2018 -0700 + + [diff.cpp17.except] Fix Rationale to be a rationale. + + "This was retained for one additional C++ standard to ease transition" + is not a rationale for removing the feature now. + + commit 043ee628bc8accbe7f1ac4dc2210e88186bc95a4 + Author: Richard Smith + Date: Fri Jun 22 16:41:51 2018 -0700 + + [diff.cpp17.except] Add a note that there is no longer a way to write + code that is non-throwing in both C++20 and C++03. + + commit fd244b515387efde9fb08ffe183985a38e93d184 + Author: Richard Smith + Date: Fri Jun 22 16:29:19 2018 -0700 + + [diff.cpp03.language.support] Remove change described in p1, which is no + longer a possible change. + + It is not possible to write a global replacement operator new or + operator delete in C++20 with code that is also valid C++03, because + + a) operator new must be declared 'throw(std::bad_alloc)' in C++03 and + must be declared with no exception specification in C++11 onwards, + and + b) operator delete must be declared 'throw()' in C++03 and must be + declared 'noexcept' in C++20 onwards. + + Therefore there is no code that is valid in C++03 and C++20 and changes + meaning due to the change identified in this section. + + Instead, expand [diff.cpp03.language.support]p2 to explain that the + affected programs are simply not valid in C++20. + + commit 3e80cd4c07563639a8ca55d41d704701ae6d0eb4 + Author: Richard Smith + Date: Fri Jun 22 16:07:09 2018 -0700 + + [complex.special] Reorder defaulted complex copy constructor to + emphasize relationship between it and the converting constructors. + + commit 74539419429281072e1f8b787a0ce0dc2bb067db + Author: Richard Smith + Date: Thu Jun 21 20:09:23 2018 -0700 + + [atomics.ref] Reword introductory sentences to avoid overfull hbox. + + commit 3c21cfcfa1091a406d4b384e4677f0fa0e8ea75c + Author: Jens Maurer + Date: Mon Jun 11 19:10:53 2018 +0200 + + [alg.shift] Avoid undefined iterator arithmetic on ForwardIterator. + Avoid using the undefined concept BidirectionalIterator. + + commit 949892305c88abd7c2ecb15a77bde3222366733d + Author: Jonathan Wakely + Date: Mon Jun 11 23:43:22 2018 +0100 + + [structure.specifications] remove "implementation-defined" from example + mentioning [[expects]] and add cross-reference to [[expects]] attribute. + + commit 23c6b62f321d463792c54db38a89b335dc232f3e + Author: Jonathan Wakely + Date: Mon Jun 11 23:41:37 2018 +0100 + + [structure.specifications] replace "paragraph" with "element" + + commit 4aa23529058e5f17f74e663ff189a1548812e009 + Author: Jonathan Wakely + Date: Mon Jun 11 23:37:31 2018 +0100 + + [res.on.required] replace "paragraph" with "element" + + commit 3b24b2dc75bd5b80d2c5fc1cb3fdb62ac3852d8d + Author: Richard Smith + Date: Tue Jun 19 17:13:17 2018 -0700 + + [diff.cpp17] Correct description of explicit(bool) compatibility. + + Parenthesized names for explicit constructors and conversion functions + are still valid if the name doesn't immediately follow the explicit + keyword. Add an example using explicit(true) as a hint indicating how + to get the same effect. + + Change affected subclauses from [dcl.fct] to the somewhat-more-precise + [class.ctor] and [class.conv.fct]. + + commit 001a2011d172cce2784857a492e2c37e25ade7e9 + Author: Richard Smith + Date: Mon Jun 18 18:19:39 2018 -0700 + + [dcl.attr.contract] Fix typeface of std::terminate in comment. + + commit 913c83a98735709462a49613f8993bca4042ed70 + Author: Jens Maurer + Date: Sun Jun 17 09:18:08 2018 +0200 + + [dcl.attr.contract] Move according to alphabetical sorting of headings + + commit 463ab8dc3726514b2adf8dcf6816262f58688da3 + Author: Jens Maurer + Date: Fri Jun 15 11:01:23 2018 +0200 + + [except.terminate] Clarify evaluation of a contract + + commit f2f60fd4c3f9810ae815a408e1fd3ac1462482c7 + Author: Jens Maurer + Date: Fri Jun 15 10:53:18 2018 +0200 + + [temp.explicit] Remove redundant rules for contracts + + given that [dcl.attr.grammar] already prohibits + attribute-specifier-seqs for an explicit instantiation. + + commit a7a0e115dbf5f149936a04f57b9dd3174c9efa6a + Author: Jens Maurer + Date: Fri Jun 15 10:51:04 2018 +0200 + + [class.virtual] Fix comment in example + + commit ca0d62cc3d8c397d843fe1e1ae4a80f8fa389587 + Author: Jens Maurer + Date: Fri Jun 15 10:42:25 2018 +0200 + + [dcl.attr.contract] Fix sentence defining violation handler + + commit 0cd3f3dc072d736b4e8572311918bdccbb91e1f7 + Author: Jens Maurer + Date: Fri Jun 15 10:33:54 2018 +0200 + + [dcl.attr.contract] Clarify evaluation of non-checked contracts + + commit 2930dc55b0c5573aad90c22e1909f98bb9bec4c2 + Author: Jens Maurer + Date: Fri Jun 15 10:18:18 2018 +0200 + + [dcl.attr.contract] Permit modifications of temporaries within the predicate. + + commit 87c3c20540b99708b02ce3dfc6a792a3fea454aa + Author: Jens Maurer + Date: Fri Jun 15 10:17:19 2018 +0200 + + [dcl.attr.contract] Clarify that assertions may apply to a null statement + + commit 072f42df7b298c3677b2a1e8f1a4687d1e005ffc + Author: Jens Maurer + Date: Fri Jun 15 10:10:53 2018 +0200 + + [dcl.attr.contract] Clarify rules on std::contract_violation + + commit 77579d2f9527552820dfc667867589da12adceda + Author: Jens Maurer + Date: Fri Jun 15 10:08:09 2018 +0200 + + [dcl.attr.contract] Predicates of a contract are potentially evaluated, + + as per the definition in [basic.def.odr], so turn the + redundant normative statement into a note. + + commit da24c5df270fc17a82b6767aef5baee94fba4a45 + Author: Jens Maurer + Date: Fri Jun 15 09:43:43 2018 +0200 + + [basic.def.odr] Rephrase ODR rule for contracts + + commit 0fc2af6bbe05e16feb03e8f24651ea12e8a6997c + Author: Jens Maurer + Date: Sun Jun 10 22:53:26 2018 +0200 + + [dcl.attr.contract] Reorder paragraphs for more coherence. + + Also move rules on virtual functions to [class.virtual]. + Rephase assertion checking along pre/postcondition checking. + + commit 42019fd86775859393e7e5edc7e8d4c2e64c8019 + Author: Jens Maurer + Date: Sun Jun 10 22:24:18 2018 +0200 + + [basic.def.odr] Rephrase build level and continuation mode requirements + + commit ac603143816388fa8fa12a8fb0802130b6643884 + Author: Jens Maurer + Date: Sun Jun 10 22:17:23 2018 +0200 + + [dcl.attr.contract] Rephrase comments in examples + + commit 19d07dec4cbe5ae86eb6231eb833d166c5939faf + Author: Jens Maurer + Date: Sun Jun 10 22:14:46 2018 +0200 + + [except.terminate] Add contract violation with continuation mode off + + commit f28517ab52f7bf80879a7883fe08bb97020f80da + Author: Jens Maurer + Date: Sun Jun 10 21:17:50 2018 +0200 + + [dcl.attr.contract] Avoid duplication of 'renaming' in enumeration + + commit a8b8e534a7a5235157333f6a9f64c339e48e0e86 + Author: Richard Smith + Date: Mon Jun 11 15:56:16 2018 -0700 + + [basic.stc.dynamic.deallocation] Remove confusing note. + + This note is only correct due to subtleties of later wording + (particularly that a destroying operator delete cannot be a function + template). Correcting it results in it simply duplicating existing + normative rules and not adding anything. So remove it instead. + + commit e4f579e421dac17ff36f98b2211d143991de7850 + Author: Jens Maurer + Date: Wed Jun 13 09:16:17 2018 +0200 + + [temp.arg.nontype] Fix example involving string literal + + P0732R2 contained some changes to this section that were missing + explicit markup; apply those changes too. Also fix missing definition of + operator<=> in class type used as type of non-type template parameter. + + commit 5cca3b5015491a6c8b5d1d63f651073940d1145e + Author: Jens Maurer + Date: Wed Jun 13 08:34:52 2018 +0200 + + [dcl.fct] Move function definition rule to [dcl.fct.def.general] + + This is the rule that requires complete non-abstract + types function parameter or return types. + + commit b39b44b32394384edcc8f7f682274fbffd22f067 + Author: Jens Maurer + Date: Wed Jun 13 08:28:26 2018 +0200 + + [temp.deduct] Forming an array of abstract class type is not deduction failure + + commit ba6cd4c525371eb98c60a025da21e5ca813b4a94 + Author: Thomas Köppe + Date: Thu Jun 14 21:48:23 2018 +0100 + + [cpp.subst] Reword paragraph to simplify the logical structure and avoid ambiguous references. + + commit 4ce05424a8774e13b9958eb9cb9165da5b19edb0 + Author: Richard Smith + Date: Tue Jun 12 16:27:40 2018 -0700 + + [depr.capture.this] Reorder so the order of Annex D matches the order of the main text + + commit 628a32db863ac10fe0fb4c45d6975a50f5497acf + Author: Richard Smith + Date: Tue Jun 12 16:26:37 2018 -0700 + + [depr.capture.this] Replace "can" with "may". + + This wording is describing permission, not capability, so should use "may". + + commit 5274b2ee4c558d39012a34d104be0d2139115c00 + Author: Thomas Köppe + Date: Fri Jun 15 14:31:14 2018 +0100 + + [temp.deduct] Fixes from editorial review of CWG2293: + + * Use "not valid" rather than "invalid", since only "valid" has been defined. + * Add an "otherwise" to improve flow. + + commit 0e771884acfdcb1dc693ef654f34cf717986f803 + Author: Jonathan Wakely + Date: Fri Jun 8 08:23:25 2018 +0100 + + [time.zone.db.remote] replace "this section" with "this subclause" (#2103) + + commit b9c5272c78fb312883cb548219b7fd2cb44280c7 + Author: Thomas Köppe + Date: Thu Jun 7 23:24:37 2018 +0200 + + [cfenv.syn] Add "optional" markers for macros from the C library that are optional (as defined by C) + + commit aa77121b3aa9bc566b8d2e428cd21a28493ce57e + Author: Alberto Barbati <2210776+iaanus@users.noreply.github.com> + Date: Thu Jun 7 21:39:51 2018 +0200 + + [dcl.attr.likelihood] Fix error in example + + commit fbee1d521da91a798d81ecc09f110a0946239630 + Author: Jens Maurer + Date: Thu Jun 7 21:36:42 2018 +0200 + + [views.general] Remove redundant introduction for span. (#2062) + + commit 069a179a0d54cad4b3d00f00eae532c827786894 + Author: Jens Maurer + Date: Tue Mar 27 14:41:13 2018 +0200 + + [cmp.syn] Rename to [compare.syn] to match the header name + + commit 8a0060d0dcda8c63a2c432016bd038c75a8de9a1 + Author: Marc Mutz + Date: Thu Jun 7 03:34:12 2018 +0200 + + [list.modifiers, forward.list.modifiers] Add missing 'to' in 'referred [to] by' (#2100) + + commit 57de3af9d24037d60d996b255c1ded8ee65387d2 + Author: Arthur O'Dwyer + Date: Wed May 30 00:18:13 2018 -0700 + + [comparisons] Fix a typo in the note for `std::less`. (#2089) + + commit 61b6c21f218e3cbb9d15426975f1a26d8b72a7fe + Author: Richard Smith + Date: Thu May 10 14:40:22 2018 -0700 + + [class.expl.init] Fix example to account for guaranteed copy omission. diff --git a/source/access.tex b/source/access.tex deleted file mode 100644 index ab35bc7109..0000000000 --- a/source/access.tex +++ /dev/null @@ -1,983 +0,0 @@ -%!TEX root = std.tex -\rSec0[class.access]{Member access control}% -\indextext{access control|(} - -\indextext{protection|see{access control}} -\indextext{\idxcode{private}|see{access control, \tcode{private}}} -\indextext{\idxcode{protected}|see{access control, \tcode{protected}}} -\indextext{\idxcode{public}|see{access control, \tcode{public}}} - -\pnum -A member of a class can be -\begin{itemize} -\item -\indextext{access control!\idxcode{private}}% -private; -that is, its name can be used only by members and friends -of the class in which it is declared. -\item -\indextext{access control!\idxcode{protected}}% -protected; -that is, its name can be used only by members and friends -of the class in which it is declared, by classes derived from that class, and by their -friends (see~\ref{class.protected}). -\item -\indextext{access control!\idxcode{public}}% -public; -that is, its name can be used anywhere without access restriction. -\end{itemize} - -\pnum -A member of a class can also access all the names to which the class has access. -A local class of a member function may access -the same names that the member function itself may access.\footnote{Access -permissions are thus transitive and cumulative to nested -and local classes.} - -\pnum -\indextext{access control!member name}% -\indextext{default access control|see{access control, default}}% -\indextext{access control!default}% -Members of a class defined with the keyword -\tcode{class} -are -\tcode{private} -by default. -Members of a class defined with the keywords -\tcode{struct} or \tcode{union} -are public by default. -\begin{example} - -\begin{codeblock} -class X { - int a; // \tcode{X::a} is private by default -}; - -struct S { - int a; // \tcode{S::a} is public by default -}; -\end{codeblock} -\end{example} - -\pnum -Access control is applied uniformly to all names, whether the names are -referred to from declarations or expressions. -\begin{note} -Access control applies to names nominated by -friend declarations\iref{class.friend} and -\grammarterm{using-declaration}{s}\iref{namespace.udecl}. -\end{note} -In the case of overloaded function names, access control is applied to -the function selected by overload resolution. -\begin{note} -Because access control applies to names, if access control is applied to a -typedef name, only the accessibility of the typedef name itself is considered. -The accessibility of the entity referred to by the typedef is not considered. -For example, - -\begin{codeblock} -class A { - class B { }; -public: - typedef B BB; -}; - -void f() { - A::BB x; // OK, typedef name \tcode{A::BB} is public - A::B y; // access error, \tcode{A::B} is private -} -\end{codeblock} -\end{note} - -\pnum -\begin{note} -Access to members and base classes is controlled, not their -visibility\iref{basic.scope.hiding}. -Names of members are still visible, and implicit conversions to base -classes are still considered, when those members and base classes are -inaccessible. -\end{note} -The interpretation of a given construct is -established without regard to access control. -If the interpretation -established makes use of inaccessible member names or base classes, -the construct is ill-formed. - -\pnum -All access controls in \ref{class.access} affect the ability to access a class member -name from the declaration of a particular -entity, including parts of the declaration preceding the name of the entity -being declared and, if the entity is a class, the definitions of members of -the class appearing outside the class's \grammarterm{member-specification}{.} -\begin{note} This access also applies to implicit references to constructors, -conversion functions, and destructors. \end{note} - -\pnum -\begin{example} -\begin{codeblock} -class A { - typedef int I; // private member - I f(); - friend I g(I); - static I x; - template struct Q; - template friend struct R; -protected: - struct B { }; -}; - -A::I A::f() { return 0; } -A::I g(A::I p = A::x); -A::I g(A::I p) { return 0; } -A::I A::x = 0; -template struct A::Q { }; -template struct R { }; - -struct D: A::B, A { }; -\end{codeblock} - -Here, all the uses of -\tcode{A::I} -are well-formed because -\tcode{A::f}, -\tcode{A::x}, and \tcode{A::Q} -are members of class -\tcode{A} -and -\tcode{g} -and \tcode{R} are friends of class -\tcode{A}. -This implies, for example, that access checking on the first use of -\tcode{A::I} -must be deferred until it is determined that this use of -\tcode{A::I} -is as the return type of a member of class -\tcode{A}. -Similarly, the use of \tcode{A::B} as a -\grammarterm{base-specifier} is well-formed because \tcode{D} -is derived from \tcode{A}, so checking of \grammarterm{base-specifier}{s} -must be deferred until the entire \grammarterm{base-specifier-list} has been seen. -\end{example} - -\pnum -\indextext{argument!access checking and default}% -\indextext{access control!default argument}% -The names in a default argument\iref{dcl.fct.default} are -bound at the point of declaration, and access is checked at that -point rather than at any points of use of the default argument. -Access checking for default arguments in function templates and in -member functions of class templates is performed as described in~\ref{temp.inst}. - -\pnum -The names in a default \grammarterm{template-argument}\iref{temp.param} -have their access checked in the context in which they appear rather than at any -points of use of the default \grammarterm{template-argument}. \begin{example} -\begin{codeblock} -class B { }; -template class C { -protected: - typedef T TT; -}; - -template -class D : public U { }; - -D >* d; // access error, \tcode{C::TT} is protected -\end{codeblock} -\end{example} - -\rSec1[class.access.spec]{Access specifiers}% -\indextext{access specifier} - -\pnum -Member declarations can be labeled by an -\grammarterm{access-specifier} -(\ref{class.derived}): - -\begin{ncsimplebnf} -access-specifier \terminal{:} \opt{member-specification} -\end{ncsimplebnf} - -An -\grammarterm{access-specifier} -specifies the access rules for members following it -until the end of the class or until another -\grammarterm{access-specifier} -is encountered. -\begin{example} - -\begin{codeblock} -class X { - int a; // \tcode{X::a} is private by default: \tcode{class} used -public: - int b; // \tcode{X::b} is public - int c; // \tcode{X::c} is public -}; -\end{codeblock} -\end{example} - -\pnum -Any number of access specifiers is allowed and no particular order is required. -\begin{example} - -\begin{codeblock} -struct S { - int a; // \tcode{S::a} is public by default: \tcode{struct} used -protected: - int b; // \tcode{S::b} is protected -private: - int c; // \tcode{S::c} is private -public: - int d; // \tcode{S::d} is public -}; -\end{codeblock} -\end{example} - -\pnum -\begin{note} The effect of access control on the order of allocation -of data members is described in~\ref{class.mem}.\end{note} - -\pnum -When a member is redeclared within its class definition, -the access specified at its redeclaration shall -be the same as at its initial declaration. -\begin{example} - -\begin{codeblock} -struct S { - class A; - enum E : int; -private: - class A { }; // error: cannot change access - enum E: int { e0 }; // error: cannot change access -}; -\end{codeblock} -\end{example} - -\pnum -\begin{note} -In a derived class, the lookup of a base class name will find the -injected-class-name instead of the name of the base class in the scope -in which it was declared. The injected-class-name might be less accessible -than the name of the base class in the scope in which it was declared. -\end{note} - -\begin{example} -\begin{codeblock} -class A { }; -class B : private A { }; -class C : public B { - A* p; // error: injected-class-name \tcode{A} is inaccessible - ::A* q; // OK -}; -\end{codeblock} -\end{example} - -\rSec1[class.access.base]{Accessibility of base classes and base class members}% -\indextext{access control!base class}% -\indextext{access specifier}% -\indextext{base class!\idxcode{private}}% -\indextext{base class!\idxcode{protected}}% -\indextext{base class!\idxcode{public}} - -\pnum -If a class is declared to be a base class\iref{class.derived} for another class using the -\tcode{public} -access specifier, the -public members of the base class are accessible as -public members of the derived class and -protected members of the base class are accessible as -protected members of the derived class. -If a class is declared to be a base class for another class using the -\tcode{protected} -access specifier, the -public and protected members of the base class are accessible as -protected members of the derived class. -If a class is declared to be a base class for another class using the -private -access specifier, the -public and protected -members of the base class are accessible as private -members of the derived class.\footnote{As specified previously in \ref{class.access}, -private members of a base class remain inaccessible even to derived classes -unless friend -declarations within the base class definition are used to grant access explicitly.} - -\pnum -In the absence of an -\grammarterm{access-specifier} -for a base class, -\tcode{public} -is assumed when the derived class is -defined with the \grammarterm{class-key} -\tcode{struct} -and -\tcode{private} -is assumed when the class is -defined with the \grammarterm{class-key} -\tcode{class}. -\begin{example} - -\begin{codeblock} -class B { @\commentellip@ }; -class D1 : private B { @\commentellip@ }; -class D2 : public B { @\commentellip@ }; -class D3 : B { @\commentellip@ }; // \tcode{B} private by default -struct D4 : public B { @\commentellip@ }; -struct D5 : private B { @\commentellip@ }; -struct D6 : B { @\commentellip@ }; // \tcode{B} public by default -class D7 : protected B { @\commentellip@ }; -struct D8 : protected B { @\commentellip@ }; -\end{codeblock} - -Here -\tcode{B} -is a public base of -\tcode{D2}, -\tcode{D4}, -and -\tcode{D6}, -a private base of -\tcode{D1}, -\tcode{D3}, -and -\tcode{D5}, -and a protected base of -\tcode{D7} -and -\tcode{D8}. -\end{example} - -\pnum -\begin{note} -A member of a private base class might be inaccessible as an inherited -member name, but accessible directly. -Because of the rules on pointer conversions\iref{conv.ptr} and explicit casts\iref{expr.cast}, a conversion from a pointer to a derived class to a pointer -to an inaccessible base class might be ill-formed if an implicit conversion -is used, but well-formed if an explicit cast is used. -For example, - -\begin{codeblock} -class B { -public: - int mi; // non-static member - static int si; // static member -}; -class D : private B { -}; -class DD : public D { - void f(); -}; - -void DD::f() { - mi = 3; // error: \tcode{mi} is private in \tcode{D} - si = 3; // error: \tcode{si} is private in \tcode{D} - ::B b; - b.mi = 3; // OK (\tcode{b.mi} is different from \tcode{this->mi}) - b.si = 3; // OK (\tcode{b.si} is different from \tcode{this->si}) - ::B::si = 3; // OK - ::B* bp1 = this; // error: \tcode{B} is a private base class - ::B* bp2 = (::B*)this; // OK with cast - bp2->mi = 3; // OK: access through a pointer to \tcode{B}. -} -\end{codeblock} -\end{note} - -\pnum -A base class -\tcode{B} -of -\tcode{N} -is -\defn{accessible} -at -\placeholder{R}, -if -\begin{itemize} -\item -an invented public member of -\tcode{B} -would be a public member of -\tcode{N}, or -\item -\placeholder{R} -occurs in a member or friend of class -\tcode{N}, -and an invented public member of -\tcode{B} -would be a private or protected member of -\tcode{N}, or -\item -\placeholder{R} -occurs in a member or friend of a class -\tcode{P} -derived from -\tcode{N}, -and an invented public member of -\tcode{B} -would be a private or protected member of -\tcode{P}, or -\item -there exists a class -\tcode{S} -such that -\tcode{B} -is a base class of -\tcode{S} -accessible at -\placeholder{R} -and -\tcode{S} -is a base class of -\tcode{N} -accessible at -\placeholder{R}. -\end{itemize} - -\begin{example} -\begin{codeblock} -class B { -public: - int m; -}; - -class S: private B { - friend class N; -}; - -class N: private S { - void f() { - B* p = this; // OK because class \tcode{S} satisfies the fourth condition above: \tcode{B} is a base class of \tcode{N} - // accessible in \tcode{f()} because \tcode{B} is an accessible base class of \tcode{S} and \tcode{S} is an accessible - // base class of \tcode{N}. - } -}; -\end{codeblock} -\end{example} - -\pnum -If a base class is accessible, one can implicitly convert a pointer to -a derived class to a pointer to that base class~(\ref{conv.ptr}, \ref{conv.mem}). -\begin{note} -It follows that -members and friends of a class -\tcode{X} -can implicitly convert an -\tcode{X*} -to a pointer to a private or protected immediate base class of -\tcode{X}. -\end{note} -The access to a member is affected by the class in which the member is -named. -This naming class is the class in which the member name was looked -up and found. -\begin{note} -This class can be explicit, e.g., when a -\grammarterm{qualified-id} -is used, or implicit, e.g., when a class member access operator\iref{expr.ref} is used (including cases where an implicit -``\tcode{this->}'' -is -added). -If both a class member access operator and a -\grammarterm{qualified-id} -are used to name the member (as in -\tcode{p->T::m}), -the class naming the member is the class denoted by the -\grammarterm{nested-name-specifier} -of the -\grammarterm{qualified-id} -(that is, -\tcode{T}). -\end{note} -A member -\tcode{m} -is accessible at the point -\placeholder{R} -when named in class -\tcode{N} -if -\begin{itemize} -\item -\tcode{m} -as a member of -\tcode{N} -is public, or -\item -\tcode{m} -as a member of -\tcode{N} -is private, and -\placeholder{R} -occurs in a member or friend of class -\tcode{N}, -or -\item -\tcode{m} -as a member of -\tcode{N} -is protected, and -\placeholder{R} -occurs in a member or friend of class -\tcode{N}, -or in a member of a class -\tcode{P} -derived from -\tcode{N}, -where -\tcode{m} -as a member of -\tcode{P} -is public, private, or protected, or -\item -there exists a base class -\tcode{B} -of -\tcode{N} -that is accessible at -\placeholder{R}, -and -\tcode{m} -is accessible at -\placeholder{R} -when named in class -\tcode{B}. -\begin{example} - -\begin{codeblock} -class B; -class A { -private: - int i; - friend void f(B*); -}; -class B : public A { }; -void f(B* p) { - p->i = 1; // OK: \tcode{B*} can be implicitly converted to \tcode{A*}, and \tcode{f} has access to \tcode{i} in \tcode{A} -} -\end{codeblock} -\end{example} -\end{itemize} - -\pnum -If a class member access operator, including an implicit -``\tcode{this->}'', -is used to access a non-static data member or non-static -member function, the reference is ill-formed if the -left operand (considered as a pointer in the -``\tcode{.}'' -operator case) cannot be implicitly converted to a -pointer to the naming class of the right operand. -\begin{note} -This requirement is in addition to the requirement that -the member be accessible as named. -\end{note} - -\rSec1[class.friend]{Friends}% -\indextext{friend function!access and}% -\indextext{access control!friend function} - -\pnum -A friend of a class is a function or class that is -given permission to use the private and protected member names from the class. -A class specifies its friends, if any, by way of friend declarations. -Such declarations give special access rights to the friends, but they -do not make the nominated friends members of the befriending class. -\begin{example} -The following example illustrates the differences between -members and friends: -\indextext{friend function!member function and}% - -\begin{codeblock} -class X { - int a; - friend void friend_set(X*, int); -public: - void member_set(int); -}; - -void friend_set(X* p, int i) { p->a = i; } -void X::member_set(int i) { a = i; } - -void f() { - X obj; - friend_set(&obj,10); - obj.member_set(10); -} -\end{codeblock} -\end{example} - -\pnum -\indextext{friend!class access and}% -Declaring a class to be a friend implies that the names of private and -protected members from the class granting friendship can be accessed in the -\grammarterm{base-specifier}{s} and member declarations of the befriended -class. \begin{example} - -\begin{codeblock} -class A { - class B { }; - friend class X; -}; - -struct X : A::B { // OK: \tcode{A::B} accessible to friend - A::B mx; // OK: \tcode{A::B} accessible to member of friend - class Y { - A::B my; // OK: \tcode{A::B} accessible to nested member of friend - }; -}; -\end{codeblock} -\end{example} -\begin{example} - -\begin{codeblock} -class X { - enum { a=100 }; - friend class Y; -}; - -class Y { - int v[X::a]; // OK, \tcode{Y} is a friend of \tcode{X} -}; - -class Z { - int v[X::a]; // error: \tcode{X::a} is private -}; -\end{codeblock} -\end{example} - -A class shall not be defined in a friend declaration. \begin{example} -\begin{codeblock} -class A { - friend class B { }; // error: cannot define class in friend declaration -}; -\end{codeblock} -\end{example} - -\pnum -A friend declaration that does not declare a function -shall have one of the following forms: - -\begin{ncsimplebnf} -\terminal{friend} elaborated-type-specifier \terminal{;}\br -\terminal{friend} simple-type-specifier \terminal{;}\br -\terminal{friend} typename-specifier \terminal{;} -\end{ncsimplebnf} - -\begin{note} A friend declaration may be the -\grammarterm{declaration} in a \grammarterm{template-declaration} -(\ref{temp}, \ref{temp.friend}).\end{note} If the -type specifier in a \tcode{friend} declaration designates a (possibly -cv-qualified) class type, that class is declared as a friend; otherwise, the -friend declaration is ignored. \begin{example} - -\begin{codeblock} -class C; -typedef C Ct; - -class X1 { - friend C; // OK: \tcode{class C} is a friend -}; - -class X2 { - friend Ct; // OK: \tcode{class C} is a friend - friend D; // error: no type-name \tcode{D} in scope - friend class D; // OK: elaborated-type-specifier declares new class -}; - -template class R { - friend T; -}; - -R rc; // \tcode{class C} is a friend of \tcode{R} -R Ri; // OK: \tcode{"friend int;"} is ignored -\end{codeblock} -\end{example} - -\pnum -\indextext{friend function!linkage of}% -A function first declared in a friend declaration -has the linkage of the namespace of which it is a member\iref{basic.link}. -Otherwise, the function retains its previous linkage\iref{dcl.stc}. - -\pnum -\indextext{declaration!overloaded name and \tcode{friend}}% -When a friend -declaration refers to an overloaded name or operator, only the function specified -by the parameter types becomes a friend. -A member function of a class -\tcode{X} -can be a friend of -a class -\tcode{Y}. -\indextext{member function!friend}% -\begin{example} - -\begin{codeblock} -class Y { - friend char* X::foo(int); - friend X::X(char); // constructors can be friends - friend X::~X(); // destructors can be friends -}; -\end{codeblock} -\end{example} - -\pnum -\indextext{friend function!inline}% -A function can be defined in a friend declaration of a class if and only if the -class is a non-local class\iref{class.local}, the function name is unqualified, -and the function has namespace scope. -\begin{example} - -\begin{codeblock} -class M { - friend void f() { } // definition of global \tcode{f}, a friend of \tcode{M}, - // not the definition of a member function -}; -\end{codeblock} -\end{example} - -\pnum -Such a function is implicitly an inline function\iref{dcl.inline}. -A friend -function defined in a class is in the (lexical) scope of the class in which it is defined. -A friend function defined outside the class is not\iref{basic.lookup.unqual}. - -\pnum -No -\grammarterm{storage-class-specifier} -shall appear in the -\grammarterm{decl-specifier-seq} -of a friend declaration. - -\pnum -\indextext{friend!access specifier and}% -A name nominated by a friend declaration shall be accessible in the scope of the -class containing the friend declaration. -The meaning of the friend declaration is the same whether the friend declaration -appears in the private, protected, or public\iref{class.mem} -portion of the class -\grammarterm{member-specification}. - -\pnum -\indextext{friend!inheritance and}% -Friendship is neither inherited nor transitive. -\begin{example} - -\begin{codeblock} -class A { - friend class B; - int a; -}; - -class B { - friend class C; -}; - -class C { - void f(A* p) { - p->a++; // error: \tcode{C} is not a friend of \tcode{A} despite being a friend of a friend - } -}; - -class D : public B { - void f(A* p) { - p->a++; // error: \tcode{D} is not a friend of \tcode{A} despite being derived from a friend - } -}; -\end{codeblock} -\end{example} - -\pnum -\indextext{local class!friend}% -\indextext{friend!local class and}% -If a friend declaration appears in a local class\iref{class.local} and the -name specified is an unqualified name, a prior declaration is looked -up without considering scopes that are outside the innermost enclosing -non-class scope. -For a friend function declaration, if there is no -prior declaration, the program is ill-formed. -For a friend class -declaration, if there is no prior declaration, the class that is -specified belongs to the innermost enclosing non-class scope, but if it is -subsequently referenced, its name is not found by name lookup -until a matching declaration is provided in the innermost enclosing -non-class scope. -\begin{example} - -\begin{codeblock} -class X; -void a(); -void f() { - class Y; - extern void b(); - class A { - friend class X; // OK, but \tcode{X} is a local class, not \tcode{::X} - friend class Y; // OK - friend class Z; // OK, introduces local class \tcode{Z} - friend void a(); // error, \tcode{::a} is not considered - friend void b(); // OK - friend void c(); // error - }; - X* px; // OK, but \tcode{::X} is found - Z* pz; // error, no \tcode{Z} is found -} -\end{codeblock} -\end{example} - -\rSec1[class.protected]{Protected member access} -\indextext{access control!\idxcode{protected}}% - -\pnum -An additional access check beyond those described earlier in \ref{class.access} -is applied when a non-static data member or non-static member function is a -protected member of its naming class\iref{class.access.base}.\footnote{This -additional check does not apply to other members, -e.g., static data members or enumerator member constants.} -As described earlier, access to a protected member is granted because the -reference occurs in a friend or member of some class \tcode{C}. If the access is -to form a pointer to member\iref{expr.unary.op}, the -\grammarterm{nested-name-specifier} shall denote \tcode{C} or a class derived from -\tcode{C}. All other accesses involve a (possibly implicit) object -expression\iref{expr.ref}. In this case, the class of the object expression shall be -\tcode{C} or a class derived from \tcode{C}. -\begin{example} - -\begin{codeblock} -class B { -protected: - int i; - static int j; -}; - -class D1 : public B { -}; - -class D2 : public B { - friend void fr(B*,D1*,D2*); - void mem(B*,D1*); -}; - -void fr(B* pb, D1* p1, D2* p2) { - pb->i = 1; // ill-formed - p1->i = 2; // ill-formed - p2->i = 3; // OK (access through a \tcode{D2}) - p2->B::i = 4; // OK (access through a \tcode{D2}, even though naming class is \tcode{B}) - int B::* pmi_B = &B::i; // ill-formed - int B::* pmi_B2 = &D2::i; // OK (type of \tcode{\&D2::i} is \tcode{int B::*}) - B::j = 5; // ill-formed (not a friend of naming class \tcode{B}) - D2::j = 6; // OK (because refers to static member) -} - -void D2::mem(B* pb, D1* p1) { - pb->i = 1; // ill-formed - p1->i = 2; // ill-formed - i = 3; // OK (access through \tcode{this}) - B::i = 4; // OK (access through \tcode{this}, qualification ignored) - int B::* pmi_B = &B::i; // ill-formed - int B::* pmi_B2 = &D2::i; // OK - j = 5; // OK (because \tcode{j} refers to static member) - B::j = 6; // OK (because \tcode{B::j} refers to static member) -} - -void g(B* pb, D1* p1, D2* p2) { - pb->i = 1; // ill-formed - p1->i = 2; // ill-formed - p2->i = 3; // ill-formed -} -\end{codeblock} -\end{example} - -\rSec1[class.access.virt]{Access to virtual functions}% -\indextext{access control!virtual function} - -\pnum -The access rules\iref{class.access} for a virtual function are determined by its declaration -and are not affected by the rules for a function that later overrides it. -\begin{example} - -\begin{codeblock} -class B { -public: - virtual int f(); -}; - -class D : public B { -private: - int f(); -}; - -void f() { - D d; - B* pb = &d; - D* pd = &d; - - pb->f(); // OK: \tcode{B::f()} is public, \tcode{D::f()} is invoked - pd->f(); // error: \tcode{D::f()} is private -} -\end{codeblock} -\end{example} - -\pnum -Access is checked at the call point using the type of the expression used -to denote the object for which the member function is called -(\tcode{B*} -in the example above). -The access of the member function in the class in which it was defined -(\tcode{D} -in the example above) is in general not known. - -\rSec1[class.paths]{Multiple access}% -\indextext{access control!multiple access} - -\pnum -If a name can be reached by several paths through a multiple inheritance -graph, the access is that of the path that gives most access. -\begin{example} - -\begin{codeblock} -class W { public: void f(); }; -class A : private virtual W { }; -class B : public virtual W { }; -class C : public A, public B { - void f() { W::f(); } // OK -}; -\end{codeblock} - -Since -\tcode{W::f()} -is available to -\tcode{C::f()} -along the public path through -\tcode{B}, -access is allowed. -\end{example} - -\rSec1[class.access.nest]{Nested classes}% -\indextext{access control!nested class}% -\indextext{member function!nested class} - -\pnum -A nested class is a member and as such has the same access rights as any other member. -The members of an enclosing class have no special access to members of a nested -class; the usual access rules\iref{class.access} shall be obeyed. -\begin{example} -\begin{codeblock} -class E { - int x; - class B { }; - - class I { - B b; // OK: \tcode{E::I} can access \tcode{E::B} - int y; - void f(E* p, int i) { - p->x = i; // OK: \tcode{E::I} can access \tcode{E::x} - } - }; - - int g(I* p) { - return p->y; // error: \tcode{I::y} is private - } -}; -\end{codeblock} -\end{example}% -\indextext{access control|)} diff --git a/source/algorithms.tex b/source/algorithms.tex index a9f0c66d93..4bf758ba93 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -19,2000 +19,2832 @@ \ref{alg.nonmodifying} & Non-modifying sequence operations & \\ \ref{alg.modifying.operations} & Mutating sequence operations & \tcode{} \\ \ref{alg.sorting} & Sorting and related operations & \\ \hline +\ref{numeric.ops} & Generalized numeric operations & \tcode{} \\ \rowsep \ref{alg.c.library} & C library algorithms & \tcode{} \\ \hline \end{libsumtab} -\rSec1[algorithm.syn]{Header \tcode{} synopsis} -\indexhdr{algorithm}% +\rSec1[algorithms.requirements]{Algorithms requirements} +\pnum +All of the algorithms are separated from the particular implementations of data structures and are +parameterized by iterator types. +Because of this, they can work with program-defined data structures, as long +as these data structures have iterator types satisfying the assumptions on the algorithms. -\begin{codeblock} -#include +\pnum +For purposes of determining the existence of data races, algorithms shall +not modify objects referenced through an iterator argument unless the +specification requires such modification. -namespace std { - // \ref{alg.nonmodifying}, non-modifying sequence operations - // \ref{alg.all_of}, all of - template - constexpr bool all_of(InputIterator first, InputIterator last, Predicate pred); - template - bool all_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, Predicate pred); +\pnum +Throughout this Clause, the names of template parameters +are used to express type requirements. +\begin{itemize} +\item +If an algorithm's template parameter is named +\tcode{InputIterator}, +\tcode{InputIterator1}, +or +\tcode{Input\-Iterator2}, +the template argument shall satisfy the +\oldconcept{InputIterator} requirements\iref{input.iterators}. +\item +If an algorithm's template parameter is named +\tcode{OutputIterator}, +\tcode{OutputIterator1}, +or +\tcode{Output\-Iterator2}, +the template argument shall satisfy the +\oldconcept{OutputIterator} requirements\iref{output.iterators}. +\item +If an algorithm's template parameter is named +\tcode{ForwardIterator}, +\tcode{ForwardIterator1}, +or +\tcode{Forward\-Iterator2}, +the template argument shall satisfy the +\oldconcept{ForwardIterator} requirements\iref{forward.iterators}. +\item +If an algorithm's template parameter is named +\tcode{BidirectionalIterator}, +\tcode{Bidirectional\-Iterator1}, +or +\tcode{BidirectionalIterator2}, +the template argument shall satisfy the +\oldconcept{BidirectionalIterator} requirements\iref{bidirectional.iterators}. +\item +If an algorithm's template parameter is named +\tcode{RandomAccessIterator}, +\tcode{Random\-AccessIterator1}, +or +\tcode{RandomAccessIterator2}, +the template argument shall satisfy the +\oldconcept{RandomAccessIterator} requirements\iref{random.access.iterators}. +\end{itemize} - // \ref{alg.any_of}, any of - template - constexpr bool any_of(InputIterator first, InputIterator last, Predicate pred); - template - bool any_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, Predicate pred); +\pnum +If an algorithm's +\effects +element specifies that a value pointed to by any iterator passed +as an argument is modified, then that algorithm has an additional +type requirement: +The type of that argument shall satisfy the requirements +of a mutable iterator\iref{iterator.requirements}. +\begin{note} +This requirement does not affect arguments that are named +\tcode{OutputIterator}, +\tcode{OutputIterator1}, +or +\tcode{OutputIterator2}, +because output iterators must always be mutable. +\end{note} - // \ref{alg.none_of}, none of - template - constexpr bool none_of(InputIterator first, InputIterator last, Predicate pred); - template - bool none_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, Predicate pred); +\pnum +Both in-place and copying versions are provided for certain +algorithms.\footnote{The decision whether to include a copying version was +usually based on complexity considerations. When the cost of doing the operation +dominates the cost of copy, the copying version is not included. For example, +\tcode{sort_copy} is not included because the cost of sorting is much more +significant, and users might as well do \tcode{copy} followed by \tcode{sort}.} +When such a version is provided for \textit{algorithm} it is called +\textit{algorithm\tcode{_copy}}. Algorithms that take predicates end with the +suffix \tcode{_if} (which follows the suffix \tcode{_copy}). - // \ref{alg.foreach}, for each - template - constexpr Function for_each(InputIterator first, InputIterator last, Function f); - template - void for_each(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, Function f); - template - constexpr InputIterator for_each_n(InputIterator first, Size n, Function f); - template - ForwardIterator for_each_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, Size n, Function f); +\pnum +The +\tcode{Predicate} +parameter is used whenever an algorithm expects a function object\iref{function.objects} +that, when applied to the result +of dereferencing the corresponding iterator, returns a value testable as +\tcode{true}. +In other words, if an algorithm +takes +\tcode{Predicate pred} +as its argument and \tcode{first} +as its iterator argument, it should work correctly in the +construct +\tcode{pred(*first)} contextually converted to \tcode{bool}\iref{conv}. +The function object +\tcode{pred} +shall not apply any non-constant +function through the dereferenced iterator. - // \ref{alg.find}, find - template - constexpr InputIterator find(InputIterator first, InputIterator last, - const T& value); - template - ForwardIterator find(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - const T& value); - template - constexpr InputIterator find_if(InputIterator first, InputIterator last, - Predicate pred); - template - ForwardIterator find_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - Predicate pred); - template - constexpr InputIterator find_if_not(InputIterator first, InputIterator last, - Predicate pred); - template - ForwardIterator find_if_not(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - Predicate pred); +\pnum +The +\tcode{BinaryPredicate} +parameter is used whenever an algorithm expects a function object that when applied to +the result of dereferencing two corresponding iterators or to dereferencing an +iterator and type +\tcode{T} +when +\tcode{T} +is part of the signature returns a value testable as +\tcode{true}. +In other words, if an algorithm takes +\tcode{BinaryPredicate binary_pred} +as its argument and \tcode{first1} and \tcode{first2} as +its iterator arguments, it should work correctly in +the construct +\tcode{binary_pred(*first1, *first2)} contextually converted to \tcode{bool}\iref{conv}. +\tcode{BinaryPredicate} +always takes the first +iterator's \tcode{value_type} +as its first argument, that is, in those cases when +\tcode{T value} +is part of the signature, it should work +correctly in the +construct \tcode{binary_pred(*first1, value)} contextually converted to \tcode{bool}\iref{conv}. +\tcode{binary_pred} shall not +apply any non-constant function through the dereferenced iterators. - // \ref{alg.find.end}, find end - template - constexpr ForwardIterator1 - find_end(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); - template - constexpr ForwardIterator1 - find_end(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); - template - ForwardIterator1 - find_end(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); - template - ForwardIterator1 - find_end(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); +\pnum +The parameters +\tcode{UnaryOperation}, +\tcode{BinaryOperation}, +\tcode{BinaryOperation1}, +and \tcode{BinaryOperation2} +are used +whenever an algorithm expects a function object\iref{function.objects}. - // \ref{alg.find.first.of}, find first - template - constexpr InputIterator - find_first_of(InputIterator first1, InputIterator last1, - ForwardIterator first2, ForwardIterator last2); - template - constexpr InputIterator - find_first_of(InputIterator first1, InputIterator last1, - ForwardIterator first2, ForwardIterator last2, - BinaryPredicate pred); - template - ForwardIterator1 - find_first_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); - template - ForwardIterator1 - find_first_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); +\pnum +\begin{note} +Unless otherwise specified, algorithms that take function objects as arguments +are permitted to copy those function objects freely. Programmers for whom object +identity is important should consider using a wrapper class that points to a +noncopied implementation object such as \tcode{reference_wrapper}\iref{refwrap}, or some equivalent solution. +\end{note} - // \ref{alg.adjacent.find}, adjacent find - template - constexpr ForwardIterator - adjacent_find(ForwardIterator first, ForwardIterator last); - template - constexpr ForwardIterator - adjacent_find(ForwardIterator first, ForwardIterator last, - BinaryPredicate pred); - template - ForwardIterator - adjacent_find(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last); - template - ForwardIterator - adjacent_find(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - BinaryPredicate pred); +\pnum +When the description of an algorithm gives an expression such as +\tcode{*first == value} +for a condition, the expression shall evaluate to +either \tcode{true} or \tcode{false} in boolean contexts. - // \ref{alg.count}, count - template - constexpr typename iterator_traits::difference_type - count(InputIterator first, InputIterator last, const T& value); +\pnum +In the description of the algorithms operators +\tcode{+} +and +\tcode{-} +are used for some of the iterator categories for which +they do not have to be defined. +In these cases the semantics of +\tcode{a+n} +is the same as that of + +\begin{codeblock} +X tmp = a; +advance(tmp, n); +return tmp; +\end{codeblock} + +and that of +\tcode{b-a} +is the same as of + +\begin{codeblock} +return distance(a, b); +\end{codeblock} + +\rSec1[algorithms.parallel]{Parallel algorithms} + +\pnum +This subclause describes components that \Cpp{} programs may use to perform +operations on containers and other sequences in parallel. + +\rSec2[algorithms.parallel.defns]{Terms and definitions} +\pnum +A \defn{parallel algorithm} is a function template listed in this document with +a template parameter named \tcode{ExecutionPolicy}. + +\pnum +Parallel algorithms access objects indirectly accessible via their arguments by +invoking the following functions: + +\begin{itemize} +\item +All operations of the categories of the iterators that the algorithm is +instantiated with. + +\item +Operations on those sequence elements that are required by its specification. + +\item +User-provided function objects to be applied during the execution of the +algorithm, if required by the specification. + +\item +Operations on those function objects required by the specification. +\begin{note} See~\ref{algorithms.requirements}.\end{note} +\end{itemize} + +These functions are herein called \defn{element access functions}. +\begin{example} +The \tcode{sort} function may invoke the following element access functions: + +\begin{itemize} +\item +Operations of the random-access iterator of the actual template argument +(as per \ref{random.access.iterators}), +as implied by the name of the template parameter \tcode{RandomAccessIterator}. + +\item +The \tcode{swap} function on the elements of the sequence (as per the +preconditions specified in \ref{sort}). + +\item +The user-provided \tcode{Compare} function object. +\end{itemize} +\end{example} + +\rSec2[algorithms.parallel.user]{Requirements on user-provided function objects} + +\pnum +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} + +\pnum +Parallel algorithms have template parameters +named \tcode{ExecutionPolicy}\iref{execpol} +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 +If an object is modified by an element access function, +the algorithm will perform no other unsynchronized accesses to that object. +The modifying element access functions are those +which are specified as modifying the object. +\begin{note} +For example, +\tcode{swap()}, \tcode{++}, \tcode{--}, \tcode{@=}, and assignments +modify the object. +For the assignment and \tcode{@=} operators, +only the left argument is modified. +\end{note} + +\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}\iref{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 +in the calling thread of execution. +\begin{note} +The invocations are not interleaved; see~\ref{intro.execution}. +\end{note} + +\pnum +The invocations of element access functions in parallel algorithms invoked with +an execution policy object of type \tcode{execution::parallel_policy} are +permitted to execute in either the invoking thread of execution or in a +thread of execution implicitly +created by the library to support parallel algorithm execution. +If the threads of execution created by \tcode{thread}\iref{thread.thread.class} provide concurrent +forward progress guarantees\iref{intro.progress}, then a thread of execution +implicitly created by the library will provide parallel forward progress guarantees; +otherwise, the provided forward progress guarantee is +\impldef{forward progress guarantees for implicit threads of parallel algorithms (if not defined for \tcode{thread})}. +Any such +invocations executing in the same thread of execution are indeterminately sequenced with +respect to each other. +\begin{note} +It is the caller's responsibility to ensure that the +invocation does not introduce data races or deadlocks. +\end{note} +\begin{example} +\begin{codeblock} +int a[] = {0,1}; +std::vector v; +std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) { + v.push_back(i*2+1); // incorrect: data race +}); +\end{codeblock} +The program above has a data race because of the unsynchronized access to the +container \tcode{v}. +\end{example} +\begin{example} +\begin{codeblock} +std::atomic x{0}; +int a[] = {1,2}; +std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) { + x.fetch_add(1, std::memory_order::relaxed); + // 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} +The above example depends on the order of execution of the iterations, and +will not terminate if both iterations are executed sequentially on the same +thread of execution. +\end{example} +\begin{example} +\begin{codeblock} +int x = 0; +std::mutex m; +int a[] = {1,2}; +std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) { + std::lock_guard guard(m); + ++x; +}); +\end{codeblock} +The above example synchronizes access to object \tcode{x} ensuring that it is +incremented correctly. +\end{example} + +\pnum +The invocations of element access functions in parallel algorithms invoked with +an execution policy of type \tcode{execution::parallel_unsequenced_policy} are +permitted to execute in an unordered fashion in unspecified threads of execution, and +unsequenced with respect to one another within each thread of execution. +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. +\begin{note} +This means that multiple function object invocations may be interleaved on a +single thread of execution, which overrides the usual guarantee from \ref{intro.execution} +that function executions do not interleave with one another. +\end{note} +Since \tcode{execution::parallel_unsequenced_policy} allows the execution of element +access functions to be interleaved on a single thread of execution, blocking synchronization, +including the use of mutexes, risks deadlock. Thus, the synchronization with +\tcode{execution::parallel_unsequenced_policy} is restricted as +follows: +A standard library function is \defn{vectorization-unsafe} if it is specified +to synchronize with another function invocation, or another function invocation +is specified to synchronize with it, and if it is not a memory allocation or +deallocation function. Vectorization-unsafe standard library functions may not +be invoked by user code called from \tcode{execution::parallel_unsequenced_policy} +algorithms. +\begin{note} +Implementations must ensure that internal synchronization inside standard +library functions does not prevent forward progress when those functions are +executed by threads of execution with weakly parallel forward progress guarantees. +\end{note} +\begin{example} +\begin{codeblock} +int x = 0; +std::mutex m; +int a[] = {1,2}; +std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) { + std::lock_guard guard(m); // incorrect: \tcode{lock_guard} constructor calls \tcode{m.lock()} + ++x; +}); +\end{codeblock} +The above program may result in two consecutive calls to \tcode{m.lock()} on +the same thread of execution (which may deadlock), because the applications of the function +object are not guaranteed to run on different threads of execution. +\end{example} +\begin{note} +The semantics of the \tcode{execution::parallel_policy} or the +\tcode{execution::parallel_unsequenced_policy} invocation allow the implementation to +fall back to sequential execution if the system cannot parallelize an algorithm +invocation due to lack of resources. +\end{note} + +\pnum +If an invocation of a parallel algorithm uses threads of execution implicitly +created by the library, then the invoking thread of execution will either + +\begin{itemize} +\item temporarily block with forward progress guarantee delegation\iref{intro.progress} + on the completion of these library-managed threads of execution, or +\item eventually execute an element access function; +\end{itemize} + +the thread of execution will continue to do so until the algorithm is finished. +\begin{note} +In blocking with forward progress guarantee delegation in this context, +a thread of execution created by the library is considered to have +finished execution as soon as it has finished the execution of the +particular element access function that the invoking thread of execution +logically depends on. +\end{note} + +\pnum +The semantics of parallel algorithms invoked with an execution policy object of +\impldef{additional execution policies supported by parallel algorithms} type are +\impldef{semantics of parallel algorithms invoked with +imple\-men\-tation-defined execution policies}. + +\rSec2[algorithms.parallel.exceptions]{Parallel algorithm exceptions} + +\pnum +During the execution of a parallel algorithm, if temporary memory resources are +required for parallelization and none are available, the algorithm throws a +\tcode{bad_alloc} exception. + +\pnum +During the execution of a parallel algorithm, if the invocation of an element +access function exits via an uncaught exception, +the behavior is determined by the \tcode{ExecutionPolicy}. + +\rSec2[algorithms.parallel.overloads]{\tcode{ExecutionPolicy} algorithm overloads} + +\pnum +Parallel algorithms are algorithm overloads. Each parallel algorithm overload +has an additional template type parameter named \tcode{ExecutionPolicy}, which +is the first template parameter. +Additionally, each parallel algorithm overload has an additional function +parameter of type \tcode{ExecutionPolicy\&\&}, which is the first +function parameter. +\begin{note} Not all algorithms have parallel algorithm overloads.\end{note} + +\pnum +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}. + +\rSec1[algorithm.syn]{Header \tcode{} synopsis} +\indexhdr{algorithm}% + +\begin{codeblock} +#include + +namespace std { + // \ref{alg.nonmodifying}, non-modifying sequence operations + // \ref{alg.all_of}, all of + template + constexpr bool all_of(InputIterator first, InputIterator last, Predicate pred); + template + bool all_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, Predicate pred); + + // \ref{alg.any_of}, any of + template + constexpr bool any_of(InputIterator first, InputIterator last, Predicate pred); + template + bool any_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, Predicate pred); + + // \ref{alg.none_of}, none of + template + constexpr bool none_of(InputIterator first, InputIterator last, Predicate pred); + template + bool none_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, Predicate pred); + + // \ref{alg.foreach}, for each + template + constexpr Function for_each(InputIterator first, InputIterator last, Function f); + template + void for_each(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, Function f); + template + constexpr InputIterator for_each_n(InputIterator first, Size n, Function f); + template + ForwardIterator for_each_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, Size n, Function f); + + // \ref{alg.find}, find + template + constexpr InputIterator find(InputIterator first, InputIterator last, + const T& value); + template + ForwardIterator find(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + const T& value); + template + constexpr InputIterator find_if(InputIterator first, InputIterator last, + Predicate pred); + template + ForwardIterator find_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + Predicate pred); + template + constexpr InputIterator find_if_not(InputIterator first, InputIterator last, + Predicate pred); + template + ForwardIterator find_if_not(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + Predicate pred); + + // \ref{alg.find.end}, find end + template + constexpr ForwardIterator1 + find_end(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + template + constexpr ForwardIterator1 + find_end(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); + template + ForwardIterator1 + find_end(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + template + ForwardIterator1 + find_end(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); + + // \ref{alg.find.first.of}, find first + template + constexpr InputIterator + find_first_of(InputIterator first1, InputIterator last1, + ForwardIterator first2, ForwardIterator last2); + template + constexpr InputIterator + find_first_of(InputIterator first1, InputIterator last1, + ForwardIterator first2, ForwardIterator last2, + BinaryPredicate pred); + template + ForwardIterator1 + find_first_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + template + ForwardIterator1 + find_first_of(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); + + // \ref{alg.adjacent.find}, adjacent find + template + constexpr ForwardIterator + adjacent_find(ForwardIterator first, ForwardIterator last); + template + constexpr ForwardIterator + adjacent_find(ForwardIterator first, ForwardIterator last, + BinaryPredicate pred); + template + ForwardIterator + adjacent_find(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last); + template + ForwardIterator + adjacent_find(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + BinaryPredicate pred); + + // \ref{alg.count}, count + template + constexpr typename iterator_traits::difference_type + count(InputIterator first, InputIterator last, const T& value); + template + typename iterator_traits::difference_type + count(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, const T& value); + template + constexpr typename iterator_traits::difference_type + count_if(InputIterator first, InputIterator last, Predicate pred); + template + typename iterator_traits::difference_type + count_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, Predicate pred); + + // \ref{mismatch}, mismatch + template + constexpr pair + mismatch(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2); + template + constexpr pair + mismatch(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, BinaryPredicate pred); + template + constexpr pair + mismatch(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2); + template + constexpr pair + mismatch(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + BinaryPredicate pred); + template + pair + mismatch(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); + template + pair + mismatch(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, BinaryPredicate pred); + template + pair + mismatch(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + template + pair + mismatch(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); + + // \ref{alg.equal}, equal + template + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2); + template + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, BinaryPredicate pred); + template + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2); + template + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + BinaryPredicate pred); + template + bool equal(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); + template + bool equal(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, BinaryPredicate pred); + template + bool equal(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + template + bool equal(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); + + // \ref{alg.is_permutation}, is permutation + template + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); + template + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, BinaryPredicate pred); + template + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + template + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); + + // \ref{alg.search}, search + template + constexpr ForwardIterator1 + search(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + template + constexpr ForwardIterator1 + search(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); + template + ForwardIterator1 + search(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + template + ForwardIterator1 + search(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); + template + constexpr ForwardIterator + search_n(ForwardIterator first, ForwardIterator last, + Size count, const T& value); + template + constexpr ForwardIterator + search_n(ForwardIterator first, ForwardIterator last, + Size count, const T& value, + BinaryPredicate pred); + template + ForwardIterator + search_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + Size count, const T& value); + template + ForwardIterator + search_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + Size count, const T& value, + BinaryPredicate pred); + + template + constexpr ForwardIterator + search(ForwardIterator first, ForwardIterator last, const Searcher& searcher); + + // \ref{alg.modifying.operations}, mutating sequence operations + // \ref{alg.copy}, copy + template + constexpr OutputIterator copy(InputIterator first, InputIterator last, + OutputIterator result); + template + ForwardIterator2 copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result); + template + constexpr OutputIterator copy_n(InputIterator first, Size n, + OutputIterator result); + template + ForwardIterator2 copy_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, Size n, + ForwardIterator2 result); + template + constexpr OutputIterator copy_if(InputIterator first, InputIterator last, + OutputIterator result, Predicate pred); + template + ForwardIterator2 copy_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, Predicate pred); + template + constexpr BidirectionalIterator2 + copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, + BidirectionalIterator2 result); + + // \ref{alg.move}, move + template + constexpr OutputIterator move(InputIterator first, InputIterator last, + OutputIterator result); + template + ForwardIterator2 move(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result); + template + constexpr BidirectionalIterator2 + move_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, + BidirectionalIterator2 result); + + // \ref{alg.swap}, swap + template + constexpr ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); + template + ForwardIterator2 swap_ranges(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); + template + constexpr void iter_swap(ForwardIterator1 a, ForwardIterator2 b); + + // \ref{alg.transform}, transform + template + constexpr OutputIterator + transform(InputIterator first, InputIterator last, + OutputIterator result, UnaryOperation op); + template + constexpr OutputIterator + transform(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, OutputIterator result, + BinaryOperation binary_op); + template + ForwardIterator2 + transform(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, UnaryOperation op); + 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 + constexpr void replace(ForwardIterator first, ForwardIterator last, + const T& old_value, const T& new_value); + template + void replace(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + const T& old_value, const T& new_value); + template + constexpr void replace_if(ForwardIterator first, ForwardIterator last, + Predicate pred, const T& new_value); + template + void replace_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + Predicate pred, const T& new_value); + template + constexpr OutputIterator replace_copy(InputIterator first, InputIterator last, + OutputIterator result, + const T& old_value, const T& new_value); + template + ForwardIterator2 replace_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + const T& old_value, const T& new_value); + template + constexpr OutputIterator replace_copy_if(InputIterator first, InputIterator last, + OutputIterator result, + Predicate pred, const T& new_value); + template + ForwardIterator2 replace_copy_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + Predicate pred, const T& new_value); + + // \ref{alg.fill}, fill + template + constexpr void fill(ForwardIterator first, ForwardIterator last, const T& value); template - typename iterator_traits::difference_type - count(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, const T& value); + void fill(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, const T& value); + template + constexpr OutputIterator fill_n(OutputIterator first, Size n, const T& value); + template + ForwardIterator fill_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, Size n, const T& value); + + // \ref{alg.generate}, generate + template + constexpr void generate(ForwardIterator first, ForwardIterator last, + Generator gen); + template + void generate(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + Generator gen); + template + constexpr OutputIterator generate_n(OutputIterator first, Size n, Generator gen); + template + ForwardIterator generate_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, Size n, Generator gen); + + // \ref{alg.remove}, remove + template + constexpr ForwardIterator remove(ForwardIterator first, ForwardIterator last, + const T& value); + template + ForwardIterator remove(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + const T& value); + template + constexpr ForwardIterator remove_if(ForwardIterator first, ForwardIterator last, + Predicate pred); + template + ForwardIterator remove_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + Predicate pred); + template + constexpr OutputIterator + remove_copy(InputIterator first, InputIterator last, + OutputIterator result, const T& value); + template + ForwardIterator2 + remove_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, const T& value); + template + constexpr OutputIterator + remove_copy_if(InputIterator first, InputIterator last, + OutputIterator result, Predicate pred); + template + ForwardIterator2 + remove_copy_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, Predicate pred); + + // \ref{alg.unique}, unique + template + constexpr ForwardIterator unique(ForwardIterator first, ForwardIterator last); + template + constexpr ForwardIterator unique(ForwardIterator first, ForwardIterator last, + BinaryPredicate pred); + template + ForwardIterator unique(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last); + template + ForwardIterator unique(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + BinaryPredicate pred); + template + constexpr OutputIterator + unique_copy(InputIterator first, InputIterator last, + OutputIterator result); + template + constexpr OutputIterator + unique_copy(InputIterator first, InputIterator last, + OutputIterator result, BinaryPredicate pred); + template + ForwardIterator2 + unique_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result); + template + ForwardIterator2 + unique_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, BinaryPredicate pred); + + // \ref{alg.reverse}, reverse + template + constexpr void reverse(BidirectionalIterator first, BidirectionalIterator last); + template + void reverse(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + BidirectionalIterator first, BidirectionalIterator last); + template + constexpr OutputIterator + reverse_copy(BidirectionalIterator first, BidirectionalIterator last, + OutputIterator result); + template + ForwardIterator + reverse_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + BidirectionalIterator first, BidirectionalIterator last, + ForwardIterator result); + + // \ref{alg.rotate}, rotate + template + constexpr ForwardIterator rotate(ForwardIterator first, + ForwardIterator middle, + ForwardIterator last); + template + ForwardIterator rotate(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, + ForwardIterator middle, + ForwardIterator last); + template + constexpr OutputIterator + rotate_copy(ForwardIterator first, ForwardIterator middle, + ForwardIterator last, OutputIterator result); + template + ForwardIterator2 + rotate_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 middle, + ForwardIterator1 last, ForwardIterator2 result); + + // \ref{alg.random.sample}, sample + template + SampleIterator sample(PopulationIterator first, PopulationIterator last, + SampleIterator out, Distance n, + UniformRandomBitGenerator&& g); + + // \ref{alg.random.shuffle}, shuffle + template + void shuffle(RandomAccessIterator first, + RandomAccessIterator last, + UniformRandomBitGenerator&& g); + + // \ref{alg.shift}, shift + template + constexpr ForwardIterator + shift_left(ForwardIterator first, ForwardIterator last, + typename iterator_traits::difference_type n); + template + ForwardIterator + shift_left(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + typename iterator_traits::difference_type n); + template + constexpr ForwardIterator + shift_right(ForwardIterator first, ForwardIterator last, + typename iterator_traits::difference_type n); + template + ForwardIterator + shift_right(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + typename iterator_traits::difference_type n); + + // \ref{alg.sorting}, sorting and related operations + // \ref{alg.sort}, sorting + template + constexpr void sort(RandomAccessIterator first, RandomAccessIterator last); + template + constexpr void sort(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + template + void sort(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator last); + template + void sort(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + + template + void stable_sort(RandomAccessIterator first, RandomAccessIterator last); + template + void stable_sort(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + template + void stable_sort(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator last); + template + void stable_sort(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + + template + constexpr void partial_sort(RandomAccessIterator first, + RandomAccessIterator middle, + RandomAccessIterator last); + template + constexpr void partial_sort(RandomAccessIterator first, + RandomAccessIterator middle, + RandomAccessIterator last, Compare comp); + template + void partial_sort(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, + RandomAccessIterator middle, + RandomAccessIterator last); + template + void partial_sort(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, + RandomAccessIterator middle, + RandomAccessIterator last, Compare comp); + template + constexpr RandomAccessIterator + partial_sort_copy(InputIterator first, InputIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last); + template + constexpr RandomAccessIterator + partial_sort_copy(InputIterator first, InputIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last, + Compare comp); + template + RandomAccessIterator + partial_sort_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last); + template + RandomAccessIterator + partial_sort_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last, + Compare comp); + template + constexpr bool is_sorted(ForwardIterator first, ForwardIterator last); + template + constexpr bool is_sorted(ForwardIterator first, ForwardIterator last, + Compare comp); + template + bool is_sorted(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last); + template + bool is_sorted(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + Compare comp); + template + constexpr ForwardIterator + is_sorted_until(ForwardIterator first, ForwardIterator last); + template + constexpr ForwardIterator + is_sorted_until(ForwardIterator first, ForwardIterator last, + Compare comp); + template + ForwardIterator + is_sorted_until(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last); + template + ForwardIterator + is_sorted_until(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + Compare comp); + + // \ref{alg.nth.element}, Nth element + template + constexpr void nth_element(RandomAccessIterator first, RandomAccessIterator nth, + RandomAccessIterator last); + template + constexpr void nth_element(RandomAccessIterator first, RandomAccessIterator nth, + RandomAccessIterator last, Compare comp); + template + void nth_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator nth, + RandomAccessIterator last); + template + void nth_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator nth, + RandomAccessIterator last, Compare comp); + + // \ref{alg.binary.search}, binary search + template + constexpr ForwardIterator + lower_bound(ForwardIterator first, ForwardIterator last, + const T& value); + template + constexpr ForwardIterator + lower_bound(ForwardIterator first, ForwardIterator last, + const T& value, Compare comp); + + template + constexpr ForwardIterator + upper_bound(ForwardIterator first, ForwardIterator last, + const T& value); + template + constexpr ForwardIterator + upper_bound(ForwardIterator first, ForwardIterator last, + const T& value, Compare comp); + + template + constexpr pair + equal_range(ForwardIterator first, ForwardIterator last, + const T& value); + template + constexpr pair + equal_range(ForwardIterator first, ForwardIterator last, + const T& value, Compare comp); + + template + constexpr bool + binary_search(ForwardIterator first, ForwardIterator last, + const T& value); + template + constexpr bool + binary_search(ForwardIterator first, ForwardIterator last, + const T& value, Compare comp); + + // \ref{alg.partitions}, partitions template - constexpr typename iterator_traits::difference_type - count_if(InputIterator first, InputIterator last, Predicate pred); + constexpr bool is_partitioned(InputIterator first, InputIterator last, Predicate pred); template - typename iterator_traits::difference_type - count_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, Predicate pred); + bool is_partitioned(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, Predicate pred); - // \ref{mismatch}, mismatch - template - constexpr pair - mismatch(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2); - template - constexpr pair - mismatch(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, BinaryPredicate pred); - template - constexpr pair - mismatch(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); - template - constexpr pair - mismatch(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - BinaryPredicate pred); - template + template + constexpr ForwardIterator partition(ForwardIterator first, + ForwardIterator last, + Predicate pred); + template + ForwardIterator partition(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, + ForwardIterator last, + Predicate pred); + template + BidirectionalIterator stable_partition(BidirectionalIterator first, + BidirectionalIterator last, + Predicate pred); + template + BidirectionalIterator stable_partition(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + BidirectionalIterator first, + BidirectionalIterator last, + Predicate pred); + template + constexpr pair + partition_copy(InputIterator first, InputIterator last, + OutputIterator1 out_true, OutputIterator2 out_false, + Predicate pred); + template pair - mismatch(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2); + partition_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + ForwardIterator1 out_true, ForwardIterator2 out_false, + Predicate pred); + template + constexpr ForwardIterator + partition_point(ForwardIterator first, ForwardIterator last, + Predicate pred); + + // \ref{alg.merge}, merge + template + constexpr OutputIterator + merge(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); + template + constexpr OutputIterator + merge(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); template - pair - mismatch(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, BinaryPredicate pred); - template - pair - mismatch(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); + class ForwardIterator> + ForwardIterator + merge(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); template - pair - mismatch(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); + class ForwardIterator, class Compare> + ForwardIterator + merge(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); - // \ref{alg.equal}, equal - template - constexpr bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2); - template - constexpr bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, BinaryPredicate pred); + template + void inplace_merge(BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last); + template + void inplace_merge(BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last, Compare comp); + template + void inplace_merge(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last); + template + void inplace_merge(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last, Compare comp); + + // \ref{alg.set.operations}, set operations template - constexpr bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); - template - constexpr bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - BinaryPredicate pred); + constexpr bool includes(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2); + template + constexpr bool includes(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + Compare comp); template - bool equal(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2); + bool includes(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + template + bool includes(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + Compare comp); + + template + constexpr OutputIterator + set_union(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); + template + constexpr OutputIterator + set_union(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); + template + ForwardIterator + set_union(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); + template + ForwardIterator + set_union(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); + + template + constexpr OutputIterator + set_intersection(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); + template + constexpr OutputIterator + set_intersection(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); template - bool equal(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, BinaryPredicate pred); - template - bool equal(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); + class ForwardIterator> + ForwardIterator + set_intersection(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); template - bool equal(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); + class ForwardIterator, class Compare> + ForwardIterator + set_intersection(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); - // \ref{alg.is_permutation}, is permutation - template - constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2); - template - constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, BinaryPredicate pred); - template - constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); - template - constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); + template + constexpr OutputIterator + set_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); + template + constexpr OutputIterator + set_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); + template + ForwardIterator + set_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); + template + ForwardIterator + set_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); - // \ref{alg.search}, search - template - constexpr ForwardIterator1 - search(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); - template - constexpr ForwardIterator1 - search(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); - template - ForwardIterator1 - search(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); + template + constexpr OutputIterator + set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); + template + constexpr OutputIterator + set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); template - ForwardIterator1 - search(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); - template - constexpr ForwardIterator - search_n(ForwardIterator first, ForwardIterator last, - Size count, const T& value); - template - constexpr ForwardIterator - search_n(ForwardIterator first, ForwardIterator last, - Size count, const T& value, - BinaryPredicate pred); - template + class ForwardIterator> ForwardIterator - search_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - Size count, const T& value); - template + set_symmetric_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); + template ForwardIterator - search_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - Size count, const T& value, - BinaryPredicate pred); + set_symmetric_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); - template - constexpr ForwardIterator - search(ForwardIterator first, ForwardIterator last, const Searcher& searcher); + // \ref{alg.heap.operations}, heap operations + template + constexpr void push_heap(RandomAccessIterator first, RandomAccessIterator last); + template + constexpr void push_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); - // \ref{alg.modifying.operations}, mutating sequence operations - // \ref{alg.copy}, copy - template - constexpr OutputIterator copy(InputIterator first, InputIterator last, - OutputIterator result); + template + constexpr void pop_heap(RandomAccessIterator first, RandomAccessIterator last); + template + constexpr void pop_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + + template + constexpr void make_heap(RandomAccessIterator first, RandomAccessIterator last); + template + constexpr void make_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + + template + constexpr void sort_heap(RandomAccessIterator first, RandomAccessIterator last); + template + constexpr void sort_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + + template + constexpr bool is_heap(RandomAccessIterator first, RandomAccessIterator last); + template + constexpr bool is_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + template + bool is_heap(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator last); + template + bool is_heap(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + template + constexpr RandomAccessIterator + is_heap_until(RandomAccessIterator first, RandomAccessIterator last); + template + constexpr RandomAccessIterator + is_heap_until(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + template + RandomAccessIterator + is_heap_until(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator last); + template + RandomAccessIterator + is_heap_until(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + RandomAccessIterator first, RandomAccessIterator last, + Compare comp); + + // \ref{alg.min.max}, minimum and maximum + template constexpr const T& min(const T& a, const T& b); + template + constexpr const T& min(const T& a, const T& b, Compare comp); + template + constexpr T min(initializer_list t); + template + constexpr T min(initializer_list t, Compare comp); + + template constexpr const T& max(const T& a, const T& b); + template + constexpr const T& max(const T& a, const T& b, Compare comp); + template + constexpr T max(initializer_list t); + template + constexpr T max(initializer_list t, Compare comp); + + template constexpr pair minmax(const T& a, const T& b); + template + constexpr pair minmax(const T& a, const T& b, Compare comp); + template + constexpr pair minmax(initializer_list t); + template + constexpr pair minmax(initializer_list t, Compare comp); + + template + constexpr ForwardIterator min_element(ForwardIterator first, ForwardIterator last); + template + constexpr ForwardIterator min_element(ForwardIterator first, ForwardIterator last, + Compare comp); + template + ForwardIterator min_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last); + template + ForwardIterator min_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + Compare comp); + template + constexpr ForwardIterator max_element(ForwardIterator first, ForwardIterator last); + template + constexpr ForwardIterator max_element(ForwardIterator first, ForwardIterator last, + Compare comp); + template + ForwardIterator max_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last); + template + ForwardIterator max_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, + Compare comp); + template + constexpr pair + minmax_element(ForwardIterator first, ForwardIterator last); + template + constexpr pair + minmax_element(ForwardIterator first, ForwardIterator last, Compare comp); + template + pair + minmax_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last); + template + pair + minmax_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, Compare comp); + + // \ref{alg.clamp}, bounded value + template + constexpr const T& clamp(const T& v, const T& lo, const T& hi); + template + constexpr const T& clamp(const T& v, const T& lo, const T& hi, Compare comp); + + // \ref{alg.lex.comparison}, lexicographical comparison + template + constexpr bool + lexicographical_compare(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2); + template + constexpr bool + lexicographical_compare(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + Compare comp); template - ForwardIterator2 copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result); - template - constexpr OutputIterator copy_n(InputIterator first, Size n, - OutputIterator result); - template - ForwardIterator2 copy_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first, Size n, - ForwardIterator2 result); - template - constexpr OutputIterator copy_if(InputIterator first, InputIterator last, - OutputIterator result, Predicate pred); + bool + lexicographical_compare(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); template - ForwardIterator2 copy_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, Predicate pred); - template - constexpr BidirectionalIterator2 - copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, - BidirectionalIterator2 result); + class Compare> + bool + lexicographical_compare(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + Compare comp); - // \ref{alg.move}, move - template - constexpr OutputIterator move(InputIterator first, InputIterator last, - OutputIterator result); - template - ForwardIterator2 move(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result); - template - constexpr BidirectionalIterator2 - move_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, - BidirectionalIterator2 result); + // \ref{alg.3way}, three-way comparison algorithms + template + constexpr auto compare_3way(const T& a, const U& b); + template + constexpr auto + lexicographical_compare_3way(InputIterator1 b1, InputIterator1 e1, + InputIterator2 b2, InputIterator2 e2, + Cmp comp) + -> common_comparison_category_t; + template + constexpr auto + lexicographical_compare_3way(InputIterator1 b1, InputIterator1 e1, + InputIterator2 b2, InputIterator2 e2); - // \ref{alg.swap}, swap - template - ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2); - template - ForwardIterator2 swap_ranges(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2); - template - void iter_swap(ForwardIterator1 a, ForwardIterator2 b); + // \ref{alg.permutation.generators}, permutations + template + constexpr bool next_permutation(BidirectionalIterator first, + BidirectionalIterator last); + template + constexpr bool next_permutation(BidirectionalIterator first, + BidirectionalIterator last, Compare comp); + template + constexpr bool prev_permutation(BidirectionalIterator first, + BidirectionalIterator last); + template + constexpr bool prev_permutation(BidirectionalIterator first, + BidirectionalIterator last, Compare comp); +} +\end{codeblock} - // \ref{alg.transform}, transform - template - constexpr OutputIterator - transform(InputIterator first, InputIterator last, - OutputIterator result, UnaryOperation op); - template - constexpr OutputIterator - transform(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, OutputIterator result, - BinaryOperation binary_op); - template - ForwardIterator2 - transform(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, UnaryOperation op); - template - ForwardIterator - transform(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator result, - BinaryOperation binary_op); +\rSec1[alg.nonmodifying]{Non-modifying sequence operations} - // \ref{alg.replace}, replace - template - constexpr void replace(ForwardIterator first, ForwardIterator last, - const T& old_value, const T& new_value); - template - void replace(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - const T& old_value, const T& new_value); - template - constexpr void replace_if(ForwardIterator first, ForwardIterator last, - Predicate pred, const T& new_value); - template - void replace_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - Predicate pred, const T& new_value); - template - constexpr OutputIterator replace_copy(InputIterator first, InputIterator last, - OutputIterator result, - const T& old_value, const T& new_value); - template - ForwardIterator2 replace_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, - const T& old_value, const T& new_value); - template - constexpr OutputIterator replace_copy_if(InputIterator first, InputIterator last, - OutputIterator result, - Predicate pred, const T& new_value); - template - ForwardIterator2 replace_copy_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, - Predicate pred, const T& new_value); +\rSec2[alg.all_of]{All of} - // \ref{alg.fill}, fill - template - constexpr void fill(ForwardIterator first, ForwardIterator last, const T& value); - template - void fill(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, const T& value); - template - constexpr OutputIterator fill_n(OutputIterator first, Size n, const T& value); - template - ForwardIterator fill_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, Size n, const T& value); +\indexlibrary{\idxcode{all_of}}% +\begin{itemdecl} +template + constexpr bool all_of(InputIterator first, InputIterator last, Predicate pred); +template + bool all_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, + Predicate pred); +\end{itemdecl} - // \ref{alg.generate}, generate - template - constexpr void generate(ForwardIterator first, ForwardIterator last, - Generator gen); - template - void generate(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - Generator gen); - template - constexpr OutputIterator generate_n(OutputIterator first, Size n, Generator gen); - template - ForwardIterator generate_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, Size n, Generator gen); +\begin{itemdescr} +\pnum +\returns \tcode{true} if +\range{first}{last} is empty or if +\tcode{pred(*i)} is \tcode{true} for every iterator \tcode{i} in the range \range{first}{last}, and \tcode{false} otherwise. - // \ref{alg.remove}, remove - template - constexpr ForwardIterator remove(ForwardIterator first, ForwardIterator last, - const T& value); - template - ForwardIterator remove(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - const T& value); - template - constexpr ForwardIterator remove_if(ForwardIterator first, ForwardIterator last, - Predicate pred); - template - ForwardIterator remove_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - Predicate pred); - template - constexpr OutputIterator - remove_copy(InputIterator first, InputIterator last, - OutputIterator result, const T& value); - template - ForwardIterator2 - remove_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, const T& value); - template - constexpr OutputIterator - remove_copy_if(InputIterator first, InputIterator last, - OutputIterator result, Predicate pred); - template - ForwardIterator2 - remove_copy_if(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, Predicate pred); +\pnum +\complexity At most \tcode{last - first} applications of the predicate. +\end{itemdescr} - // \ref{alg.unique}, unique - template - constexpr ForwardIterator unique(ForwardIterator first, ForwardIterator last); - template - constexpr ForwardIterator unique(ForwardIterator first, ForwardIterator last, - BinaryPredicate pred); - template - ForwardIterator unique(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last); - template - ForwardIterator unique(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - BinaryPredicate pred); - template - constexpr OutputIterator - unique_copy(InputIterator first, InputIterator last, - OutputIterator result); - template - constexpr OutputIterator - unique_copy(InputIterator first, InputIterator last, - OutputIterator result, BinaryPredicate pred); - template - ForwardIterator2 - unique_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result); - template - ForwardIterator2 - unique_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, BinaryPredicate pred); +\rSec2[alg.any_of]{Any of} + +\indexlibrary{\idxcode{any_of}}% +\begin{itemdecl} +template + constexpr bool any_of(InputIterator first, InputIterator last, Predicate pred); +template + bool any_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, + Predicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{false} if \range{first}{last} is empty or +if there is no iterator \tcode{i} in the range +\range{first}{last} such that \tcode{pred(*i)} is \tcode{true}, and \tcode{true} otherwise. - // \ref{alg.reverse}, reverse - template - void reverse(BidirectionalIterator first, BidirectionalIterator last); - template - void reverse(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - BidirectionalIterator first, BidirectionalIterator last); - template - constexpr OutputIterator - reverse_copy(BidirectionalIterator first, BidirectionalIterator last, - OutputIterator result); - template - ForwardIterator - reverse_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - BidirectionalIterator first, BidirectionalIterator last, - ForwardIterator result); +\pnum +\complexity At most \tcode{last - first} applications of the predicate. +\end{itemdescr} - // \ref{alg.rotate}, rotate - template - ForwardIterator rotate(ForwardIterator first, - ForwardIterator middle, - ForwardIterator last); - template - ForwardIterator rotate(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, - ForwardIterator middle, - ForwardIterator last); - template - constexpr OutputIterator - rotate_copy(ForwardIterator first, ForwardIterator middle, - ForwardIterator last, OutputIterator result); - template - ForwardIterator2 - rotate_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first, ForwardIterator1 middle, - ForwardIterator1 last, ForwardIterator2 result); +\rSec2[alg.none_of]{None of} - // \ref{alg.random.sample}, sample - template - SampleIterator sample(PopulationIterator first, PopulationIterator last, - SampleIterator out, Distance n, - UniformRandomBitGenerator&& g); +\indexlibrary{\idxcode{none_of}}% +\begin{itemdecl} +template + constexpr bool none_of(InputIterator first, InputIterator last, Predicate pred); +template + bool none_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, + Predicate pred); +\end{itemdecl} - // \ref{alg.random.shuffle}, shuffle - template - void shuffle(RandomAccessIterator first, - RandomAccessIterator last, - UniformRandomBitGenerator&& g); +\begin{itemdescr} +\pnum +\returns \tcode{true} if +\range{first}{last} is empty or if +\tcode{pred(*i)} is \tcode{false} for every iterator \tcode{i} in the range \range{first}{last}, and \tcode{false} otherwise. - // \ref{alg.partitions}, partitions - template - constexpr bool is_partitioned(InputIterator first, InputIterator last, Predicate pred); - template - bool is_partitioned(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, Predicate pred); +\pnum +\complexity At most \tcode{last - first} applications of the predicate. +\end{itemdescr} - template - ForwardIterator partition(ForwardIterator first, - ForwardIterator last, - Predicate pred); - template - ForwardIterator partition(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, - ForwardIterator last, - Predicate pred); - template - BidirectionalIterator stable_partition(BidirectionalIterator first, - BidirectionalIterator last, - Predicate pred); - template - BidirectionalIterator stable_partition(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - BidirectionalIterator first, - BidirectionalIterator last, - Predicate pred); - template - constexpr 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} - ForwardIterator first, ForwardIterator last, - ForwardIterator1 out_true, ForwardIterator2 out_false, - Predicate pred); - template - constexpr ForwardIterator - partition_point(ForwardIterator first, ForwardIterator last, - Predicate pred); +\rSec2[alg.foreach]{For each} - // \ref{alg.sorting}, sorting and related operations - // \ref{alg.sort}, sorting - template - void sort(RandomAccessIterator first, RandomAccessIterator last); - template - void sort(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); - template - void sort(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - RandomAccessIterator first, RandomAccessIterator last); - template - void sort(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - RandomAccessIterator first, RandomAccessIterator last, - Compare comp); +\indexlibrary{\idxcode{for_each}}% +\begin{itemdecl} +template + constexpr Function for_each(InputIterator first, InputIterator last, Function f); +\end{itemdecl} - template - void stable_sort(RandomAccessIterator first, RandomAccessIterator last); - template - void stable_sort(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); - template - void stable_sort(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - RandomAccessIterator first, RandomAccessIterator last); - template - void stable_sort(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - RandomAccessIterator first, RandomAccessIterator last, - Compare comp); +\begin{itemdescr} +\pnum +\requires \tcode{Function} shall satisfy the +\oldconcept{MoveConstructible} requirements (\tref{moveconstructible}). +\begin{note} \tcode{Function} need not meet the requirements of +\oldconcept{CopyConstructible} (\tref{copyconstructible}). \end{note} - template - void partial_sort(RandomAccessIterator first, - RandomAccessIterator middle, - RandomAccessIterator last); - template - void partial_sort(RandomAccessIterator first, - RandomAccessIterator middle, - RandomAccessIterator last, Compare comp); - template - void partial_sort(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - RandomAccessIterator first, - RandomAccessIterator middle, - RandomAccessIterator last); - template - void partial_sort(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - RandomAccessIterator first, - RandomAccessIterator middle, - RandomAccessIterator last, Compare comp); - template - RandomAccessIterator - partial_sort_copy(InputIterator first, InputIterator last, - RandomAccessIterator result_first, - RandomAccessIterator result_last); - template - RandomAccessIterator - partial_sort_copy(InputIterator first, InputIterator last, - RandomAccessIterator result_first, - RandomAccessIterator result_last, - Compare comp); - template - RandomAccessIterator - partial_sort_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - RandomAccessIterator result_first, - RandomAccessIterator result_last); - template - RandomAccessIterator - partial_sort_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - RandomAccessIterator result_first, - RandomAccessIterator result_last, - Compare comp); - template - constexpr bool is_sorted(ForwardIterator first, ForwardIterator last); - template - constexpr bool is_sorted(ForwardIterator first, ForwardIterator last, - Compare comp); - template - bool is_sorted(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last); - template - bool is_sorted(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - Compare comp); - template - constexpr ForwardIterator - is_sorted_until(ForwardIterator first, ForwardIterator last); - template - constexpr ForwardIterator - is_sorted_until(ForwardIterator first, ForwardIterator last, - Compare comp); - template - ForwardIterator - is_sorted_until(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last); - template - ForwardIterator - is_sorted_until(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - Compare comp); +\pnum +\effects +Applies +\tcode{f} to the result of dereferencing every iterator in the range +\range{first}{last}, +starting from +\tcode{first} +and proceeding to +\tcode{last - 1}. +\begin{note} If the type of \tcode{first} satisfies the +requirements of a mutable iterator, \tcode{f} may apply non-constant +functions through the dereferenced iterator.\end{note} + +\pnum +\returns +\tcode{f}. + +\pnum +\complexity +Applies \tcode{f} +exactly +\tcode{last - first} +times. + +\pnum +\remarks +If \tcode{f} returns a result, the result is ignored. +\end{itemdescr} + +\indexlibrary{\idxcode{for_each}}% +\begin{itemdecl} +template + void for_each(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + Function f); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires +\tcode{Function} shall satisfy the \oldconcept{CopyConstructible} requirements. + +\pnum +\effects +Applies \tcode{f} to the result of dereferencing every iterator in the range +\range{first}{last}. +\begin{note} +If the type of \tcode{first} satisfies the requirements of a mutable iterator, +\tcode{f} may apply non-constant functions through the dereferenced iterator. +\end{note} - // \ref{alg.nth.element}, Nth element - template - void nth_element(RandomAccessIterator first, RandomAccessIterator nth, - RandomAccessIterator last); - template - void nth_element(RandomAccessIterator first, RandomAccessIterator nth, - RandomAccessIterator last, Compare comp); - template - void nth_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - RandomAccessIterator first, RandomAccessIterator nth, - RandomAccessIterator last); - template - void nth_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - RandomAccessIterator first, RandomAccessIterator nth, - RandomAccessIterator last, Compare comp); +\pnum +\complexity +Applies \tcode{f} exactly \tcode{last - first} times. - // \ref{alg.binary.search}, binary search - template - constexpr ForwardIterator - lower_bound(ForwardIterator first, ForwardIterator last, - const T& value); - template - constexpr ForwardIterator - lower_bound(ForwardIterator first, ForwardIterator last, - const T& value, Compare comp); +\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. - template - constexpr ForwardIterator - upper_bound(ForwardIterator first, ForwardIterator last, - const T& value); - template - constexpr ForwardIterator - upper_bound(ForwardIterator first, ForwardIterator last, - const T& value, Compare comp); +\pnum +\begin{note} +Does not return a copy of its \tcode{Function} parameter, since +parallelization may not permit efficient state accumulation. +\end{note} +\end{itemdescr} - template - constexpr pair - equal_range(ForwardIterator first, ForwardIterator last, - const T& value); - template - constexpr pair - equal_range(ForwardIterator first, ForwardIterator last, - const T& value, Compare comp); +\indexlibrary{\idxcode{for_each_n}}% +\begin{itemdecl} +template + constexpr InputIterator for_each_n(InputIterator first, Size n, Function f); +\end{itemdecl} - template - constexpr bool - binary_search(ForwardIterator first, ForwardIterator last, - const T& value); - template - constexpr bool - binary_search(ForwardIterator first, ForwardIterator last, - const T& value, Compare comp); +\begin{itemdescr} +\pnum +\requires +\tcode{Function} shall satisfy the \oldconcept{MoveConstructible} requirements +\begin{note} \tcode{Function} need not meet the requirements of +\oldconcept{CopyConstructible}. \end{note} - // \ref{alg.merge}, merge - template - constexpr OutputIterator - merge(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); - template - constexpr OutputIterator - merge(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); - template - ForwardIterator - merge(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result); - template - ForwardIterator - merge(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result, Compare comp); +\pnum +\requires +\tcode{n >= 0}. - template - void inplace_merge(BidirectionalIterator first, - BidirectionalIterator middle, - BidirectionalIterator last); - template - void inplace_merge(BidirectionalIterator first, - BidirectionalIterator middle, - BidirectionalIterator last, Compare comp); - template - void inplace_merge(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - BidirectionalIterator first, - BidirectionalIterator middle, - BidirectionalIterator last); - template - void inplace_merge(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - BidirectionalIterator first, - BidirectionalIterator middle, - BidirectionalIterator last, Compare comp); +\pnum +\effects +Applies \tcode{f} to the result of dereferencing every iterator in the range +\range{first}{first + n} in order. +\begin{note} +If the type of \tcode{first} satisfies the requirements of a mutable iterator, +\tcode{f} may apply non-constant functions through the dereferenced iterator. +\end{note} - // \ref{alg.set.operations}, set operations - template - constexpr bool includes(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); - template - constexpr bool includes(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - Compare comp); - template - bool includes(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); - template - bool includes(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - Compare comp); +\pnum +\returns +\tcode{first + n}. - template - constexpr OutputIterator - set_union(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); - template - constexpr OutputIterator - set_union(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); - template - ForwardIterator - set_union(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result); - template - ForwardIterator - set_union(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result, Compare comp); +\pnum +\remarks +If \tcode{f} returns a result, the result is ignored. +\end{itemdescr} - template - constexpr OutputIterator - set_intersection(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); - template - constexpr OutputIterator - set_intersection(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); - template - ForwardIterator - set_intersection(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result); - template - ForwardIterator - set_intersection(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result, Compare comp); +\indexlibrary{\idxcode{for_each_n}}% +\begin{itemdecl} +template + ForwardIterator for_each_n(ExecutionPolicy&& exec, ForwardIterator first, Size n, + Function f); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires +\tcode{Function} shall satisfy the \oldconcept{CopyConstructible} requirements. + +\pnum +\requires +\tcode{n >= 0}. + +\pnum +\effects +Applies \tcode{f} to the result of dereferencing every iterator in the range +\range{first}{first + n}. +\begin{note} +If the type of \tcode{first} satisfies the requirements of a mutable iterator, +\tcode{f} may apply non-constant functions through the dereferenced iterator. +\end{note} + +\pnum +\returns +\tcode{first + n}. + +\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. +\end{itemdescr} + + +\rSec2[alg.find]{Find} + +\indexlibrary{\idxcode{find}}% +\indexlibrary{\idxcode{find_if}}% +\indexlibrary{\idxcode{find_if_not}}% +\begin{itemdecl} +template + constexpr InputIterator find(InputIterator first, InputIterator last, + const T& value); +template + ForwardIterator find(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, + const T& value); + +template + constexpr InputIterator find_if(InputIterator first, InputIterator last, + Predicate pred); +template + ForwardIterator find_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, + Predicate pred); + +template + constexpr InputIterator find_if_not(InputIterator first, InputIterator last, + Predicate pred); +template + ForwardIterator find_if_not(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, + Predicate pred); +\end{itemdecl} - template - constexpr OutputIterator - set_difference(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); - template - constexpr OutputIterator - set_difference(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); - template - ForwardIterator - set_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result); - template - ForwardIterator - set_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result, Compare comp); +\begin{itemdescr} +\pnum +\returns +The first iterator +\tcode{i} +in the range +\range{first}{last} +for which the following corresponding +conditions hold: +\tcode{*i == value}, \tcode{pred(*i) != false}, \tcode{pred(*i) == false}. +Returns \tcode{last} if no such iterator is found. - template - constexpr OutputIterator - set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); - template - constexpr OutputIterator - set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); - template - ForwardIterator - set_symmetric_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result); - template - ForwardIterator - set_symmetric_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result, Compare comp); +\pnum +\complexity +At most +\tcode{last - first} +applications of the corresponding predicate. +\end{itemdescr} - // \ref{alg.heap.operations}, heap operations - template - void push_heap(RandomAccessIterator first, RandomAccessIterator last); - template - void push_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); +\rSec2[alg.find.end]{Find end} - template - void pop_heap(RandomAccessIterator first, RandomAccessIterator last); - template - void pop_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); +\indexlibrary{\idxcode{find_end}}% +\begin{itemdecl} +template + constexpr ForwardIterator1 + find_end(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); +template + ForwardIterator1 + find_end(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); - template - void make_heap(RandomAccessIterator first, RandomAccessIterator last); - template - void make_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); +template + constexpr ForwardIterator1 + find_end(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); +template + ForwardIterator1 + find_end(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); +\end{itemdecl} - template - void sort_heap(RandomAccessIterator first, RandomAccessIterator last); - template - void sort_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); +\begin{itemdescr} +\pnum +\effects +Finds a subsequence of equal values in a sequence. - template - constexpr bool is_heap(RandomAccessIterator first, RandomAccessIterator last); - template - constexpr bool is_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); - template - bool is_heap(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - RandomAccessIterator first, RandomAccessIterator last); - template - bool is_heap(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - RandomAccessIterator first, RandomAccessIterator last, - Compare comp); - template - constexpr RandomAccessIterator - is_heap_until(RandomAccessIterator first, RandomAccessIterator last); - template - constexpr RandomAccessIterator - is_heap_until(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); - template - RandomAccessIterator - is_heap_until(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - RandomAccessIterator first, RandomAccessIterator last); - template - RandomAccessIterator - is_heap_until(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - RandomAccessIterator first, RandomAccessIterator last, - Compare comp); +\pnum +\returns +The last iterator +\tcode{i} +in the range \range{first1}{last1 - (last2 - first2)} +such that for every non-negative integer +\tcode{n < (last2 - first2)}, +the following corresponding conditions hold: +\tcode{*(i + n) == *(\brk{}first2 + n), pred(*(i + n), *(first2 + n)) != false}. +Returns \tcode{last1} +if +\range{first2}{last2} is empty or if +no such iterator is found. - // \ref{alg.min.max}, minimum and maximum - template constexpr const T& min(const T& a, const T& b); - template - constexpr const T& min(const T& a, const T& b, Compare comp); - template - constexpr T min(initializer_list t); - template - constexpr T min(initializer_list t, Compare comp); +\pnum +\complexity +At most +\tcode{(last2 - first2) * (last1 - first1 - (last2 - first2) + 1)} +applications of the corresponding predicate. +\end{itemdescr} - template constexpr const T& max(const T& a, const T& b); - template - constexpr const T& max(const T& a, const T& b, Compare comp); - template - constexpr T max(initializer_list t); - template - constexpr T max(initializer_list t, Compare comp); +\rSec2[alg.find.first.of]{Find first} - template constexpr pair minmax(const T& a, const T& b); - template - constexpr pair minmax(const T& a, const T& b, Compare comp); - template - constexpr pair minmax(initializer_list t); - template - constexpr pair minmax(initializer_list t, Compare comp); +\indexlibrary{\idxcode{find_first_of}}% +\begin{itemdecl} +template + constexpr InputIterator + find_first_of(InputIterator first1, InputIterator last1, + ForwardIterator first2, ForwardIterator last2); +template + ForwardIterator1 + find_first_of(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); - template - constexpr ForwardIterator min_element(ForwardIterator first, ForwardIterator last); - template - constexpr ForwardIterator min_element(ForwardIterator first, ForwardIterator last, - Compare comp); - template - ForwardIterator min_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last); - template - ForwardIterator min_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - Compare comp); - template - constexpr ForwardIterator max_element(ForwardIterator first, ForwardIterator last); - template - constexpr ForwardIterator max_element(ForwardIterator first, ForwardIterator last, - Compare comp); - template - ForwardIterator max_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last); - template - ForwardIterator max_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, - Compare comp); - template - constexpr pair - minmax_element(ForwardIterator first, ForwardIterator last); - template - constexpr pair - minmax_element(ForwardIterator first, ForwardIterator last, Compare comp); - template - pair - minmax_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last); - template - pair - minmax_element(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, Compare comp); +template + constexpr InputIterator + find_first_of(InputIterator first1, InputIterator last1, + ForwardIterator first2, ForwardIterator last2, + BinaryPredicate pred); +template + ForwardIterator1 + find_first_of(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Finds an element that matches one of a set of values. + +\pnum +\returns +The first iterator +\tcode{i} +in the range \range{first1}{last1} +such that for some +iterator +\tcode{j} +in the range \range{first2}{last2} +the following conditions hold: +\tcode{*i == *j, pred(*i,*j) != false}. +Returns \tcode{last1} +if \range{first2}{last2} is empty or +if no such iterator is found. - // \ref{alg.clamp}, bounded value - template - constexpr const T& clamp(const T& v, const T& lo, const T& hi); - template - constexpr const T& clamp(const T& v, const T& lo, const T& hi, Compare comp); +\pnum +\complexity +At most +\tcode{(last1-first1) * (last2-first2)} +applications of the corresponding predicate. +\end{itemdescr} - // \ref{alg.lex.comparison}, lexicographical comparison - template - constexpr bool - lexicographical_compare(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); - template - constexpr bool - lexicographical_compare(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - Compare comp); - template - bool - lexicographical_compare(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); - template - bool - lexicographical_compare(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - Compare comp); +\rSec2[alg.adjacent.find]{Adjacent find} - // \ref{alg.3way}, three-way comparison algorithms - template - constexpr auto compare_3way(const T& a, const U& b); - template - constexpr auto - lexicographical_compare_3way(InputIterator1 b1, InputIterator1 e1, - InputIterator2 b2, InputIterator2 e2, - Cmp comp) - -> common_comparison_category_t; - template - constexpr auto - lexicographical_compare_3way(InputIterator1 b1, InputIterator1 e1, - InputIterator2 b2, InputIterator2 e2); +\indexlibrary{\idxcode{adjacent_find}}% +\begin{itemdecl} +template + constexpr ForwardIterator + adjacent_find(ForwardIterator first, ForwardIterator last); +template + ForwardIterator + adjacent_find(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last); - // \ref{alg.permutation.generators}, permutations - template - bool next_permutation(BidirectionalIterator first, - BidirectionalIterator last); - template - bool next_permutation(BidirectionalIterator first, - BidirectionalIterator last, Compare comp); - template - bool prev_permutation(BidirectionalIterator first, - BidirectionalIterator last); - template - bool prev_permutation(BidirectionalIterator first, - BidirectionalIterator last, Compare comp); -} -\end{codeblock} +template + constexpr ForwardIterator + adjacent_find(ForwardIterator first, ForwardIterator last, + BinaryPredicate pred); +template + ForwardIterator + adjacent_find(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + BinaryPredicate pred); +\end{itemdecl} -\rSec1[algorithms.requirements]{Algorithms requirements} +\begin{itemdescr} \pnum -All of the algorithms are separated from the particular implementations of data structures and are -parameterized by iterator types. -Because of this, they can work with program-defined data structures, as long -as these data structures have iterator types satisfying the assumptions on the algorithms. +\returns +The first iterator +\tcode{i} +such that both +\tcode{i} +and +\tcode{i + 1} +are in +the range +\range{first}{last} +for which +the following corresponding conditions hold: +\tcode{*i == *(i + 1), pred(*i, *(i + 1)) != false}. +Returns \tcode{last} +if no such iterator is found. \pnum -For purposes of determining the existence of data races, algorithms shall -not modify objects referenced through an iterator argument unless the -specification requires such modification. +\complexity +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. For the overloads with an \tcode{ExecutionPolicy}, +\bigoh{\tcode{last - first}} applications of the corresponding predicate. +\end{itemdescr} -\pnum -Throughout this Clause, the names of template parameters -are used to express type requirements. -\begin{itemize} -\item -If an algorithm's template parameter is named -\tcode{InputIterator}, -\tcode{InputIterator1}, -or -\tcode{Input\-Iterator2}, -the template argument shall satisfy the -requirements of an input iterator\iref{input.iterators}. -\item -If an algorithm's template parameter is named -\tcode{OutputIterator}, -\tcode{OutputIterator1}, -or -\tcode{Output\-Iterator2}, -the template argument shall satisfy the requirements -of an output iterator\iref{output.iterators}. -\item -If an algorithm's template parameter is named -\tcode{ForwardIterator}, -\tcode{ForwardIterator1}, -or -\tcode{Forward\-Iterator2}, -the template argument shall satisfy the requirements -of a forward iterator\iref{forward.iterators}. -\item -If an algorithm's template parameter is named -\tcode{BidirectionalIterator}, -\tcode{Bidirectional\-Iterator1}, -or -\tcode{BidirectionalIterator2}, -the template argument shall satisfy the requirements -of a bidirectional iterator\iref{bidirectional.iterators}. -\item -If an algorithm's template parameter is named -\tcode{RandomAccessIterator}, -\tcode{Random\-AccessIterator1}, -or -\tcode{RandomAccessIterator2}, -the template argument shall satisfy the requirements -of a random-access iterator\iref{random.access.iterators}. -\end{itemize} +\rSec2[alg.count]{Count} + +\indexlibrary{\idxcode{count}}% +\indexlibrary{\idxcode{count_if}}% +\begin{itemdecl} +template + constexpr typename iterator_traits::difference_type + count(InputIterator first, InputIterator last, const T& value); +template + typename iterator_traits::difference_type + count(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, const T& value); + +template + constexpr typename iterator_traits::difference_type + count_if(InputIterator first, InputIterator last, Predicate pred); +template + typename iterator_traits::difference_type + count_if(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, Predicate pred); +\end{itemdecl} +\begin{itemdescr} \pnum -If an algorithm's \effects -element specifies that a value pointed to by any iterator passed -as an argument is modified, then that algorithm has an additional -type requirement: -The type of that argument shall satisfy the requirements -of a mutable iterator\iref{iterator.requirements}. -\begin{note} -This requirement does not affect arguments that are named -\tcode{OutputIterator}, -\tcode{OutputIterator1}, -or -\tcode{OutputIterator2}, -because output iterators must always be mutable. -\end{note} +Returns the number of iterators +\tcode{i} +in the range \range{first}{last} +for which the following corresponding +conditions hold: +\tcode{*i == value, pred(*i) != false}. \pnum -Both in-place and copying versions are provided for certain -algorithms.\footnote{The decision whether to include a copying version was -usually based on complexity considerations. When the cost of doing the operation -dominates the cost of copy, the copying version is not included. For example, -\tcode{sort_copy} is not included because the cost of sorting is much more -significant, and users might as well do \tcode{copy} followed by \tcode{sort}.} -When such a version is provided for \textit{algorithm} it is called -\textit{algorithm\tcode{_copy}}. Algorithms that take predicates end with the -suffix \tcode{_if} (which follows the suffix \tcode{_copy}). +\complexity +Exactly +\tcode{last - first} +applications of the corresponding predicate. +\end{itemdescr} -\pnum -The -\tcode{Predicate} -parameter is used whenever an algorithm expects a function object\iref{function.objects} -that, when applied to the result -of dereferencing the corresponding iterator, returns a value testable as -\tcode{true}. -In other words, if an algorithm -takes -\tcode{Predicate pred} -as its argument and \tcode{first} -as its iterator argument, it should work correctly in the -construct -\tcode{pred(*first)} contextually converted to \tcode{bool}\iref{conv}. -The function object -\tcode{pred} -shall not apply any non-constant -function through the dereferenced iterator. +\rSec2[mismatch]{Mismatch} + +\indexlibrary{\idxcode{mismatch}}% +\begin{itemdecl} +template + constexpr pair + mismatch(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2); +template + pair + mismatch(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); + +template + constexpr pair + mismatch(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, BinaryPredicate pred); +template + pair + mismatch(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, BinaryPredicate pred); + +template + constexpr pair + mismatch(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2); +template + pair + mismatch(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); -\pnum -The -\tcode{BinaryPredicate} -parameter is used whenever an algorithm expects a function object that when applied to -the result of dereferencing two corresponding iterators or to dereferencing an -iterator and type -\tcode{T} -when -\tcode{T} -is part of the signature returns a value testable as -\tcode{true}. -In other words, if an algorithm takes -\tcode{BinaryPredicate binary_pred} -as its argument and \tcode{first1} and \tcode{first2} as -its iterator arguments, it should work correctly in -the construct -\tcode{binary_pred(*first1, *first2)} contextually converted to \tcode{bool}\iref{conv}. -\tcode{BinaryPredicate} -always takes the first -iterator's \tcode{value_type} -as its first argument, that is, in those cases when -\tcode{T value} -is part of the signature, it should work -correctly in the -construct \tcode{binary_pred(*first1, value)} contextually converted to \tcode{bool}\iref{conv}. -\tcode{binary_pred} shall not -apply any non-constant function through the dereferenced iterators. +template + constexpr pair + mismatch(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + BinaryPredicate pred); +template + pair + mismatch(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); +\end{itemdecl} +\begin{itemdescr} \pnum -\begin{note} -Unless otherwise specified, algorithms that take function objects as arguments -are permitted to copy those function objects freely. Programmers for whom object -identity is important should consider using a wrapper class that points to a -noncopied implementation object such as \tcode{reference_wrapper}\iref{refwrap}, or some equivalent solution. -\end{note} +\remarks If \tcode{last2} was not given in the argument list, it denotes +\tcode{first2 + (last1 - first1)} below. \pnum -When the description of an algorithm gives an expression such as -\tcode{*first == value} -for a condition, the expression shall evaluate to -either \tcode{true} or \tcode{false} in boolean contexts. +\returns +A pair of iterators \tcode{first1 + n} and +\tcode{first2 + n}, where \tcode{n} is the smallest integer +such that, respectively, +\begin{itemize} +\item \tcode{!(*(first1 + n) == *(first2 + n))} or +\item \tcode{pred(*(first1 + n), *(first2 + n)) == false}, +\end{itemize} +or \tcode{min(last1 - first1, last2 - first2)} if no such integer exists. \pnum -In the description of the algorithms operators -\tcode{+} -and -\tcode{-} -are used for some of the iterator categories for which -they do not have to be defined. -In these cases the semantics of -\tcode{a+n} -is the same as that of +\complexity +At most +\tcode{min(last1 - first1, last2 - first2)} +applications of the corresponding predicate. +\end{itemdescr} -\begin{codeblock} -X tmp = a; -advance(tmp, n); -return tmp; -\end{codeblock} +\rSec2[alg.equal]{Equal} -and that of -\tcode{b-a} -is the same as of +\indexlibrary{\idxcode{equal}}% +\begin{itemdecl} +template + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2); +template + bool equal(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); -\begin{codeblock} -return distance(a, b); -\end{codeblock} +template + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, BinaryPredicate pred); +template + bool equal(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, BinaryPredicate pred); -\rSec1[algorithms.parallel]{Parallel algorithms} +template + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2); +template + bool equal(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); -\pnum -This subclause describes components that \Cpp{} programs may use to perform -operations on containers and other sequences in parallel. +template + constexpr bool equal(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + BinaryPredicate pred); +template + bool equal(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); +\end{itemdecl} -\rSec2[algorithms.parallel.defns]{Terms and definitions} +\begin{itemdescr} \pnum -A \defn{parallel algorithm} is a function template listed in this document with -a template parameter named \tcode{ExecutionPolicy}. +\remarks If \tcode{last2} was not given in the argument list, it denotes +\tcode{first2 + (last1 - first1)} below. \pnum -Parallel algorithms access objects indirectly accessible via their arguments by -invoking the following functions: +\returns +If +\tcode{last1 - first1 != last2 - first2}, +return +\tcode{false}. +Otherwise return +\tcode{true} +if for every iterator +\tcode{i} +in the range \range{first1}{last1} +the following corresponding conditions hold: +\tcode{*i == *(first2 + (i - first1)), pred(*i, *(first2 + (i - first1))) != false}. +Otherwise, returns +\tcode{false}. +\pnum +\complexity \begin{itemize} \item -All operations of the categories of the iterators that the algorithm is -instantiated with. - -\item -Operations on those sequence elements that are required by its specification. - +For the overloads with no \tcode{ExecutionPolicy}, +\begin{itemize} \item -User-provided function objects to be applied during the execution of the -algorithm, if required by the specification. +if +\tcode{InputIterator1} +and +\tcode{InputIterator2} +meet the \oldconcept{RandomAccessIterator} requirements\iref{random.access.iterators} +and +\tcode{last1 - first1 != last2 - first2}, +then +no applications of the corresponding predicate; otherwise, \item -Operations on those function objects required by the specification. -\begin{note} See~\ref{algorithms.requirements}.\end{note} +at most +$\min(\tcode{last1 - first1}, \tcode{last2 - first2})$ +applications of the corresponding predicate. \end{itemize} -These functions are herein called \defn{element access functions}. -\begin{example} -The \tcode{sort} function may invoke the following element access functions: - -\begin{itemize} \item -Operations of the random-access iterator of the actual template argument -(as per \ref{random.access.iterators}), -as implied by the name of the template parameter \tcode{RandomAccessIterator}. - +For the overloads with an \tcode{ExecutionPolicy}, +\begin{itemize} \item -The \tcode{swap} function on the elements of the sequence (as per the -preconditions specified in \ref{sort}). +if +\tcode{ForwardIterator1} +and +\tcode{ForwardIterator2} +meet the \oldconcept{RandomAccessIterator} requirements and +\tcode{last1 - first1 != last2 - first2}, then +no applications of the corresponding predicate; otherwise, \item -The user-provided \tcode{Compare} function object. +\bigoh{\min(\tcode{last1 - first1}, \tcode{last2 - first2})} applications +of the corresponding predicate. \end{itemize} -\end{example} - -\rSec2[algorithms.parallel.user]{Requirements on user-provided function objects} +\end{itemize} +\end{itemdescr} -\pnum -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[alg.is_permutation]{Is permutation} -\rSec2[algorithms.parallel.exec]{Effect of execution policies on algorithm execution} +\indexlibrary{\idxcode{is_permutation}}% +\begin{itemdecl} +template + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); +template + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, BinaryPredicate pred); +template + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); +template + constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); +\end{itemdecl} +\begin{itemdescr} \pnum -Parallel algorithms have template parameters -named \tcode{ExecutionPolicy}\iref{execpol} -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. +\requires \tcode{ForwardIterator1} and \tcode{ForwardIterator2} shall have the same +value type. The comparison function shall be an equivalence relation. \pnum -If an object is modified by an element access function, -the algorithm will perform no other unsynchronized accesses to that object. -The modifying element access functions are those -which are specified as modifying the object. -\begin{note} -For example, -\tcode{swap()}, \tcode{++}, \tcode{--}, \tcode{@=}, and assignments -modify the object. -For the assignment and \tcode{@=} operators, -only the left argument is modified. -\end{note} +\remarks If \tcode{last2} was not given in the argument list, it denotes +\tcode{first2 + (last1 - first1)} below. \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}\iref{refwrap} or some equivalent -solution. -\end{note} +\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 +\tcode{equal(first1, last1, begin, pred)} returns \tcode{true}; otherwise, returns +\tcode{false}. \pnum -The invocations of element access functions in parallel algorithms invoked with -an execution policy object of type \tcode{execution::sequenced_policy} all occur -in the calling thread of execution. -\begin{note} -The invocations are not interleaved; see~\ref{intro.execution}. -\end{note} +\complexity No applications of the corresponding predicate if \tcode{ForwardIterator1} +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)} +would return \tcode{true} if \tcode{pred} was not given in the argument list +or \tcode{equal(first1, last1, first2, last2, pred)} would return \tcode{true} if pred was given in the argument list; otherwise, at +worst \bigoh{N^2}, where $N$ has the value \tcode{last1 - first1}. +\end{itemdescr} + +\rSec2[alg.search]{Search} + +\indexlibrary{\idxcode{search}}% +\begin{itemdecl} +template + constexpr ForwardIterator1 + search(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); +template + ForwardIterator1 + search(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); +template + constexpr ForwardIterator1 + search(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); +template + ForwardIterator1 + search(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); +\end{itemdecl} + +\begin{itemdescr} \pnum -The invocations of element access functions in parallel algorithms invoked with -an execution policy object of type \tcode{execution::parallel_policy} are -permitted to execute in either the invoking thread of execution or in a -thread of execution implicitly -created by the library to support parallel algorithm execution. -If the threads of execution created by \tcode{thread}\iref{thread.thread.class} provide concurrent -forward progress guarantees\iref{intro.progress}, then a thread of execution -implicitly created by the library will provide parallel forward progress guarantees; -otherwise, the provided forward progress guarantee is -\impldef{forward progress guarantees for implicit threads of parallel algorithms (if not defined for \tcode{thread})}. -Any such -invocations executing in the same thread of execution are indeterminately sequenced with -respect to each other. -\begin{note} -It is the caller's responsibility to ensure that the -invocation does not introduce data races or deadlocks. -\end{note} -\begin{example} -\begin{codeblock} -int a[] = {0,1}; -std::vector v; -std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) { - v.push_back(i*2+1); // incorrect: data race -}); -\end{codeblock} -The program above has a data race because of the unsynchronized access to the -container \tcode{v}. -\end{example} -\begin{example} -\begin{codeblock} -std::atomic x{0}; -int a[] = {1,2}; -std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) { - x.fetch_add(1, std::memory_order::relaxed); - // 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} -The above example depends on the order of execution of the iterations, and -will not terminate if both iterations are executed sequentially on the same -thread of execution. -\end{example} -\begin{example} -\begin{codeblock} -int x = 0; -std::mutex m; -int a[] = {1,2}; -std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int) { - std::lock_guard guard(m); - ++x; -}); -\end{codeblock} -The above example synchronizes access to object \tcode{x} ensuring that it is -incremented correctly. -\end{example} +\effects +Finds a subsequence of equal values in a sequence. \pnum -The invocations of element access functions in parallel algorithms invoked with -an execution policy of type \tcode{execution::parallel_unsequenced_policy} are -permitted to execute in an unordered fashion in unspecified threads of execution, and -unsequenced with respect to one another within each thread of execution. -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. -\begin{note} -This means that multiple function object invocations may be interleaved on a -single thread of execution, which overrides the usual guarantee from \ref{intro.execution} -that function executions do not interleave with one another. -\end{note} -Since \tcode{execution::parallel_unsequenced_policy} allows the execution of element -access functions to be interleaved on a single thread of execution, blocking synchronization, -including the use of mutexes, risks deadlock. Thus, the synchronization with -\tcode{execution::parallel_unsequenced_policy} is restricted as -follows: -A standard library function is \defn{vectorization-unsafe} if it is specified -to synchronize with another function invocation, or another function invocation -is specified to synchronize with it, and if it is not a memory allocation or -deallocation function. Vectorization-unsafe standard library functions may not -be invoked by user code called from \tcode{execution::parallel_unsequenced_policy} -algorithms. -\begin{note} -Implementations must ensure that internal synchronization inside standard -library functions does not prevent forward progress when those functions are -executed by threads of execution with weakly parallel forward progress guarantees. -\end{note} -\begin{example} -\begin{codeblock} -int x = 0; -std::mutex m; -int a[] = {1,2}; -std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int) { - std::lock_guard guard(m); // incorrect: \tcode{lock_guard} constructor calls \tcode{m.lock()} - ++x; -}); -\end{codeblock} -The above program may result in two consecutive calls to \tcode{m.lock()} on -the same thread of execution (which may deadlock), because the applications of the function -object are not guaranteed to run on different threads of execution. -\end{example} -\begin{note} -The semantics of the \tcode{execution::parallel_policy} or the -\tcode{execution::parallel_unsequenced_policy} invocation allow the implementation to -fall back to sequential execution if the system cannot parallelize an algorithm -invocation due to lack of resources. -\end{note} +\returns +The first iterator +\tcode{i} +in the range \range{first1}{last1 - (last2-first2)} +such that for every non-negative integer +\tcode{n} +less than +\tcode{last2 - first2} +the following corresponding conditions hold: +\tcode{*(i + n) == *(first2 + n), pred(*(i + n), *(first2 + n)) != false}. +Returns \tcode{first1} +if \range{first2}{last2} is empty, +otherwise returns \tcode{last1} +if no such iterator is found. \pnum -If an invocation of a parallel algorithm uses threads of execution implicitly -created by the library, then the invoking thread of execution will either +\complexity +At most +\tcode{(last1 - first1) * (last2 - first2)} +applications of the corresponding predicate. +\end{itemdescr} -\begin{itemize} -\item temporarily block with forward progress guarantee delegation\iref{intro.progress} - on the completion of these library-managed threads of execution, or -\item eventually execute an element access function; -\end{itemize} +\indexlibrary{\idxcode{search_n}}% +\begin{itemdecl} +template + constexpr ForwardIterator + search_n(ForwardIterator first, ForwardIterator last, + Size count, const T& value); +template + ForwardIterator + search_n(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + Size count, const T& value); -the thread of execution will continue to do so until the algorithm is finished. -\begin{note} -In blocking with forward progress guarantee delegation in this context, -a thread of execution created by the library is considered to have -finished execution as soon as it has finished the execution of the -particular element access function that the invoking thread of execution -logically depends on. -\end{note} +template + constexpr ForwardIterator + search_n(ForwardIterator first, ForwardIterator last, + Size count, const T& value, + BinaryPredicate pred); +template + ForwardIterator + search_n(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + Size count, const T& value, + BinaryPredicate pred); +\end{itemdecl} +\begin{itemdescr} \pnum -The semantics of parallel algorithms invoked with an execution policy object of -\impldef{additional execution policies supported by parallel algorithms} type are -\impldef{semantics of parallel algorithms invoked with -imple\-men\-tation-defined execution policies}. +\requires +The type +\tcode{Size} +shall be convertible to integral type~(\ref{conv.integral}, \ref{class.conv}). -\rSec2[algorithms.parallel.exceptions]{Parallel algorithm exceptions} +\pnum +\effects +Finds a subsequence of equal values in a sequence. \pnum -During the execution of a parallel algorithm, if temporary memory resources are -required for parallelization and none are available, the algorithm throws a -\tcode{bad_alloc} exception. +\returns +The first iterator +\tcode{i} +in the range \range{first}{last-count} +such that for every non-negative integer +\tcode{n} +less than +\tcode{count} +the following corresponding conditions hold: +\tcode{*(i + n) == value, pred(*(i + n),value) != false}. +Returns \tcode{last} +if no such iterator is found. \pnum -During the execution of a parallel algorithm, if the invocation of an element -access function exits via an uncaught exception, -the behavior is determined by the \tcode{ExecutionPolicy}. - -\rSec2[algorithms.parallel.overloads]{\tcode{ExecutionPolicy} algorithm overloads} +\complexity +At most +\tcode{last - first} +applications of the corresponding predicate. +\end{itemdescr} -\pnum -Parallel algorithms are algorithm overloads. Each parallel algorithm overload -has an additional template type parameter named \tcode{ExecutionPolicy}, which -is the first template parameter. -Additionally, each parallel algorithm overload has an additional function -parameter of type \tcode{ExecutionPolicy\&\&}, which is the first -function parameter. -\begin{note} Not all algorithms have parallel algorithm overloads.\end{note} +\indexlibrary{\idxcode{search}}% +\begin{itemdecl} +template + constexpr ForwardIterator + search(ForwardIterator first, ForwardIterator last, const Searcher& searcher); +\end{itemdecl} +\begin{itemdescr} \pnum -Unless otherwise specified, the semantics of \tcode{ExecutionPolicy} algorithm -overloads are identical to their overloads without. +\effects +Equivalent to: \tcode{return searcher(first, last).first;} \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}}. +\remarks +\tcode{Searcher} need not meet the \oldconcept{CopyConstructible} requirements. +\end{itemdescr} -\pnum -Parallel algorithms shall not participate in overload resolution unless -\tcode{is_execution_policy_v>} is \tcode{true}. -\rSec1[alg.nonmodifying]{Non-modifying sequence operations} +\rSec1[alg.modifying.operations]{Mutating sequence operations} -\rSec2[alg.all_of]{All of} +\rSec2[alg.copy]{Copy} -\indexlibrary{\idxcode{all_of}}% +\indexlibrary{\idxcode{copy}}% \begin{itemdecl} -template - constexpr bool all_of(InputIterator first, InputIterator last, Predicate pred); -template - bool all_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, - Predicate pred); +template + constexpr OutputIterator copy(InputIterator first, InputIterator last, + OutputIterator result); \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{true} if -\range{first}{last} is empty or if -\tcode{pred(*i)} is \tcode{true} for every iterator \tcode{i} in the range \range{first}{last}, and \tcode{false} otherwise. +\requires \tcode{result} shall not be in the range \range{first}{last}. \pnum -\complexity At most \tcode{last - first} applications of the predicate. -\end{itemdescr} +\effects Copies elements in the range \range{first}{last} into the range \range{result}{result + (last - first)} starting from \tcode{first} and proceeding to \tcode{last}. For each non-negative integer \tcode{n < (last - first)}, performs \tcode{*(result + n) = *(first + n)}. -\rSec2[alg.any_of]{Any of} +\pnum +\returns \tcode{result + (last - first)}. -\indexlibrary{\idxcode{any_of}}% +\pnum +\complexity Exactly \tcode{last - first} assignments. +\end{itemdescr} + +\indexlibrary{\idxcode{copy}}% \begin{itemdecl} -template - constexpr bool any_of(InputIterator first, InputIterator last, Predicate pred); -template - bool any_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, - Predicate pred); +template + ForwardIterator2 copy(ExecutionPolicy&& policy, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result); \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{false} if \range{first}{last} is empty or -if there is no iterator \tcode{i} in the range -\range{first}{last} such that \tcode{pred(*i)} is \tcode{true}, and \tcode{true} otherwise. +\requires The ranges \range{first}{last} and +\range{result}{result + (last - first)} shall not overlap. \pnum -\complexity At most \tcode{last - first} applications of the predicate. -\end{itemdescr} +\effects Copies elements in the range \range{first}{last} into +the range \range{result}{result + (last - first)}. +For each non-negative integer \tcode{n < (last - first)}, +performs \tcode{*(result + n) = *(first + n)}. -\rSec2[alg.none_of]{None of} +\pnum +\returns \tcode{result + (last - first)}. -\indexlibrary{\idxcode{none_of}}% +\pnum +\complexity Exactly \tcode{last - first} assignments. +\end{itemdescr} + +\indexlibrary{\idxcode{copy_n}}% \begin{itemdecl} -template - constexpr bool none_of(InputIterator first, InputIterator last, Predicate pred); -template - bool none_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, - Predicate pred); +template + constexpr OutputIterator copy_n(InputIterator first, Size n, + OutputIterator result); +template + ForwardIterator2 copy_n(ExecutionPolicy&& exec, + ForwardIterator1 first, Size n, + ForwardIterator2 result); \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{true} if -\range{first}{last} is empty or if -\tcode{pred(*i)} is \tcode{false} for every iterator \tcode{i} in the range \range{first}{last}, and \tcode{false} otherwise. +\effects For each non-negative integer +$i < n$, performs \tcode{*(result + i) = *(first + i)}. \pnum -\complexity At most \tcode{last - first} applications of the predicate. -\end{itemdescr} +\returns \tcode{result + n}. -\rSec2[alg.foreach]{For each} +\pnum +\complexity Exactly \tcode{n} assignments. +\end{itemdescr} -\indexlibrary{\idxcode{for_each}}% +\indexlibrary{\idxcode{copy_if}}% \begin{itemdecl} -template - constexpr Function for_each(InputIterator first, InputIterator last, Function f); +template + constexpr OutputIterator copy_if(InputIterator first, InputIterator last, + OutputIterator result, Predicate pred); +template + ForwardIterator2 copy_if(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, Predicate pred); \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{Function} shall satisfy the -\tcode{MoveConstructible} requirements (\tref{moveconstructible}). -\begin{note} \tcode{Function} need not meet the requirements of -\tcode{CopyConstructible} (\tref{copyconstructible}). \end{note} +\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 +\oldconcept{\-Move\-Constructible} (\tref{moveconstructible}). +\end{note} \pnum -\effects -Applies -\tcode{f} to the result of dereferencing every iterator in the range -\range{first}{last}, -starting from -\tcode{first} -and proceeding to -\tcode{last - 1}. -\begin{note} If the type of \tcode{first} satisfies the -requirements of a mutable iterator, \tcode{f} may apply non-constant -functions through the dereferenced iterator.\end{note} +\effects Copies all of the elements referred to by the iterator \tcode{i} in the range \range{first}{last} +for which \tcode{pred(*i)} is \tcode{true}. \pnum -\returns -\tcode{f}. +\returns The end of the resulting range. \pnum -\complexity -Applies \tcode{f} -exactly -\tcode{last - first} -times. +\complexity Exactly \tcode{last - first} applications of the corresponding predicate. \pnum -\remarks -If \tcode{f} returns a result, the result is ignored. +\remarks Stable\iref{algorithm.stable}. \end{itemdescr} -\indexlibrary{\idxcode{for_each}}% +\indexlibrary{\idxcode{copy_backward}}% \begin{itemdecl} -template - void for_each(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, - Function f); +template + constexpr BidirectionalIterator2 + copy_backward(BidirectionalIterator1 first, + BidirectionalIterator1 last, + BidirectionalIterator2 result); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{Function} shall satisfy the \tcode{CopyConstructible} requirements. +\tcode{result} +shall not be in the range +\brange{first}{last}. \pnum \effects -Applies \tcode{f} to the result of dereferencing every iterator in the range -\range{first}{last}. -\begin{note} -If the type of \tcode{first} satisfies the requirements of a mutable iterator, -\tcode{f} may apply non-constant functions through the dereferenced iterator. -\end{note} - -\pnum -\complexity -Applies \tcode{f} exactly \tcode{last - first} times. +Copies elements in the range \range{first}{last} +into the +range \range{result - (last-first)}{result} +starting from +\tcode{last - 1} +and proceeding to \tcode{first}.\footnote{\tcode{copy_backward} +should be used instead of copy when \tcode{last} +is in +the range +\range{result - (last - first)}{result}.} +For each positive integer +\tcode{n <= (last - first)}, +performs +\tcode{*(result - n) = *(last - n)}. \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. +\returns +\tcode{result - (last - first)}. \pnum -\begin{note} -Does not return a copy of its \tcode{Function} parameter, since -parallelization may not permit efficient state accumulation. -\end{note} +\complexity +Exactly +\tcode{last - first} +assignments. \end{itemdescr} -\indexlibrary{\idxcode{for_each_n}}% +\rSec2[alg.move]{Move} + +\indexlibrary{\idxcode{move}!algorithm}% \begin{itemdecl} -template - constexpr InputIterator for_each_n(InputIterator first, Size n, Function f); +template + constexpr OutputIterator move(InputIterator first, InputIterator last, + OutputIterator result); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{Function} shall satisfy the \tcode{MoveConstructible} requirements -\begin{note} \tcode{Function} need not meet the requirements of -\tcode{CopyConstructible}. \end{note} - -\pnum -\requires -\tcode{n >= 0}. +\tcode{result} +shall not be in the range +\range{first}{last}. \pnum \effects -Applies \tcode{f} to the result of dereferencing every iterator in the range -\range{first}{first + n} in order. -\begin{note} -If the type of \tcode{first} satisfies the requirements of a mutable iterator, -\tcode{f} may apply non-constant functions through the dereferenced iterator. -\end{note} +Moves elements in the range \range{first}{last} +into the range \range{result}{result + (last - first)} +starting from first and proceeding to last. +For each non-negative integer +\tcode{n < (last-first)}, +performs +\tcode{*(result + n)} \tcode{= std::move(*(first + n))}. \pnum \returns -\tcode{first + n}. +\tcode{result + (last - first)}. \pnum -\remarks -If \tcode{f} returns a result, the result is ignored. +\complexity +Exactly +\tcode{last - first} +move assignments. \end{itemdescr} -\indexlibrary{\idxcode{for_each_n}}% +\indexlibrary{\idxcode{move}!algorithm}% \begin{itemdecl} -template - ForwardIterator for_each_n(ExecutionPolicy&& exec, ForwardIterator first, Size n, - Function f); +template + ForwardIterator2 move(ExecutionPolicy&& policy, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result); \end{itemdecl} \begin{itemdescr} \pnum -\requires -\tcode{Function} shall satisfy the \tcode{CopyConstructible} requirements. - -\pnum -\requires -\tcode{n >= 0}. +\requires The ranges \range{first}{last} and +\range{result}{result + (last - first)} shall not overlap. \pnum -\effects -Applies \tcode{f} to the result of dereferencing every iterator in the range -\range{first}{first + n}. -\begin{note} -If the type of \tcode{first} satisfies the requirements of a mutable iterator, -\tcode{f} may apply non-constant functions through the dereferenced iterator. -\end{note} +\effects Moves elements in the range \range{first}{last} into +the range \range{result}{result + (last - first)}. +For each non-negative integer \tcode{n < (last - first)}, +performs \tcode{*(result + n) = std::\brk{}move(*(first + n))}. \pnum -\returns -\tcode{first + n}. +\returns \tcode{result + (last - first)}. \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. +\complexity Exactly \tcode{last - first} assignments. \end{itemdescr} - -\rSec2[alg.find]{Find} - -\indexlibrary{\idxcode{find}}% -\indexlibrary{\idxcode{find_if}}% -\indexlibrary{\idxcode{find_if_not}}% +\indexlibrary{\idxcode{move_backward}}% \begin{itemdecl} -template - constexpr InputIterator find(InputIterator first, InputIterator last, - const T& value); -template - ForwardIterator find(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, - const T& value); - -template - constexpr InputIterator find_if(InputIterator first, InputIterator last, - Predicate pred); -template - ForwardIterator find_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, - Predicate pred); - -template - constexpr InputIterator find_if_not(InputIterator first, InputIterator last, - Predicate pred); -template - ForwardIterator find_if_not(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, - Predicate pred); +template + constexpr BidirectionalIterator2 + move_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, + BidirectionalIterator2 result); \end{itemdecl} \begin{itemdescr} +\pnum +\requires +\tcode{result} +shall not be in the range +\brange{first}{last}. + +\pnum +\effects +Moves elements in the range \range{first}{last} +into the +range \range{result - (last-first)}{result} +starting from +\tcode{last - 1} +and proceeding to first.\footnote{\tcode{move_backward} +should be used instead of move when last +is in +the range +\range{result - (last - first)}{result}.} +For each positive integer +\tcode{n <= (last - first)}, +performs +\tcode{*(result - n) = std::move(*(last - n))}. + \pnum \returns -The first iterator -\tcode{i} -in the range -\range{first}{last} -for which the following corresponding -conditions hold: -\tcode{*i == value}, \tcode{pred(*i) != false}, \tcode{pred(*i) == false}. -Returns \tcode{last} if no such iterator is found. +\tcode{result - (last - first)}. \pnum \complexity -At most +Exactly \tcode{last - first} -applications of the corresponding predicate. +assignments. \end{itemdescr} -\rSec2[alg.find.end]{Find end} +\rSec2[alg.swap]{Swap} -\indexlibrary{\idxcode{find_end}}% +\indexlibrary{\idxcode{swap_ranges}}% \begin{itemdecl} template - constexpr ForwardIterator1 - find_end(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); + constexpr ForwardIterator2 + swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); template - ForwardIterator1 - find_end(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); - -template - constexpr ForwardIterator1 - find_end(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); -template - ForwardIterator1 - find_end(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); + ForwardIterator2 + swap_ranges(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2); \end{itemdecl} \begin{itemdescr} +\pnum +\requires +The two ranges \range{first1}{last1} +and +\range{first2}{first2 + (last1 - first1)} +shall not overlap. +\tcode{*(first1 + n)} shall be swappable with\iref{swappable.requirements} +\tcode{*(first2 + n)}. + \pnum \effects -Finds a subsequence of equal values in a sequence. +For each non-negative integer +\tcode{n < (last1 - first1)} +performs: +\tcode{swap(*(first1 + n), \brk{}*(first2 + n))}. \pnum \returns -The last iterator -\tcode{i} -in the range \range{first1}{last1 - (last2 - first2)} -such that for every non-negative integer -\tcode{n < (last2 - first2)}, -the following corresponding conditions hold: -\tcode{*(i + n) == *(\brk{}first2 + n), pred(*(i + n), *(first2 + n)) != false}. -Returns \tcode{last1} -if -\range{first2}{last2} is empty or if -no such iterator is found. +\tcode{first2 + (last1 - first1)}. \pnum \complexity -At most -\tcode{(last2 - first2) * (last1 - first1 - (last2 - first2) + 1)} -applications of the corresponding predicate. +Exactly +\tcode{last1 - first1} +swaps. \end{itemdescr} -\rSec2[alg.find.first.of]{Find first} - -\indexlibrary{\idxcode{find_first_of}}% +\indexlibrary{\idxcode{iter_swap}}% \begin{itemdecl} -template - constexpr InputIterator - find_first_of(InputIterator first1, InputIterator last1, - ForwardIterator first2, ForwardIterator last2); -template - ForwardIterator1 - find_first_of(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); - -template - constexpr InputIterator - find_first_of(InputIterator first1, InputIterator last1, - ForwardIterator first2, ForwardIterator last2, - BinaryPredicate pred); -template - ForwardIterator1 - find_first_of(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); +template + constexpr void iter_swap(ForwardIterator1 a, ForwardIterator2 b); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Finds an element that matches one of a set of values. - -\pnum -\returns -The first iterator -\tcode{i} -in the range \range{first1}{last1} -such that for some -iterator -\tcode{j} -in the range \range{first2}{last2} -the following conditions hold: -\tcode{*i == *j, pred(*i,*j) != false}. -Returns \tcode{last1} -if \range{first2}{last2} is empty or -if no such iterator is found. +\requires +\tcode{a} and \tcode{b} shall be dereferenceable. \tcode{*a} shall be +swappable with\iref{swappable.requirements} \tcode{*b}. \pnum -\complexity -At most -\tcode{(last1-first1) * (last2-first2)} -applications of the corresponding predicate. +\effects +As if by \tcode{swap(*a, *b)}. \end{itemdescr} -\rSec2[alg.adjacent.find]{Adjacent find} +\rSec2[alg.transform]{Transform} -\indexlibrary{\idxcode{adjacent_find}}% +\indexlibrary{\idxcode{transform}}% \begin{itemdecl} -template - constexpr ForwardIterator - adjacent_find(ForwardIterator first, ForwardIterator last); -template - ForwardIterator - adjacent_find(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last); +template + constexpr OutputIterator + transform(InputIterator first, InputIterator last, + OutputIterator result, UnaryOperation op); +template + ForwardIterator2 + transform(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, UnaryOperation op); -template - constexpr ForwardIterator - adjacent_find(ForwardIterator first, ForwardIterator last, - BinaryPredicate pred); -template +template + constexpr OutputIterator + transform(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, OutputIterator result, + BinaryOperation binary_op); +template ForwardIterator - adjacent_find(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, - BinaryPredicate pred); + transform(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator result, + BinaryOperation binary_op); \end{itemdecl} \begin{itemdescr} \pnum -\returns -The first iterator -\tcode{i} -such that both +\requires +\tcode{op} and \tcode{binary_op} +shall not invalidate iterators or subranges, or modify elements in the ranges +\begin{itemize} +\item \crange{first1}{last1}, +\item \crange{first2}{first2 + (last1 - first1)}, and +\item \crange{result}{result + (last1 - first1)}.\footnote{The use of fully +closed ranges is intentional.} +\end{itemize} + +\pnum +\effects +Assigns through every iterator \tcode{i} -and -\tcode{i + 1} -are in -the range -\range{first}{last} -for which -the following corresponding conditions hold: -\tcode{*i == *(i + 1), pred(*i, *(i + 1)) != false}. -Returns \tcode{last} -if no such iterator is found. +in the range +\range{result}{result + (last1 - first1)} +a new +corresponding value equal to +\tcode{op(*(first1 + (i - result)))} +or +\tcode{binary_op(*(first1 + (i - result)), *(first2 + (i - result)))}. + +\pnum +\returns +\tcode{result + (last1 - first1)}. \pnum \complexity -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. For the overloads with an \tcode{ExecutionPolicy}, -\bigoh{\tcode{last - first}} applications of the corresponding predicate. +Exactly +\tcode{last1 - first1} +applications of +\tcode{op} or \tcode{binary_op}. This requirement also applies to the overload +with an \tcode{ExecutionPolicy} . + +\pnum +\remarks +\tcode{result} may be equal to \tcode{first} +in case of unary transform, +or to \tcode{first1} or \tcode{first2} +in case of binary transform. \end{itemdescr} -\rSec2[alg.count]{Count} +\rSec2[alg.replace]{Replace} -\indexlibrary{\idxcode{count}}% -\indexlibrary{\idxcode{count_if}}% +\indexlibrary{\idxcode{replace}}% +\indexlibrary{\idxcode{replace_if}}% \begin{itemdecl} -template - constexpr typename iterator_traits::difference_type - count(InputIterator first, InputIterator last, const T& value); +template + constexpr void replace(ForwardIterator first, ForwardIterator last, + const T& old_value, const T& new_value); template - typename iterator_traits::difference_type - count(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, const T& value); + void replace(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + const T& old_value, const T& new_value); -template - constexpr typename iterator_traits::difference_type - count_if(InputIterator first, InputIterator last, Predicate pred); -template - typename iterator_traits::difference_type - count_if(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, Predicate pred); +template + constexpr void replace_if(ForwardIterator first, ForwardIterator last, + Predicate pred, const T& new_value); +template + void replace_if(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + Predicate pred, const T& new_value); \end{itemdecl} \begin{itemdescr} +\pnum +\requires +The expression +\tcode{*first = new_value} +shall be valid. + \pnum \effects -Returns the number of iterators +Substitutes elements referred by the iterator \tcode{i} in the range \range{first}{last} -for which the following corresponding -conditions hold: -\tcode{*i == value, pred(*i) != false}. +with \tcode{new_value}, +when the following corresponding conditions hold: +\tcode{*i == old_value}, \tcode{pred(*i) != false}. \pnum \complexity @@ -2021,514 +2853,501 @@ applications of the corresponding predicate. \end{itemdescr} -\rSec2[mismatch]{Mismatch} - -\indexlibrary{\idxcode{mismatch}}% +\indexlibrary{\idxcode{replace_copy}}% +\indexlibrary{\idxcode{replace_copy_if}}% \begin{itemdecl} -template - constexpr pair - mismatch(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2); -template - pair - mismatch(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2); - -template - constexpr pair - mismatch(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, BinaryPredicate pred); -template - pair - mismatch(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, BinaryPredicate pred); - -template - constexpr pair - mismatch(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); -template - pair - mismatch(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); +template + constexpr OutputIterator + replace_copy(InputIterator first, InputIterator last, + OutputIterator result, + const T& old_value, const T& new_value); +template + ForwardIterator2 + replace_copy(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + const T& old_value, const T& new_value); -template - constexpr pair - mismatch(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - BinaryPredicate pred); +template + constexpr OutputIterator + replace_copy_if(InputIterator first, InputIterator last, + OutputIterator result, + Predicate pred, const T& new_value); template - pair - mismatch(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); + class Predicate, class T> + ForwardIterator2 + replace_copy_if(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + Predicate pred, const T& new_value); \end{itemdecl} \begin{itemdescr} \pnum -\remarks If \tcode{last2} was not given in the argument list, it denotes -\tcode{first2 + (last1 - first1)} below. - -\pnum -\returns -A pair of iterators \tcode{first1 + n} and -\tcode{first2 + n}, where \tcode{n} is the smallest integer -such that, respectively, -\begin{itemize} -\item \tcode{!(*(first1 + n) == *(first2 + n))} or -\item \tcode{pred(*(first1 + n), *(first2 + n)) == false}, -\end{itemize} -or \tcode{min(last1 - first1, last2 - first2)} if no such integer exists. +\requires +The results of the expressions +\tcode{*first} +and +\tcode{new_value} +shall be writable\iref{iterator.requirements.general} to the +\tcode{result} +output iterator. +The ranges +\range{first}{last} +and +\range{result}{result + (last - first)} +shall not overlap. \pnum -\complexity -At most -\tcode{min(last1 - first1, last2 - first2)} -applications of the corresponding predicate. -\end{itemdescr} - -\rSec2[alg.equal]{Equal} - -\indexlibrary{\idxcode{equal}}% -\begin{itemdecl} -template - constexpr bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2); -template - bool equal(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2); - -template - constexpr bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, BinaryPredicate pred); -template - bool equal(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, BinaryPredicate pred); - -template - constexpr bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); -template - bool equal(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); - -template - constexpr bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - BinaryPredicate pred); -template - bool equal(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); -\end{itemdecl} +\effects +Assigns to every iterator +\tcode{i} +in the +range +\range{result}{result + (last - first)} +either +\tcode{new_value} +or +\tcode{*\brk(first + (i - result))} +depending on whether the following corresponding conditions hold: -\begin{itemdescr} -\pnum -\remarks If \tcode{last2} was not given in the argument list, it denotes -\tcode{first2 + (last1 - first1)} below. +\begin{codeblock} +*(first + (i - result)) == old_value +pred(*(first + (i - result))) != false +\end{codeblock} \pnum \returns -If -\tcode{last1 - first1 != last2 - first2}, -return -\tcode{false}. -Otherwise return -\tcode{true} -if for every iterator -\tcode{i} -in the range \range{first1}{last1} -the following corresponding conditions hold: -\tcode{*i == *(first2 + (i - first1)), pred(*i, *(first2 + (i - first1))) != false}. -Otherwise, returns -\tcode{false}. +\tcode{result + (last - first)}. \pnum \complexity -\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\iref{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})$ +Exactly +\tcode{last - first} applications of the corresponding predicate. -\end{itemize} - -\item -For the overloads with an \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} +\rSec2[alg.fill]{Fill} -\indexlibrary{\idxcode{is_permutation}}% +\indexlibrary{\idxcode{fill}}% +\indexlibrary{\idxcode{fill_n}}% \begin{itemdecl} -template - constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2); -template - constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, BinaryPredicate pred); -template - constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); -template - constexpr bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); +template + constexpr void fill(ForwardIterator first, ForwardIterator last, const T& value); +template + void fill(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, const T& value); + +template + constexpr OutputIterator fill_n(OutputIterator first, Size n, const T& value); +template + ForwardIterator fill_n(ExecutionPolicy&& exec, + ForwardIterator first, Size n, const T& value); + \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{ForwardIterator1} and \tcode{ForwardIterator2} shall have the same -value type. The comparison function shall be an equivalence relation. +\requires +The expression +\tcode{value} +shall be writable\iref{iterator.requirements.general} to the output iterator. The type +\tcode{Size} +shall be convertible to an integral type~(\ref{conv.integral}, \ref{class.conv}). \pnum -\remarks If \tcode{last2} was not given in the argument list, it denotes -\tcode{first2 + (last1 - first1)} below. +\effects +The \tcode{fill} algorithms assign \tcode{value} through all the iterators in the range +\range{first}{last}. The \tcode{fill_n} algorithms assign \tcode{value} +through all the iterators in the range \range{first}{first + n} +if \tcode{n} is positive, otherwise they do nothing. \pnum -\returns If \tcode{last1 - first1 != last2 - first2}, return \tcode{false}. -Otherwise return \tcode{true} if there exists a permutation of the elements in the -range \range{first2}{first2 + (last1 - first1)}, beginning with \tcode{ForwardIterator2 -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}. +\returns \tcode{fill_n} returns \tcode{first + n} for non-negative values of \tcode{n} +and \tcode{first} for negative values. \pnum -\complexity No applications of the corresponding predicate if \tcode{ForwardIterator1} -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)} -would return \tcode{true} if \tcode{pred} was not given in the argument list -or \tcode{equal(first1, last1, first2, last2, pred)} would return \tcode{true} if pred was given in the argument list; otherwise, at -worst \bigoh{N^2}, where $N$ has the value \tcode{last1 - first1}. +\complexity +Exactly +\tcode{last - first}, +\tcode{n}, or 0 assignments, respectively. \end{itemdescr} -\rSec2[alg.search]{Search} +\rSec2[alg.generate]{Generate} -\indexlibrary{\idxcode{search}}% +\indexlibrary{\idxcode{generate}}% +\indexlibrary{\idxcode{generate_n}}% \begin{itemdecl} -template - constexpr ForwardIterator1 - search(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); -template - ForwardIterator1 - search(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); +template + constexpr void generate(ForwardIterator first, ForwardIterator last, + Generator gen); +template + void generate(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + Generator gen); -template - constexpr ForwardIterator1 - search(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); -template - ForwardIterator1 - search(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate pred); +template + constexpr OutputIterator generate_n(OutputIterator first, Size n, Generator gen); +template + ForwardIterator generate_n(ExecutionPolicy&& exec, + ForwardIterator first, Size n, Generator gen); \end{itemdecl} \begin{itemdescr} +\pnum +\requires +\tcode{gen} takes no arguments, +\tcode{Size} +shall be convertible to an integral type~(\ref{conv.integral}, \ref{class.conv}). + \pnum \effects -Finds a subsequence of equal values in a sequence. +The \tcode{generate} algorithms invoke the function object \tcode{gen} and assign the return +value of \tcode{gen} through all the iterators in the range +\range{first}{last}. The \tcode{generate_n} algorithms invoke the function object +\tcode{gen} and assign the return value of \tcode{gen} through all the iterators in +the range \range{first}{first + n} if \tcode{n} is positive, +otherwise they do nothing. \pnum -\returns -The first iterator -\tcode{i} -in the range \range{first1}{last1 - (last2-first2)} -such that for every non-negative integer -\tcode{n} -less than -\tcode{last2 - first2} -the following corresponding conditions hold: -\tcode{*(i + n) == *(first2 + n), pred(*(i + n), *(first2 + n)) != false}. -Returns \tcode{first1} -if \range{first2}{last2} is empty, -otherwise returns \tcode{last1} -if no such iterator is found. +\returns \tcode{generate_n} returns \tcode{first + n} for non-negative values of \tcode{n} +and \tcode{first} for negative values. \pnum \complexity -At most -\tcode{(last1 - first1) * (last2 - first2)} -applications of the corresponding predicate. +Exactly +\tcode{last - first}, +\tcode{n}, or 0 +invocations of \tcode{gen} and assignments, respectively. \end{itemdescr} -\indexlibrary{\idxcode{search_n}}% +\rSec2[alg.remove]{Remove} + +\indexlibrary{\idxcode{remove}}% +\indexlibrary{\idxcode{remove_if}}% \begin{itemdecl} -template - constexpr ForwardIterator - search_n(ForwardIterator first, ForwardIterator last, - Size count, const T& value); -template - ForwardIterator - search_n(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, - Size count, const T& value); +template + constexpr ForwardIterator remove(ForwardIterator first, ForwardIterator last, + const T& value); +template + ForwardIterator remove(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + const T& value); -template - constexpr ForwardIterator - search_n(ForwardIterator first, ForwardIterator last, - Size count, const T& value, - BinaryPredicate pred); -template - ForwardIterator - search_n(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, - Size count, const T& value, - BinaryPredicate pred); +template + constexpr ForwardIterator remove_if(ForwardIterator first, ForwardIterator last, + Predicate pred); +template + ForwardIterator remove_if(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + Predicate pred); \end{itemdecl} \begin{itemdescr} \pnum \requires -The type -\tcode{Size} -shall be convertible to integral type~(\ref{conv.integral}, \ref{class.conv}). +The type of +\tcode{*first} +shall satisfy the \oldconcept{MoveAssignable} +requirements (\tref{moveassignable}). \pnum \effects -Finds a subsequence of equal values in a sequence. +Eliminates all the elements referred to by iterator +\tcode{i} +in the range \range{first}{last} +for which the following corresponding conditions hold: +\tcode{*i == value, pred(*i) != false}. \pnum \returns -The first iterator -\tcode{i} -in the range \range{first}{last-count} -such that for every non-negative integer -\tcode{n} -less than -\tcode{count} -the following corresponding conditions hold: -\tcode{*(i + n) == value, pred(*(i + n),value) != false}. -Returns \tcode{last} -if no such iterator is found. +The end of the resulting range. + +\pnum +\remarks Stable\iref{algorithm.stable}. \pnum \complexity -At most +Exactly \tcode{last - first} applications of the corresponding predicate. + +\pnum +\begin{note} +Each element in the range \range{ret}{last}, where \tcode{ret} is +the returned value, has a valid but unspecified state, because the algorithms +can eliminate elements by moving from elements that were originally +in that range. +\end{note} \end{itemdescr} -\indexlibrary{\idxcode{search}}% +\indexlibrary{\idxcode{remove_copy}}% +\indexlibrary{\idxcode{remove_copy_if}}% \begin{itemdecl} -template - constexpr ForwardIterator - search(ForwardIterator first, ForwardIterator last, const Searcher& searcher); +template + constexpr OutputIterator + remove_copy(InputIterator first, InputIterator last, + OutputIterator result, const T& value); +template + ForwardIterator2 + remove_copy(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, const T& value); + +template + constexpr OutputIterator + remove_copy_if(InputIterator first, InputIterator last, + OutputIterator result, Predicate pred); +template + ForwardIterator2 + remove_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. The expression \tcode{*result = *first} shall be valid. +\begin{note} +For the overloads with an \tcode{ExecutionPolicy}, there may be a performance +cost if \tcode{iterator_traits::value_type} is not +\oldconcept{\-Move\-Constructible} (\tref{moveconstructible}). +\end{note} + \pnum \effects -Equivalent to: \tcode{return searcher(first, last).first;} +Copies all the elements referred to by the iterator +\tcode{i} +in the range +\range{first}{last} +for which the following corresponding conditions do not hold: +\tcode{*i == value, pred(*i) != false}. \pnum -\remarks -\tcode{Searcher} need not meet the \tcode{CopyConstructible} requirements. -\end{itemdescr} +\returns +The end of the resulting range. +\pnum +\complexity +Exactly +\tcode{last - first} +applications of the corresponding predicate. -\rSec1[alg.modifying.operations]{Mutating sequence operations} +\pnum +\remarks Stable\iref{algorithm.stable}. +\end{itemdescr} -\rSec2[alg.copy]{Copy} +\rSec2[alg.unique]{Unique} -\indexlibrary{\idxcode{copy}}% +\indexlibrary{\idxcode{unique}}% \begin{itemdecl} -template - constexpr OutputIterator copy(InputIterator first, InputIterator last, - OutputIterator result); +template + constexpr ForwardIterator unique(ForwardIterator first, ForwardIterator last); +template + ForwardIterator unique(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last); + +template + constexpr ForwardIterator unique(ForwardIterator first, ForwardIterator last, + BinaryPredicate pred); +template + ForwardIterator unique(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + BinaryPredicate pred); \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{result} shall not be in the range \range{first}{last}. +\requires +The comparison function shall be an equivalence relation. +The type of \tcode{*first} shall satisfy the +\oldconcept{MoveAssignable} requirements (\tref{moveassignable}). \pnum -\effects Copies elements in the range \range{first}{last} into the range \range{result}{result + (last - first)} starting from \tcode{first} and proceeding to \tcode{last}. For each non-negative integer \tcode{n < (last - first)}, performs \tcode{*(result + n) = *(first + n)}. +\effects +For a nonempty range, eliminates all but the first element from every +consecutive group of equivalent elements referred to by the iterator +\tcode{i} +in the range +\range{first + 1}{last} +for which the following conditions hold: +\tcode{*(i - 1) == *i} +or +\tcode{pred(*(i - 1), *i) != false}. \pnum -\returns \tcode{result + (last - first)}. +\returns +The end of the resulting range. \pnum -\complexity Exactly \tcode{last - first} assignments. +\complexity +For nonempty ranges, exactly +\tcode{(last - first) - 1} +applications of the corresponding predicate. \end{itemdescr} -\indexlibrary{\idxcode{copy}}% +\indexlibrary{\idxcode{unique_copy}}% \begin{itemdecl} +template + constexpr OutputIterator + unique_copy(InputIterator first, InputIterator last, + OutputIterator result); template - ForwardIterator2 copy(ExecutionPolicy&& policy, - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result); + ForwardIterator2 + unique_copy(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result); + +template + constexpr OutputIterator + unique_copy(InputIterator first, InputIterator last, + OutputIterator result, BinaryPredicate pred); +template + ForwardIterator2 + unique_copy(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, BinaryPredicate pred); \end{itemdecl} -\begin{itemdescr} -\pnum -\requires The ranges \range{first}{last} and -\range{result}{result + (last - first)} shall not overlap. +\begin{itemdescr} \pnum -\effects Copies elements in the range \range{first}{last} into -the range \range{result}{result + (last - first)}. -For each non-negative integer \tcode{n < (last - first)}, -performs \tcode{*(result + n) = *(first + n)}. +\requires +\begin{itemize} +\item +The comparison function shall be an equivalence relation. -\pnum -\returns \tcode{result + (last - first)}. +\item +The ranges +\range{first}{last} +and +\range{result}{result+(last-first)} +shall not overlap. -\pnum -\complexity Exactly \tcode{last - first} assignments. -\end{itemdescr} +\item +The expression +\tcode{*result = *first} +shall be valid. -\indexlibrary{\idxcode{copy_n}}% -\begin{itemdecl} -template - constexpr OutputIterator copy_n(InputIterator first, Size n, - OutputIterator result); -template - ForwardIterator2 copy_n(ExecutionPolicy&& exec, - ForwardIterator1 first, Size n, - ForwardIterator2 result); -\end{itemdecl} +\item +For the overloads with no \tcode{ExecutionPolicy}, +let \tcode{T} be the value type of \tcode{InputIterator}. +If \tcode{InputIterator} meets the \oldconcept{ForwardIterator} requirements, +then there are no additional requirements for \tcode{T}. +Otherwise, if \tcode{OutputIterator} meets the \oldconcept{ForwardIterator} +requirements and its value type is the same as \tcode{T}, +then \tcode{T} shall be \oldconcept{CopyAssignable} (\tref{copyassignable}). +Otherwise, \tcode{T} shall be both +\oldconcept{CopyConstructible} (\tref{copyconstructible}) and \oldconcept{CopyAssignable}. +\begin{note} +For the overloads with an \tcode{ExecutionPolicy}, there may be a performance +cost if the value type of \tcode{ForwardIterator1} is not both +\oldconcept{CopyConstructible} and \oldconcept{CopyAssignable}. +\end{note} +\end{itemize} -\begin{itemdescr} \pnum -\effects For each non-negative integer -$i < n$, performs \tcode{*(result + i) = *(first + i)}. +\effects +Copies only the first element from every consecutive group of equal elements referred to by +the iterator +\tcode{i} +in the range +\range{first}{last} +for which the following corresponding conditions hold: +\tcode{*i == *(i - 1)} +or +\tcode{pred(*i, *(i - 1)) != false}. \pnum -\returns \tcode{result + n}. +\returns +The end of the resulting range. \pnum -\complexity Exactly \tcode{n} assignments. +\complexity +For nonempty ranges, exactly +\tcode{last - first - 1} +applications of the corresponding predicate. \end{itemdescr} -\indexlibrary{\idxcode{copy_if}}% +\rSec2[alg.reverse]{Reverse} + +\indexlibrary{\idxcode{reverse}}% \begin{itemdecl} -template - constexpr OutputIterator copy_if(InputIterator first, InputIterator last, - OutputIterator result, Predicate pred); -template - ForwardIterator2 copy_if(ExecutionPolicy&& exec, - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, Predicate pred); +template + constexpr void reverse(BidirectionalIterator first, BidirectionalIterator last); +template + void reverse(ExecutionPolicy&& exec, + BidirectionalIterator first, BidirectionalIterator last); \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} (\tref{moveconstructible}). -\end{note} - -\pnum -\effects Copies all of the elements referred to by the iterator \tcode{i} in the range \range{first}{last} -for which \tcode{pred(*i)} is \tcode{true}. - -\pnum -\returns The end of the resulting range. +\requires +\tcode{BidirectionalIterator} shall satisfy the +\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. \pnum -\complexity Exactly \tcode{last - first} applications of the corresponding predicate. +\effects +For each non-negative integer +\tcode{i < (last - first) / 2}, +applies +\tcode{iter_swap} +to all pairs of iterators +\tcode{first + i, (last - i) - 1}. \pnum -\remarks Stable\iref{algorithm.stable}. +\complexity +Exactly +\tcode{(last - first)/2} +swaps. \end{itemdescr} -\indexlibrary{\idxcode{copy_backward}}% +\indexlibrary{\idxcode{reverse_copy}}% \begin{itemdecl} -template - constexpr BidirectionalIterator2 - copy_backward(BidirectionalIterator1 first, - BidirectionalIterator1 last, - BidirectionalIterator2 result); +template + constexpr OutputIterator + reverse_copy(BidirectionalIterator first, BidirectionalIterator last, + OutputIterator result); +template + ForwardIterator + reverse_copy(ExecutionPolicy&& exec, + BidirectionalIterator first, BidirectionalIterator last, + ForwardIterator result); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{result} -shall not be in the range -\brange{first}{last}. +The ranges +\range{first}{last} +and +\range{result}{result + (last - first)} +shall not overlap. \pnum \effects -Copies elements in the range \range{first}{last} -into the -range \range{result - (last-first)}{result} -starting from -\tcode{last - 1} -and proceeding to \tcode{first}.\footnote{\tcode{copy_backward} -should be used instead of copy when \tcode{last} -is in -the range -\range{result - (last - first)}{result}.} -For each positive integer -\tcode{n <= (last - first)}, -performs -\tcode{*(result - n) = *(last - n)}. +Copies the range +\range{first}{last} +to the range +\range{result}{result + (last - first)} +such that +for every non-negative integer +\tcode{i < (last - first)} +the following assignment takes place: +\tcode{*(result + (last - first) - 1 - i) = *(first + i)}. \pnum \returns -\tcode{result - (last - first)}. +\tcode{result + (last - first)}. \pnum \complexity @@ -2537,3174 +3356,3622 @@ assignments. \end{itemdescr} -\rSec2[alg.move]{Move} +\rSec2[alg.rotate]{Rotate} -\indexlibrary{\idxcode{move}!algorithm}% +\indexlibrary{\idxcode{rotate}}% \begin{itemdecl} -template - constexpr OutputIterator move(InputIterator first, InputIterator last, - OutputIterator result); +template + constexpr ForwardIterator + rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last); +template + ForwardIterator + rotate(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator middle, ForwardIterator last); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{result} -shall not be in the range -\range{first}{last}. +\range{first}{middle} +and +\range{middle}{last} +shall be valid ranges. +\tcode{ForwardIterator} shall satisfy the +\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. The type of \tcode{*first} shall satisfy +the \oldconcept{MoveConstructible} (\tref{moveconstructible}) and +\oldconcept{MoveAssignable} (\tref{moveassignable}) requirements. \pnum \effects -Moves elements in the range \range{first}{last} -into the range \range{result}{result + (last - first)} -starting from first and proceeding to last. For each non-negative integer -\tcode{n < (last-first)}, -performs -\tcode{*(result + n)} \tcode{= std::move(*(first + n))}. +\tcode{i < (last - first)}, +places the element from the position +\tcode{first + i} +into position +\tcode{first + (i + (last - middle)) \% (last - first)}. \pnum -\returns -\tcode{result + (last - first)}. +\returns \tcode{first + (last - middle)}. + +\pnum +\remarks +This is a left rotate. \pnum \complexity -Exactly +At most \tcode{last - first} -move assignments. +swaps. \end{itemdescr} -\indexlibrary{\idxcode{move}!algorithm}% +\indexlibrary{\idxcode{rotate_copy}}% \begin{itemdecl} +template + constexpr OutputIterator + rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, + OutputIterator result); template - ForwardIterator2 move(ExecutionPolicy&& policy, - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result); + ForwardIterator2 + rotate_copy(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 middle, ForwardIterator1 last, + ForwardIterator2 result); \end{itemdecl} \begin{itemdescr} \pnum -\requires The ranges \range{first}{last} and -\range{result}{result + (last - first)} shall not overlap. +\requires +The ranges +\range{first}{last} +and +\range{result}{result + (last - first)} +shall not overlap. \pnum -\effects Moves elements in the range \range{first}{last} into -the range \range{result}{result + (last - first)}. -For each non-negative integer \tcode{n < (last - first)}, -performs \tcode{*(result + n) = std::\brk{}move(*(first + n))}. +\effects +Copies the range +\range{first}{last} +to the range +\range{result}{result + (last - first)} +such that for each non-negative integer +\tcode{i < (last - first)} +the following assignment takes place: +\tcode{*(result + i) = *(first + +(i + (middle - first)) \% (last - first))}. \pnum -\returns \tcode{result + (last - first)}. +\returns +\tcode{result + (last - first)}. \pnum -\complexity Exactly \tcode{last - first} assignments. +\complexity +Exactly +\tcode{last - first} +assignments. \end{itemdescr} -\indexlibrary{\idxcode{move_backward}}% +\rSec2[alg.random.sample]{Sample} + +\indexlibrary{\idxcode{sample}}% \begin{itemdecl} -template - constexpr BidirectionalIterator2 - move_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, - BidirectionalIterator2 result); +template + SampleIterator sample(PopulationIterator first, PopulationIterator last, + SampleIterator out, Distance n, + UniformRandomBitGenerator&& g); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{result} -shall not be in the range -\brange{first}{last}. +\begin{itemize} +\item +\tcode{PopulationIterator} shall satisfy the \oldconcept{InputIterator} requirements\iref{input.iterators}. +\item +\tcode{SampleIterator} shall satisfy the \oldconcept{OutputIterator} requirements\iref{output.iterators}. +\item +\tcode{SampleIterator} shall satisfy the \oldconcept{RandomAccessIterator} requirements\iref{random.access.iterators} +unless \tcode{Pop\-ulat\-ion\-Iter\-ator} satisfies the \oldconcept{ForwardIterator} requirements\iref{forward.iterators}. +\item +\tcode{PopulationIterator}'s value type shall be writable\iref{iterator.requirements.general} to \tcode{out}. +\item +\tcode{Distance} shall be an integer type. +\item +\tcode{remove_reference_t} +shall satisfy the requirements of a uniform random bit generator type\iref{rand.req.urng} +whose return type is convertible to \tcode{Distance}. +\item +\tcode{out} shall not be in the range \range{first}{last}. +\end{itemize} \pnum \effects -Moves elements in the range \range{first}{last} -into the -range \range{result - (last-first)}{result} -starting from -\tcode{last - 1} -and proceeding to first.\footnote{\tcode{move_backward} -should be used instead of move when last -is in -the range -\range{result - (last - first)}{result}.} -For each positive integer -\tcode{n <= (last - first)}, -performs -\tcode{*(result - n) = std::move(*(last - n))}. +Copies \tcode{min(last - first, n)} elements (the \defn{sample}) +from \range{first}{last} (the \defn{population}) to \tcode{out} +such that each possible sample has equal probability of appearance. +\begin{note} +Algorithms that obtain such effects include \term{selection sampling} +and \term{reservoir sampling}. +\end{note} \pnum \returns -\tcode{result - (last - first)}. +The end of the resulting sample range. \pnum \complexity -Exactly -\tcode{last - first} -assignments. +\bigoh{\tcode{last - first}}. + +\pnum +\remarks +\begin{itemize} +\item +Stable if and only if \tcode{PopulationIterator} satisfies the +\oldconcept{ForwardIterator} requirements. +\item +To the extent that the implementation of this function makes use of +random numbers, the object \tcode{g} shall serve as the +implementation's source of randomness. +\end{itemize} \end{itemdescr} -\rSec2[alg.swap]{Swap} +\rSec2[alg.random.shuffle]{Shuffle} -\indexlibrary{\idxcode{swap_ranges}}% +\indexlibrary{\idxcode{shuffle}}% \begin{itemdecl} -template - ForwardIterator2 - swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2); -template - ForwardIterator2 - swap_ranges(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2); +template + void shuffle(RandomAccessIterator first, + RandomAccessIterator last, + UniformRandomBitGenerator&& g); \end{itemdecl} \begin{itemdescr} \pnum \requires -The two ranges \range{first1}{last1} -and -\range{first2}{first2 + (last1 - first1)} -shall not overlap. -\tcode{*(first1 + n)} shall be swappable with\iref{swappable.requirements} -\tcode{*(first2 + n)}. - -\pnum -\effects -For each non-negative integer -\tcode{n < (last1 - first1)} -performs: -\tcode{swap(*(first1 + n), \brk{}*(first2 + n))}. +\tcode{RandomAccessIterator} shall satisfy the +\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. +The type +\tcode{remove_reference_t} +shall satisfy the requirements of a +uniform random bit generator\iref{rand.req.urng} type whose return type is +convertible to +\tcode{iterator_traits::difference_type}. \pnum -\returns -\tcode{first2 + (last1 - first1)}. +\effects +Permutes the elements in the range +\range{first}{last} +such that each possible permutation of those elements has equal probability of appearance. \pnum \complexity Exactly -\tcode{last1 - first1} +\tcode{(last - first) - 1} swaps. -\end{itemdescr} - -\indexlibrary{\idxcode{iter_swap}}% -\begin{itemdecl} -template - void iter_swap(ForwardIterator1 a, ForwardIterator2 b); -\end{itemdecl} -\begin{itemdescr} \pnum -\requires -\tcode{a} and \tcode{b} shall be dereferenceable. \tcode{*a} shall be -swappable with\iref{swappable.requirements} \tcode{*b}. +\remarks +To the extent that the implementation of this function makes use of random +numbers, the object \tcode{g} shall serve as the implementation's source of +randomness. -\pnum -\effects -As if by \tcode{swap(*a, *b)}. \end{itemdescr} -\rSec2[alg.transform]{Transform} +\rSec2[alg.shift]{Shift} -\indexlibrary{\idxcode{transform}}% +\indexlibrary{\idxcode{shift_left}}% \begin{itemdecl} -template - constexpr OutputIterator - transform(InputIterator first, InputIterator last, - OutputIterator result, UnaryOperation op); -template - ForwardIterator2 - transform(ExecutionPolicy&& exec, - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, UnaryOperation op); - -template - constexpr OutputIterator - transform(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, OutputIterator result, - BinaryOperation binary_op); -template +template + constexpr ForwardIterator + shift_left(ForwardIterator first, ForwardIterator last, + typename iterator_traits::difference_type n); +template ForwardIterator - transform(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator result, - BinaryOperation binary_op); + shift_left(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, + typename iterator_traits::difference_type n); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{op} and \tcode{binary_op} -shall not invalidate iterators or subranges, or modify elements in the ranges -\begin{itemize} -\item \crange{first1}{last1}, -\item \crange{first2}{first2 + (last1 - first1)}, and -\item \crange{result}{result + (last1 - first1)}.\footnote{The use of fully -closed ranges is intentional.} -\end{itemize} +The type of \tcode{*first} shall satisfy +the \oldconcept{MoveAssignable} requirements. \pnum \effects -Assigns through every iterator -\tcode{i} -in the range -\range{result}{result + (last1 - first1)} -a new -corresponding value equal to -\tcode{op(*(first1 + (i - result)))} -or -\tcode{binary_op(*(first1 + (i - result)), *(first2 + (i - result)))}. +If \tcode{n <= 0} or \tcode{n >= last - first}, does nothing. +Otherwise, moves the element +from position \tcode{first + n + i} +into position \tcode{first + i} +for each non-negative integer \tcode{i < (last - first) - n}. +In the first overload case, does so in order starting +from \tcode{i = 0} and proceeding to \tcode{i = (last - first) - n - 1}. \pnum \returns -\tcode{result + (last1 - first1)}. +\tcode{first + (last - first - n)} +if \tcode{n} is positive and \tcode{n < last - first}, +otherwise \tcode{first} if \tcode{n} is positive, otherwise \tcode{last}. \pnum \complexity -Exactly -\tcode{last1 - first1} -applications of -\tcode{op} or \tcode{binary_op}. This requirement also applies to the overload -with an \tcode{ExecutionPolicy} . - -\pnum -\remarks -\tcode{result} may be equal to \tcode{first} -in case of unary transform, -or to \tcode{first1} or \tcode{first2} -in case of binary transform. +At most \tcode{(last - first) - n} assignments. \end{itemdescr} -\rSec2[alg.replace]{Replace} - -\indexlibrary{\idxcode{replace}}% -\indexlibrary{\idxcode{replace_if}}% +\indexlibrary{\idxcode{shift_right}}% \begin{itemdecl} -template - constexpr void replace(ForwardIterator first, ForwardIterator last, - const T& old_value, const T& new_value); -template - void replace(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, - const T& old_value, const T& new_value); - -template - constexpr void replace_if(ForwardIterator first, ForwardIterator last, - Predicate pred, const T& new_value); -template - void replace_if(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, - Predicate pred, const T& new_value); +template + constexpr ForwardIterator + shift_right(ForwardIterator first, ForwardIterator last, + typename iterator_traits::difference_type n); +template + ForwardIterator + shift_right(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, + typename iterator_traits::difference_type n); \end{itemdecl} \begin{itemdescr} \pnum \requires -The expression -\tcode{*first = new_value} -shall be valid. +The type of \tcode{*first} shall satisfy +the \oldconcept{MoveAssignable} requirements. +\tcode{ForwardIterator} shall meet +the \oldconcept{BidirectionalIterator} requirements\iref{bidirectional.iterators} or +the \oldconcept{ValueSwappable} requirements. \pnum \effects -Substitutes elements referred by the iterator -\tcode{i} -in the range \range{first}{last} -with \tcode{new_value}, -when the following corresponding conditions hold: -\tcode{*i == old_value}, \tcode{pred(*i) != false}. +If \tcode{n <= 0} or \tcode{n >= last - first}, does nothing. +Otherwise, moves the element +from position \tcode{first + i} into \tcode{position first + n + i} +for each non-negative integer \tcode{i < (last - first) - n}. +In the first overload case, if \tcode{ForwardIterator} satisfies +the \oldconcept{BidirectionalIterator} requirements, +does so in order starting +from \tcode{i = (last - first) - n - 1} and proceeding to \tcode{i = 0}. + +\pnum +\returns +\tcode{first + n} +if \tcode{n} is positive and \tcode{n < last - first}, +otherwise \tcode{last} if \tcode{n} is positive, otherwise \tcode{first}. \pnum \complexity -Exactly -\tcode{last - first} -applications of the corresponding predicate. +At most \tcode{(last - first) - n} assignments or swaps. \end{itemdescr} -\indexlibrary{\idxcode{replace_copy}}% -\indexlibrary{\idxcode{replace_copy_if}}% -\begin{itemdecl} -template - constexpr OutputIterator - replace_copy(InputIterator first, InputIterator last, - OutputIterator result, - const T& old_value, const T& new_value); -template - ForwardIterator2 - replace_copy(ExecutionPolicy&& exec, - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, - const T& old_value, const T& new_value); +\rSec1[alg.sorting]{Sorting and related operations} -template - constexpr OutputIterator - replace_copy_if(InputIterator first, InputIterator last, - OutputIterator result, - Predicate pred, const T& new_value); -template - ForwardIterator2 - replace_copy_if(ExecutionPolicy&& exec, - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, - Predicate pred, const T& new_value); -\end{itemdecl} +\pnum +All the operations in~\ref{alg.sorting} have two versions: one that takes a function object of type +\tcode{Compare} +and one that uses an +\tcode{operator<}. -\begin{itemdescr} \pnum -\requires -The results of the expressions -\tcode{*first} -and -\tcode{new_value} -shall be writable\iref{iterator.requirements.general} to the -\tcode{result} -output iterator. -The ranges -\range{first}{last} -and -\range{result}{result + (last - first)} -shall not overlap. +\tcode{Compare} +is a function object +type\iref{function.objects}. The return value of the function call operation applied to +an object of type \tcode{Compare}, when contextually converted to +\tcode{bool}\iref{conv}, +yields \tcode{true} if the first argument of the call +is less than the second, and +\tcode{false} +otherwise. +\tcode{Compare comp} +is used throughout for algorithms assuming an ordering relation. +It is assumed that +\tcode{comp} +will not apply any non-constant function through the dereferenced iterator. \pnum -\effects -Assigns to every iterator -\tcode{i} -in the -range -\range{result}{result + (last - first)} -either -\tcode{new_value} -or -\tcode{*\brk(first + (i - result))} -depending on whether the following corresponding conditions hold: +For all algorithms that take +\tcode{Compare}, +there is a version that uses +\tcode{operator<} +instead. +That is, +\tcode{comp(*i, *j) != false} +defaults to +\tcode{*i < *j != false}. +For algorithms other than those described in~\ref{alg.binary.search}, +\tcode{comp} shall induce a strict weak ordering on the values. -\begin{codeblock} -*(first + (i - result)) == old_value -pred(*(first + (i - result))) != false -\end{codeblock} +\pnum +The term +\term{strict} +refers to the +requirement of an irreflexive relation (\tcode{!comp(x, x)} for all \tcode{x}), +and the term +\term{weak} +to requirements that are not as strong as +those for a total ordering, +but stronger than those for a partial +ordering. +If we define +\tcode{equiv(a, b)} +as +\tcode{!comp(a, b) \&\& !comp(b, a)}, +then the requirements are that +\tcode{comp} +and +\tcode{equiv} +both be transitive relations: + +\begin{itemize} +\item +\tcode{comp(a, b) \&\& comp(b, c)} +implies +\tcode{comp(a, c)} +\item +\tcode{equiv(a, b) \&\& equiv(b, c)} +implies +\tcode{equiv(a, c)} +\end{itemize} +\begin{note} +Under these conditions, it can be shown that +\begin{itemize} +\item +\tcode{equiv} +is an equivalence relation, +\item +\tcode{comp} +induces a well-defined relation on the equivalence +classes determined by +\tcode{equiv}, and +\item +the induced relation is a strict total ordering. +\end{itemize} +\end{note} + +\pnum +A sequence is +\term{sorted with respect to a comparator} +\tcode{comp} if for every iterator +\tcode{i} +pointing to the sequence and every non-negative integer +\tcode{n} +such that +\tcode{i + n} +is a valid iterator pointing to an element of the sequence, +\tcode{comp(*(i + n), *i) == false}. \pnum -\returns -\tcode{result + (last - first)}. +A sequence +\range{start}{finish} +is +\term{partitioned with respect to an expression} +\tcode{f(e)} +if there exists an integer +\tcode{n} +such that for all +\tcode{0 <= i < (finish - start)}, +\tcode{f(*(start + i))} +is \tcode{true} if and only if +\tcode{i < n}. \pnum -\complexity -Exactly -\tcode{last - first} -applications of the corresponding predicate. -\end{itemdescr} +In the descriptions of the functions that deal with ordering relationships we frequently use a notion of +equivalence to describe concepts such as stability. +The equivalence to which we refer is not necessarily an +\tcode{operator==}, +but an equivalence relation induced by the strict weak ordering. +That is, two elements +\tcode{a} +and +\tcode{b} +are considered equivalent if and only if +\tcode{!(a < b) \&\& !(b < a)}. -\rSec2[alg.fill]{Fill} +\rSec2[alg.sort]{Sorting} -\indexlibrary{\idxcode{fill}}% -\indexlibrary{\idxcode{fill_n}}% -\begin{itemdecl} -template - constexpr void fill(ForwardIterator first, ForwardIterator last, const T& value); -template - void fill(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, const T& value); +\rSec3[sort]{\tcode{sort}} -template - constexpr OutputIterator fill_n(OutputIterator first, Size n, const T& value); -template - ForwardIterator fill_n(ExecutionPolicy&& exec, - ForwardIterator first, Size n, const T& value); +\indexlibrary{\idxcode{sort}}% +\begin{itemdecl} +template + constexpr void sort(RandomAccessIterator first, RandomAccessIterator last); +template + void sort(ExecutionPolicy&& exec, + RandomAccessIterator first, RandomAccessIterator last); +template + constexpr void sort(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); +template + void sort(ExecutionPolicy&& exec, + RandomAccessIterator first, RandomAccessIterator last, + Compare comp); \end{itemdecl} \begin{itemdescr} \pnum \requires -The expression -\tcode{value} -shall be writable\iref{iterator.requirements.general} to the output iterator. The type -\tcode{Size} -shall be convertible to an integral type~(\ref{conv.integral}, \ref{class.conv}). +\tcode{RandomAccessIterator} shall satisfy the +\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. The type +of \tcode{*first} shall satisfy the +\oldconcept{MoveConstructible} (\tref{moveconstructible}) and +\oldconcept{MoveAssignable} (\tref{moveassignable}) requirements. \pnum \effects -The \tcode{fill} algorithms assign \tcode{value} through all the iterators in the range -\range{first}{last}. The \tcode{fill_n} algorithms assign \tcode{value} -through all the iterators in the range \range{first}{first + n} -if \tcode{n} is positive, otherwise they do nothing. - -\pnum -\returns \tcode{fill_n} returns \tcode{first + n} for non-negative values of \tcode{n} -and \tcode{first} for negative values. +Sorts the elements in the range +\range{first}{last}. \pnum \complexity -Exactly -\tcode{last - first}, -\tcode{n}, or 0 assignments, respectively. +\bigoh{N \log N} comparisons, where $N = \tcode{last - first}$. \end{itemdescr} -\rSec2[alg.generate]{Generate} +\rSec3[stable.sort]{\tcode{stable_sort}} -\indexlibrary{\idxcode{generate}}% -\indexlibrary{\idxcode{generate_n}}% +\indexlibrary{\idxcode{stable_sort}}% \begin{itemdecl} -template - constexpr void generate(ForwardIterator first, ForwardIterator last, - Generator gen); -template - void generate(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, - Generator gen); +template + void stable_sort(RandomAccessIterator first, RandomAccessIterator last); +template + void stable_sort(ExecutionPolicy&& exec, + RandomAccessIterator first, RandomAccessIterator last); -template - constexpr OutputIterator generate_n(OutputIterator first, Size n, Generator gen); -template - ForwardIterator generate_n(ExecutionPolicy&& exec, - ForwardIterator first, Size n, Generator gen); +template + void stable_sort(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); +template + void stable_sort(ExecutionPolicy&& exec, + RandomAccessIterator first, RandomAccessIterator last, + Compare comp); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{gen} takes no arguments, -\tcode{Size} -shall be convertible to an integral type~(\ref{conv.integral}, \ref{class.conv}). +\tcode{RandomAccessIterator} shall satisfy the +\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. The type +of \tcode{*first} shall satisfy the +\oldconcept{MoveConstructible} (\tref{moveconstructible}) and +\oldconcept{MoveAssignable} (\tref{moveassignable}) requirements. \pnum \effects -The \tcode{generate} algorithms invoke the function object \tcode{gen} and assign the return -value of \tcode{gen} through all the iterators in the range -\range{first}{last}. The \tcode{generate_n} algorithms invoke the function object -\tcode{gen} and assign the return value of \tcode{gen} through all the iterators in -the range \range{first}{first + n} if \tcode{n} is positive, -otherwise they do nothing. +Sorts the elements in the range \range{first}{last}. \pnum -\returns \tcode{generate_n} returns \tcode{first + n} for non-negative values of \tcode{n} -and \tcode{first} for negative values. +\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. \pnum -\complexity -Exactly -\tcode{last - first}, -\tcode{n}, or 0 -invocations of \tcode{gen} and assignments, respectively. +\remarks Stable\iref{algorithm.stable}. \end{itemdescr} -\rSec2[alg.remove]{Remove} +\rSec3[partial.sort]{\tcode{partial_sort}} -\indexlibrary{\idxcode{remove}}% -\indexlibrary{\idxcode{remove_if}}% +\indexlibrary{\idxcode{partial_sort}}% \begin{itemdecl} -template - constexpr ForwardIterator remove(ForwardIterator first, ForwardIterator last, - const T& value); -template - ForwardIterator remove(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, - const T& value); +template + constexpr void partial_sort(RandomAccessIterator first, + RandomAccessIterator middle, + RandomAccessIterator last); +template + void partial_sort(ExecutionPolicy&& exec, + RandomAccessIterator first, + RandomAccessIterator middle, + RandomAccessIterator last); + +template + constexpr void partial_sort(RandomAccessIterator first, + RandomAccessIterator middle, + RandomAccessIterator last, + Compare comp); +template + void partial_sort(ExecutionPolicy&& exec, + RandomAccessIterator first, + RandomAccessIterator middle, + RandomAccessIterator last, + Compare comp); -template - constexpr ForwardIterator remove_if(ForwardIterator first, ForwardIterator last, - Predicate pred); -template - ForwardIterator remove_if(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, - Predicate pred); \end{itemdecl} \begin{itemdescr} \pnum \requires -The type of -\tcode{*first} -shall satisfy the \tcode{MoveAssignable} -requirements (\tref{moveassignable}). +\tcode{RandomAccessIterator} shall satisfy the +\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. The type +of \tcode{*first} shall satisfy the +\oldconcept{MoveConstructible} (\tref{moveconstructible}) and +\oldconcept{MoveAssignable} (\tref{moveassignable}) requirements. \pnum \effects -Eliminates all the elements referred to by iterator -\tcode{i} -in the range \range{first}{last} -for which the following corresponding conditions hold: -\tcode{*i == value, pred(*i) != false}. - -\pnum -\returns -The end of the resulting range. - -\pnum -\remarks Stable\iref{algorithm.stable}. +Places the first +\tcode{middle - first} +sorted elements from the range +\range{first}{last} +into the range +\range{first}{middle}. +The rest of the elements in the range +\range{middle}{last} +are placed in an unspecified order. +\indextext{unspecified}% \pnum \complexity -Exactly -\tcode{last - first} -applications of the corresponding predicate. - -\pnum -\begin{note} -Each element in the range \range{ret}{last}, where \tcode{ret} is -the returned value, has a valid but unspecified state, because the algorithms -can eliminate elements by moving from elements that were originally -in that range. -\end{note} +Approximately +\tcode{(last - first) * log(middle - first)} +comparisons. \end{itemdescr} -\indexlibrary{\idxcode{remove_copy}}% -\indexlibrary{\idxcode{remove_copy_if}}% +\rSec3[partial.sort.copy]{\tcode{partial_sort_copy}} + +\indexlibrary{\idxcode{partial_sort_copy}}% \begin{itemdecl} -template - constexpr OutputIterator - remove_copy(InputIterator first, InputIterator last, - OutputIterator result, const T& value); -template - ForwardIterator2 - remove_copy(ExecutionPolicy&& exec, - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, const T& value); +template + constexpr RandomAccessIterator + partial_sort_copy(InputIterator first, InputIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last); +template + RandomAccessIterator + partial_sort_copy(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last); -template - constexpr OutputIterator - remove_copy_if(InputIterator first, InputIterator last, - OutputIterator result, Predicate pred); -template - ForwardIterator2 - remove_copy_if(ExecutionPolicy&& exec, - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, Predicate pred); +template + constexpr RandomAccessIterator + partial_sort_copy(InputIterator first, InputIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last, + Compare comp); +template + RandomAccessIterator + partial_sort_copy(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + RandomAccessIterator result_first, + RandomAccessIterator result_last, + Compare comp); \end{itemdecl} \begin{itemdescr} \pnum \requires -The ranges -\range{first}{last} -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} (\tref{moveconstructible}). -\end{note} +\tcode{RandomAccessIterator} shall satisfy the +\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. The type +of \tcode{*result_first} shall satisfy the +\oldconcept{MoveConstructible} (\tref{moveconstructible}) and +\oldconcept{\-Move\-Assignable} (\tref{moveassignable}) requirements. \pnum \effects -Copies all the elements referred to by the iterator -\tcode{i} -in the range -\range{first}{last} -for which the following corresponding conditions do not hold: -\tcode{*i == value, pred(*i) != false}. +Places the first +\tcode{min(last - first, result_last - result_first)} +sorted elements into the range +\range{result_first}{result_first + min(last - first, result_last - result_first)}. \pnum \returns -The end of the resulting range. +The smaller of: +\tcode{result_last} or +\tcode{result_first + (last - first)}. \pnum \complexity -Exactly -\tcode{last - first} -applications of the corresponding predicate. - -\pnum -\remarks Stable\iref{algorithm.stable}. +Approximately +\tcode{(last - first) * log(min(last - first, result_last - result_first))} +comparisons. \end{itemdescr} -\rSec2[alg.unique]{Unique} +\rSec3[is.sorted]{\tcode{is_sorted}} -\indexlibrary{\idxcode{unique}}% +\indexlibrary{\idxcode{is_sorted}}% \begin{itemdecl} template - constexpr ForwardIterator unique(ForwardIterator first, ForwardIterator last); -template - ForwardIterator unique(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last); - -template - constexpr ForwardIterator unique(ForwardIterator first, ForwardIterator last, - BinaryPredicate pred); -template - ForwardIterator unique(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, - BinaryPredicate pred); + constexpr bool is_sorted(ForwardIterator first, ForwardIterator last); \end{itemdecl} \begin{itemdescr} \pnum -\requires -The comparison function shall be an equivalence relation. -The type of \tcode{*first} shall satisfy the -\tcode{MoveAssignable} requirements (\tref{moveassignable}). - -\pnum -\effects -For a nonempty range, eliminates all but the first element from every -consecutive group of equivalent elements referred to by the iterator -\tcode{i} -in the range -\range{first + 1}{last} -for which the following conditions hold: -\tcode{*(i - 1) == *i} -or -\tcode{pred(*(i - 1), *i) != false}. +\returns \tcode{is_sorted_until(first, last) == last}. +\end{itemdescr} -\pnum -\returns -The end of the resulting range. +\indexlibrary{\idxcode{is_sorted}}% +\begin{itemdecl} +template + bool is_sorted(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last); +\end{itemdecl} +\begin{itemdescr} \pnum -\complexity -For nonempty ranges, exactly -\tcode{(last - first) - 1} -applications of the corresponding predicate. +\returns \tcode{is_sorted_until(std::forward(exec), first, last) == last}. \end{itemdescr} -\indexlibrary{\idxcode{unique_copy}}% -\begin{itemdecl} -template - constexpr OutputIterator - unique_copy(InputIterator first, InputIterator last, - OutputIterator result); -template - ForwardIterator2 - unique_copy(ExecutionPolicy&& exec, - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result); -template - constexpr OutputIterator - unique_copy(InputIterator first, InputIterator last, - OutputIterator result, BinaryPredicate pred); -template - ForwardIterator2 - unique_copy(ExecutionPolicy&& exec, - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, BinaryPredicate pred); +\indexlibrary{\idxcode{is_sorted}}% +\begin{itemdecl} +template + constexpr bool is_sorted(ForwardIterator first, ForwardIterator last, + Compare comp); \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. - -\item -The expression -\tcode{*result = *first} -shall be valid. +\returns \tcode{is_sorted_until(first, last, comp) == last}. +\end{itemdescr} -\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} (\tref{copyassignable}). -Otherwise, \tcode{T} shall be both -\tcode{CopyConstructible} (\tref{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 -Copies only the first element from every consecutive group of equal elements referred to by -the iterator -\tcode{i} -in the range -\range{first}{last} -for which the following corresponding conditions hold: -\tcode{*i == *(i - 1)} -or -\tcode{pred(*i, *(i - 1)) != false}. +\indexlibrary{\idxcode{is_sorted}}% +\begin{itemdecl} +template + bool is_sorted(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + Compare comp); +\end{itemdecl} +\begin{itemdescr} \pnum \returns -The end of the resulting range. - -\pnum -\complexity -For nonempty ranges, exactly -\tcode{last - first - 1} -applications of the corresponding predicate. +\begin{codeblock} +is_sorted_until(std::forward(exec), first, last, comp) == last +\end{codeblock} \end{itemdescr} -\rSec2[alg.reverse]{Reverse} -\indexlibrary{\idxcode{reverse}}% +\indexlibrary{\idxcode{is_sorted_until}}% \begin{itemdecl} -template - void reverse(BidirectionalIterator first, BidirectionalIterator last); -template - void reverse(ExecutionPolicy&& exec, - BidirectionalIterator first, BidirectionalIterator last); +template + constexpr ForwardIterator + is_sorted_until(ForwardIterator first, ForwardIterator last); +template + ForwardIterator + is_sorted_until(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last); + +template + constexpr ForwardIterator + is_sorted_until(ForwardIterator first, ForwardIterator last, + Compare comp); +template + ForwardIterator + is_sorted_until(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + Compare comp); \end{itemdecl} -\begin{itemdescr} -\pnum -\requires -\tcode{BidirectionalIterator} shall satisfy the -\tcode{ValueSwappable} requirements\iref{swappable.requirements}. +\begin{itemdescr} \pnum -\effects -For each non-negative integer -\tcode{i < (last - first) / 2}, -applies -\tcode{iter_swap} -to all pairs of iterators -\tcode{first + i, (last - i) - 1}. +\returns If \tcode{(last - first) < 2}, returns +\tcode{last}. Otherwise, returns +the last iterator \tcode{i} in \crange{first}{last} for which the +range \range{first}{i} is sorted. \pnum -\complexity -Exactly -\tcode{(last - first)/2} -swaps. +\complexity Linear. \end{itemdescr} -\indexlibrary{\idxcode{reverse_copy}}% +\rSec2[alg.nth.element]{Nth element} + +\indexlibrary{\idxcode{nth_element}}% \begin{itemdecl} -template - constexpr OutputIterator - reverse_copy(BidirectionalIterator first, BidirectionalIterator last, - OutputIterator result); -template - ForwardIterator - reverse_copy(ExecutionPolicy&& exec, - BidirectionalIterator first, BidirectionalIterator last, - ForwardIterator result); -\end{itemdecl} +template + constexpr void nth_element(RandomAccessIterator first, RandomAccessIterator nth, + RandomAccessIterator last); +template + void nth_element(ExecutionPolicy&& exec, + RandomAccessIterator first, RandomAccessIterator nth, + RandomAccessIterator last); -\begin{itemdescr} -\pnum -\requires -The ranges -\range{first}{last} -and -\range{result}{result + (last - first)} -shall not overlap. +template + constexpr void nth_element(RandomAccessIterator first, RandomAccessIterator nth, + RandomAccessIterator last, Compare comp); +template + void nth_element(ExecutionPolicy&& exec, + RandomAccessIterator first, RandomAccessIterator nth, + RandomAccessIterator last, Compare comp); +\end{itemdecl} +\begin{itemdescr} \pnum -\effects -Copies the range -\range{first}{last} -to the range -\range{result}{result + (last - first)} -such that -for every non-negative integer -\tcode{i < (last - first)} -the following assignment takes place: -\tcode{*(result + (last - first) - 1 - i) = *(first + i)}. +\requires +\tcode{RandomAccessIterator} shall satisfy the +\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. The type +of \tcode{*first} shall satisfy the +\oldconcept{MoveConstructible} (\tref{moveconstructible}) and +\oldconcept{MoveAssignable} (\tref{moveassignable}) requirements. \pnum -\returns -\tcode{result + (last - first)}. +\effects +After +\tcode{nth_element} +the element in the position pointed to by \tcode{nth} +is the element that would be +in that position if the whole range were sorted, unless \tcode{nth == last}. +Also for every iterator +\tcode{i} +in the range +\range{first}{nth} +and every iterator +\tcode{j} +in the range +\range{nth}{last} +it holds that: +\tcode{!(*j < *i)} +or +\tcode{comp(*j, *i) == false}. \pnum \complexity -Exactly -\tcode{last - first} -assignments. +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.rotate]{Rotate} +\rSec2[alg.binary.search]{Binary search} -\indexlibrary{\idxcode{rotate}}% +\pnum +All of the algorithms in this subclause are versions of binary search +and assume that the sequence being searched is partitioned with respect to +an expression formed by binding the search key to an argument of the +implied or explicit comparison function. +They work on non-random access iterators minimizing the number of comparisons, +which will be logarithmic for all types of iterators. +They are especially appropriate for random access iterators, +because these algorithms do a logarithmic number of steps +through the data structure. +For non-random access iterators they execute a linear number of steps. + +\rSec3[lower.bound]{\tcode{lower_bound}} + +\indexlibrary{\idxcode{lower_bound}}% \begin{itemdecl} -template - ForwardIterator - rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last); -template - ForwardIterator - rotate(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator middle, ForwardIterator last); +template + constexpr ForwardIterator + lower_bound(ForwardIterator first, ForwardIterator last, + const T& value); + +template + constexpr ForwardIterator + lower_bound(ForwardIterator first, ForwardIterator last, + const T& value, Compare comp); \end{itemdecl} \begin{itemdescr} \pnum \requires -\range{first}{middle} -and -\range{middle}{last} -shall be valid ranges. -\tcode{ForwardIterator} shall satisfy the -\tcode{ValueSwappable} requirements\iref{swappable.requirements}. The type of \tcode{*first} shall satisfy -the \tcode{MoveConstructible} (\tref{moveconstructible}) and -\tcode{MoveAssignable} (\tref{moveassignable}) requirements. - -\pnum -\effects -For each non-negative integer -\tcode{i < (last - first)}, -places the element from the position -\tcode{first + i} -into position -\tcode{first + (i + (last - middle)) \% (last - first)}. - -\pnum -\returns \tcode{first + (last - middle)}. +The elements +\tcode{e} +of +\range{first}{last} +shall be partitioned with respect to the expression +\tcode{e < value} +or +\tcode{comp(e, value)}. \pnum -\remarks -This is a left rotate. +\returns +The furthermost iterator +\tcode{i} +in the range +\crange{first}{last} +such that for every iterator +\tcode{j} +in the range +\range{first}{i} +the following corresponding conditions hold: +\tcode{*j < value} +or +\tcode{comp(*j, value) != false}. \pnum \complexity At most -\tcode{last - first} -swaps. +$\log_2(\tcode{last - first}) + \bigoh{1}$ +comparisons. \end{itemdescr} -\indexlibrary{\idxcode{rotate_copy}}% +\rSec3[upper.bound]{\tcode{upper_bound}} + +\indexlibrary{\idxcode{upper_bound}}% \begin{itemdecl} -template - constexpr OutputIterator - rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, - OutputIterator result); -template - ForwardIterator2 - rotate_copy(ExecutionPolicy&& exec, - ForwardIterator1 first, ForwardIterator1 middle, ForwardIterator1 last, - ForwardIterator2 result); +template + constexpr ForwardIterator + upper_bound(ForwardIterator first, ForwardIterator last, + const T& value); + +template + constexpr ForwardIterator + upper_bound(ForwardIterator first, ForwardIterator last, + const T& value, Compare comp); \end{itemdecl} \begin{itemdescr} \pnum \requires -The ranges -\range{first}{last} -and -\range{result}{result + (last - first)} -shall not overlap. - -\pnum -\effects -Copies the range +The elements +\tcode{e} +of \range{first}{last} -to the range -\range{result}{result + (last - first)} -such that for each non-negative integer -\tcode{i < (last - first)} -the following assignment takes place: -\tcode{*(result + i) = *(first + -(i + (middle - first)) \% (last - first))}. +shall be partitioned with respect to the expression +\tcode{!(value < e)} +or +\tcode{!comp(\brk{}value, e)}. \pnum \returns -\tcode{result + (last - first)}. +The furthermost iterator +\tcode{i} +in the range +\crange{first}{last} +such that for every iterator +\tcode{j} +in the range +\range{first}{i} +the following corresponding conditions hold: +\tcode{!(value < *j)} +or +\tcode{comp(value, *j) == false}. \pnum \complexity -Exactly -\tcode{last - first} -assignments. +At most +$\log_2(\tcode{last - first}) + \bigoh{1}$ +comparisons. \end{itemdescr} -\rSec2[alg.random.sample]{Sample} +\rSec3[equal.range]{\tcode{equal_range}} -\indexlibrary{\idxcode{sample}}% +\indexlibrary{\idxcode{equal_range}}% \begin{itemdecl} -template - SampleIterator sample(PopulationIterator first, PopulationIterator last, - SampleIterator out, Distance n, - UniformRandomBitGenerator&& g); +template + constexpr pair + equal_range(ForwardIterator first, + ForwardIterator last, const T& value); + +template + constexpr pair + equal_range(ForwardIterator first, + ForwardIterator last, const T& value, + Compare comp); \end{itemdecl} \begin{itemdescr} \pnum \requires -\begin{itemize} -\item -\tcode{PopulationIterator} shall satisfy the requirements of an input iterator\iref{input.iterators}. -\item -\tcode{SampleIterator} shall satisfy the requirements of an output iterator\iref{output.iterators}. -\item -\tcode{SampleIterator} shall satisfy the additional requirements of a random access iterator\iref{random.access.iterators} -unless \tcode{PopulationIterator} satisfies the additional requirements of a forward iterator\iref{forward.iterators}. -\item -\tcode{PopulationIterator}'s value type shall be writable\iref{iterator.requirements.general} to \tcode{out}. -\item -\tcode{Distance} shall be an integer type. -\item -\tcode{remove_reference_t} -shall satisfy the requirements of a uniform random bit generator type\iref{rand.req.urng} -whose return type is convertible to \tcode{Distance}. -\item -\tcode{out} shall not be in the range \range{first}{last}. -\end{itemize} - -\pnum -\effects -Copies \tcode{min(last - first, n)} elements (the \defn{sample}) -from \range{first}{last} (the \defn{population}) to \tcode{out} -such that each possible sample has equal probability of appearance. -\begin{note} -Algorithms that obtain such effects include \term{selection sampling} -and \term{reservoir sampling}. -\end{note} +The elements +\tcode{e} +of +\range{first}{last} +shall be partitioned with respect to the expressions +\tcode{e < value} +and +\tcode{!(value < e)} +or +\tcode{comp(e, value)} +and +\tcode{!comp(value, e)}. +Also, for all elements +\tcode{e} +of +\tcode{[first, last)}, +\tcode{e < value} +shall imply +\tcode{!(value < e)} +or +\tcode{comp(e, value)} +shall imply +\tcode{!comp(value, e)}. \pnum \returns -The end of the resulting sample range. +\begin{codeblock} +make_pair(lower_bound(first, last, value), + upper_bound(first, last, value)) +\end{codeblock} +or +\begin{codeblock} +make_pair(lower_bound(first, last, value, comp), + upper_bound(first, last, value, comp)) +\end{codeblock} \pnum \complexity -\bigoh{\tcode{last - first}}. - -\pnum -\remarks -\begin{itemize} -\item -Stable if and only if \tcode{PopulationIterator} satisfies the -requirements of a forward iterator. -\item -To the extent that the implementation of this function makes use of -random numbers, the object \tcode{g} shall serve as the -implementation's source of randomness. -\end{itemize} +At most +$2 * \log_2(\tcode{last - first}) + \bigoh{1}$ +comparisons. \end{itemdescr} -\rSec2[alg.random.shuffle]{Shuffle} +\rSec3[binary.search]{\tcode{binary_search}} -\indexlibrary{\idxcode{shuffle}}% +\indexlibrary{\idxcode{binary_search}}% \begin{itemdecl} -template - void shuffle(RandomAccessIterator first, - RandomAccessIterator last, - UniformRandomBitGenerator&& g); +template + constexpr bool + binary_search(ForwardIterator first, ForwardIterator last, + const T& value); + +template + constexpr bool + binary_search(ForwardIterator first, ForwardIterator last, + const T& value, Compare comp); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{RandomAccessIterator} shall satisfy the -\tcode{ValueSwappable} requirements\iref{swappable.requirements}. -The type -\tcode{remove_reference_t} -shall satisfy the requirements of a -uniform random bit generator\iref{rand.req.urng} type whose return type is -convertible to -\tcode{iterator_traits::difference_type}. +The elements +\tcode{e} +of +\range{first}{last} +shall be partitioned with respect to the expressions +\tcode{e < value} +and +\tcode{!(value < e)} +or +\tcode{comp(e, value)} +and +\tcode{!comp(value, e)}. +Also, for all elements +\tcode{e} +of +\tcode{[first, last)}, +\tcode{e < value} +shall imply +\tcode{!(value < e)} +or +\tcode{comp(e, value)} +shall imply +\tcode{!comp(value, e)}. \pnum -\effects -Permutes the elements in the range +\returns +\tcode{true} +if there is an iterator +\tcode{i} +in the range \range{first}{last} -such that each possible permutation of those elements has equal probability of appearance. +that satisfies the corresponding conditions: +\tcode{!(*i < value) \&\& !(value < *i)} +or +\tcode{comp(*i, value) == false \&\& comp(value, *i) == false}. \pnum \complexity -Exactly -\tcode{(last - first) - 1} -swaps. - -\pnum -\remarks -To the extent that the implementation of this function makes use of random -numbers, the object \tcode{g} shall serve as the implementation's source of -randomness. - +At most +$\log_2(\tcode{last - first}) + \bigoh{1}$ +comparisons. \end{itemdescr} -\rSec1[alg.sorting]{Sorting and related operations} +\rSec2[alg.partitions]{Partitions} -\pnum -All the operations in~\ref{alg.sorting} have two versions: one that takes a function object of type -\tcode{Compare} -and one that uses an -\tcode{operator<}. +\indexlibrary{\idxcode{is_partitioned}}% +\begin{itemdecl} +template + constexpr bool is_partitioned(InputIterator first, InputIterator last, Predicate pred); +template + bool is_partitioned(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, Predicate pred); +\end{itemdecl} +\begin{itemdescr} \pnum -\tcode{Compare} -is a function object -type\iref{function.objects}. The return value of the function call operation applied to -an object of type \tcode{Compare}, when contextually converted to -\tcode{bool}\iref{conv}, -yields \tcode{true} if the first argument of the call -is less than the second, and -\tcode{false} -otherwise. -\tcode{Compare comp} -is used throughout for algorithms assuming an ordering relation. -It is assumed that -\tcode{comp} -will not apply any non-constant function through the dereferenced iterator. +\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 -For all algorithms that take -\tcode{Compare}, -there is a version that uses -\tcode{operator<} -instead. -That is, -\tcode{comp(*i, *j) != false} -defaults to -\tcode{*i < *j != false}. -For algorithms other than those described in~\ref{alg.binary.search}, -\tcode{comp} shall induce a strict weak ordering on the values. +\returns \tcode{true} if +\range{first}{last} is empty or if +the elements \tcode{e} of +\range{first}{last} are partitioned with respect to the expression +\tcode{pred(e)}. \pnum -The term -\techterm{strict} -refers to the -requirement of an irreflexive relation (\tcode{!comp(x, x)} for all \tcode{x}), -and the term -\techterm{weak} -to requirements that are not as strong as -those for a total ordering, -but stronger than those for a partial -ordering. -If we define -\tcode{equiv(a, b)} -as -\tcode{!comp(a, b) \&\& !comp(b, a)}, -then the requirements are that -\tcode{comp} -and -\tcode{equiv} -both be transitive relations: +\complexity Linear. At most \tcode{last - first} applications of \tcode{pred}. +\end{itemdescr} -\begin{itemize} -\item -\tcode{comp(a, b) \&\& comp(b, c)} -implies -\tcode{comp(a, c)} -\item -\tcode{equiv(a, b) \&\& equiv(b, c)} -implies -\tcode{equiv(a, c)} -\end{itemize} -\begin{note} -Under these conditions, it can be shown that -\begin{itemize} -\item -\tcode{equiv} -is an equivalence relation -\item -\tcode{comp} -induces a well-defined relation on the equivalence -classes determined by -\tcode{equiv} -\item -The induced relation is a strict total ordering. -\end{itemize} -\end{note} +\indexlibrary{\idxcode{partition}}% +\begin{itemdecl} +template + constexpr ForwardIterator + partition(ForwardIterator first, ForwardIterator last, Predicate pred); +template + ForwardIterator + partition(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, Predicate pred); +\end{itemdecl} +\begin{itemdescr} \pnum -A sequence is -\techterm{sorted with respect to a comparator} -\tcode{comp} if for every iterator -\tcode{i} -pointing to the sequence and every non-negative integer -\tcode{n} -such that -\tcode{i + n} -is a valid iterator pointing to an element of the sequence, -\tcode{comp(*(i + n), *i) == false}. +\requires +\tcode{ForwardIterator} shall satisfy the +\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. \pnum -A sequence -\range{start}{finish} -is -\techterm{partitioned with respect to an expression} -\tcode{f(e)} -if there exists an integer -\tcode{n} -such that for all -\tcode{0 <= i < (finish - start)}, -\tcode{f(*(start + i))} -is \tcode{true} if and only if -\tcode{i < n}. +\effects Places all the elements in the range \range{first}{last} that satisfy \tcode{pred} before all the elements that do not satisfy it. \pnum -In the descriptions of the functions that deal with ordering relationships we frequently use a notion of -equivalence to describe concepts such as stability. -The equivalence to which we refer is not necessarily an -\tcode{operator==}, -but an equivalence relation induced by the strict weak ordering. -That is, two elements -\tcode{a} -and -\tcode{b} -are considered equivalent if and only if -\tcode{!(a < b) \&\& !(b < a)}. - -\rSec2[alg.sort]{Sorting} - -\rSec3[sort]{\tcode{sort}} - -\indexlibrary{\idxcode{sort}}% -\begin{itemdecl} -template - void sort(RandomAccessIterator first, RandomAccessIterator last); -template - void sort(ExecutionPolicy&& exec, - RandomAccessIterator first, RandomAccessIterator last); +\returns An iterator \tcode{i} such that for every iterator \tcode{j} in the range +\range{first}{i} \tcode{pred(*j) != false}, and for every iterator \tcode{k} in the +range \range{i}{last}, \tcode{pred(*k) == false}. -template - void sort(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); -template - void sort(ExecutionPolicy&& exec, - RandomAccessIterator first, RandomAccessIterator last, - Compare comp); +\pnum +\complexity Let $N = \tcode{last - first}$: +\begin{itemize} +\item For the overload with no \tcode{ExecutionPolicy}, exactly $N$ applications +of the predicate. At most $N / 2$ swaps if \tcode{ForwardIterator} meets the +\oldconcept{BidirectionalIterator} requirements and at most $N$ swaps otherwise. +\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}}% +\begin{itemdecl} +template + BidirectionalIterator + stable_partition(BidirectionalIterator first, BidirectionalIterator last, Predicate pred); +template + BidirectionalIterator + stable_partition(ExecutionPolicy&& exec, + BidirectionalIterator first, BidirectionalIterator last, Predicate pred); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{RandomAccessIterator} shall satisfy the -\tcode{ValueSwappable} requirements\iref{swappable.requirements}. The type +\tcode{BidirectionalIterator} shall satisfy the +\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. The type of \tcode{*first} shall satisfy the -\tcode{MoveConstructible} (\tref{moveconstructible}) and -\tcode{MoveAssignable} (\tref{moveassignable}) requirements. +\oldconcept{MoveConstructible} (\tref{moveconstructible}) and +\oldconcept{MoveAssignable} (\tref{moveassignable}) requirements. \pnum \effects -Sorts the elements in the range -\range{first}{last}. +Places all the elements in the range +\range{first}{last} +that satisfy \tcode{pred} before all the +elements that do not satisfy it. + +\pnum +\returns +An iterator +\tcode{i} +such that for every iterator +\tcode{j} +in the range +\range{first}{i}, +\tcode{pred(*j) != false}, +and for every iterator +\tcode{k} +in the range +\range{i}{last}, +\tcode{pred(*k) == false}. +The relative order of the elements in both groups is preserved. \pnum \complexity -\bigoh{N \log N} comparisons, where $N = \tcode{last - first}$. -\end{itemdescr} +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} -\rSec3[stable.sort]{\tcode{stable_sort}} +\end{itemdescr} -\indexlibrary{\idxcode{stable_sort}}% +\indexlibrary{\idxcode{partition_copy}}% \begin{itemdecl} -template - void stable_sort(RandomAccessIterator first, RandomAccessIterator last); -template - void stable_sort(ExecutionPolicy&& exec, - RandomAccessIterator first, RandomAccessIterator last); - -template - void stable_sort(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); -template - void stable_sort(ExecutionPolicy&& exec, - RandomAccessIterator first, RandomAccessIterator last, - Compare comp); +template + constexpr pair + partition_copy(InputIterator first, InputIterator last, + OutputIterator1 out_true, OutputIterator2 out_false, Predicate pred); +template + pair + partition_copy(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + ForwardIterator1 out_true, ForwardIterator2 out_false, Predicate pred); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{RandomAccessIterator} shall satisfy the -\tcode{ValueSwappable} requirements\iref{swappable.requirements}. The type -of \tcode{*first} shall satisfy the -\tcode{MoveConstructible} (\tref{moveconstructible}) and -\tcode{MoveAssignable} (\tref{moveassignable}) requirements. +\begin{itemize} +\item +For the overload with no \tcode{ExecutionPolicy}, \tcode{InputIterator}'s +value type shall be \oldconcept{\-Copy\-Assign\-able} (\tref{copyassignable}), +and shall be writable\iref{iterator.requirements.general} to the \tcode{out_true} +and \tcode{out_false} \tcode{Output\-Iter\-ator}s, and shall be convertible to +\tcode{Predicate}'s argument type. + +\item +For the overload with an \tcode{ExecutionPolicy}, \tcode{ForwardIterator}'s +value type shall be \oldconcept{\-Copy\-Assign\-able}, and shall be writable to the +\tcode{out_true} and \tcode{out_false} \tcode{ForwardIterator}s, and shall be +convertible to \tcode{Predicate}'s argument type. +\begin{note} +There may be a performance cost if \tcode{ForwardIterator}'s value type is not +\oldconcept{CopyConstructible}. +\end{note} + +\item +For both overloads, the input range shall not overlap with either of the output ranges. +\end{itemize} \pnum -\effects -Sorts the elements in the range \range{first}{last}. +\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. \pnum -\complexity -At most $N \log^2(N)$ -comparisons, where -$N = \tcode{last - first}$, but only $N \log N$ comparisons if there is enough extra memory. +\returns A pair \tcode{p} such that \tcode{p.first} is the end of the output range beginning at \tcode{out_true} and \tcode{p.second} is the end of the output range beginning at \tcode{out_false}. \pnum -\remarks Stable\iref{algorithm.stable}. +\complexity Exactly \tcode{last - first} applications of \tcode{pred}. \end{itemdescr} -\rSec3[partial.sort]{\tcode{partial_sort}} - -\indexlibrary{\idxcode{partial_sort}}% +\indexlibrary{\idxcode{partition_point}}% \begin{itemdecl} -template - void partial_sort(RandomAccessIterator first, - RandomAccessIterator middle, - RandomAccessIterator last); -template - void partial_sort(ExecutionPolicy&& exec, - RandomAccessIterator first, - RandomAccessIterator middle, - RandomAccessIterator last); - -template - void partial_sort(RandomAccessIterator first, - RandomAccessIterator middle, - RandomAccessIterator last, - Compare comp); -template - void partial_sort(ExecutionPolicy&& exec, - RandomAccessIterator first, - RandomAccessIterator middle, - RandomAccessIterator last, - Compare comp); - +template + constexpr ForwardIterator + partition_point(ForwardIterator first, ForwardIterator last, Predicate pred); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{RandomAccessIterator} shall satisfy the -\tcode{ValueSwappable} requirements\iref{swappable.requirements}. The type -of \tcode{*first} shall satisfy the -\tcode{MoveConstructible} (\tref{moveconstructible}) and -\tcode{MoveAssignable} (\tref{moveassignable}) requirements. +\tcode{ForwardIterator}'s value type shall be convertible to +\tcode{Predicate}'s argument type. The elements \tcode{e} of \range{first}{last} +shall be partitioned with respect to the expression \tcode{pred(e)}. \pnum -\effects -Places the first -\tcode{middle - first} -sorted elements from the range -\range{first}{last} -into the range -\range{first}{middle}. -The rest of the elements in the range -\range{middle}{last} -are placed in an unspecified order. -\indextext{unspecified}% +\returns An iterator \tcode{mid} such that \tcode{all_of(first, mid, pred)} and \tcode{none_of(mid, last, pred)} are both \tcode{true}. \pnum -\complexity -Approximately -\tcode{(last - first) * log(middle - first)} -comparisons. +\complexity \bigoh{\log(\tcode{last - first})} applications of \tcode{pred}. \end{itemdescr} -\rSec3[partial.sort.copy]{\tcode{partial_sort_copy}} +\rSec2[alg.merge]{Merge} -\indexlibrary{\idxcode{partial_sort_copy}}% +\indexlibrary{\idxcode{merge}}% \begin{itemdecl} -template - RandomAccessIterator - partial_sort_copy(InputIterator first, InputIterator last, - RandomAccessIterator result_first, - RandomAccessIterator result_last); -template - RandomAccessIterator - partial_sort_copy(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, - RandomAccessIterator result_first, - RandomAccessIterator result_last); +template + constexpr OutputIterator + merge(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); +template + ForwardIterator + merge(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); -template - RandomAccessIterator - partial_sort_copy(InputIterator first, InputIterator last, - RandomAccessIterator result_first, - RandomAccessIterator result_last, - Compare comp); -template - RandomAccessIterator - partial_sort_copy(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, - RandomAccessIterator result_first, - RandomAccessIterator result_last, - Compare comp); +template + constexpr OutputIterator + merge(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); +template + ForwardIterator + merge(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires The ranges \range{first1}{last1} and \range{first2}{last2} shall be +sorted with respect to \tcode{oper\-ator<} or \tcode{comp}. +The resulting range shall not overlap with either of the original ranges. + +\pnum +\effects Copies all the elements of the two ranges \range{first1}{last1} and +\range{first2}{last2} into the range \range{result}{result_last}, where \tcode{result_last} +is \tcode{result + (last1 - first1) + (last2 - first2)}, such that the resulting range satisfies +\tcode{is_sorted(result, result_last)} or \tcode{is_sorted(re\-sult, result_last, comp)}, respectively. + +\pnum +\returns +\tcode{result + (last1 - first1) + (last2 - first2)}. + +\pnum +\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\iref{algorithm.stable}. +\end{itemdescr} + +\indexlibrary{\idxcode{inplace_merge}}% +\begin{itemdecl} +template + void inplace_merge(BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last); +template + void inplace_merge(ExecutionPolicy&& exec, + BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last); + +template + void inplace_merge(BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last, Compare comp); +template + void inplace_merge(ExecutionPolicy&& exec, + BidirectionalIterator first, + BidirectionalIterator middle, + BidirectionalIterator last, Compare comp); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{RandomAccessIterator} shall satisfy the -\tcode{ValueSwappable} requirements\iref{swappable.requirements}. The type -of \tcode{*result_first} shall satisfy the -\tcode{MoveConstructible} (\tref{moveconstructible}) and -\tcode{Move\-Assignable} (\tref{moveassignable}) requirements. +The ranges \range{first}{middle} and \range{middle}{last} shall be +sorted with respect to \tcode{operator<} or \tcode{comp}. +\tcode{BidirectionalIterator} shall satisfy the +\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. The type +of \tcode{*first} shall satisfy the +\oldconcept{MoveConstructible} (\tref{moveconstructible}) and +\oldconcept{MoveAssignable} (\tref{moveassignable}) requirements. \pnum \effects -Places the first -\tcode{min(last - first, result_last - result_first)} -sorted elements into the range -\range{result_first}{result_first + min(last - first, result_last - result_first)}. +Merges two sorted consecutive ranges +\range{first}{middle} +and +\range{middle}{last}, +putting the result of the merge into the range +\range{first}{last}. +The resulting range will be in non-decreasing order; +that is, for every iterator +\tcode{i} +in +\range{first}{last} +other than +\tcode{first}, +the condition +\tcode{*i < *(i - 1)} +or, respectively, +\tcode{comp(*i, *(i - 1))} +will be \tcode{false}. \pnum -\returns -The smaller of: -\tcode{result_last} or -\tcode{result_first + (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 -\complexity -Approximately -\tcode{(last - first) * log(min(last - first, result_last - result_first))} -comparisons. +\remarks Stable\iref{algorithm.stable}. \end{itemdescr} -\rSec3[is.sorted]{\tcode{is_sorted}} - -\indexlibrary{\idxcode{is_sorted}}% -\begin{itemdecl} -template - constexpr bool is_sorted(ForwardIterator first, ForwardIterator last); -\end{itemdecl} +\rSec2[alg.set.operations]{Set operations on sorted structures} -\begin{itemdescr} \pnum -\returns \tcode{is_sorted_until(first, last) == last}. -\end{itemdescr} +This subclause defines all the basic set operations on sorted structures. +They also work with +\tcode{multiset}s\iref{multiset} +containing multiple copies of equivalent elements. +The semantics of the set operations are generalized to +\tcode{multiset}s +in a standard way by defining +\tcode{set_union()} +to contain the maximum number of occurrences of every element, +\tcode{set_intersection()} +to contain the minimum, and so on. -\indexlibrary{\idxcode{is_sorted}}% +\rSec3[includes]{\tcode{includes}} + +\indexlibrary{\idxcode{includes}}% \begin{itemdecl} -template - bool is_sorted(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last); +template + constexpr bool includes(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2); +template + bool includes(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); + +template + constexpr bool includes(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + Compare comp); +template + bool includes(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + Compare comp); \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{is_sorted_until(std::forward(exec), first, last) == last}. +\returns +\tcode{true} +if \range{first2}{last2} is empty or +if every element in the range +\range{first2}{last2} +is contained in the range +\range{first1}{last1}. +Returns +\tcode{false} +otherwise. + +\pnum +\complexity +At most +\tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} +comparisons. \end{itemdescr} +\rSec3[set.union]{\tcode{set_union}} -\indexlibrary{\idxcode{is_sorted}}% +\indexlibrary{\idxcode{set_union}}% \begin{itemdecl} -template - constexpr bool is_sorted(ForwardIterator first, ForwardIterator last, - Compare comp); +template + constexpr OutputIterator + set_union(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); +template + ForwardIterator + set_union(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); + +template + constexpr OutputIterator + set_union(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); +template + ForwardIterator + set_union(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{is_sorted_until(first, last, comp) == last}. -\end{itemdescr} - +\requires +The resulting range shall not overlap with either of the original ranges. -\indexlibrary{\idxcode{is_sorted}}% -\begin{itemdecl} -template - bool is_sorted(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, - Compare comp); -\end{itemdecl} +\pnum +\effects +Constructs a sorted union of the elements from the two ranges; +that is, the set of elements that are present in one or both of the ranges. -\begin{itemdescr} \pnum \returns -\begin{codeblock} -is_sorted_until(std::forward(exec), first, last, comp) == last -\end{codeblock} +The end of the constructed range. + +\pnum +\complexity +At most +\tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} +comparisons. + +\pnum +\remarks If \range{first1}{last1} contains $m$ elements that are equivalent to +each other and \range{first2}{last2} contains $n$ elements that are equivalent +to them, then all $m$ elements from the first range shall be copied to the output +range, in order, and then $\max(n - m, 0)$ elements from the second range shall +be copied to the output range, in order. \end{itemdescr} +\rSec3[set.intersection]{\tcode{set_intersection}} -\indexlibrary{\idxcode{is_sorted_until}}% +\indexlibrary{\idxcode{set_intersection}}% \begin{itemdecl} -template - constexpr ForwardIterator - is_sorted_until(ForwardIterator first, ForwardIterator last); -template +template + constexpr OutputIterator + set_intersection(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); +template ForwardIterator - is_sorted_until(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last); + set_intersection(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); -template - constexpr ForwardIterator - is_sorted_until(ForwardIterator first, ForwardIterator last, - Compare comp); -template +template + constexpr OutputIterator + set_intersection(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); +template ForwardIterator - is_sorted_until(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, - Compare comp); + set_intersection(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); \end{itemdecl} - \begin{itemdescr} \pnum -\returns If \tcode{(last - first) < 2}, returns -\tcode{last}. Otherwise, returns -the last iterator \tcode{i} in \crange{first}{last} for which the -range \range{first}{i} is sorted. +\requires +The resulting range shall not overlap with either of the original ranges. \pnum -\complexity Linear. +\effects +Constructs a sorted intersection of the elements from the two ranges; +that is, the set of elements that are present in both of the ranges. + +\pnum +\returns +The end of the constructed range. + +\pnum +\complexity +At most +\tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} +comparisons. + +\pnum +\remarks If \range{first1}{last1} contains $m$ elements that are equivalent to +each other and \range{first2}{last2} contains $n$ elements that are equivalent +to them, the first $\min(m, n)$ elements shall be copied from the first range +to the output range, in order. \end{itemdescr} -\rSec2[alg.nth.element]{Nth element} +\rSec3[set.difference]{\tcode{set_difference}} -\indexlibrary{\idxcode{nth_element}}% -\begin{itemdecl} -template - void nth_element(RandomAccessIterator first, RandomAccessIterator nth, - RandomAccessIterator last); -template - void nth_element(ExecutionPolicy&& exec, - RandomAccessIterator first, RandomAccessIterator nth, - RandomAccessIterator last); +\indexlibrary{\idxcode{set_difference}}% +\begin{itemdecl} +template + constexpr OutputIterator + set_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); +template + ForwardIterator + set_difference(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); -template - void nth_element(RandomAccessIterator first, RandomAccessIterator nth, - RandomAccessIterator last, Compare comp); -template - void nth_element(ExecutionPolicy&& exec, - RandomAccessIterator first, RandomAccessIterator nth, - RandomAccessIterator last, Compare comp); +template + constexpr OutputIterator + set_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); +template + ForwardIterator + set_difference(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{RandomAccessIterator} shall satisfy the -\tcode{ValueSwappable} requirements\iref{swappable.requirements}. The type -of \tcode{*first} shall satisfy the -\tcode{MoveConstructible} (\tref{moveconstructible}) and -\tcode{MoveAssignable} (\tref{moveassignable}) requirements. +The resulting range shall not overlap with either of the original ranges. \pnum \effects -After -\tcode{nth_element} -the element in the position pointed to by \tcode{nth} -is the element that would be -in that position if the whole range were sorted, unless \tcode{nth == last}. -Also for every iterator -\tcode{i} -in the range -\range{first}{nth} -and every iterator -\tcode{j} -in the range -\range{nth}{last} -it holds that: -\tcode{!(*j < *i)} -or -\tcode{comp(*j, *i) == false}. +Copies the elements of the range +\range{first1}{last1} +which are not present in the range +\range{first2}{last2} +to the range beginning at +\tcode{result}. +The elements in the constructed range are sorted. \pnum -\complexity -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} +\returns +The end of the constructed range. -\rSec2[alg.binary.search]{Binary search} +\pnum +\complexity +At most +\tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} +comparisons. \pnum -All of the algorithms in this subclause are versions of binary search -and assume that the sequence being searched is partitioned with respect to -an expression formed by binding the search key to an argument of the -implied or explicit comparison function. -They work on non-random access iterators minimizing the number of comparisons, -which will be logarithmic for all types of iterators. -They are especially appropriate for random access iterators, -because these algorithms do a logarithmic number of steps -through the data structure. -For non-random access iterators they execute a linear number of steps. +\remarks +If +\range{first1}{last1} +contains $m$ +elements that are equivalent to each other and +\range{first2}{last2} +contains $n$ +elements that are equivalent to them, the last +$\max(m - n, 0)$ +elements from +\range{first1}{last1} +shall be copied to the output range. +\end{itemdescr} -\rSec3[lower.bound]{\tcode{lower_bound}} +\rSec3[set.symmetric.difference]{\tcode{set_symmetric_difference}} -\indexlibrary{\idxcode{lower_bound}}% +\indexlibrary{\idxcode{set_symmetric_difference}}% \begin{itemdecl} -template - constexpr ForwardIterator - lower_bound(ForwardIterator first, ForwardIterator last, - const T& value); +template + constexpr OutputIterator + set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result); +template + ForwardIterator + set_symmetric_difference(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); -template - constexpr ForwardIterator - lower_bound(ForwardIterator first, ForwardIterator last, - const T& value, Compare comp); +template + constexpr OutputIterator + set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + OutputIterator result, Compare comp); +template + ForwardIterator + set_symmetric_difference(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); \end{itemdecl} \begin{itemdescr} \pnum \requires -The elements -\tcode{e} -of -\range{first}{last} -shall be partitioned with respect to the expression -\tcode{e < value} -or -\tcode{comp(e, value)}. +The resulting range shall not overlap with either of the original ranges. + +\pnum +\effects +Copies the elements of the range +\range{first1}{last1} +that are not present in the range +\range{first2}{last2}, +and the elements of the range +\range{first2}{last2} +that are not present in the range +\range{first1}{last1} +to the range beginning at +\tcode{result}. +The elements in the constructed range are sorted. \pnum \returns -The furthermost iterator -\tcode{i} -in the range -\crange{first}{last} -such that for every iterator -\tcode{j} -in the range -\range{first}{i} -the following corresponding conditions hold: -\tcode{*j < value} -or -\tcode{comp(*j, value) != false}. +The end of the constructed range. \pnum \complexity At most -$\log_2(\tcode{last - first}) + \bigoh{1}$ +\tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} comparisons. + +\pnum +\remarks +If \range{first1}{last1} contains $m$ elements that are equivalent to each other and +\range{first2}{last2} contains $n$ elements that are equivalent to them, then +$|m - n|$ of those elements shall be copied to the output range: the last +$m - n$ of these elements from \range{first1}{last1} if $m > n$, and the last +$n - m$ of these elements from \range{first2}{last2} if $m < n$. \end{itemdescr} -\rSec3[upper.bound]{\tcode{upper_bound}} +\rSec2[alg.heap.operations]{Heap operations} -\indexlibrary{\idxcode{upper_bound}}% +\pnum +A +\term{heap} +is a particular organization of elements in a range between two random access iterators +\range{a}{b} such that: + +\begin{itemize} +\item With \tcode{$N$ = b - a}, for all $i$, $0 < i < N$, +\tcode{comp(a[$\left \lfloor{\frac{i - 1}{2}}\right \rfloor$], a[$i$])} +is \tcode{false}. +\item \tcode{*a} +may be removed by +\tcode{pop_heap()}, +or a new element added by +\tcode{push_heap()}, +in +\bigoh{\log N} +time. +\end{itemize} + +\pnum +These properties make heaps useful as priority queues. + +\pnum +\tcode{make_heap()} +converts a range into a heap and +\tcode{sort_heap()} +turns a heap into a sorted sequence. + +\rSec3[push.heap]{\tcode{push_heap}} + +\indexlibrary{\idxcode{push_heap}}% \begin{itemdecl} -template - constexpr ForwardIterator - upper_bound(ForwardIterator first, ForwardIterator last, - const T& value); +template + constexpr void push_heap(RandomAccessIterator first, RandomAccessIterator last); -template - constexpr ForwardIterator - upper_bound(ForwardIterator first, ForwardIterator last, - const T& value, Compare comp); +template + constexpr void push_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); \end{itemdecl} \begin{itemdescr} \pnum \requires -The elements -\tcode{e} -of -\range{first}{last} -shall be partitioned with respect to the expression -\tcode{!(value < e)} -or -\tcode{!comp(\brk{}value, e)}. +The range +\range{first}{last - 1} +shall be a valid heap. +The type of \tcode{*first} shall satisfy +the \oldconcept{MoveConstructible} requirements +(\tref{moveconstructible}) and the +\oldconcept{MoveAssignable} requirements +(\tref{moveassignable}). \pnum -\returns -The furthermost iterator -\tcode{i} -in the range -\crange{first}{last} -such that for every iterator -\tcode{j} -in the range -\range{first}{i} -the following corresponding conditions hold: -\tcode{!(value < *j)} -or -\tcode{comp(value, *j) == false}. +\effects +Places the value in the location +\tcode{last - 1} +into the resulting heap +\range{first}{last}. \pnum \complexity At most -$\log_2(\tcode{last - first}) + \bigoh{1}$ +$\log(\tcode{last - first})$ comparisons. \end{itemdescr} -\rSec3[equal.range]{\tcode{equal_range}} +\rSec3[pop.heap]{\tcode{pop_heap}} -\indexlibrary{\idxcode{equal_range}}% +\indexlibrary{\idxcode{pop_heap}}% \begin{itemdecl} -template - constexpr pair - equal_range(ForwardIterator first, - ForwardIterator last, const T& value); +template + constexpr void pop_heap(RandomAccessIterator first, RandomAccessIterator last); -template - constexpr pair - equal_range(ForwardIterator first, - ForwardIterator last, const T& value, - Compare comp); +template + constexpr void pop_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); \end{itemdecl} \begin{itemdescr} \pnum \requires -The elements -\tcode{e} -of +The range \range{first}{last} -shall be partitioned with respect to the expressions -\tcode{e < value} -and -\tcode{!(value < e)} -or -\tcode{comp(e, value)} -and -\tcode{!comp(value, e)}. -Also, for all elements -\tcode{e} -of -\tcode{[first, last)}, -\tcode{e < value} -shall imply -\tcode{!(value < e)} -or -\tcode{comp(e, value)} -shall imply -\tcode{!comp(value, e)}. +shall be a valid non-empty heap. +\tcode{RandomAccessIterator} shall satisfy the +\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. The type +of \tcode{*first} shall satisfy the +\oldconcept{MoveConstructible} (\tref{moveconstructible}) and +\oldconcept{MoveAssignable} (\tref{moveassignable}) requirements. + \pnum -\returns -\begin{codeblock} -make_pair(lower_bound(first, last, value), - upper_bound(first, last, value)) -\end{codeblock} -or -\begin{codeblock} -make_pair(lower_bound(first, last, value, comp), - upper_bound(first, last, value, comp)) -\end{codeblock} +\effects +Swaps the value in the location \tcode{first} +with the value in the location +\tcode{last - 1} +and makes +\range{first}{last - 1} +into a heap. \pnum \complexity At most -$2 * \log_2(\tcode{last - first}) + \bigoh{1}$ +$2 \log(\tcode{last - first})$ comparisons. \end{itemdescr} -\rSec3[binary.search]{\tcode{binary_search}} +\rSec3[make.heap]{\tcode{make_heap}} -\indexlibrary{\idxcode{binary_search}}% +\indexlibrary{\idxcode{make_heap}}% \begin{itemdecl} -template - constexpr bool - binary_search(ForwardIterator first, ForwardIterator last, - const T& value); +template + constexpr void make_heap(RandomAccessIterator first, RandomAccessIterator last); -template - constexpr bool - binary_search(ForwardIterator first, ForwardIterator last, - const T& value, Compare comp); +template + constexpr void make_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); \end{itemdecl} \begin{itemdescr} \pnum -\requires -The elements -\tcode{e} -of -\range{first}{last} -shall be partitioned with respect to the expressions -\tcode{e < value} -and -\tcode{!(value < e)} -or -\tcode{comp(e, value)} -and -\tcode{!comp(value, e)}. -Also, for all elements -\tcode{e} -of -\tcode{[first, last)}, -\tcode{e < value} -shall imply -\tcode{!(value < e)} -or -\tcode{comp(e, value)} -shall imply -\tcode{!comp(value, e)}. +\requires The type of \tcode{*first} shall satisfy +the \oldconcept{MoveConstructible} requirements +(\tref{moveconstructible}) and the +\oldconcept{MoveAssignable} requirements +(\tref{moveassignable}). \pnum -\returns -\tcode{true} -if there is an iterator -\tcode{i} -in the range -\range{first}{last} -that satisfies the corresponding conditions: -\tcode{!(*i < value) \&\& !(value < *i)} -or -\tcode{comp(*i, value) == false \&\& comp(value, *i) == false}. +\effects +Constructs a heap out of the range +\range{first}{last}. \pnum \complexity At most -$\log_2(\tcode{last - first}) + \bigoh{1}$ +$3(\tcode{last - first})$ comparisons. \end{itemdescr} -\rSec2[alg.partitions]{Partitions} +\rSec3[sort.heap]{\tcode{sort_heap}} -\indexlibrary{\idxcode{is_partitioned}}% +\indexlibrary{\idxcode{sort_heap}}% \begin{itemdecl} -template - constexpr bool is_partitioned(InputIterator first, InputIterator last, Predicate pred); -template - bool is_partitioned(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, Predicate pred); +template + constexpr void sort_heap(RandomAccessIterator first, RandomAccessIterator last); + +template + constexpr void sort_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); \end{itemdecl} \begin{itemdescr} \pnum -\requires For the overload with no \tcode{ExecutionPolicy}, -\tcode{InputIterator}'s value type shall be convertible to \tcode{Predicate}'s -argument type. For the overload with an \tcode{ExecutionPolicy}, -\tcode{ForwardIterator}'s value type shall be convertible to \tcode{Predicate}'s -argument type. +\requires The range \range{first}{last} shall be a valid heap. +\tcode{RandomAccessIterator} shall satisfy the +\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. The type +of \tcode{*first} shall satisfy the +\oldconcept{MoveConst\-ruct\-ible} (\tref{moveconstructible}) and +\oldconcept{MoveAssignable} (\tref{moveassignable}) requirements. \pnum -\returns \tcode{true} if -\range{first}{last} is empty or if -the elements \tcode{e} of -\range{first}{last} are partitioned with respect to the expression -\tcode{pred(e)}. +\effects +Sorts elements in the heap +\range{first}{last}. \pnum -\complexity Linear. At most \tcode{last - first} applications of \tcode{pred}. +\complexity +At most $2N \log N$ +comparisons, where +$N = \tcode{last - first}$. \end{itemdescr} -\indexlibrary{\idxcode{partition}}% +\rSec3[is.heap]{\tcode{is_heap}} + +\indexlibrary{\idxcode{is_heap}}% \begin{itemdecl} -template - ForwardIterator - partition(ForwardIterator first, ForwardIterator last, Predicate pred); -template - ForwardIterator - partition(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, Predicate pred); +template + constexpr bool is_heap(RandomAccessIterator first, RandomAccessIterator last); \end{itemdecl} \begin{itemdescr} \pnum -\requires -\tcode{ForwardIterator} shall satisfy the -\tcode{ValueSwappable} requirements\iref{swappable.requirements}. +\returns \tcode{is_heap_until(first, last) == last}. +\end{itemdescr} + + +\indexlibrary{\idxcode{is_heap}}% +\begin{itemdecl} +template + bool is_heap(ExecutionPolicy&& exec, + RandomAccessIterator first, RandomAccessIterator last); +\end{itemdecl} +\begin{itemdescr} \pnum -\effects Places all the elements in the range \range{first}{last} that satisfy \tcode{pred} before all the elements that do not satisfy it. +\returns \tcode{is_heap_until(std::forward(exec), first, last) == last}. +\end{itemdescr} + + +\indexlibrary{\idxcode{is_heap}}% +\begin{itemdecl} +template + constexpr bool is_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); +\end{itemdecl} +\begin{itemdescr} \pnum -\returns An iterator \tcode{i} such that for every iterator \tcode{j} in the range -\range{first}{i} \tcode{pred(*j) != false}, and for every iterator \tcode{k} in the -range \range{i}{last}, \tcode{pred(*k) == false}. +\returns \tcode{is_heap_until(first, last, comp) == last}. +\end{itemdescr} + + +\indexlibrary{\idxcode{is_heap}}% +\begin{itemdecl} +template + bool is_heap(ExecutionPolicy&& exec, + RandomAccessIterator first, RandomAccessIterator last, + Compare comp); +\end{itemdecl} +\begin{itemdescr} \pnum -\complexity Let $N = \tcode{last - first}$: -\begin{itemize} -\item For the overload with no \tcode{ExecutionPolicy}, exactly $N$ applications -of the predicate. At most $N / 2$ swaps if \tcode{ForwardIterator} meets the -\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} +\returns +\begin{codeblock} +is_heap_until(std::forward(exec), first, last, comp) == last +\end{codeblock} +\end{itemdescr} + + +\indexlibrary{\idxcode{is_heap_until}}% +\begin{itemdecl} +template + constexpr RandomAccessIterator + is_heap_until(RandomAccessIterator first, RandomAccessIterator last); +template + RandomAccessIterator + is_heap_until(ExecutionPolicy&& exec, + RandomAccessIterator first, RandomAccessIterator last); + +template + constexpr RandomAccessIterator + is_heap_until(RandomAccessIterator first, RandomAccessIterator last, + Compare comp); +template + RandomAccessIterator + is_heap_until(ExecutionPolicy&& exec, + RandomAccessIterator first, RandomAccessIterator last, + Compare comp); +\end{itemdecl} + + +\begin{itemdescr} +\pnum +\returns If \tcode{(last - first) < 2}, returns +\tcode{last}. Otherwise, returns +the last iterator \tcode{i} in \crange{first}{last} for which the +range \range{first}{i} is a heap. +\pnum +\complexity Linear. \end{itemdescr} -\indexlibrary{\idxcode{stable_partition}}% + +\rSec2[alg.min.max]{Minimum and maximum} + +\indexlibrary{\idxcode{min}}% \begin{itemdecl} -template - BidirectionalIterator - stable_partition(BidirectionalIterator first, BidirectionalIterator last, Predicate pred); -template - BidirectionalIterator - stable_partition(ExecutionPolicy&& exec, - BidirectionalIterator first, BidirectionalIterator last, Predicate pred); +template constexpr const T& min(const T& a, const T& b); +template + constexpr const T& min(const T& a, const T& b, Compare comp); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{BidirectionalIterator} shall satisfy the -\tcode{ValueSwappable} requirements\iref{swappable.requirements}. The type -of \tcode{*first} shall satisfy the -\tcode{MoveConstructible} (\tref{moveconstructible}) and -\tcode{MoveAssignable} (\tref{moveassignable}) requirements. +For the first form, type \tcode{T} shall be +\oldconcept{LessThanComparable} (\tref{lessthancomparable}). \pnum -\effects -Places all the elements in the range -\range{first}{last} -that satisfy \tcode{pred} before all the -elements that do not satisfy it. +\returns +The smaller value. \pnum -\returns -An iterator -\tcode{i} -such that for every iterator -\tcode{j} -in the range -\range{first}{i}, -\tcode{pred(*j) != false}, -and for every iterator -\tcode{k} -in the range -\range{i}{last}, -\tcode{pred(*k) == false}. -The relative order of the elements in both groups is preserved. +\remarks +Returns the first argument when the arguments are equivalent. \pnum \complexity -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} - +Exactly one comparison. \end{itemdescr} -\indexlibrary{\idxcode{partition_copy}}% +\indexlibrary{\idxcode{min}}% \begin{itemdecl} -template - constexpr pair - partition_copy(InputIterator first, InputIterator last, - OutputIterator1 out_true, OutputIterator2 out_false, Predicate pred); -template - pair - partition_copy(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, - ForwardIterator1 out_true, ForwardIterator2 out_false, Predicate pred); +template + constexpr T min(initializer_list t); +template + constexpr T min(initializer_list t, Compare comp); \end{itemdecl} \begin{itemdescr} \pnum -\requires -\begin{itemize} -\item -For the overload with no \tcode{ExecutionPolicy}, \tcode{InputIterator}'s -value type shall be \tcode{CopyAssignable} (\tref{copyassignable}), -and shall be writable\iref{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} +\requires \tcode{T} shall be \oldconcept{CopyConstructible} and \tcode{t.size() > 0}. +For the first form, type \tcode{T} shall be \oldconcept{LessThanComparable}. \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. +\returns The smallest value in the initializer list. \pnum -\returns A pair \tcode{p} such that \tcode{p.first} is the end of the output range beginning at \tcode{out_true} and \tcode{p.second} is the end of the output range beginning at \tcode{out_false}. +\remarks Returns a copy of the leftmost argument when several arguments are equivalent to the smallest. \pnum -\complexity Exactly \tcode{last - first} applications of \tcode{pred}. +\complexity +Exactly \tcode{t.size() - 1} comparisons. \end{itemdescr} -\indexlibrary{\idxcode{partition_point}}% +\indexlibrary{\idxcode{max}}% \begin{itemdecl} -template - constexpr ForwardIterator - partition_point(ForwardIterator first, ForwardIterator last, Predicate pred); +template constexpr const T& max(const T& a, const T& b); +template + constexpr const T& max(const T& a, const T& b, Compare comp); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{ForwardIterator}'s value type shall be convertible to -\tcode{Predicate}'s argument type. The elements \tcode{e} of \range{first}{last} -shall be partitioned with respect to the expression \tcode{pred(e)}. +For the first form, type \tcode{T} shall be +\oldconcept{LessThanComparable} (\tref{lessthancomparable}). \pnum -\returns An iterator \tcode{mid} such that \tcode{all_of(first, mid, pred)} and \tcode{none_of(mid, last, pred)} are both \tcode{true}. +\returns +The larger value. \pnum -\complexity \bigoh{\log(\tcode{last - first})} applications of \tcode{pred}. -\end{itemdescr} +\remarks +Returns the first argument when the arguments are equivalent. -\rSec2[alg.merge]{Merge} +\pnum +\complexity +Exactly one comparison. +\end{itemdescr} -\indexlibrary{\idxcode{merge}}% +\indexlibrary{\idxcode{max}}% \begin{itemdecl} -template - constexpr OutputIterator - merge(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); -template - ForwardIterator - merge(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result); - -template - constexpr OutputIterator - merge(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); -template - ForwardIterator - merge(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result, Compare comp); +template + constexpr T max(initializer_list t); +template + constexpr T max(initializer_list t, Compare comp); \end{itemdecl} \begin{itemdescr} \pnum -\requires The ranges \range{first1}{last1} and \range{first2}{last2} shall be -sorted with respect to \tcode{oper\-ator<} or \tcode{comp}. -The resulting range shall not overlap with either of the original ranges. - -\pnum -\effects Copies all the elements of the two ranges \range{first1}{last1} and -\range{first2}{last2} into the range \range{result}{result_last}, where \tcode{result_last} -is \tcode{result + (last1 - first1) + (last2 - first2)}, such that the resulting range satisfies -\tcode{is_sorted(result, result_last)} or \tcode{is_sorted(re\-sult, result_last, comp)}, respectively. +\requires \tcode{T} shall be \oldconcept{CopyConstructible} and \tcode{t.size() > 0}. +For the first form, type \tcode{T} shall be \oldconcept{LessThanComparable}. \pnum -\returns -\tcode{result + (last1 - first1) + (last2 - first2)}. +\returns The largest value in the initializer list. \pnum -\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} +\remarks Returns a copy of the leftmost argument when several arguments are equivalent to the largest. \pnum -\remarks Stable\iref{algorithm.stable}. +\complexity +Exactly \tcode{t.size() - 1} comparisons. \end{itemdescr} -\indexlibrary{\idxcode{inplace_merge}}% +\indexlibrary{\idxcode{minmax}}% \begin{itemdecl} -template - void inplace_merge(BidirectionalIterator first, - BidirectionalIterator middle, - BidirectionalIterator last); -template - void inplace_merge(ExecutionPolicy&& exec, - BidirectionalIterator first, - BidirectionalIterator middle, - BidirectionalIterator last); - -template - void inplace_merge(BidirectionalIterator first, - BidirectionalIterator middle, - BidirectionalIterator last, Compare comp); -template - void inplace_merge(ExecutionPolicy&& exec, - BidirectionalIterator first, - BidirectionalIterator middle, - BidirectionalIterator last, Compare comp); +template constexpr pair minmax(const T& a, const T& b); +template + constexpr pair minmax(const T& a, const T& b, Compare comp); \end{itemdecl} + \begin{itemdescr} \pnum \requires -The ranges \range{first}{middle} and \range{middle}{last} shall be -sorted with respect to \tcode{operator<} or \tcode{comp}. -\tcode{BidirectionalIterator} shall satisfy the -\tcode{ValueSwappable} requirements\iref{swappable.requirements}. The type -of \tcode{*first} shall satisfy the -\tcode{MoveConstructible} (\tref{moveconstructible}) and -\tcode{MoveAssignable} (\tref{moveassignable}) requirements. +For the first form, type \tcode{T} shall be +\oldconcept{LessThanComparable} (\tref{lessthancomparable}). \pnum -\effects -Merges two sorted consecutive ranges -\range{first}{middle} -and -\range{middle}{last}, -putting the result of the merge into the range -\range{first}{last}. -The resulting range will be in non-decreasing order; -that is, for every iterator -\tcode{i} -in -\range{first}{last} -other than -\tcode{first}, -the condition -\tcode{*i < *(i - 1)} -or, respectively, -\tcode{comp(*i, *(i - 1))} -will be \tcode{false}. +\returns +\tcode{pair(b, a)} if \tcode{b} is smaller +than \tcode{a}, and +\tcode{pair(a, b)} otherwise. \pnum -\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} - +\remarks +Returns \tcode{pair(a, b)} when the arguments are equivalent. \pnum -\remarks Stable\iref{algorithm.stable}. +\complexity +Exactly one comparison. \end{itemdescr} -\rSec2[alg.set.operations]{Set operations on sorted structures} +\indexlibrary{\idxcode{minmax}}% +\begin{itemdecl} +template + constexpr pair minmax(initializer_list t); +template + constexpr pair minmax(initializer_list t, Compare comp); +\end{itemdecl} +\begin{itemdescr} \pnum -This subclause defines all the basic set operations on sorted structures. -They also work with -\tcode{multiset}s\iref{multiset} -containing multiple copies of equivalent elements. -The semantics of the set operations are generalized to -\tcode{multiset}s -in a standard way by defining -\tcode{set_union()} -to contain the maximum number of occurrences of every element, -\tcode{set_intersection()} -to contain the minimum, and so on. +\requires \tcode{T} shall be \oldconcept{CopyConstructible} and \tcode{t.size() > 0}. +For the first form, type \tcode{T} shall be \oldconcept{LessThanComparable}. + +\pnum +\returns \tcode{pair(x, y)}, where \tcode{x} has the smallest and \tcode{y} has the +largest value in the initializer list. -\rSec3[includes]{\tcode{includes}} +\pnum +\remarks \tcode{x} is a copy of the leftmost argument when several arguments are equivalent to +the smallest. \tcode{y} is a copy of the rightmost argument when several arguments are +equivalent to the largest. -\indexlibrary{\idxcode{includes}}% +\pnum +\complexity At most $(3/2)\tcode{t.size()}$ applications of the corresponding predicate. +\end{itemdescr} + +\indexlibrary{\idxcode{min_element}}% \begin{itemdecl} -template - constexpr bool includes(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); -template - bool includes(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); +template + constexpr ForwardIterator min_element(ForwardIterator first, ForwardIterator last); -template - constexpr bool includes(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - Compare comp); -template - bool includes(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - Compare comp); +template + ForwardIterator min_element(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last); + +template + constexpr ForwardIterator min_element(ForwardIterator first, ForwardIterator last, + Compare comp); +template + ForwardIterator min_element(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + Compare comp); \end{itemdecl} \begin{itemdescr} \pnum \returns -\tcode{true} -if \range{first2}{last2} is empty or -if every element in the range -\range{first2}{last2} -is contained in the range -\range{first1}{last1}. +The first iterator +\tcode{i} +in the range +\range{first}{last} +such that for every iterator +\tcode{j} +in the range +\range{first}{last} +the following corresponding conditions hold: +\tcode{!(*j < *i)} +or +\tcode{comp(*j, *i) == false}. Returns -\tcode{false} -otherwise. +\tcode{last} +if +\tcode{first == last}. \pnum \complexity -At most -\tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} -comparisons. +Exactly +$\max(\tcode{last - first - 1}, 0)$ +applications of the corresponding comparisons. \end{itemdescr} -\rSec3[set.union]{\tcode{set_union}} - -\indexlibrary{\idxcode{set_union}}% +\indexlibrary{\idxcode{max_element}}% \begin{itemdecl} -template - constexpr OutputIterator - set_union(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); -template - ForwardIterator - set_union(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result); +template + constexpr ForwardIterator max_element(ForwardIterator first, ForwardIterator last); +template + ForwardIterator max_element(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last); -template - constexpr OutputIterator - set_union(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); -template - ForwardIterator - set_union(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result, Compare comp); +template + constexpr ForwardIterator max_element(ForwardIterator first, ForwardIterator last, + Compare comp); +template + ForwardIterator max_element(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, + Compare comp); \end{itemdecl} \begin{itemdescr} -\pnum -\requires -The resulting range shall not overlap with either of the original ranges. - -\pnum -\effects -Constructs a sorted union of the elements from the two ranges; -that is, the set of elements that are present in one or both of the ranges. - \pnum \returns -The end of the constructed range. +The first iterator +\tcode{i} +in the range +\range{first}{last} +such that for every iterator +\tcode{j} +in the range +\range{first}{last} +the following corresponding conditions hold: +\tcode{!(*i < *j)} +or +\tcode{comp(*i, *j) == false}. +Returns +\tcode{last} +if +\tcode{first == last}. \pnum \complexity -At most -\tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} -comparisons. - -\pnum -\remarks If \range{first1}{last1} contains $m$ elements that are equivalent to -each other and \range{first2}{last2} contains $n$ elements that are equivalent -to them, then all $m$ elements from the first range shall be copied to the output -range, in order, and then $\max(n - m, 0)$ elements from the second range shall -be copied to the output range, in order. +Exactly +$\max(\tcode{last - first - 1}, 0)$ +applications of the corresponding comparisons. \end{itemdescr} -\rSec3[set.intersection]{\tcode{set_intersection}} - -\indexlibrary{\idxcode{set_intersection}}% +\indexlibrary{\idxcode{minmax_element}}% \begin{itemdecl} -template - constexpr OutputIterator - set_intersection(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); -template - ForwardIterator - set_intersection(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result); +template + constexpr pair + minmax_element(ForwardIterator first, ForwardIterator last); +template + pair + minmax_element(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last); -template - constexpr OutputIterator - set_intersection(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); -template - ForwardIterator - set_intersection(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result, Compare comp); +template + constexpr pair + minmax_element(ForwardIterator first, ForwardIterator last, Compare comp); +template + pair + minmax_element(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, Compare comp); \end{itemdecl} -\begin{itemdescr} -\pnum -\requires -The resulting range shall not overlap with either of the original ranges. - -\pnum -\effects -Constructs a sorted intersection of the elements from the two ranges; -that is, the set of elements that are present in both of the ranges. +\begin{itemdescr} \pnum \returns -The end of the constructed range. +\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()}.} +in \range{first}{last} such that no iterator in the range refers to a larger element. \pnum \complexity At most -\tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} -comparisons. - -\pnum -\remarks If \range{first1}{last1} contains $m$ elements that are equivalent to -each other and \range{first2}{last2} contains $n$ elements that are equivalent -to them, the first $\min(m, n)$ elements shall be copied from the first range -to the output range, in order. +$\max(\bigl\lfloor{\frac{3}{2}} (N-1)\bigr\rfloor, 0)$ +applications of the corresponding predicate, where $N$ is \tcode{last - first}. \end{itemdescr} -\rSec3[set.difference]{\tcode{set_difference}} - -\indexlibrary{\idxcode{set_difference}}% -\begin{itemdecl} -template - constexpr OutputIterator - set_difference(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); -template - ForwardIterator - set_difference(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result); - -template - constexpr OutputIterator - set_difference(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); -template - ForwardIterator - set_difference(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result, Compare comp); +\rSec2[alg.clamp]{Bounded value} + +\indexlibrary{\idxcode{clamp}}% +\begin{itemdecl} +template + constexpr const T& clamp(const T& v, const T& lo, const T& hi); +template + constexpr const T& clamp(const T& v, const T& lo, const T& hi, Compare comp); \end{itemdecl} \begin{itemdescr} \pnum \requires -The resulting range shall not overlap with either of the original ranges. - -\pnum -\effects -Copies the elements of the range -\range{first1}{last1} -which are not present in the range -\range{first2}{last2} -to the range beginning at -\tcode{result}. -The elements in the constructed range are sorted. +The value of \tcode{lo} shall be no greater than \tcode{hi}. +For the first form, type \tcode{T} +shall be \oldconcept{LessThan\-Comparable} (\tref{lessthancomparable}). \pnum \returns -The end of the constructed range. +\tcode{lo} if \tcode{v} is less than \tcode{lo}, +\tcode{hi} if \tcode{hi} is less than \tcode{v}, +otherwise \tcode{v}. \pnum -\complexity -At most -\tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} -comparisons. +\begin{note} +If NaN is avoided, \tcode{T} can be a floating-point type. +\end{note} \pnum -\remarks -If -\range{first1}{last1} -contains $m$ -elements that are equivalent to each other and -\range{first2}{last2} -contains $n$ -elements that are equivalent to them, the last -$\max(m - n, 0)$ -elements from -\range{first1}{last1} -shall be copied to the output range. +\complexity +At most two comparisons. \end{itemdescr} -\rSec3[set.symmetric.difference]{\tcode{set_symmetric_difference}} +\rSec2[alg.lex.comparison]{Lexicographical comparison} -\indexlibrary{\idxcode{set_symmetric_difference}}% +\indexlibrary{\idxcode{lexicographical_compare}}% \begin{itemdecl} -template - constexpr OutputIterator - set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result); -template - ForwardIterator - set_symmetric_difference(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result); +template + constexpr bool + lexicographical_compare(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2); +template + bool + lexicographical_compare(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2); -template - constexpr OutputIterator - set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp); +template + constexpr bool + lexicographical_compare(InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + Compare comp); template - ForwardIterator - set_symmetric_difference(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - ForwardIterator result, Compare comp); + class Compare> + bool + lexicographical_compare(ExecutionPolicy&& exec, + ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2, + Compare comp); \end{itemdecl} \begin{itemdescr} -\pnum -\requires -The resulting range shall not overlap with either of the original ranges. - -\pnum -\effects -Copies the elements of the range -\range{first1}{last1} -that are not present in the range -\range{first2}{last2}, -and the elements of the range -\range{first2}{last2} -that are not present in the range -\range{first1}{last1} -to the range beginning at -\tcode{result}. -The elements in the constructed range are sorted. - \pnum \returns -The end of the constructed range. +\tcode{true} +if the sequence of elements defined by the range +\range{first1}{last1} +is lexicographically less than the sequence of elements defined by the range +\range{first2}{last2} and +\tcode{false} +otherwise. \pnum \complexity At most -\tcode{2 * ((last1 - first1) + (last2 - first2)) - 1} -comparisons. +$2 \min(\tcode{last1 - first1}, \ \tcode{last2 - first2})$ +applications of the corresponding comparison. \pnum \remarks -If \range{first1}{last1} contains $m$ elements that are equivalent to each other and -\range{first2}{last2} contains $n$ elements that are equivalent to them, then -$|m - n|$ of those elements shall be copied to the output range: the last -$m - n$ of these elements from \range{first1}{last1} if $m > n$, and the last -$n - m$ of these elements from \range{first2}{last2} if $m < n$. -\end{itemdescr} +If two sequences have the same number of elements and their corresponding +elements (if any) are equivalent, then neither sequence is lexicographically +less than the other. +If one sequence is a prefix of the other, then the shorter sequence is +lexicographically less than the longer sequence. +Otherwise, the lexicographical comparison of the sequences yields the same +result as the comparison of the first corresponding pair of +elements that are not equivalent. -\rSec2[alg.heap.operations]{Heap operations} +\pnum +\begin{example} +The following sample implementation satisfies these requirements: +\begin{codeblock} +for ( ; first1 != last1 && first2 != last2 ; ++first1, (void) ++first2) { + if (*first1 < *first2) return true; + if (*first2 < *first1) return false; +} +return first1 == last1 && first2 != last2; +\end{codeblock} +\end{example} \pnum -A -\techterm{heap} -is a particular organization of elements in a range between two random access iterators -\range{a}{b} such that: +\begin{note} An empty sequence is lexicographically less than any non-empty sequence, but +not less than any empty sequence. +\end{note} + +\end{itemdescr} + +\rSec2[alg.3way]{Three-way comparison algorithms} +\indexlibrary{\idxcode{compare_3way}}% +\begin{itemdecl} +template constexpr auto compare_3way(const T& a, const U& b); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Compares two values and produces a result of the strongest applicable +comparison category type: \begin{itemize} -\item With \tcode{$N$ = b - a}, for all $i$, $0 < i < N$, -\tcode{comp(a[$\left \lfloor{\frac{i - 1}{2}}\right \rfloor$], a[$i$])} -is \tcode{false}. -\item \tcode{*a} -may be removed by -\tcode{pop_heap()}, -or a new element added by -\tcode{push_heap()}, -in -\bigoh{\log N} -time. +\item +Returns \tcode{a <=> b} if that expression is well-formed. +\item +Otherwise, if the expressions \tcode{a == b} and \tcode{a < b} +are each well-formed and convertible to \tcode{bool}, +returns \tcode{strong_ordering::equal} +when \tcode{a == b} is \tcode{true}, +otherwise returns \tcode{strong_ordering::less} +when \tcode{a < b} is \tcode{true}, +and otherwise returns \tcode{strong_ordering::greater}. +\item +Otherwise, if the expression \tcode{a == b} +is well-formed and convertible to \tcode{bool}, +returns \tcode{strong_equality::equal} +when \tcode{a == b} is \tcode{true}, +and otherwise returns \tcode{strong_equality::nonequal}. +\item +Otherwise, the function is defined as deleted. \end{itemize} +\end{itemdescr} + +\indexlibrary{\idxcode{lexicographical_compare_3way}}% +\begin{itemdecl} +template + constexpr auto + lexicographical_compare_3way(InputIterator1 b1, InputIterator1 e1, + InputIterator2 b2, InputIterator2 e2, + Cmp comp) + -> common_comparison_category_t; +\end{itemdecl} +\begin{itemdescr} \pnum -These properties make heaps useful as priority queues. +\requires +\tcode{Cmp} shall be a function object type +whose return type is a comparison category type. \pnum -\tcode{make_heap()} -converts a range into a heap and -\tcode{sort_heap()} -turns a heap into a sorted sequence. +\effects +Lexicographically compares two ranges and +produces a result of the strongest applicable +comparison category type. +Equivalent to: +\begin{codeblock} +for ( ; b1 != e1 && b2 != e2; void(++b1), void(++b2) ) + if (auto cmp = comp(*b1,*b2); cmp != 0) + return cmp; +return b1 != e1 ? strong_ordering::greater : + b2 != e2 ? strong_ordering::less : + strong_ordering::equal; +\end{codeblock} +\end{itemdescr} -\rSec3[push.heap]{\tcode{push_heap}} +\indexlibrary{\idxcode{lexicographical_compare_3way}}% +\begin{itemdecl} +template + constexpr auto + lexicographical_compare_3way(InputIterator1 b1, InputIterator1 e1, + InputIterator2 b2, InputIterator2 e2); +\end{itemdecl} -\indexlibrary{\idxcode{push_heap}}% +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return lexicographical_compare_3way(b1, e1, b2, e2, + [](const auto& t, const auto& u) { + return compare_3way(t, u); + }); +\end{codeblock} +\end{itemdescr} + +\rSec2[alg.permutation.generators]{Permutation generators} + +\indexlibrary{\idxcode{next_permutation}}% \begin{itemdecl} -template - void push_heap(RandomAccessIterator first, RandomAccessIterator last); +template + constexpr bool next_permutation(BidirectionalIterator first, + BidirectionalIterator last); -template - void push_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); +template + constexpr bool next_permutation(BidirectionalIterator first, + BidirectionalIterator last, Compare comp); \end{itemdecl} \begin{itemdescr} \pnum \requires -The range -\range{first}{last - 1} -shall be a valid heap. -The type of \tcode{*first} shall satisfy -the \tcode{MoveConstructible} requirements -(\tref{moveconstructible}) and the -\tcode{MoveAssignable} requirements -(\tref{moveassignable}). +\tcode{BidirectionalIterator} shall satisfy the +\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. \pnum \effects -Places the value in the location -\tcode{last - 1} -into the resulting heap -\range{first}{last}. +Takes a sequence defined by the range +\range{first}{last} +and transforms it into the next permutation. +The next permutation is found by assuming that the set of all permutations is +lexicographically sorted with respect to +\tcode{operator<} +or \tcode{comp}. + +\pnum +\returns +\tcode{true} +if such a permutation exists. +Otherwise, it transforms the sequence into the smallest permutation, +that is, the ascendingly sorted one, and returns +\tcode{false}. \pnum \complexity At most -$\log(\tcode{last - first})$ -comparisons. +\tcode{(last - first) / 2} +swaps. \end{itemdescr} -\rSec3[pop.heap]{\tcode{pop_heap}} - -\indexlibrary{\idxcode{pop_heap}}% +\indexlibrary{\idxcode{prev_permutation}}% \begin{itemdecl} -template - void pop_heap(RandomAccessIterator first, RandomAccessIterator last); +template + constexpr bool prev_permutation(BidirectionalIterator first, + BidirectionalIterator last); -template - void pop_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); +template + constexpr bool prev_permutation(BidirectionalIterator first, + BidirectionalIterator last, Compare comp); \end{itemdecl} \begin{itemdescr} \pnum \requires -The range -\range{first}{last} -shall be a valid non-empty heap. -\tcode{RandomAccessIterator} shall satisfy the -\tcode{ValueSwappable} requirements\iref{swappable.requirements}. The type -of \tcode{*first} shall satisfy the -\tcode{MoveConstructible} (\tref{moveconstructible}) and -\tcode{MoveAssignable} (\tref{moveassignable}) requirements. - +\tcode{BidirectionalIterator} shall satisfy the +\oldconcept{ValueSwappable} requirements\iref{swappable.requirements}. \pnum \effects -Swaps the value in the location \tcode{first} -with the value in the location -\tcode{last - 1} -and makes -\range{first}{last - 1} -into a heap. +Takes a sequence defined by the range +\range{first}{last} +and transforms it into the previous permutation. +The previous permutation is found by assuming that the set of all permutations is +lexicographically sorted with respect to +\tcode{operator<} +or \tcode{comp}. + +\pnum +\returns +\tcode{true} +if such a permutation exists. +Otherwise, it transforms the sequence into the largest permutation, +that is, the descendingly sorted one, and returns +\tcode{false}. \pnum \complexity At most -$2 \log(\tcode{last - first})$ -comparisons. +\tcode{(last - first) / 2} +swaps. \end{itemdescr} -\rSec3[make.heap]{\tcode{make_heap}} +\rSec1[numeric.ops.overview]{Header \tcode{} synopsis} -\indexlibrary{\idxcode{make_heap}}% -\begin{itemdecl} -template - void make_heap(RandomAccessIterator first, RandomAccessIterator last); +\indexhdr{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); + template + T reduce(InputIterator first, InputIterator last, T init); + template + T reduce(InputIterator first, InputIterator last, T init, BinaryOperation binary_op); + template + typename iterator_traits::value_type + reduce(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last); + template + T reduce(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, T init); + template + T reduce(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator first, ForwardIterator last, T init, BinaryOperation binary_op); + + // \ref{inner.product}, inner product + template + T inner_product(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); + + // \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, + OutputIterator result); + template + OutputIterator partial_sum(InputIterator first, + InputIterator last, + OutputIterator result, + BinaryOperation binary_op); -template - void make_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); -\end{itemdecl} + // \ref{exclusive.scan}, exclusive scan + template + OutputIterator exclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, + T init); + template + OutputIterator exclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, + T init, BinaryOperation binary_op); + template + ForwardIterator2 exclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + T init); + template + ForwardIterator2 exclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + T init, BinaryOperation binary_op); -\begin{itemdescr} -\pnum -\requires The type of \tcode{*first} shall satisfy -the \tcode{MoveConstructible} requirements -(\tref{moveconstructible}) and the -\tcode{MoveAssignable} requirements -(\tref{moveassignable}). + // \ref{inclusive.scan}, inclusive scan + template + OutputIterator inclusive_scan(InputIterator first, InputIterator last, + OutputIterator result); + template + OutputIterator inclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, + BinaryOperation binary_op); + template + OutputIterator inclusive_scan(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); + template + ForwardIterator2 inclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + BinaryOperation binary_op); + 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, + 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, + BinaryOperation binary_op, + UnaryOperation unary_op); + template + 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, + OutputIterator result); + template + OutputIterator adjacent_difference(InputIterator first, + InputIterator last, + OutputIterator result, + BinaryOperation binary_op); + template + ForwardIterator2 adjacent_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, + ForwardIterator1 last, + ForwardIterator2 result); + template + ForwardIterator2 adjacent_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + ForwardIterator1 first, + ForwardIterator1 last, + ForwardIterator2 result, + BinaryOperation binary_op); -\pnum -\effects -Constructs a heap out of the range -\range{first}{last}. + // \ref{numeric.iota}, iota + template + void iota(ForwardIterator first, ForwardIterator last, T value); + + // \ref{numeric.ops.gcd}, greatest common divisor + template + constexpr common_type_t gcd(M m, N n); + + // \ref{numeric.ops.lcm}, least common multiple + template + constexpr common_type_t lcm(M m, N n); +} +\end{codeblock} + +\rSec1[numeric.ops]{Generalized numeric operations} \pnum -\complexity -At most -$3(\tcode{last - first})$ -comparisons. -\end{itemdescr} +\begin{note} +The use of closed ranges as well as semi-open ranges to specify requirements +throughout this subclause is intentional. +\end{note} -\rSec3[sort.heap]{\tcode{sort_heap}} +\rSec2[accumulate]{Accumulate} -\indexlibrary{\idxcode{sort_heap}}% +\indexlibrary{\idxcode{accumulate}}% \begin{itemdecl} -template - void sort_heap(RandomAccessIterator first, RandomAccessIterator last); - -template - void sort_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); +template + T accumulate(InputIterator first, InputIterator last, T init); +template + T accumulate(InputIterator first, InputIterator last, T init, + BinaryOperation binary_op); \end{itemdecl} \begin{itemdescr} \pnum -\requires The range \range{first}{last} shall be a valid heap. -\tcode{RandomAccessIterator} shall satisfy the -\tcode{ValueSwappable} requirements\iref{swappable.requirements}. The type -of \tcode{*first} shall satisfy the -\tcode{MoveConstructible} (\tref{moveconstructible}) and -\tcode{MoveAssignable} (\tref{moveassignable}) requirements. +\requires +\tcode{T} shall satisfy the \oldconcept{CopyConstructible} (\tref{copyconstructible}) +and \oldconcept{CopyAssignable} (\tref{copyassignable}) requirements. +In the range +\crange{first}{last}, +\tcode{binary_op} +shall neither modify elements nor invalidate iterators or subranges.\footnote{The use of fully closed ranges is intentional.} \pnum \effects -Sorts elements in the heap -\range{first}{last}. - -\pnum -\complexity -At most $2N \log N$ -comparisons, where -$N = \tcode{last - first}$. +Computes its result by initializing the accumulator +\tcode{acc} +with the initial value +\tcode{init} +and then modifies it with +\tcode{acc = std::move(acc) + *i} +or +\tcode{acc = binary_op(std::move(acc), *i)} +for every iterator +\tcode{i} +in the range \range{first}{last} +in order.\footnote{\tcode{accumulate} +is similar to the APL reduction operator and Common Lisp reduce function, but +it avoids the difficulty of defining the result of reduction on an empty +sequence by always requiring an initial value.} \end{itemdescr} -\rSec3[is.heap]{\tcode{is_heap}} +\rSec2[reduce]{Reduce} -\indexlibrary{\idxcode{is_heap}}% +\indexlibrary{\idxcode{reduce}}% \begin{itemdecl} -template - constexpr bool is_heap(RandomAccessIterator first, RandomAccessIterator last); +template + typename iterator_traits::value_type + reduce(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{is_heap_until(first, last) == last}. +\effects Equivalent to: +\begin{codeblock} +return reduce(first, last, + typename iterator_traits::value_type{}); +\end{codeblock} \end{itemdescr} - -\indexlibrary{\idxcode{is_heap}}% +\indexlibrary{\idxcode{reduce}}% \begin{itemdecl} -template - bool is_heap(ExecutionPolicy&& exec, - RandomAccessIterator first, RandomAccessIterator last); +template + typename iterator_traits::value_type + reduce(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last); \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{is_heap_until(std::forward(exec), first, last) == last}. +\effects Equivalent to: +\begin{codeblock} +return reduce(std::forward(exec), first, last, + typename iterator_traits::value_type{}); +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{is_heap}}% +\indexlibrary{\idxcode{reduce}}% \begin{itemdecl} -template - constexpr bool is_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); +template + T reduce(InputIterator first, InputIterator last, T init); \end{itemdecl} \begin{itemdescr} \pnum -\returns \tcode{is_heap_until(first, last, comp) == last}. +\effects Equivalent to: +\begin{codeblock} +return reduce(first, last, init, plus<>()); +\end{codeblock} \end{itemdescr} - -\indexlibrary{\idxcode{is_heap}}% +\indexlibrary{\idxcode{reduce}}% \begin{itemdecl} -template - bool is_heap(ExecutionPolicy&& exec, - RandomAccessIterator first, RandomAccessIterator last, - Compare comp); +template + T reduce(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, T init); \end{itemdecl} \begin{itemdescr} \pnum -\returns +\effects Equivalent to: \begin{codeblock} -is_heap_until(std::forward(exec), first, last, comp) == last +return reduce(std::forward(exec), first, last, init, plus<>()); \end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{is_heap_until}}% +\indexlibrary{\idxcode{reduce}}% \begin{itemdecl} -template - constexpr RandomAccessIterator - is_heap_until(RandomAccessIterator first, RandomAccessIterator last); -template - RandomAccessIterator - is_heap_until(ExecutionPolicy&& exec, - RandomAccessIterator first, RandomAccessIterator last); - -template - constexpr RandomAccessIterator - is_heap_until(RandomAccessIterator first, RandomAccessIterator last, - Compare comp); -template - RandomAccessIterator - is_heap_until(ExecutionPolicy&& exec, - RandomAccessIterator first, RandomAccessIterator last, - Compare comp); +template + T reduce(InputIterator first, InputIterator last, T init, + BinaryOperation binary_op); +template + T reduce(ExecutionPolicy&& exec, + ForwardIterator first, ForwardIterator last, T init, + BinaryOperation binary_op); \end{itemdecl} +\begin{itemdescr} +\pnum +\requires +\begin{itemize} +\item \tcode{T} shall be \oldconcept{MoveConstructible} (\tref{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{\placeholdernc{GENERALIZED_SUM}(binary_op, init, *i, ...)} for every \tcode{i} in \range{first}{last}. + +\pnum +\complexity +\bigoh{\tcode{last - first}} applications of \tcode{binary_op}. + +\pnum +\begin{note} +The difference between \tcode{reduce} and \tcode{accumulate} is that +\tcode{reduce} applies \tcode{binary_op} in an unspecified order, which yields +a nondeterministic result for non-associative or non-commutative +\tcode{binary_op} such as floating-point addition. +\end{note} +\end{itemdescr} + +\rSec2[inner.product]{Inner product} + +\indexlibrary{\idxcode{inner_product}}% +\begin{itemdecl} +template + T inner_product(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); +\end{itemdecl} \begin{itemdescr} \pnum -\returns If \tcode{(last - first) < 2}, returns -\tcode{last}. Otherwise, returns -the last iterator \tcode{i} in \crange{first}{last} for which the -range \range{first}{i} is a heap. +\requires +\tcode{T} shall satisfy the \oldconcept{CopyConstructible} (\tref{copyconstructible}) +and \oldconcept{CopyAssignable} (\tref{copyassignable}) requirements. +In the ranges +\crange{first1}{last1} +and +\crange{first2}{first2 + (last1 - first1)} +\tcode{binary_op1} +and +\tcode{binary_op2} +shall neither modify elements nor invalidate iterators or subranges.\footnote{The use of fully closed ranges is intentional.} \pnum -\complexity Linear. +\effects +Computes its result by initializing the accumulator +\tcode{acc} +with the initial value +\tcode{init} +and then modifying it with +\tcode{acc = std::move(acc) + (*i1) * (*i2)} +or +\tcode{acc = binary_op1(std::move(acc), binary_op2(*i1, *i2))} +for every iterator +\tcode{i1} +in the range \range{first1}{last1} +and iterator +\tcode{i2} +in the range +\range{first2}{first2 + (last1 - first1)} +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); +\end{itemdecl} -\rSec2[alg.min.max]{Minimum and maximum} +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +return transform_reduce(first1, last1, first2, init, plus<>(), multiplies<>()); +\end{codeblock} +\end{itemdescr} -\indexlibrary{\idxcode{min}}% +\indexlibrary{\idxcode{transform_reduce}}% \begin{itemdecl} -template constexpr const T& min(const T& a, const T& b); -template - constexpr const T& min(const T& a, const T& b, Compare comp); +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(std::forward(exec), + 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 -For the first form, type \tcode{T} shall be -\tcode{LessThanComparable} (\tref{lessthancomparable}). +\begin{itemize} +\item \tcode{T} shall be \oldconcept{MoveConstructible} (\tref{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 -The smaller value. - -\pnum -\remarks -Returns the first argument when the arguments are equivalent. +\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 -Exactly one comparison. +\complexity \bigoh{\tcode{last1 - first1}} applications each of \tcode{binary_op1} and +\tcode{binary_op2}. \end{itemdescr} -\indexlibrary{\idxcode{min}}% +\indexlibrary{\idxcode{transform_reduce}}% \begin{itemdecl} -template - constexpr T min(initializer_list t); -template - constexpr T min(initializer_list t, Compare comp); +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 \tcode{T} shall be \tcode{CopyConstructible} and \tcode{t.size() > 0}. -For the first form, type \tcode{T} shall be \tcode{LessThanComparable}. +\requires +\begin{itemize} +\item \tcode{T} shall be \oldconcept{MoveConstructible} (\tref{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 The smallest value in the initializer list. +\returns +\begin{codeblock} +@\placeholdernc{GENERALIZED_SUM}@(binary_op, init, unary_op(*i), ...) +\end{codeblock} +for every iterator \tcode{i} in \range{first}{last}. \pnum -\remarks Returns a copy of the leftmost argument when several arguments are equivalent to the smallest. +\complexity +\bigoh{\tcode{last - first}} applications each of \tcode{unary_op} and +\tcode{binary_op}. \pnum -\complexity -Exactly \tcode{t.size() - 1} comparisons. +\begin{note} +\tcode{transform_reduce} does not apply \tcode{unary_op} to \tcode{init}. +\end{note} \end{itemdescr} -\indexlibrary{\idxcode{max}}% +\rSec2[partial.sum]{Partial sum} + +\indexlibrary{\idxcode{partial_sum}}% \begin{itemdecl} -template constexpr const T& max(const T& a, const T& b); -template - constexpr const T& max(const T& a, const T& b, Compare comp); +template + OutputIterator partial_sum( + InputIterator first, InputIterator last, + OutputIterator result); +template + OutputIterator partial_sum( + InputIterator first, InputIterator last, + OutputIterator result, BinaryOperation binary_op); \end{itemdecl} \begin{itemdescr} \pnum \requires -For the first form, type \tcode{T} shall be -\tcode{LessThanComparable} (\tref{lessthancomparable}). +\tcode{InputIterator}'s value type shall be constructible from the type of \tcode{*first}. +The result of the expression \tcode{std::move(acc) + *i} or \tcode{binary_op(std::move(acc), *i)} shall be +implicitly convertible to \tcode{InputIterator}'s value type. \tcode{acc} +shall be writable\iref{iterator.requirements.general} to the \tcode{result} output iterator. +In the ranges +\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. +} \pnum -\returns -The larger value. +\effects For 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} +in order, \tcode{acc} is then modified by \tcode{acc = std::move(acc) + *i} or \tcode{acc = binary_op(std::move(acc), *i)} +and the result is assigned to \tcode{*(result + (i - first))}. \pnum -\remarks -Returns the first argument when the arguments are equivalent. +\returns +\tcode{result + (last - first)}. \pnum \complexity -Exactly one comparison. +Exactly +\tcode{(last - first) - 1} +applications of +the binary operation. + +\pnum +\remarks +\tcode{result} +may be equal to +\tcode{first}. \end{itemdescr} -\indexlibrary{\idxcode{max}}% +\rSec2[exclusive.scan]{Exclusive scan} + +\indexlibrary{\idxcode{exclusive_scan}}% \begin{itemdecl} -template - constexpr T max(initializer_list t); -template - constexpr T max(initializer_list t, Compare comp); +template + OutputIterator exclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, T init); \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{T} shall be \tcode{CopyConstructible} and \tcode{t.size() > 0}. -For the first form, type \tcode{T} shall be \tcode{LessThanComparable}. - -\pnum -\returns The largest value in the initializer list. +\effects Equivalent to: +\begin{codeblock} +return exclusive_scan(first, last, result, init, plus<>()); +\end{codeblock} +\end{itemdescr} -\pnum -\remarks Returns a copy of the leftmost argument when several arguments are equivalent to the largest. +\indexlibrary{\idxcode{exclusive_scan}}% +\begin{itemdecl} +template + ForwardIterator2 exclusive_scan(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, T init); +\end{itemdecl} +\begin{itemdescr} \pnum -\complexity -Exactly \tcode{t.size() - 1} comparisons. +\effects Equivalent to: +\begin{codeblock} +return exclusive_scan(std::forward(exec), + first, last, result, init, plus<>()); +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{minmax}}% + +\indexlibrary{\idxcode{exclusive_scan}}% \begin{itemdecl} -template constexpr pair minmax(const T& a, const T& b); -template - constexpr pair minmax(const T& a, const T& b, Compare comp); +template + OutputIterator exclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, T init, BinaryOperation binary_op); +template + ForwardIterator2 exclusive_scan(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, T init, BinaryOperation binary_op); \end{itemdecl} - \begin{itemdescr} \pnum \requires -For the first form, type \tcode{T} shall be -\tcode{LessThanComparable} (\tref{lessthancomparable}). +\begin{itemize} +\item \tcode{T} shall be \oldconcept{MoveConstructible} (\tref{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 +For each integer \tcode{K} in \range{0}{last - first} +assigns through \tcode{result + K} the value of: +\begin{codeblock} +@\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}@( + binary_op, init, *(first + 0), *(first + 1), ..., *(first + K - 1)) +\end{codeblock} \pnum \returns -\tcode{pair(b, a)} if \tcode{b} is smaller -than \tcode{a}, and -\tcode{pair(a, b)} otherwise. +The end of the resulting range beginning at \tcode{result}. + +\pnum +\complexity +\bigoh{\tcode{last - first}} applications of \tcode{binary_op}. \pnum \remarks -Returns \tcode{pair(a, b)} when the arguments are equivalent. +\tcode{result} may be equal to \tcode{first}. \pnum -\complexity -Exactly one comparison. +\begin{note} +The difference between \tcode{exclusive_scan} and \tcode{inclusive_scan} is +that \tcode{exclusive_scan} excludes the $i^\text{th}$ input element from the +$i^\text{th}$ sum. If \tcode{binary_op} is not mathematically associative, the +behavior of \tcode{exclusive_scan} may be nondeterministic. +\end{note} \end{itemdescr} -\indexlibrary{\idxcode{minmax}}% +\rSec2[inclusive.scan]{Inclusive scan} + +\indexlibrary{\idxcode{inclusive_scan}}% \begin{itemdecl} -template - constexpr pair minmax(initializer_list t); -template - constexpr pair minmax(initializer_list t, Compare comp); +template + OutputIterator inclusive_scan(InputIterator first, InputIterator last, OutputIterator result); \end{itemdecl} \begin{itemdescr} \pnum -\requires \tcode{T} shall be \tcode{CopyConstructible} and \tcode{t.size() > 0}. -For the first form, type \tcode{T} shall be \tcode{LessThanComparable}. - -\pnum -\returns \tcode{pair(x, y)}, where \tcode{x} has the smallest and \tcode{y} has the -largest value in the initializer list. - -\pnum -\remarks \tcode{x} is a copy of the leftmost argument when several arguments are equivalent to -the smallest. \tcode{y} is a copy of the rightmost argument when several arguments are -equivalent to the largest. - -\pnum -\complexity At most $(3/2)\tcode{t.size()}$ applications of the corresponding predicate. +\effects Equivalent to: +\begin{codeblock} +return inclusive_scan(first, last, result, plus<>()); +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{min_element}}% +\indexlibrary{\idxcode{inclusive_scan}}% \begin{itemdecl} -template - constexpr ForwardIterator min_element(ForwardIterator first, ForwardIterator last); - -template - ForwardIterator min_element(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last); - -template - constexpr ForwardIterator min_element(ForwardIterator first, ForwardIterator last, - Compare comp); -template - ForwardIterator min_element(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, - Compare comp); +template + ForwardIterator2 inclusive_scan(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result); \end{itemdecl} \begin{itemdescr} \pnum -\returns -The first iterator -\tcode{i} -in the range -\range{first}{last} -such that for every iterator -\tcode{j} -in the range -\range{first}{last} -the following corresponding conditions hold: -\tcode{!(*j < *i)} -or -\tcode{comp(*j, *i) == false}. -Returns -\tcode{last} -if -\tcode{first == last}. - -\pnum -\complexity -Exactly -$\max(\tcode{last - first - 1}, 0)$ -applications of the corresponding comparisons. +\effects Equivalent to: +\begin{codeblock} +return inclusive_scan(std::forward(exec), first, last, result, plus<>()); +\end{codeblock} \end{itemdescr} -\indexlibrary{\idxcode{max_element}}% -\begin{itemdecl} -template - constexpr ForwardIterator max_element(ForwardIterator first, ForwardIterator last); -template - ForwardIterator max_element(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last); -template - constexpr ForwardIterator max_element(ForwardIterator first, ForwardIterator last, - Compare comp); -template - ForwardIterator max_element(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, - Compare comp); +\indexlibrary{\idxcode{inclusive_scan}}% +\begin{itemdecl} +template + OutputIterator inclusive_scan(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 + ForwardIterator2 inclusive_scan(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, BinaryOperation binary_op, T init); \end{itemdecl} \begin{itemdescr} \pnum -\returns -The first iterator -\tcode{i} -in the range -\range{first}{last} -such that for every iterator -\tcode{j} -in the range -\range{first}{last} -the following corresponding conditions hold: -\tcode{!(*i < *j)} -or -\tcode{comp(*i, *j) == false}. -Returns -\tcode{last} -if -\tcode{first == last}. +\requires +\begin{itemize} +\item If \tcode{init} is provided, \tcode{T} shall be \oldconcept{MoveConstructible} +(\tref{moveconstructible}); otherwise, \tcode{ForwardIterator1}'s value +type shall be \oldconcept{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 -\complexity -Exactly -$\max(\tcode{last - first - 1}, 0)$ -applications of the corresponding comparisons. -\end{itemdescr} - -\indexlibrary{\idxcode{minmax_element}}% -\begin{itemdecl} -template - constexpr pair - minmax_element(ForwardIterator first, ForwardIterator last); -template - pair - minmax_element(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last); - -template - constexpr pair - minmax_element(ForwardIterator first, ForwardIterator last, Compare comp); -template - pair - minmax_element(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, Compare comp); -\end{itemdecl} - +\effects +For each integer \tcode{K} in \range{0}{last - first} +assigns through \tcode{result + K} the value of +\begin{itemize} +\item + \tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(\\\phantom{\tcode{\ \ \ \ }}binary_op, + init, *(first + 0), *(first + 1), ..., *(first + K))}\\if \tcode{init} is provided, or +\item + \tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(\\\phantom{\tcode{\ \ \ \ }}binary_op, + *(first + 0), *(first + 1), ..., *(first + K))}\\otherwise. +\end{itemize} -\begin{itemdescr} \pnum \returns -\tcode{make_pair(first, first)} if \range{first}{last} is empty, otherwise -\tcode{make_pair(m, M)}, where \tcode{m} is -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. +The end of the resulting range beginning at \tcode{result}. \pnum \complexity -At most -$\max(\bigl\lfloor{\frac{3}{2}} (N-1)\bigr\rfloor, 0)$ -applications of the corresponding predicate, where $N$ is \tcode{last - first}. +\bigoh{\tcode{last - first}} applications of \tcode{binary_op}. + +\pnum +\remarks +\tcode{result} may be equal to \tcode{first}. + +\pnum +\begin{note} +The difference between \tcode{exclusive_scan} and \tcode{inclusive_scan} is +that \tcode{inclusive_scan} includes the $i^\text{th}$ input element in the +$i^\text{th}$ sum. If \tcode{binary_op} is not mathematically associative, the +behavior of \tcode{inclusive_scan} may be nondeterministic. +\end{note} \end{itemdescr} -\rSec2[alg.clamp]{Bounded value} +\rSec2[transform.exclusive.scan]{Transform exclusive scan} -\indexlibrary{\idxcode{clamp}}% +\indexlibrary{\idxcode{transform_exclusive_scan}}% \begin{itemdecl} -template - constexpr const T& clamp(const T& v, const T& lo, const T& hi); -template - constexpr const T& clamp(const T& v, const T& lo, const T& hi, Compare comp); +template + OutputIterator transform_exclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, 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 -The value of \tcode{lo} shall be no greater than \tcode{hi}. -For the first form, type \tcode{T} -shall be \tcode{LessThan\-Comparable} (\tref{lessthancomparable}). +\begin{itemize} +\item \tcode{T} shall be \oldconcept{MoveConstructible} (\tref{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 +\crange{first}{last} or +\crange{result}{result + (last - first)}. +\end{itemize} \pnum -\returns -\tcode{lo} if \tcode{v} is less than \tcode{lo}, -\tcode{hi} if \tcode{hi} is less than \tcode{v}, -otherwise \tcode{v}. +\effects +For each integer \tcode{K} in \range{0}{last - first} +assigns through \tcode{result + K} the value of: +\begin{codeblock} +@\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}@( + binary_op, init, + unary_op(*(first + 0)), unary_op(*(first + 1)), ..., unary_op(*(first + K - 1))) +\end{codeblock} \pnum -\begin{note} -If NaN is avoided, \tcode{T} can be a floating-point type. -\end{note} +\returns +The end of the resulting range beginning at \tcode{result}. \pnum \complexity -At most two comparisons. +\bigoh{\tcode{last - first}} applications each of \tcode{unary_op} and +\tcode{binary_op}. + +\pnum +\remarks +\tcode{result} may be equal to \tcode{first}. + +\pnum +\begin{note} +The difference between \tcode{transform_exclusive_scan} and +\tcode{transform_inclusive_scan} is that \tcode{transform_exclusive_scan} +excludes the $i^\text{th}$ input element from the $i^\text{th}$ sum. If \tcode{binary_op} is not +mathematically associative, the behavior of \tcode{transform_exclusive_scan} +may be nondeterministic. \tcode{transform_exclusive_scan} does not apply +\tcode{unary_op} to \tcode{init}. +\end{note} \end{itemdescr} -\rSec2[alg.lex.comparison]{Lexicographical comparison} +\rSec2[transform.inclusive.scan]{Transform inclusive scan} -\indexlibrary{\idxcode{lexicographical_compare}}% +\indexlibrary{\idxcode{transform_inclusive_scan}}% \begin{itemdecl} -template - constexpr bool - lexicographical_compare(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2); -template - bool - lexicographical_compare(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2); - -template - constexpr bool - lexicographical_compare(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - Compare comp); -template - bool - lexicographical_compare(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - Compare comp); +template + OutputIterator transform_inclusive_scan(InputIterator first, InputIterator last, + OutputIterator result, + 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 + 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, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, + BinaryOperation binary_op, UnaryOperation unary_op, + T init); \end{itemdecl} \begin{itemdescr} +\pnum +\requires +\begin{itemize} +\item If \tcode{init} is provided, \tcode{T} shall be \oldconcept{MoveConstructible} +(\tref{moveconstructible}); otherwise, \tcode{ForwardIterator1}'s value +type shall be \oldconcept{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 +For each integer \tcode{K} in \range{0}{last - first} +assigns through \tcode{result + K} the value of +\begin{itemize} +\item + \tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(\\\phantom{\tcode{\ \ \ \ }}binary_op, init,\\\phantom{\tcode{\ \ \ \ }}unary_op(*(first + 0)), unary_op(*(first + 1)), ..., unary_op(*(first + K)))}\\ + if \tcode{init} is provided, or +\item + \tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(\\\phantom{\tcode{\ \ \ \ }}binary_op,\\\phantom{\tcode{\ \ \ \ }}unary_op(*(first + 0)), unary_op(*(first + 1)), ..., unary_op(*(first + K)))}\\ + otherwise. +\end{itemize} + \pnum \returns -\tcode{true} -if the sequence of elements defined by the range -\range{first1}{last1} -is lexicographically less than the sequence of elements defined by the range -\range{first2}{last2} and -\tcode{false} -otherwise. +The end of the resulting range beginning at \tcode{result}. \pnum \complexity -At most -$2 \min(\tcode{last1 - first1}, \ \tcode{last2 - first2})$ -applications of the corresponding comparison. +\bigoh{\tcode{last - first}} applications each of \tcode{unary_op} and +\tcode{binary_op}. \pnum \remarks -If two sequences have the same number of elements and their corresponding -elements (if any) are equivalent, then neither sequence is lexicographically -less than the other. -If one sequence is a prefix of the other, then the shorter sequence is -lexicographically less than the longer sequence. -Otherwise, the lexicographical comparison of the sequences yields the same -result as the comparison of the first corresponding pair of -elements that are not equivalent. - -\pnum -\begin{example} -The following sample implementation satisfies these requirements: -\begin{codeblock} -for ( ; first1 != last1 && first2 != last2 ; ++first1, (void) ++first2) { - if (*first1 < *first2) return true; - if (*first2 < *first1) return false; -} -return first1 == last1 && first2 != last2; -\end{codeblock} -\end{example} +\tcode{result} may be equal to \tcode{first}. \pnum -\begin{note} An empty sequence is lexicographically less than any non-empty sequence, but -not less than any empty sequence. +\begin{note} +The difference between \tcode{transform_exclusive_scan} and +\tcode{transform_inclusive_scan} is that \tcode{transform_inclusive_scan} +includes the $i^\text{th}$ input element in the $i^\text{th}$ sum. If \tcode{binary_op} is not +mathematically associative, the behavior of \tcode{transform_inclusive_scan} +may be nondeterministic. \tcode{transform_inclusive_scan} does not apply +\tcode{unary_op} to \tcode{init}. \end{note} - \end{itemdescr} -\rSec2[alg.3way]{Three-way comparison algorithms} +\rSec2[adjacent.difference]{Adjacent difference} -\indexlibrary{\idxcode{compare_3way}}% +\indexlibrary{\idxcode{adjacent_difference}}% \begin{itemdecl} -template constexpr auto compare_3way(const T& a, const U& b); +template + OutputIterator + adjacent_difference(InputIterator first, InputIterator last, OutputIterator result); +template + ForwardIterator2 + adjacent_difference(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); + +template + OutputIterator + adjacent_difference(InputIterator first, InputIterator last, + OutputIterator result, BinaryOperation binary_op); +template + ForwardIterator2 + adjacent_difference(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, BinaryOperation binary_op); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Compares two values and produces a result of the strongest applicable -comparison category type: +Let \tcode{T} be the value type of \tcode{decltype(first)}. +For the overloads that do not take an argument \tcode{binary_op}, +let \tcode{binary_op} be an lvalue +that denotes an object of type \tcode{minus<>}. + +\pnum +\requires \begin{itemize} \item -Returns \tcode{a <=> b} if that expression is well-formed. -\item -Otherwise, if the expressions \tcode{a == b} and \tcode{a < b} -are each well-formed and convertible to \tcode{bool}, -returns \tcode{strong_ordering::equal} -when \tcode{a == b} is \tcode{true}, -otherwise returns \tcode{strong_ordering::less} -when \tcode{a < b} is \tcode{true}, -and otherwise returns \tcode{strong_ordering::greater}. +For the overloads with no \tcode{ExecutionPolicy}, +\tcode{T} shall be \oldconcept{MoveAssignable} (\tref{moveassignable}) and shall +be constructible from the type of \tcode{*first}. \tcode{acc} (defined below) +shall be writable\iref{iterator.requirements.general} to the \tcode{result} +output iterator. The result of the expression +\tcode{binary_op(val, std::move(acc))} shall be writable to the \tcode{result} output iterator. + \item -Otherwise, if the expression \tcode{a == b} -is well-formed and convertible to \tcode{bool}, -returns \tcode{strong_equality::equal} -when \tcode{a == b} is \tcode{true}, -and otherwise returns \tcode{strong_equality::nonequal}. +For the overloads with an \tcode{ExecutionPolicy}, +the result of the expressions \tcode{binary_op(*first, *first)} and +\tcode{*first} shall be writable to \tcode{result}. + \item -Otherwise, the function is defined as deleted. +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} -\end{itemdescr} -\indexlibrary{\idxcode{lexicographical_compare_3way}}% -\begin{itemdecl} -template - constexpr auto - lexicographical_compare_3way(InputIterator1 b1, InputIterator1 e1, - InputIterator2 b2, InputIterator2 e2, - Cmp comp) - -> common_comparison_category_t; -\end{itemdecl} +\pnum +\effects For the overloads with no \tcode{ExecutionPolicy} and a non-empty range, +the function creates an accumulator \tcode{acc} of type \tcode{T}, +initializes it with \tcode{*first}, +and assigns the result to \tcode{*result}. For every iterator \tcode{i} in \range{first + 1}{last} +in order, creates an object \tcode{val} whose type is \tcode{T}, initializes it +with \tcode{*i}, computes \tcode{binary_op(val, std::move(acc))}, assigns the result +to \tcode{*(result + (i - first))}, and move assigns from \tcode{val} to \tcode{acc}. -\begin{itemdescr} \pnum -\requires -\tcode{Cmp} shall be a function object type -whose return type is a comparison category type. +For the overloads with an \tcode{ExecutionPolicy} and a non-empty range, +performs \tcode{*result = *first}. +Then, for every \tcode{d} in \tcode{[1, last - first - 1]}, +performs \tcode{*(result + d) = binary_op(*(first + d), *(first + (d - 1)))}. \pnum -\effects -Lexicographically compares two ranges and -produces a result of the strongest applicable -comparison category type. -Equivalent to: -\begin{codeblock} -for ( ; b1 != e1 && b2 != e2; void(++b1), void(++b2) ) - if (auto cmp = comp(*b1,*b2); cmp != 0) - return cmp; -return b1 != e1 ? strong_ordering::greater : - b2 != e2 ? strong_ordering::less : - strong_ordering::equal; -\end{codeblock} +\returns +\tcode{result + (last - first)}. + +\pnum +\complexity +Exactly +\tcode{(last - first) - 1} +applications of +the binary operation. + +\pnum +\remarks +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} -\indexlibrary{\idxcode{lexicographical_compare_3way}}% +\rSec2[numeric.iota]{Iota} + +\indexlibrary{\idxcode{iota}}% \begin{itemdecl} -template - constexpr auto - lexicographical_compare_3way(InputIterator1 b1, InputIterator1 e1, - InputIterator2 b2, InputIterator2 e2); +template + void iota(ForwardIterator first, ForwardIterator last, T value); \end{itemdecl} \begin{itemdescr} \pnum -\effects -Equivalent to: -\begin{codeblock} -return lexicographical_compare_3way(b1, e1, b2, e2, - [](const auto& t, const auto& u) { - return compare_3way(t, u); - }); -\end{codeblock} +\requires \tcode{T} shall be convertible to \tcode{ForwardIterator}'s value +type. The expression \tcode{++val}, where \tcode{val} has type \tcode{T}, shall +be well-formed. + +\pnum +\effects For each element referred to by the iterator \tcode{i} in the range +\range{first}{last}, assigns \tcode{*i = value} and increments \tcode{value} as +if by \tcode{++value}. + +\pnum +\complexity Exactly \tcode{last - first} increments and assignments. \end{itemdescr} -\rSec2[alg.permutation.generators]{Permutation generators} +\rSec2[numeric.ops.gcd]{Greatest common divisor} -\indexlibrary{\idxcode{next_permutation}}% +\indexlibrary{\idxcode{gcd}}% \begin{itemdecl} -template - bool next_permutation(BidirectionalIterator first, - BidirectionalIterator last); - -template - bool next_permutation(BidirectionalIterator first, - BidirectionalIterator last, Compare comp); +template + constexpr common_type_t gcd(M m, N n); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{BidirectionalIterator} shall satisfy the -\tcode{ValueSwappable} requirements\iref{swappable.requirements}. +$|\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)} = |\tcode{m}|$ is representable as a value of type \tcode{M}. \end{note} \pnum -\effects -Takes a sequence defined by the range -\range{first}{last} -and transforms it into the next permutation. -The next permutation is found by assuming that the set of all permutations is -lexicographically sorted with respect to -\tcode{operator<} -or \tcode{comp}. +\remarks +If either \tcode{M} or \tcode{N} is not an integer type, or +if either is \cv{}~\tcode{bool}, the program is ill-formed. \pnum \returns -\tcode{true} -if such a permutation exists. -Otherwise, it transforms the sequence into the smallest permutation, -that is, the ascendingly sorted one, and returns -\tcode{false}. +Zero when \tcode{m} and \tcode{n} are both zero. +Otherwise, returns the greatest common divisor of $|\tcode{m}|$ and $|\tcode{n}|$. \pnum -\complexity -At most -\tcode{(last - first) / 2} -swaps. +\throws +Nothing. \end{itemdescr} -\indexlibrary{\idxcode{prev_permutation}}% -\begin{itemdecl} -template - bool prev_permutation(BidirectionalIterator first, - BidirectionalIterator last); +\rSec2[numeric.ops.lcm]{Least common multiple} -template - bool prev_permutation(BidirectionalIterator first, - BidirectionalIterator last, Compare comp); +\indexlibrary{\idxcode{lcm}}% +\begin{itemdecl} +template + constexpr common_type_t lcm(M m, N n); \end{itemdecl} \begin{itemdescr} \pnum \requires -\tcode{BidirectionalIterator} shall satisfy the -\tcode{ValueSwappable} requirements\iref{swappable.requirements}. +$|\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}. \pnum -\effects -Takes a sequence defined by the range -\range{first}{last} -and transforms it into the previous permutation. -The previous permutation is found by assuming that the set of all permutations is -lexicographically sorted with respect to -\tcode{operator<} -or \tcode{comp}. +\remarks +If either \tcode{M} or \tcode{N} is not an integer type, or +if either is \cv{}~\tcode{bool} the program is ill-formed. \pnum \returns -\tcode{true} -if such a permutation exists. -Otherwise, it transforms the sequence into the largest permutation, -that is, the descendingly sorted one, and returns -\tcode{false}. +Zero when either \tcode{m} or \tcode{n} is zero. +Otherwise, returns the least common multiple of $|\tcode{m}|$ and $|\tcode{n}|$. \pnum -\complexity -At most -\tcode{(last - first) / 2} -swaps. +\throws +Nothing. \end{itemdescr} \rSec1[alg.c.library]{C library algorithms} diff --git a/source/atomics.tex b/source/atomics.tex index 67bfb5b828..8474ede06f 100644 --- a/source/atomics.tex +++ b/source/atomics.tex @@ -12,18 +12,22 @@ and operations, as summarized below. \begin{libsumtab}{Atomics library summary}{tab:atomics.lib.summary} -\ref{atomics.order} & Order and Consistency & - \\ -\ref{atomics.lockfree} & Lock-free Property & - \\ -\ref{atomics.types.generic} & Atomic Types & \tcode{} - \\ -\ref{atomics.types.operations} & Operations on Atomic Types & - \\ -\ref{atomics.flag} & Flag Type and Operations & - \\ -\ref{atomics.fences} & Fences & - \\ +\ref{atomics.alias} & Type aliases & + \\ \rowsep +\ref{atomics.order} & Order and consistency & + \\ \rowsep +\ref{atomics.lockfree} & Lock-free property & + \\ \rowsep +\ref{atomics.ref.generic} & Class template \tcode{atomic_ref} & \tcode{} + \\ \rowsep +\ref{atomics.types.generic} & Class template \tcode{atomic} & \tcode{} + \\ \rowsep +\ref{atomics.nonmembers} & Non-member functions & \tcode{} + \\ \rowsep +\ref{atomics.flag} & Flag type and operations & \tcode{} + \\ \rowsep +\ref{atomics.fences} & Fences & \tcode{} + \\ \rowsep \end{libsumtab} \rSec1[atomics.syn]{Header \tcode{} synopsis} @@ -48,7 +52,12 @@ #define ATOMIC_LLONG_LOCK_FREE @\unspec@ #define ATOMIC_POINTER_LOCK_FREE @\unspec@ - // \ref{atomics.types.generic}, atomic + // \ref{atomics.ref.generic}, class template \tcode{atomic_ref} + template struct atomic_ref; + // \ref{atomics.ref.pointer}, partial specialization for pointers + template struct atomic_ref; + + // \ref{atomics.types.generic}, class template \tcode{atomic} template struct atomic; // \ref{atomics.types.pointer}, partial specialization for pointers template struct atomic; @@ -305,19 +314,19 @@ are defined, respectively. \rSec1[atomics.order]{Order and consistency} -\indexlibrary{memory_order}% +\indexlibrary{\idxcode{memory_order}}% \indexlibrarymember{relaxed}{memory_order}% \indexlibrarymember{consume}{memory_order}% \indexlibrarymember{acquire}{memory_order}% \indexlibrarymember{release}{memory_order}% \indexlibrarymember{acq_rel}{memory_order}% \indexlibrarymember{seq_cst}{memory_order}% -\indexlibrary{memory_order_relaxed}% -\indexlibrary{memory_order_consume}% -\indexlibrary{memory_order_acquire}% -\indexlibrary{memory_order_release}% -\indexlibrary{memory_order_acq_rel}% -\indexlibrary{memory_order_seq_cst}% +\indexlibrary{\idxcode{memory_order_relaxed}}% +\indexlibrary{\idxcode{memory_order_consume}}% +\indexlibrary{\idxcode{memory_order_acquire}}% +\indexlibrary{\idxcode{memory_order_release}}% +\indexlibrary{\idxcode{memory_order_acq_rel}}% +\indexlibrary{\idxcode{memory_order_seq_cst}}% \begin{codeblock} namespace std { @@ -559,6 +568,724 @@ mapped into a process more than once and by memory that is shared between two processes. \end{note} +\rSec1[atomics.ref.generic]{Class template \tcode{atomic_ref}} + +\indexlibrary{\idxcode{atomic_ref}}% +\indexlibrarymember{value_type}{atomic_ref}% +\begin{codeblock} +namespace std { + template struct atomic_ref { + private: + T* ptr; // \expos + public: + using value_type = T; + static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic_ref} type's operations are always lock free}@; + static constexpr size_t required_alignment = @\impdefx{required alignment for \tcode{atomic_ref} type's operations}@; + + atomic_ref() = delete; + atomic_ref& operator=(const atomic_ref&) = delete; + + explicit atomic_ref(T&); + atomic_ref(const atomic_ref&) noexcept; + + T operator=(T) const noexcept; + operator T() const noexcept; + + bool is_lock_free() const noexcept; + void store(T, memory_order = memory_order_seq_cst) const noexcept; + T load(memory_order = memory_order_seq_cst) const noexcept; + T exchange(T, memory_order = memory_order_seq_cst) const noexcept; + bool compare_exchange_weak(T&, T, + memory_order, memory_order) const noexcept; + bool compare_exchange_strong(T&, T, + memory_order, memory_order) const noexcept; + bool compare_exchange_weak(T&, T, + memory_order = memory_order_seq_cst) const noexcept; + bool compare_exchange_strong(T&, T, + memory_order = memory_order_seq_cst) const noexcept; + }; +} +\end{codeblock} + +\pnum +An \tcode{atomic_ref} object applies atomic operations\iref{atomics.general} to +the object referenced by \tcode{*ptr} such that, +for the lifetime\iref{basic.life} of the \tcode{atomic_ref} object, +the object referenced by \tcode{*ptr} is an atomic object\iref{intro.races}. + +\pnum +The template argument for \tcode{T} +shall be trivially copyable\iref{basic.types}. + +\pnum +The lifetime\iref{basic.life} of an object referenced by \tcode{*ptr} +shall exceed the lifetime of all \tcode{atomic_ref}s that reference the object. +While any \tcode{atomic_ref} instances exist +that reference the \tcode{*ptr} object, +all accesses to that object shall exclusively occur +through those \tcode{atomic_ref} instances. +No subobject of the object referenced by \tcode{atomic_ref} +shall be concurrently referenced by any other \tcode{atomic_ref} object. + +\pnum +Atomic operations applied to an object +through a referencing \tcode{atomic_ref} are atomic with respect to +atomic operations applied through any other \tcode{atomic_ref} +referencing the same object. +\begin{note} +Atomic operations or the \tcode{atomic_ref} constructor could acquire +a shared resource, such as a lock associated with the referenced object, +to enable atomic operations to be applied to the referenced object. +\end{note} + +\rSec2[atomics.ref.operations]{Operations} + +\indexlibrarymember{is_always_lock_free}{atomic_ref}% +\indexlibrarymember{is_always_lock_free}{atomic_ref}% +\indexlibrarymember{is_always_lock_free}{atomic_ref<\placeholder{integral}>}% +\indexlibrarymember{is_always_lock_free}{atomic_ref<\placeholder{floating-point}>}% +\begin{itemdecl} +static constexpr bool is_always_lock_free; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The static data member \tcode{is_always_lock_free} is \tcode{true} +if the \tcode{atomic_ref} type's operations are always lock-free, +and \tcode{false} otherwise. +\end{itemdescr} + +\indexlibrarymember{required_alignment}{atomic_ref}% +\indexlibrarymember{required_alignment}{atomic_ref}% +\indexlibrarymember{required_alignment}{atomic_ref<\placeholder{integral}>}% +\indexlibrarymember{required_alignment}{atomic_ref<\placeholder{floating-point}>}% +\begin{itemdecl} +static constexpr size_t required_alignment; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The alignment required for an object to be referenced by an atomic reference, +which is at least \tcode{alignof(T)}. + +\pnum +\begin{note} +Hardware could require an object +referenced by an \tcode{atomic_ref} +to have stricter alignment\iref{basic.align} +than other objects of type \tcode{T}. +Further, whether operations on an \tcode{atomic_ref} +are lock-free could depend on the alignment of the referenced object. +For example, lock-free operations on \tcode{std::complex} +could be supported only if aligned to \tcode{2*alignof(double)}. +\end{note} +\end{itemdescr} + +\indexlibrary{\idxcode{atomic_ref}!constructor}% +\indexlibrary{\idxcode{atomic_ref}!constructor}% +\indexlibrary{\idxcode{atomic_ref<\placeholder{integral}>}!constructor}% +\indexlibrary{\idxcode{atomic_ref<\placeholder{floating-point}>}!constructor}% +\begin{itemdecl} +atomic_ref(T& obj); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires The referenced object shall be aligned to \tcode{required_alignment}. + +\pnum +\effects Constructs an atomic reference that references the object. + +\pnum +\throws Nothing. +\end{itemdescr} + +\indexlibrary{\idxcode{atomic_ref}!constructor}% +\indexlibrary{\idxcode{atomic_ref}!constructor}% +\indexlibrary{\idxcode{atomic_ref<\placeholder{integral}>}!constructor}% +\indexlibrary{\idxcode{atomic_ref<\placeholder{floating-point}>}!constructor}% +\begin{itemdecl} +atomic_ref(const atomic_ref& ref) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Constructs an atomic reference +that references the object referenced by \tcode{ref}. +\end{itemdescr} + +\indexlibrarymember{operator=}{atomic_ref}% +\indexlibrarymember{operator=}{atomic_ref}% +\indexlibrarymember{operator=}{atomic_ref<\placeholder{integral}>}% +\indexlibrarymember{operator=}{atomic_ref<\placeholder{floating-point}>}% +\begin{itemdecl} +T operator=(T desired) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\begin{codeblock} +store(desired); +return desired; +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator \placeholder{type}}{atomic_ref}% +\indexlibrarymember{operator T*}{atomic_ref}% +\indexlibrarymember{operator \placeholder{integral}}{atomic_ref<\placeholder{integral}>}% +\indexlibrarymember{operator \placeholder{floating-point}}{atomic_ref<\placeholder{floating-point}>}% +\begin{itemdecl} +operator T() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return load();} +\end{itemdescr} + +\indexlibrarymember{is_lock_free}{atomic_ref}% +\indexlibrarymember{is_lock_free}{atomic_ref}% +\indexlibrarymember{is_lock_free}{atomic_ref<\placeholder{integral}>}% +\indexlibrarymember{is_lock_free}{atomic_ref<\placeholder{floating-point}>}% +\begin{itemdecl} +bool is_lock_free() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{true} if the object's operations are lock-free, +\tcode{false} otherwise. +\end{itemdescr} + +\indexlibrarymember{store}{atomic_ref}% +\indexlibrarymember{store}{atomic_ref}% +\indexlibrarymember{store}{atomic_ref<\placeholder{integral}>}% +\indexlibrarymember{store}{atomic_ref<\placeholder{floating-point}>}% +\begin{itemdecl} +void store(T desired, memory_order order = memory_order_seq_cst) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires The \tcode{order} argument shall not be +\tcode{memory_order_consume}, +\tcode{memory_order_acquire}, nor +\tcode{memory_order_acq_rel}. + +\pnum +\effects Atomically replaces the value referenced by \tcode{*ptr} +with the value of \tcode{desired}. +Memory is affected according to the value of \tcode{order}. +\end{itemdescr} + +\indexlibrarymember{load}{atomic_ref}% +\indexlibrarymember{load}{atomic_ref}% +\indexlibrarymember{load}{atomic_ref<\placeholder{integral}>}% +\indexlibrarymember{load}{atomic_ref<\placeholder{floating-point}>}% +\begin{itemdecl} +T load(memory_order order = memory_order_seq_cst) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires The \tcode{order} argument shall not be +\tcode{memory_order_release} nor \tcode{memory_order_acq_rel}. + +\pnum +\effects Memory is affected according to the value of \tcode{order}. + +\pnum +\returns Atomically returns the value referenced by \tcode{*ptr}. +\end{itemdescr} + +\indexlibrarymember{exchange}{atomic_ref}% +\indexlibrarymember{exchange}{atomic_ref}% +\indexlibrarymember{exchange}{atomic_ref<\placeholder{integral}>}% +\indexlibrarymember{exchange}{atomic_ref<\placeholder{floating-point}>}% +\begin{itemdecl} +T exchange(T desired, memory_order order = memory_order_seq_cst) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Atomically replaces the value referenced by \tcode{*ptr} +with \tcode{desired}. +Memory is affected according to the value of \tcode{order}. +This operation is an atomic read-modify-write operation\iref{intro.multithread}. + +\pnum +\returns Atomically returns the value referenced by \tcode{*ptr} +immediately before the effects. +\end{itemdescr} + +\indexlibrarymember{compare_exchange_weak}{atomic_ref}% +\indexlibrarymember{compare_exchange_weak}{atomic_ref}% +\indexlibrarymember{compare_exchange_weak}{atomic_ref<\placeholder{integral}>}% +\indexlibrarymember{compare_exchange_weak}{atomic_ref<\placeholder{floating-point}>}% +\indexlibrarymember{compare_exchange_strong}{atomic_ref}% +\indexlibrarymember{compare_exchange_strong}{atomic_ref}% +\indexlibrarymember{compare_exchange_strong}{atomic_ref<\placeholder{integral}>}% +\indexlibrarymember{compare_exchange_strong}{atomic_ref<\placeholder{floating-point}>}% +\begin{itemdecl} +bool compare_exchange_weak(T& expected, T desired, + memory_order success, memory_order failure) const noexcept; + +bool compare_exchange_strong(T& expected, T desired, + memory_order success, memory_order failure) const noexcept; + +bool compare_exchange_weak(T& expected, T desired, + memory_order order = memory_order_seq_cst) const noexcept; + +bool compare_exchange_strong(T& expected, T desired, + memory_order order = memory_order_seq_cst) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires The \tcode{failure} argument shall not be +\tcode{memory_order_release} nor \tcode{memory_order_acq_rel}. + +\pnum +\effects Retrieves the value in \tcode{expected}. +It then atomically compares the value referenced by \tcode{*ptr} for equality +with that previously retrieved from \tcode{expected}, +and if \tcode{true}, replaces the value referenced by \tcode{*ptr} +with that in \tcode{desired}. +If and only if the comparison is \tcode{true}, +memory is affected according to the value of \tcode{success}, and +if the comparison is \tcode{false}, +memory is affected according to the value of \tcode{failure}. +When only one \tcode{memory_order} argument is supplied, +the value of \tcode{success} is \tcode{order}, and +the value of \tcode{failure} is \tcode{order} +except that a value of \tcode{memory_order_acq_rel} shall be replaced by +the value \tcode{memory_order_acquire} and +a value of \tcode{memory_order_release} shall be replaced by +the value \tcode{memory_order_relaxed}. +If and only if the comparison is \tcode{false} then, +after the atomic operation, +the contents of the memory in \tcode{expected} are replaced by +the value read from the value referenced by \tcode{*ptr} +during the atomic comparison. +If the operation returns \tcode{true}, +these operations are atomic read-modify-write operations\iref{intro.races} +on the value referenced by \tcode{*ptr}. +Otherwise, these operations are atomic load operations on that memory. + +\pnum +\returns The result of the comparison. + +\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{ptr} are equal, +it may return \tcode{false} and +store back to \tcode{expected} the same memory contents +that were originally there. +\begin{note} +This spurious failure enables implementation of compare-and-exchange +on a broader class of machines, e.g., load-locked store-conditional machines. +A consequence of spurious failure is +that nearly all uses of weak compare-and-exchange will be in a loop. +When a compare-and-exchange is in a loop, +the weak version will yield better performance on some platforms. +When a weak compare-and-exchange would require a loop and +a strong one would not, the strong one is preferable. +\end{note} +\end{itemdescr} + +\rSec2[atomics.ref.int]{Specializations for integral types} + +\pnum +\indexlibrary{\idxcode{atomic_ref<\placeholder{integral}>}}% +There are specializations of the \tcode{atomic_ref} class 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 type \tcode{\placeholder{integral}}, +the specialization \tcode{atomic_ref<\placeholder{integral}>} provides +additional atomic operations appropriate to integral types. +\begin{note} +For the specialization \tcode{atomic_ref}, see \ref{atomics.ref.generic}. +\end{note} + +\begin{codeblock} +namespace std { + template<> struct atomic_ref<@\placeholder{integral}@> { + private: + @\placeholder{integral}@* ptr; // \expos + public: + using value_type = @\placeholder{integral}@; + using difference_type = value_type; + static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic_ref} type's operations are always lock free}@; + static constexpr size_t required_alignment = @\impdefx{required alignment for \tcode{atomic_ref} type's operations}@; + + atomic_ref() = delete; + atomic_ref& operator=(const atomic_ref&) = delete; + + explicit atomic_ref(@\placeholder{integral}@&); + atomic_ref(const atomic_ref&) noexcept; + + @\placeholdernc{integral}@ operator=(@\placeholder{integral}@) const noexcept; + operator @\placeholdernc{integral}@() const noexcept; + + bool is_lock_free() const noexcept; + void store(@\placeholdernc{integral}@, memory_order = memory_order_seq_cst) const noexcept; + @\placeholdernc{integral}@ load(memory_order = memory_order_seq_cst) const noexcept; + @\placeholdernc{integral}@ exchange(@\placeholdernc{integral}@, + memory_order = memory_order_seq_cst) const noexcept; + bool compare_exchange_weak(@\placeholder{integral}@&, @\placeholder{integral}@, + memory_order, memory_order) const noexcept; + bool compare_exchange_strong(@\placeholder{integral}@&, @\placeholder{integral}@, + memory_order, memory_order) const noexcept; + bool compare_exchange_weak(@\placeholder{integral}@&, @\placeholder{integral}@, + memory_order = memory_order_seq_cst) const noexcept; + bool compare_exchange_strong(@\placeholder{integral}@&, @\placeholder{integral}@, + memory_order = memory_order_seq_cst) const noexcept; + + @\placeholdernc{integral}@ fetch_add(@\placeholdernc{integral}@, + memory_order = memory_order_seq_cst) const noexcept; + @\placeholdernc{integral}@ fetch_sub(@\placeholdernc{integral}@, + memory_order = memory_order_seq_cst) const noexcept; + @\placeholdernc{integral}@ fetch_and(@\placeholdernc{integral}@, + memory_order = memory_order_seq_cst) const noexcept; + @\placeholdernc{integral}@ fetch_or(@\placeholdernc{integral}@, + memory_order = memory_order_seq_cst) const noexcept; + @\placeholdernc{integral}@ fetch_xor(@\placeholdernc{integral}@, + memory_order = memory_order_seq_cst) const noexcept; + + @\placeholdernc{integral}@ operator++(int) const noexcept; + @\placeholdernc{integral}@ operator--(int) const noexcept; + @\placeholdernc{integral}@ operator++() const noexcept; + @\placeholdernc{integral}@ operator--() const noexcept; + @\placeholdernc{integral}@ operator+=(@\placeholdernc{integral}@) const noexcept; + @\placeholdernc{integral}@ operator-=(@\placeholdernc{integral}@) const noexcept; + @\placeholdernc{integral}@ operator&=(@\placeholdernc{integral}@) const noexcept; + @\placeholdernc{integral}@ operator|=(@\placeholdernc{integral}@) const noexcept; + @\placeholdernc{integral}@ operator^=(@\placeholdernc{integral}@) const noexcept; + }; +} +\end{codeblock} + +\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 identified +in \tref{atomic.arithmetic.computations}. + +\indexlibrarymember{fetch_add}{atomic_ref<\placeholder{integral}>}% +\indexlibrarymember{fetch_and}{atomic_ref<\placeholder{integral}>}% +\indexlibrarymember{fetch_or}{atomic_ref<\placeholder{integral}>}% +\indexlibrarymember{fetch_sub}{atomic_ref<\placeholder{integral}>}% +\indexlibrarymember{fetch_xor}{atomic_ref<\placeholder{integral}>}% +\begin{itemdecl} +@\placeholdernc{integral}@ fetch_@\placeholdernc{key}@(@\placeholdernc{integral}@ operand, memory_order order = memory_order_seq_cst) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Atomically replaces the value referenced by \tcode{*ptr} with +the result of the computation applied to the value referenced by \tcode{*ptr} +and the given operand. +Memory is affected according to the value of \tcode{order}. +These operations are atomic read-modify-write operations\iref{intro.races}. + +\pnum +\returns Atomically, the value referenced by \tcode{*ptr} +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. +\end{itemdescr} + +\indexlibrarymember{operator+=}{atomic_ref<\placeholder{integral}>}% +\indexlibrarymember{operator-=}{atomic_ref<\placeholder{integral}>}% +\indexlibrarymember{operator\&=}{atomic_ref<\placeholder{integral}>}% +\indexlibrarymember{operator"|=}{atomic_ref<\placeholder{integral}>}% +\indexlibrarymember{operator\caret=}{atomic_ref<\placeholder{integral}>}% +\begin{itemdecl} +@\placeholdernc{integral}@ operator @\placeholder{op}@=(@\placeholdernc{integral}@ operand) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\tcode{return fetch_\placeholdernc{key}(operand) \placeholder{op} operand;} +\end{itemdescr} + +\rSec2[atomics.ref.float]{Specializations for floating-point types} + +\pnum +\indexlibrary{\idxcode{atomic_ref<\placeholder{floating-point}>}}% +There are specializations of the \tcode{atomic_ref} class template +for the floating-point types +\tcode{float}, +\tcode{double}, and +\tcode{long double}. +For each such type \tcode{\placeholder{floating-point}}, +the specialization \tcode{atomic_ref<\placeholder{floating-\-point}>} provides +additional atomic operations appropriate to floating-point types. + +\begin{codeblock} +namespace std { + template<> struct atomic_ref<@\placeholder{floating-point}@> { + private: + @\placeholder{floating-point}@* ptr; // \expos + public: + using value_type = @\placeholder{floating-point}@; + using difference_type = value_type; + static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic_ref} type's operations are always lock free}@; + static constexpr size_t required_alignment = @\impdefx{required alignment for \tcode{atomic_ref} type's operations}@; + + atomic_ref() = delete; + atomic_ref& operator=(const atomic_ref&) = delete; + + explicit atomic_ref(@\placeholder{floating-point}@&); + atomic_ref(const atomic_ref&) noexcept; + + @\placeholder{floating-point}@ operator=(@\placeholder{floating-point}@) noexcept; + operator @\placeholdernc{floating-point}@() const noexcept; + + bool is_lock_free() const noexcept; + void store(@\placeholder{floating-point}@, memory_order = memory_order_seq_cst) const noexcept; + @\placeholder{floating-point}@ load(memory_order = memory_order_seq_cst) const noexcept; + @\placeholder{floating-point}@ exchange(@\placeholder{floating-point}@, + memory_order = memory_order_seq_cst) const noexcept; + bool compare_exchange_weak(@\placeholder{floating-point}@&, @\placeholder{floating-point}@, + memory_order, memory_order) const noexcept; + bool compare_exchange_strong(@\placeholder{floating-point}@&, @\placeholder{floating-point}@, + memory_order, memory_order) const noexcept; + bool compare_exchange_weak(@\placeholder{floating-point}@&, @\placeholder{floating-point}@, + memory_order = memory_order_seq_cst) const noexcept; + bool compare_exchange_strong(@\placeholder{floating-point}@&, @\placeholder{floating-point}@, + memory_order = memory_order_seq_cst) const noexcept; + + @\placeholder{floating-point}@ fetch_add(@\placeholder{floating-point}@, + memory_order = memory_order_seq_cst) const noexcept; + @\placeholder{floating-point}@ fetch_sub(@\placeholder{floating-point}@, + memory_order = memory_order_seq_cst) const noexcept; + + @\placeholder{floating-point}@ operator+=(@\placeholder{floating-point}@) const noexcept; + @\placeholder{floating-point}@ operator-=(@\placeholder{floating-point}@) const noexcept; + }; +} +\end{codeblock} + +\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 are identified +in \tref{atomic.arithmetic.computations}. + +\indexlibrarymember{fetch_add}{atomic_ref<\placeholder{floating-point}>}% +\indexlibrarymember{fetch_sub}{atomic_ref<\placeholder{floating-point}>}% +\begin{itemdecl} +@\placeholder{floating-point}@ fetch_@\placeholdernc{key}@(@\placeholder{floating-point}@ operand, + memory_order order = memory_order_seq_cst) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Atomically replaces the value referenced by \tcode{*ptr} with +the result of the computation applied to the value referenced by \tcode{*ptr} +and the given operand. +Memory is affected according to the value of \tcode{order}. +These operations are atomic read-modify-write operations\iref{intro.races}. + +\pnum +\returns Atomically, the value referenced by \tcode{*ptr} +immediately before the effects. + +\pnum +\remarks If the result is not a representable value for its type\iref{expr.pre}, +the result is unspecified, +but the operations otherwise have no undefined behavior. +Atomic arithmetic operations on \tcode{\placeholder{floating-point}} should conform to +the \tcode{std::numeric_limits<\placeholder{floating-point}>} traits +associated with the floating-point type\iref{limits.syn}. +The floating-point environment\iref{cfenv} +for atomic arithmetic operations on \tcode{\placeholder{floating-point}} +may be different than the calling thread's floating-point environment. +\end{itemdescr} + +\indexlibrarymember{operator+=}{atomic_ref<\placeholder{floating-point}>}% +\indexlibrarymember{operator-=}{atomic_ref<\placeholder{floating-point}>}% +\begin{itemdecl} +@\placeholder{floating-point}@ operator @\placeholder{op}@=(@\placeholder{floating-point}@ operand) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\effects Equivalent to: +\tcode{return fetch_\placeholder{key}(operand) \placeholdernc{op} operand;} +\end{itemdescr} + +\rSec2[atomics.ref.pointer]{Partial specialization for pointers} +\indexlibrary{\idxcode{atomic_ref}}% + +\begin{codeblock} +namespace std { + template struct atomic_ref { + private: + T** ptr; // \expos + public: + using value_type = T*; + using difference_type = ptrdiff_t; + static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic_ref} type's operations are always lock free}@; + static constexpr size_t required_alignment = @\impdefx{required alignment for \tcode{atomic_ref} type's operations}@; + + atomic_ref() = delete; + atomic_ref& operator=(const atomic_ref&) = delete; + + explicit atomic_ref(T*&); + atomic_ref(const atomic_ref&) noexcept; + + T* operator=(T*) const noexcept; + operator T*() const noexcept; + + bool is_lock_free() const noexcept; + void store(T*, memory_order = memory_order_seq_cst) const noexcept; + T* load(memory_order = memory_order_seq_cst) const noexcept; + T* exchange(T*, memory_order = memory_order_seq_cst) const noexcept; + bool compare_exchange_weak(T*&, T*, + memory_order, memory_order) const noexcept; + bool compare_exchange_strong(T*&, T*, + memory_order, memory_order) const noexcept; + bool compare_exchange_weak(T*&, T*, + memory_order = memory_order_seq_cst) const noexcept; + bool compare_exchange_strong(T*&, T*, + memory_order = memory_order_seq_cst) const noexcept; + + T* fetch_add(difference_type, memory_order = memory_order_seq_cst) const noexcept; + T* fetch_sub(difference_type, memory_order = memory_order_seq_cst) const noexcept; + + T* operator++(int) const noexcept; + T* operator--(int) const noexcept; + T* operator++() const noexcept; + T* operator--() const noexcept; + T* operator+=(difference_type) const noexcept; + T* operator-=(difference_type) const noexcept; + }; +} +\end{codeblock} + +\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 identified +in \tref{atomic.pointer.computations}. + +\indexlibrarymember{fetch_add}{atomic_ref}% +\indexlibrarymember{fetch_sub}{atomic_ref}% +\begin{itemdecl} +T* fetch_@\placeholdernc{key}@(difference_type operand, memory_order order = memory_order_seq_cst) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{T} shall be an object type, +otherwise the program is ill-formed. + +\pnum +\effects Atomically replaces the value referenced by \tcode{*ptr} with +the result of the computation applied to the value referenced by \tcode{*ptr} +and the given operand. +Memory is affected according to the value of \tcode{order}. +These operations are atomic read-modify-write operations\iref{intro.races}. + +\pnum +\returns Atomically, the value referenced by \tcode{*ptr} +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_ref}% +\indexlibrarymember{operator-=}{atomic_ref}% +\begin{itemdecl} +T* operator @\placeholder{op}@=(difference_type operand) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: +\tcode{return fetch_\placeholder{key}(operand) \placeholdernc{op} operand;} +\end{itemdescr} + +\rSec2[atomics.ref.memop]{Member operators + common to integers and pointers to objects} + +\indexlibrarymember{operator++}{atomic_ref}% +\indexlibrarymember{operator++}{atomic_ref<\placeholder{integral}>}% +\begin{itemdecl} +T* operator++(int) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return fetch_add(1);} +\end{itemdescr} + +\indexlibrarymember{operator\dcr}{atomic_ref}% +\indexlibrarymember{operator\dcr}{atomic_ref<\placeholder{integral}>}% +\begin{itemdecl} +T* operator--(int) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return fetch_sub(1);} +\end{itemdescr} + +\indexlibrarymember{operator++}{atomic_ref}% +\indexlibrarymember{operator++}{atomic_ref<\placeholder{integral}>}% +\begin{itemdecl} +T* operator++() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return fetch_add(1) + 1;} +\end{itemdescr} + +\indexlibrarymember{operator\dcr}{atomic_ref}% +\indexlibrarymember{operator\dcr}{atomic_ref<\placeholder{integral}>}% +\begin{itemdecl} +T* operator--(int) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to: \tcode{return fetch_sub(1) - 1;} +\end{itemdescr} + \rSec1[atomics.types.generic]{Class template \tcode{atomic}} \indexlibrary{\idxcode{atomic}}% @@ -849,10 +1576,11 @@ \tcode{memory_order::acq_rel}. \pnum -\effects Retrieves the value in \tcode{expected}. It then atomically -compares the contents of the memory pointed to by \tcode{this} +\effects +Retrieves the value in \tcode{expected}. It then atomically +compares the value representation of the value 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 +and if true, replaces the value pointed to 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 @@ -863,8 +1591,8 @@ \tcode{memory_order::release} shall be replaced by the value \tcode{memory_order::relaxed}. If and only if the comparison is false then, after the atomic operation, -the contents of the memory in \tcode{expected} are replaced by the value -read from the memory pointed to by \tcode{this} during the atomic comparison. +the value in \tcode{expected} is replaced by the value +pointed to by \tcode{this} during the atomic comparison. If the operation returns \tcode{true}, these operations are atomic read-modify-write operations\iref{intro.multithread} on the memory @@ -875,8 +1603,10 @@ \returns The result of the comparison. \pnum -\begin{note} For example, the effect of -\tcode{compare_exchange_strong} is +\begin{note} +For example, the effect of +\tcode{compare_exchange_strong} +on objects without padding bits\iref{basic.types} is \begin{codeblock} if (memcmp(this, &expected, sizeof(*this)) == 0) memcpy(this, &desired, sizeof(*this)); @@ -928,14 +1658,54 @@ \end{note} \pnum -\begin{note} The \tcode{memcpy} and \tcode{memcmp} semantics of the compare-and-exchange -operations may result in failed comparisons for values that compare equal with -\tcode{operator==} if the underlying type has padding bits, trap bits, or alternate +\begin{note} +Under cases where the \tcode{memcpy} and \tcode{memcmp} semantics of the compare-and-exchange +operations apply, the outcome might be failed comparisons for values that compare equal with +\tcode{operator==} if the value representation has trap bits or alternate representations of the same value. Notably, on implementations conforming to ISO/IEC/IEEE 60559, floating-point \tcode{-0.0} and \tcode{+0.0} will not compare equal with \tcode{memcmp} but will compare equal with \tcode{operator==}, and NaNs with the same payload will compare equal with \tcode{memcmp} but will not -compare equal with \tcode{operator==}.\end{note} +compare equal with \tcode{operator==}. +\end{note} +\begin{note} +Because compare-and-exchange acts on an object's value representation, +padding bits that never participate in the object's value representation +are ignored. As a consequence, the following code is guaranteed to avoid +spurious failure: +\begin{codeblock} +struct padded { + char clank = 0x42; + // Padding here. + unsigned biff = 0xC0DEFEFE; +}; +atomic pad = ATOMIC_VAR_INIT({}); + +bool zap() { + padded expected, desired{0, 0}; + return pad.compare_exchange_strong(expected, desired); +} +\end{codeblock} +\end{note} +\begin{note} +For a union with bits that participate in the value representation +of some members but not others, compare-and-exchange might always fail. +This is because such padding bits have an indeteminate value when they +do not participate in the value representation of the active member. +As a consequence, the following code is not guaranteed to ever succeed: +\begin{codeblock} +union pony { + double celestia = 0.; + short luna; // padded +}; +atomic princesses = ATOMIC_VAR_INIT({}); + +bool party(pony desired) { + pony expected; + return princesses.compare_exchange_strong(expected, desired); +} +\end{codeblock} +\end{note} \end{itemdescr} \rSec2[atomics.types.int]{Specializations for integers} @@ -943,7 +1713,7 @@ \indexlibrary{\idxcode{atomic<\placeholder{integral}>}}% \pnum There are specializations of the \tcode{atomic} -template for the integral types +class template for the integral types \tcode{char}, \tcode{signed char}, \tcode{unsigned char}, @@ -959,7 +1729,7 @@ \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 +For each such 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}. @@ -1135,11 +1905,11 @@ \indexlibrary{\idxcode{atomic<\placeholder{floating-point}>}}% \pnum There are specializations of the \tcode{atomic} -template for the floating-point types +class template for the floating-point types \tcode{float}, \tcode{double}, and \tcode{long double}. -For each such floating-point type \tcode{\placeholdernc{floating-point}}, +For each such type \tcode{\placeholdernc{floating-point}}, the specialization \tcode{atomic<\placeholder{floating-point}>} provides additional atomic operations appropriate to floating-point types. diff --git a/source/basic.tex b/source/basic.tex index d51914e242..845de84588 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -217,10 +217,8 @@ \indextext{implementation-generated}% In some circumstances, \Cpp{} implementations implicitly define the default constructor\iref{class.ctor}, -copy constructor\iref{class.copy}, -move constructor\iref{class.copy}, -copy assignment operator\iref{class.copy}, -move assignment operator\iref{class.copy}, +copy constructor, move constructor\iref{class.copy.ctor}, +copy assignment operator, move assignment operator\iref{class.copy.assign}, or destructor\iref{class.dtor} member functions. \end{note} \begin{example} Given @@ -262,8 +260,11 @@ \pnum \indextext{type!incomplete}% -A program is ill-formed if the definition of any object gives the object -an incomplete type\iref{basic.types}. +In the definition of an object, +the type of that object shall not be +an incomplete type\iref{basic.types}, +an abstract class type\iref{class.abstract}, or +a (possibly multi-dimensional) array thereof. \indextext{object!definition}% \indextext{function!definition}% @@ -341,7 +342,7 @@ non-default initialization\iref{dcl.init}. A constructor selected to copy or move an object of class type is considered to be named by an expression - even if the call is actually elided by the implementation\iref{class.copy}. \end{note} + even if the call is actually elided by the implementation\iref{class.copy.elision}. \end{note} \item An allocation or deallocation function for a class is named by a \grammarterm{new-expression} @@ -389,7 +390,7 @@ An assignment operator function in a class is odr-used by an implicitly-defined copy-assignment or move-assignment function for another class as specified -in~\ref{class.copy}. +in~\ref{class.copy.assign}. A constructor for a class is odr-used as specified in~\ref{dcl.init}. A destructor for a class is odr-used if it is potentially invoked\iref{class.dtor}. @@ -439,8 +440,9 @@ outside of a discarded statement\iref{stmt.if}; no diagnostic required. The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is -implicitly defined (see~\ref{class.ctor}, \ref{class.dtor} and -\ref{class.copy}). An inline function or variable shall be defined in every +implicitly defined (see~\ref{class.ctor}, \ref{class.dtor}, +\ref{class.copy.ctor}, and \ref{class.copy.assign}). +An inline function or variable shall be defined in every translation unit in which it is odr-used outside of a discarded statement. \pnum @@ -550,6 +552,14 @@ requirement applies recursively)\footnote{\ref{dcl.fct.default} describes how default argument names are looked up.}; and +\item if \tcode{D} invokes a function with a precondition, +or is a function +that contains an assertion or has a contract condition\iref{dcl.attr.contract}, +it is \impldef{consistency of build level and violation continuation mode} +under which conditions all definitions of \tcode{D} +shall be translated using the same build level +and violation continuation mode; and + \item if \tcode{D} is a class with an implicitly-declared constructor\iref{class.ctor}, it is as if the constructor was implicitly defined in every translation unit where it is odr-used, and the @@ -614,7 +624,7 @@ \indextext{region!declarative}% \indextext{scope!potential}% \defn{declarative region}, which is the largest part of the program -in which that name is \defn{valid}, that is, in which that name may +in which that name is valid, that is, in which that name may be used as an unqualified name to refer to the same entity. In general, each particular name is valid only within some possibly discontiguous portion of program text called its \defn{scope}. To determine the @@ -808,9 +818,14 @@ \pnum The point of declaration for a function-local predefined -variable\iref{dcl.fct.def} is immediately before the +variable\iref{dcl.fct.def.general} is immediately before the \grammarterm{function-body} of a function definition. +\pnum +The point of declaration of a structured binding\iref{dcl.struct.bind} +is immediately after +the \grammarterm{identifier-list} of the structured binding declaration. + \pnum The point of declaration for the variable or the structured bindings declared in the \grammarterm{for-range-declaration} @@ -975,11 +990,8 @@ \pnum The potential scope of a name declared in a class consists not 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 -default member initializers\iref{class.mem} -in that class (including such -things in nested classes). +declaration, but also of all complete-class contexts\iref{class.mem} +of that class. \pnum A name \tcode{N} used in a class \tcode{S} shall refer to the same @@ -1319,12 +1331,12 @@ \end{example} \pnum -A name used in the definition of a class \tcode{X} outside of a member -function body, default argument, \grammarterm{noexcept-specifier}, -default member initializer\iref{class.mem}, -or nested class definition\footnote{This refers to unqualified names -following the class name; such a name may be used in the -\grammarterm{base-clause} or may be used in the class definition.} +A name used in the definition of a class \tcode{X}% +\footnote{This +refers to unqualified names following the class name; +such a name may be used in a \grammarterm{base-specifier} or +in the \grammarterm{member-specification} of the class definition.} +outside of a complete-class context\iref{class.mem} of \tcode{X} shall be declared in one of the following ways: \begin{itemize} \item before its use in class \tcode{X} or be a member of a base class @@ -1385,11 +1397,10 @@ \end{note} \pnum -For the members of a class \tcode{X}, a name used in a member function -body, in a default argument, in a \grammarterm{noexcept-specifier}, in a -default member initializer\iref{class.mem}, or in the definition of a class member -outside of the definition of \tcode{X}, following the -member's +For the members of a class \tcode{X}, a name used +in a complete-class context\iref{class.mem} of \tcode{X} or +in the definition of a class member outside of the definition of \tcode{X}, +following the member's \grammarterm{declarator-id}\footnote{That is, an unqualified name that occurs, for instance, in a type in the @@ -3139,7 +3150,7 @@ If a variable with static storage duration has initialization or a destructor with side effects, it shall not be eliminated even if it appears to be unused, except that a class object or its copy/move may be -eliminated as specified in~\ref{class.copy}. +eliminated as specified in~\ref{class.copy.elision}. \pnum \indextext{object!local static@local \tcode{static}}% @@ -3187,7 +3198,7 @@ effects, an implementation shall not destroy it before the end of its block nor eliminate it as an optimization, even if it appears to be unused, except that a class object or its copy/move may be eliminated as -specified in~\ref{class.copy}. +specified in~\ref{class.copy.elision}. \rSec3[basic.stc.dynamic]{Dynamic storage duration}% \indextext{storage duration!dynamic|(} @@ -3352,36 +3363,47 @@ declared in a namespace scope other than global scope or declared static in global scope. +\pnum +A deallocation function +is a \defn{destroying operator delete} +if it has at least two parameters +and its second parameter +is of type \tcode{std::destroying_delete_t}. +A destroying operator delete +shall be a class member function named \tcode{operator delete}. +\begin{note} +Array deletion cannot use a destroying operator delete. +\end{note} + \pnum \indextext{\idxcode{delete}!overloading and}% -Each deallocation function shall return \tcode{void} and its first +Each deallocation function shall return \tcode{void}. +If the function is a destroying operator delete +declared in class type \tcode{C}, +the type of its first parameter shall be \tcode{C*}; +otherwise, the type of its first parameter shall be \tcode{void*}. A deallocation function may have more than one parameter. \indextext{deallocation function!usual}% -A \defn{usual deallocation function} is a deallocation function that has: +A \defn{usual deallocation function} is a deallocation function +whose parameters after the first are \begin{itemize} \item -exactly one parameter; or +optionally, a parameter of type \tcode{std::destroying_delete_t}, then \item -exactly two parameters, -the type of the second being either -\tcode{std::align_val_t} or -\tcode{std::size_t}% +optionally, a parameter of type \tcode{std::size_t}% \footnote{The global \tcode{operator delete(void*, std::size_t)} precludes use of an allocation function \tcode{void operator new(std::size_t, std::size_t)} as a placement -allocation function~(\ref{diff.cpp11.basic}).}; or +allocation function~(\ref{diff.cpp11.basic}).}, then \item -exactly three parameters, -the type of the second being \tcode{std::size_t} -and -the type of the third being \tcode{std::align_val_t}. +optionally, a parameter of type \tcode{std::align_val_t}. \end{itemize} +A destroying operator delete shall be a usual deallocation function. A deallocation function may be an instance of a function template. Neither the first parameter nor the return type shall depend -on a template parameter. \begin{note} That is, a deallocation function -template shall have a first parameter of type \tcode{void*} and a return -type of \tcode{void} (as specified above). \end{note} A deallocation +on a template parameter. +A deallocation function template shall have two or more function parameters. A template instance is never a usual deallocation function, regardless of its signature. @@ -3584,6 +3606,369 @@ If a request for a specific extended alignment in a specific context is not supported by an implementation, the program is ill-formed. +\rSec2[class.temporary]{Temporary objects} + +\pnum +\indextext{object temporary|see{temporary}}% +\indextext{temporary}% +\indextext{optimization of temporary|see{temporary, elimination of}}% +\indextext{temporary!elimination of}% +\indextext{temporary!implementation-defined generation of}% +Temporary objects are created +\begin{itemize} +\item +when a prvalue is materialized so that it can be used as a glvalue\iref{conv.rval}, +\item +when needed by the implementation to pass or return an object of trivially-copyable type (see below), +and +\item +when throwing an exception\iref{except.throw}. +\begin{note} +The lifetime of exception objects is described in~\ref{except.throw}. +\end{note} +\end{itemize} +Even when the creation of the temporary object is +unevaluated\iref{expr.prop}, +all the semantic restrictions shall be respected as if the temporary object +had been created and later destroyed. +\begin{note} +This includes accessibility\iref{class.access} and whether it is deleted, +for the constructor selected and for the destructor. However, in the special +case of the operand of a +\grammarterm{decltype-specifier}\iref{expr.call}, no temporary is introduced, +so the foregoing does not apply to such a prvalue. +\end{note} + +\pnum +The materialization of a temporary object is generally +delayed as long as possible +in order to avoid creating unnecessary temporary objects. +\begin{note} +Temporary objects are materialized: +\begin{itemize} +\item +when binding a reference to a prvalue~(\ref{dcl.init.ref}, \ref{expr.type.conv}, +\ref{expr.dynamic.cast}, \ref{expr.static.cast}, \ref{expr.const.cast}, \ref{expr.cast}), +\item +when performing member access on a class prvalue~(\ref{expr.ref}, \ref{expr.mptr.oper}), +\item +when performing an array-to-pointer conversion or subscripting on an array prvalue~(\ref{conv.array}, \ref{expr.sub}), +\item +when initializing an object of type \tcode{std::initializer_list} from a \grammarterm{braced-init-list}\iref{dcl.init.list}, +\item +for certain unevaluated operands~(\ref{expr.typeid}, \ref{expr.sizeof}), and +\item +when a prvalue appears as a discarded-value expression\iref{expr.prop}. +\end{itemize} +\end{note} +\begin{example} Consider the following code: +\begin{codeblock} +class X { +public: + X(int); + X(const X&); + X& operator=(const X&); + ~X(); +}; + +class Y { +public: + Y(int); + Y(Y&&); + ~Y(); +}; + +X f(X); +Y g(Y); + +void h() { + X a(1); + X b = f(X(2)); + Y c = g(Y(3)); + a = f(a); +} +\end{codeblock} + +\indextext{class object copy|see{constructor, copy}}% +\indextext{constructor!copy}% +\tcode{X(2)} is constructed in the space used to hold \tcode{f()}'s argument and +\tcode{Y(3)} is constructed in the space used to hold \tcode{g()}'s argument. +Likewise, +\tcode{f()}'s result is constructed directly in \tcode{b} and +\tcode{g()}'s result is constructed directly in \tcode{c}. +On the other hand, the expression +\tcode{a = f(a)} +requires a temporary for +the result of \tcode{f(a)}, +which is materialized so that the reference parameter +of \tcode{A::operator=(const A\&)} can bind to it. +\end{example} + +\pnum +When an object of class type \tcode{X} +is passed to or returned from a function, +if each copy constructor, move constructor, and destructor of \tcode{X} +is either trivial or deleted, +and \tcode{X} +has at least one non-deleted copy or move constructor, +implementations are permitted +to create a temporary object +to hold the function parameter or result object. +The temporary object is constructed +from the function argument or return value, respectively, +and the function's parameter or return object +is initialized as if by +using the non-deleted trivial constructor to copy the temporary +(even if that constructor is inaccessible +or would not be selected by overload resolution +to perform a copy or move of the object). +\begin{note} +This latitude is granted to allow objects of class type to be passed to or returned from functions in registers. +\end{note} + +\pnum +\indextext{temporary!constructor for}% +\indextext{temporary!destructor for}% +\indextext{temporary!destruction of}% +When an implementation introduces a temporary object of a class that has a +non-trivial constructor~(\ref{class.ctor}, \ref{class.copy.ctor}), +it shall ensure that a constructor is called for the temporary object. +Similarly, the destructor shall be called for a temporary with a non-trivial +destructor\iref{class.dtor}. +Temporary objects are destroyed as the last step +in evaluating +the full-expression\iref{intro.execution} +that (lexically) contains the point where +they were created. +This is true even if that evaluation ends in throwing an exception. +The +\indextext{value computation}% +value computations and +\indextext{side effects}% +side effects of destroying a temporary object +are associated only with the full-expression, not with any specific +subexpression. + +\pnum +\indextext{initializer!temporary and declarator}% +\indextext{temporary!order of destruction of}% +There are three contexts in which temporaries are destroyed at a different +point than the end of the full-expression. +The first context is when a default constructor is called to initialize +an element of an array with no corresponding initializer\iref{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.capture}, \ref{class.copy.ctor}). +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. + +\pnum +The third context is when a reference is bound to a +temporary object.\footnote{The same rules apply to initialization of an + \tcode{initializer_list} object\iref{dcl.init.list} with its + underlying temporary array.} +The temporary object to which the reference is bound or the temporary object +that is the complete object of a subobject to which the reference is bound +persists for the lifetime of the reference if the glvalue +to which the reference is bound +was obtained through one of the following: +\begin{itemize} +\item + a temporary materialization conversion\iref{conv.rval}, +\item + \tcode{(} \grammarterm{expression} \tcode{)}, + where \grammarterm{expression} is one of these expressions, +\item + subscripting\iref{expr.sub} of an array operand, + where that operand is one of these expressions, +\item + a class member access\iref{expr.ref} using the \tcode{.} operator + where the left operand is one of these expressions and + the right operand designates a non-static data member of non-reference type, +\item + a pointer-to-member operation\iref{expr.mptr.oper} using the \tcode{.*} operator + where the left operand is one of these expressions and + the right operand is a pointer to data member of non-reference type, +\item + a + \begin{itemize} + \item \tcode{const_cast}\iref{expr.const.cast}, + \item \tcode{static_cast}\iref{expr.static.cast}, + \item \tcode{dynamic_cast}\iref{expr.dynamic.cast}, or + \item \tcode{reinterpret_cast}\iref{expr.reinterpret.cast} + \end{itemize} + converting, without a user-defined conversion, + a glvalue operand that is one of these expressions + to a glvalue that refers + to the object designated by the operand, or + to its complete object or a subobject thereof, +\item + a conditional expression\iref{expr.cond} that is a glvalue + where the second or third operand is one of these expressions, or +\item + a comma expression\iref{expr.comma} that is a glvalue + where the right operand is one of these expressions. +\end{itemize} +\begin{example} +\begin{codeblock} +template using id = T; + +int i = 1; +int&& a = id{1, 2, 3}[i]; // temporary array has same lifetime as \tcode{a} +const int& b = static_cast(0); // temporary \tcode{int} has same lifetime as \tcode{b} +int&& c = cond ? id{1, 2, 3}[i] : static_cast(0); + // exactly one of the two temporaries is lifetime-extended +\end{codeblock} +\end{example} +\begin{note} +An explicit type conversion~(\ref{expr.type.conv}, \ref{expr.cast}) +is interpreted as +a sequence of elementary casts, +covered above. +\begin{example} +\begin{codeblock} +const int& x = (const int&)1; // temporary for value 1 has same lifetime as x +\end{codeblock} +\end{example} +\end{note} +\begin{note} +If a temporary object has a reference member initialized by another temporary object, +lifetime extension applies recursively to such a member's initializer. +\begin{example} +\begin{codeblock} +struct S { + const int& m; +}; +const S& s = S{1}; // both \tcode{S} and \tcode{int} temporaries have lifetime of \tcode{s} +\end{codeblock} +\end{example} +\end{note} + +The exceptions to this lifetime rule are: +\begin{itemize} +\item A temporary object bound to a reference parameter in a function call\iref{expr.call} +persists until the completion of the full-expression containing the call. + +\item The lifetime of a temporary bound to the returned value in a function \tcode{return} statement\iref{stmt.return} is not extended; the temporary is destroyed at the end of the full-expression in the \tcode{return} statement. + +\item A temporary bound to a reference in a \grammarterm{new-initializer}\iref{expr.new} persists until the completion of the full-expression containing the \grammarterm{new-initializer}. +\begin{note} This may introduce a dangling reference. \end{note} +\begin{example} +\begin{codeblock} +struct S { int mi; const std::pair& mp; }; +S a { 1, {2,3} }; +S* p = new S{ 1, {2,3} }; // creates dangling reference +\end{codeblock} +\end{example} +\end{itemize} + +\pnum +The destruction of a temporary whose lifetime is not extended by being +bound to a reference is sequenced before the destruction of every +temporary which is constructed earlier in the same full-expression. +If the lifetime of two or more temporaries to which references are bound ends +at the same point, +these temporaries are destroyed at that point in the reverse order of the +completion of their construction. +In addition, the destruction of temporaries bound to references shall +take into account the ordering of destruction of objects with static, thread, or +automatic storage duration~(\ref{basic.stc.static}, \ref{basic.stc.thread}, \ref{basic.stc.auto}); +that is, if +\tcode{obj1} +is an object with the same storage duration as the temporary and +created before the temporary is created +the temporary shall be destroyed before +\tcode{obj1} +is destroyed; +if +\tcode{obj2} +is an object with the same storage duration as the temporary and +created after the temporary is created +the temporary shall be destroyed after +\tcode{obj2} +is destroyed. + +\pnum +\begin{example} +\begin{codeblock} +struct S { + S(); + S(int); + friend S operator+(const S&, const S&); + ~S(); +}; +S obj1; +const S& cr = S(16)+S(23); +S obj2; +\end{codeblock} + +The expression +\tcode{S(16) + S(23)} +creates three temporaries: +a first temporary +\tcode{T1} +to hold the result of the expression +\tcode{S(16)}, +a second temporary +\tcode{T2} +to hold the result of the expression +\tcode{S(23)}, +and a third temporary +\tcode{T3} +to hold the result of the addition of these two expressions. +The temporary +\tcode{T3} +is then bound to the reference +\tcode{cr}. +It is unspecified whether +\tcode{T1} +or +\tcode{T2} +is created first. +On an implementation where +\tcode{T1} +is created before +\tcode{T2}, +\tcode{T2} +shall be destroyed before +\tcode{T1}. +The temporaries +\tcode{T1} +and +\tcode{T2} +are bound to the reference parameters of +\tcode{operator+}; +these temporaries are destroyed at the end of the full-expression +containing the call to +\tcode{operator+}. +The temporary +\tcode{T3} +bound to the reference +\tcode{cr} +is destroyed at the end of +\tcode{cr}'s +lifetime, that is, at the end of the program. +In addition, the order in which +\tcode{T3} +is destroyed takes into account the destruction order of other objects with +static storage duration. +That is, because +\tcode{obj1} +is constructed before +\tcode{T3}, +and +\tcode{T3} +is constructed before +\tcode{obj2}, +\tcode{obj2} +shall be destroyed before +\tcode{T3}, +and +\tcode{T3} +shall be destroyed before +\tcode{obj1}. +\end{example} + \rSec1[basic.types]{Types}% \indextext{type|(} @@ -3728,17 +4113,19 @@ a function type, not a reference type, and not \cv{}~\tcode{void}. \pnum -Arithmetic types\iref{basic.fundamental}, enumeration types, pointer -types, pointer-to-member types\iref{basic.compound}, +\indextext{class!trivial}% +\indextext{class!trivially copyable}% +\indextext{class!standard-layout}% +Arithmetic types\iref{basic.fundamental}, enumeration types, +pointer types, pointer-to-member types\iref{basic.compound}, \tcode{std::nullptr_t}, and cv-qualified\iref{basic.type.qualifier} versions of these types are collectively called \defnx{scalar types}{scalar type}. -Cv-unqualified scalar types, trivially copyable class types\iref{class}, arrays of -such types, and cv-qualified versions of these -types are collectively called \defn{trivially -copyable types}. +Cv-unqualified scalar types, trivially copyable class types\iref{class}, +arrays of such types, and cv-qualified versions of these +types are collectively called \defn{trivially copyable types}. Scalar types, trivial class types\iref{class}, arrays of such types and cv-qualified versions of these types are collectively called @@ -3789,7 +4176,6 @@ \rSec2[basic.fundamental]{Fundamental types} \pnum -\indextext{type!fundamental}% \indextext{type!integral}% \indextext{floating-point type|see{type, floating-point}}% \indextext{type!implementation-defined \tcode{sizeof}}% @@ -4019,8 +4405,11 @@ \tcode{sizeof(std::nullptr_t)} shall be equal to \tcode{sizeof(void*)}. \pnum +\indextext{type!fundamental}% +The types described in this subclause +are called \defnx{fundamental types}{fundamental type}. \begin{note} -Even if the implementation defines two or more basic types to have the +Even if the implementation defines two or more fundamental types to have the same value representation, they are nevertheless different types. \end{note} @@ -4156,7 +4545,7 @@ one is a standard-layout class object and the other is the first non-static data member of that object, or, if the object has no non-static data members, -the first base class subobject of that object\iref{class.mem}, or +any base class subobject of that object\iref{class.mem}, or \item there exists an object \placeholder{c} such that \placeholder{a} and \placeholder{c} are pointer-interconvertible, and @@ -5485,9 +5874,10 @@ in which threads and at which points in the program such deferred dynamic initialization occurs. \pnum -If the initialization of a non-local variable with static or thread storage duration -exits via -an exception, \tcode{std::terminate} is called\iref{except.terminate}.% +If the initialization of +a non-local variable with static or thread storage duration +exits via an exception, +the function \tcode{std::terminate} is called\iref{except.terminate}.% \indextext{program!start|)} \rSec3[basic.start.term]{Termination} @@ -5533,7 +5923,7 @@ of the subobjects is destroyed. If the destruction of an object with static or thread storage duration exits via an exception, -\tcode{std::terminate} is called\iref{except.terminate}. +the function \tcode{std::terminate} is called\iref{except.terminate}. \pnum If a function contains a block-scope object of static or thread storage duration that has been diff --git a/source/classes.tex b/source/classes.tex index bb143e6f8f..af6e193cdc 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -80,6 +80,20 @@ the \grammarterm{attribute-specifier-seq} are thereafter considered attributes of the class whenever it is named. +\pnum +If a \grammarterm{class-head-name} contains a \grammarterm{nested-name-specifier}, +the \grammarterm{class-specifier} shall refer to a class that was +previously declared directly in the class or namespace to which the +\grammarterm{nested-name-specifier} refers, +or in an element of the inline namespace set\iref{namespace.def} of that namespace +(i.e., not merely inherited or +introduced by a \grammarterm{using-declaration}), and the +\grammarterm{class-specifier} shall appear in a namespace enclosing the +previous declaration. +In such cases, the \grammarterm{nested-name-specifier} of the +\grammarterm{class-head-name} of the +definition shall not begin with a \grammarterm{decltype-specifier}. + \pnum If a class is marked with the \grammarterm{class-virt-specifier} \tcode{final} and it appears as a \grammarterm{class-or-decltype} in a \grammarterm{base-clause}\iref{class.derived}, @@ -110,47 +124,46 @@ \pnum \begin{note} -Class objects can be assigned, passed as arguments to functions, and +Class objects can be assigned~(\ref{expr.ass}, \ref{over.ass}, \ref{class.copy.assign}), +passed as arguments to functions~(\ref{dcl.init}, \ref{class.copy.ctor}), and returned by functions (except objects of classes for which copying or moving has -been restricted; see~\ref{class.copy}). Other plausible operators, such -as equality comparison, can be defined by the user; see~\ref{over.oper}. +been restricted; see~\ref{dcl.fct.def.delete} and \ref{class.access}). +Other plausible operators, such as equality comparison, +can be defined by the user; see~\ref{over.oper}. \end{note} \pnum -\indextext{\idxcode{struct}!\tcode{class} versus}% -\indextext{structure}% -\indextext{\idxcode{union}!\tcode{class} versus}% A \defn{union} is a class defined with the \grammarterm{class-key} \tcode{union}; -\indextext{access control!\idxcode{union} default member}% it holds at most one data member at a time\iref{class.union}. \begin{note} Aggregates of class type are described in~\ref{dcl.init.aggr}. \end{note} -\indextext{trivial class|see{class, trivial}}% +\rSec1[class.prop]{Properties of classes} + \pnum -A \defnx{trivially copyable class}{class!trivially copyable} is a class: +A \defnadj{trivially copyable}{class} is a class: \begin{itemize} \item where each copy constructor, move constructor, copy assignment operator, -and move assignment operator~(\ref{class.copy}, \ref{over.ass}) +and move assignment operator~(\ref{class.copy.ctor}, \ref{class.copy.assign}) is either deleted or trivial, \item that has at least one non-deleted copy constructor, move constructor, copy assignment operator, or move assignment operator, and \item that has a trivial, non-deleted destructor\iref{class.dtor}. \end{itemize} -A \defnx{trivial class}{class!trivial} is a class that is trivially copyable and +\pnum +A \defnadj{trivial}{class} is a class that is trivially copyable and has one or more default constructors\iref{class.ctor}, all of which are either trivial or deleted and at least one of which is not deleted. \begin{note} In particular, a trivially copyable or trivial class does not have virtual functions or virtual base classes.\end{note} -\indextext{standard-layout|see{class, standard-layout}}% \pnum -A class \tcode{S} is a \defnx{standard-layout class}{class!standard-layout} if it: +A class \tcode{S} is a \defnadj{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, @@ -168,14 +181,15 @@ \item has all non-static data members and bit-fields in the class and its base classes first declared in the same class, and -\item has no element of the set $M(\mathtt{S})$ of types (defined below) -as a base class.\footnote{This ensures that two subobjects that have the -same class type and that +\item has no element of the set $M(\mathtt{S})$ of types +as a base class, +where for any type \tcode{X}, $M(\mathtt{X})$ is defined as follows.\footnote{ +This ensures that two subobjects that have the same class type and that belong to the same most derived object are not allocated at the same address\iref{expr.eq}.} -\end{itemize} +\begin{note} $M(\mathtt{X})$ is the set of the types of all non-base-class subobjects +that may be at a zero offset in \tcode{X}. \end{note} -$M(\mathtt{X})$ is defined as follows: \begin{itemize} \item If \tcode{X} is a non-union class type with no (possibly inherited\iref{class.derived}) non-static data members, the set @@ -191,7 +205,7 @@ \item If \tcode{X} is a union type, the set $M(\mathtt{X})$ is the union of all $M(\mathtt{U}_i)$ and the set containing all $\mathtt{U}_i$, -where each $\mathtt{U}_i$ is the type of the $i$th non-static data member +where each $\mathtt{U}_i$ is the type of the $i^\text{th}$ non-static data member of \tcode{X}. \item If \tcode{X} is an array type with element type $\mathtt{X}_e$, @@ -200,10 +214,9 @@ \item If \tcode{X} is a non-class, non-array type, the set $M(\mathtt{X})$ is empty. \end{itemize} +\end{itemize} -\begin{note} $M(\mathtt{X})$ is the set of the types of all non-base-class subobjects -that may be at a zero offset in \tcode{X}. \end{note} - +\pnum \begin{example} \begin{codeblock} struct B { int i; }; // standard-layout class @@ -259,20 +272,6 @@ \end{codeblock} \end{example} -\pnum -If a \grammarterm{class-head-name} contains a \grammarterm{nested-name-specifier}, -the \grammarterm{class-specifier} shall refer to a class that was -previously declared directly in the class or namespace to which the -\grammarterm{nested-name-specifier} refers, -or in an element of the inline namespace set\iref{namespace.def} of that namespace -(i.e., not merely inherited or -introduced by a \grammarterm{using-declaration}), and the -\grammarterm{class-specifier} shall appear in a namespace enclosing the -previous declaration. -In such cases, the \grammarterm{nested-name-specifier} of the -\grammarterm{class-head-name} of the -definition shall not begin with a \grammarterm{decltype-specifier}. - \rSec1[class.name]{Class names} \indextext{definition!class name as type}% \indextext{structure tag|see{class name}}% @@ -561,16 +560,27 @@ \pnum \indextext{completely defined}% +A \defn{complete-class context} of a class is a +\begin{itemize} +\item function body\iref{dcl.fct.def.general}, +\item default argument\iref{dcl.fct.default}, +\item \grammarterm{noexcept-specifier}\iref{except.spec}, +\item contract condition\iref{dcl.attr.contract}, or +\item default member initializer +\end{itemize} +within the \grammarterm{member-specification} of the class. +\begin{note} +A complete-class context of a nested class is also a complete-class +context of any enclosing class, if the nested class is defined within +the \grammarterm{member-specification} of the enclosing class. +\end{note} + +\pnum A class is considered a completely-defined object type\iref{basic.types} (or complete type) at the closing \tcode{\}} of the \grammarterm{class-specifier}. -Within the class -\grammarterm{member-specification}, the class is regarded as complete -within function bodies, default arguments, -\grammarterm{noexcept-specifier}{s}, and -default member initializers -(including such things in nested classes). -Otherwise it is regarded as incomplete within its own class +The class is regarded as complete within its complete-class contexts; +otherwise it is regarded as incomplete within its own class \grammarterm{member-specification}. \pnum @@ -653,10 +663,15 @@ \pnum \indextext{class object!member}% -Non-static data members shall not have -incomplete types. In particular, a class \tcode{C} shall not contain a -non-static member of class \tcode{C}, but it can contain a pointer or -reference to an object of class \tcode{C}. +The type of a non-static data member shall not be an +incomplete type\iref{basic.types}, +an abstract class type\iref{class.abstract}, +or a (possibly multi-dimensional) array thereof. +\begin{note} +In particular, a class \tcode{C} cannot contain +a non-static member of class \tcode{C}, +but it can contain a pointer or reference to an object of class \tcode{C}. +\end{note} \pnum \begin{note} @@ -799,16 +814,18 @@ \end{codeblock} \end{example} \begin{note} -Reading a volatile object through a non-volatile glvalue has +Reading a volatile object through a glvalue of non-volatile type has undefined behavior\iref{dcl.type.cv}. \end{note} \pnum If a standard-layout class object has any non-static data members, its address -is the same as the address of its first non-static data member. Otherwise, its -address is the same as the address of its first base class subobject (if any). +is the same as the address of its first non-static data member +if that member is not a bit-field. Its +address is also the same as the address of each of its base class subobjects. \begin{note} -There might therefore be unnamed padding within a standard-layout struct object, but +There might therefore be unnamed padding within a standard-layout struct object +inserted by an implementation, but not at its beginning, as necessary to achieve appropriate alignment. \end{note} \begin{note} @@ -1045,7 +1062,7 @@ \pnum \indextext{this pointer@\tcode{this} pointer|see{\tcode{this}}}% In the body of a non-static\iref{class.mfct} member function, the -keyword \tcode{this} is a prvalue expression whose value is the +keyword \tcode{this} is a prvalue whose value is the address of the object for which the function is called. \indextext{\idxcode{this}!type of}% The type of \tcode{this} in a member function of a class \tcode{X} is @@ -1115,183 +1132,1787 @@ see~\ref{class.ctor} and~\ref{class.dtor}. \end{note} -\rSec2[class.static]{Static members}% -\indextext{member!static}% +\rSec2[special]{Special member functions} + +\indextext{\idxcode{X(X\&)}|see{constructor, copy}}% +\indextext{~@\tcode{\~}|see{destructor}}% +\indextext{assignment!copy|see{assignment operator, copy}}% +\indextext{assignment!move|see{assignment operator, move}}% +\indextext{implicitly-declared default constructor|see{constructor, default}} \pnum -A static member \tcode{s} of class \tcode{X} may be referred to -using the \grammarterm{qualified-id} expression \tcode{X::s}; it is not -necessary to use the class member access syntax\iref{expr.ref} to -refer to a static member. A static member may be -referred to using the class member access syntax, in which case the -object expression is evaluated. +\indextext{constructor!default}% +\indextext{constructor!copy}% +\indextext{constructor!move}% +\indextext{assignment operator!copy}% +\indextext{assignment operator!move}% +The default constructor\iref{class.ctor}, +copy constructor, move constructor\iref{class.copy.ctor}, +copy assignment operator, move assignment operator\iref{class.copy.assign}, +and destructor\iref{class.dtor} are +\term{special member functions}. +\begin{note} The implementation will implicitly declare these member functions for some class +types when the program does not explicitly declare them. +The implementation will implicitly define them +if they are odr-used\iref{basic.def.odr} or +needed for constant evaluation\iref{expr.const}. +\end{note} +An implicitly-declared special member function is declared at the closing +\tcode{\}} of the \grammarterm{class-specifier}. +Programs shall not define implicitly-declared special member functions. + +\pnum +Programs may explicitly refer to implicitly-declared special member functions. \begin{example} +A program may explicitly call or form a pointer to member +to an implicitly-declared special member function. \begin{codeblock} -struct process { - static void reschedule(); +struct A { }; // implicitly declared \tcode{A::operator=} +struct B : A { + B& operator=(const B &); }; -process& g(); - -void f() { - process::reschedule(); // OK: no object necessary - g().reschedule(); // \tcode{g()} is called +B& B::operator=(const B& s) { + this->A::operator=(s); // well-formed + return *this; } \end{codeblock} \end{example} \pnum -A static member may be referred to directly in the scope of its -class or in the scope of a class derived\iref{class.derived} -from its class; in this case, the static member is referred to -as if a \grammarterm{qualified-id} expression was used, with the -\grammarterm{nested-name-specifier} of the \grammarterm{qualified-id} naming -the class scope from which the static member is referenced. +\begin{note} +The special member functions affect the way objects of class type are created, +copied, moved, and destroyed, and how values can be converted to values of other types. +Often such special member functions are called implicitly. +\end{note} + +\pnum +\indextext{access control!member function and}% +Special member functions obey the usual access rules\iref{class.access}. +\begin{example} +Declaring a constructor protected +ensures that only derived classes and friends can create objects using it. +\end{example} + +\pnum +For a class, its non-static data members, its non-virtual direct base classes, +and, if the class is not abstract\iref{class.abstract}, its virtual base +classes are called its \term{potentially constructed subobjects}. + +\rSec2[class.ctor]{Constructors}% +\indextext{constructor}% +\indextext{special member function|see{constructor}}% + +\pnum +Constructors do not have names. +In a declaration of a constructor, the \grammarterm{declarator} is a +function declarator\iref{dcl.fct} of the form + +\begin{ncbnf} +ptr-declarator \terminal{(} parameter-declaration-clause \terminal{)} \opt{noexcept-specifier} \opt{attribute-specifier-seq} +\end{ncbnf} + +where the \grammarterm{ptr-declarator} consists solely of an +\grammarterm{id-expression}, an optional \grammarterm{attribute-specifier-seq}, +and optional surrounding parentheses, and the \grammarterm{id-expression} has +one of the following forms: + +\begin{itemize} +\item +in a \grammarterm{member-declaration} that belongs to the +\grammarterm{member-specification} of a class or class template +but is not a friend +declaration\iref{class.friend}, the \grammarterm{id-expression} is the +injected-class-name\iref{class} of the immediately-enclosing entity or + +\item +in a declaration at namespace scope or in a friend declaration, the +\grammarterm{id-expression} is a \grammarterm{qualified-id} that names a +constructor\iref{class.qual}. +\end{itemize} + +The \grammarterm{class-name} shall not be a \grammarterm{typedef-name}. In a constructor +declaration, each \grammarterm{decl-specifier} in the optional +\grammarterm{decl-specifier-seq} shall be \tcode{friend}, \tcode{inline}, +\tcode{constexpr}, or an \grammarterm{explicit-specifier}. \begin{example} \begin{codeblock} -int g(); -struct X { - static int g(); -}; -struct Y : X { - static int i; +struct S { + S(); // declares the constructor }; -int Y::i = g(); // equivalent to \tcode{Y::g();} + +S::S() { } // defines the constructor \end{codeblock} \end{example} \pnum -If an \grammarterm{unqualified-id}\iref{expr.prim.id.unqual} is used in the -definition of a static member following the member's -\grammarterm{declarator-id}, and name lookup\iref{basic.lookup.unqual} -finds that the \grammarterm{unqualified-id} refers to a static -member, enumerator, or nested type of the member's class (or of a base -class of the member's class), the \grammarterm{unqualified-id} is -transformed into a \grammarterm{qualified-id} expression in which the -\grammarterm{nested-name-specifier} names the class scope from which the -member is referenced. +A constructor is used to initialize objects of its class type. +Because constructors do not have names, they are never found during +name lookup; however an explicit type conversion using the functional +notation\iref{expr.type.conv} will cause a constructor to be called to +initialize an object. \begin{note} -See~\ref{expr.prim.id} for restrictions on the use of non-static data -members and non-static member functions. +For initialization of objects of class type see~\ref{class.init}. \end{note} +\pnum +\indextext{\idxcode{const}!constructor and}% +\indextext{\idxcode{volatile}!constructor and}% +A constructor can be invoked for a +\tcode{const}, +\tcode{volatile} +or +\tcode{const} +\tcode{volatile} +object. +\indextext{restriction!constructor}% +\tcode{const} +and +\tcode{volatile} +semantics\iref{dcl.type.cv} are not applied on an object under construction. +They come into effect when the constructor for the +most derived object\iref{intro.object} ends. + +\pnum +\indextext{constructor!inheritance of}% +\indextext{constructor!non-trivial}% +A +\defnx{default}{constructor!default} +constructor for a class +\tcode{X} +is a constructor of class +\tcode{X} +for which +each parameter +that is not a function parameter pack +has a default argument +(including the case of a constructor with no parameters). +\indextext{implicitly-declared default constructor}% +If there is no user-declared constructor for class +\tcode{X}, +a non-explicit constructor having no parameters is implicitly declared +as defaulted\iref{dcl.fct.def}. +An implicitly-declared default constructor is an +inline public member of its class. \pnum -Static members obey the usual class member access rules\iref{class.access}. -When used in the declaration of a class -member, the \tcode{static} specifier shall only be used in the member -declarations that appear within the \grammarterm{member-specification} of -the class definition. +A defaulted default constructor for class \tcode{X} is defined as deleted if: + +\begin{itemize} +\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} +has a default member initializer, + +\item any non-static data member with no default member initializer\iref{class.mem} is +of reference type, + +\item any non-variant non-static data member of const-qualified type (or array +thereof) with no \grammarterm{brace-or-equal-initializer} does not have a user-provided default constructor, + +\item \tcode{X} is a union and all of its variant members are of const-qualified +type (or array thereof), + +\item \tcode{X} is a non-union class and all members of any anonymous union member are +of const-qualified type (or array thereof), + +\item any potentially constructed subobject, except for a non-static data member +with a \grammarterm{brace-or-equal-initializer}, has +class type \tcode{M} (or array thereof) and either \tcode{M} +has no default constructor or overload resolution\iref{over.match} +as applied to find \tcode{M}'s corresponding +constructor results in an ambiguity or in a function that is deleted or +inaccessible from the defaulted default constructor, or + +\item any potentially constructed subobject has a type +with a destructor that is deleted or inaccessible from the defaulted default +constructor. +\end{itemize} + +\pnum +A default constructor is +\defnx{trivial}{constructor!default!trivial} +if it is not user-provided and if: + +\begin{itemize} +\item +its class has no virtual functions\iref{class.virtual} and no virtual base +classes\iref{class.mi}, and + +\item no non-static data member of its class has +a default member initializer\iref{class.mem}, and + +\item +all the direct base classes of its class have trivial default constructors, and + +\item +for all the non-static data members of its class that are of class +type (or array thereof), each such class has a trivial default constructor. +\end{itemize} + +Otherwise, the default constructor is +\defnx{non-trivial}{constructor!default!non-trivial}. + +\pnum +A default constructor +that is defaulted and not defined as deleted +is +\defnx{implicitly defined}{constructor!implicitly defined} +when it is odr-used\iref{basic.def.odr} +to create an object of its class type\iref{intro.object}, +when it is needed for constant evaluation\iref{expr.const}, or +when it is explicitly defaulted after its first declaration. +The implicitly-defined default constructor performs the set of +initializations of the class that would be performed by a user-written default +constructor for that class with no +\grammarterm{ctor-initializer}\iref{class.base.init} and an empty +\grammarterm{compound-statement}. +If that user-written default constructor would be ill-formed, +the program is ill-formed. +If that user-written default constructor would satisfy the requirements +of a constexpr constructor\iref{dcl.constexpr}, the implicitly-defined +default constructor is \tcode{constexpr}. +Before the defaulted default constructor for a class is +implicitly defined, +all the non-user-provided default constructors for its base classes and +its non-static data members shall have been implicitly defined. \begin{note} -It cannot be specified in member declarations that appear in namespace scope. +An implicitly-declared default constructor has an +exception specification\iref{except.spec}. +An explicitly-defaulted definition might have an +implicit exception specification, see~\ref{dcl.fct.def}. \end{note} -\rSec3[class.static.mfct]{Static member functions} -\indextext{member function!static}% +\pnum +\indextext{constructor!implicitly called}% +Default constructors are called implicitly to create class objects of static, thread, +or automatic storage duration~(\ref{basic.stc.static}, \ref{basic.stc.thread}, \ref{basic.stc.auto}) defined +without an initializer\iref{dcl.init}, +are called to create class objects of dynamic storage duration\iref{basic.stc.dynamic} created by a +\grammarterm{new-expression} +in which the +\grammarterm{new-initializer} +is omitted\iref{expr.new}, or +are called when the explicit type conversion syntax\iref{expr.type.conv} is +used. +A program is ill-formed if the default constructor for an object +is implicitly used and the constructor is not accessible\iref{class.access}. \pnum \begin{note} -The rules described in~\ref{class.mfct} apply to static member -functions. +\indextext{order of execution!base class constructor}% +\indextext{order of execution!member constructor}% +\ref{class.base.init} describes the order in which constructors for base +classes and non-static data members are called and +describes how arguments can be specified for the calls to these constructors. \end{note} \pnum +\indextext{restriction!constructor}% +A +\tcode{return} +statement in the body of a constructor shall not specify a return value. +\indextext{constructor!address of}% +The address of a constructor shall not be taken. + +\pnum +\indextext{object!unnamed}% +\indextext{constructor!explicit call}% +A functional notation type conversion\iref{expr.type.conv} can be used +to create new objects of its type. \begin{note} -A static member function does not have a \tcode{this} -pointer\iref{class.this}. +The syntax looks like an explicit call of the constructor. \end{note} -A static member function shall not be \tcode{virtual}. There -shall not be a static and a non-static member function with the -same name and the same parameter types\iref{over.load}. A -static member function shall not be declared \tcode{const}, -\tcode{volatile}, or \tcode{const volatile}. +\begin{example} +\begin{codeblock} +complex zz = complex(1,2.3); +cprint( complex(7.8,1.2) ); +\end{codeblock} +\end{example} -\rSec3[class.static.data]{Static data members} -\indextext{member data!static}% +\pnum +An object created in this way is unnamed. +\begin{note} +\ref{class.temporary} describes the lifetime of temporary objects. +\end{note} +\begin{note} +Explicit constructor calls do not yield lvalues, see~\ref{basic.lval}. +\end{note} \pnum -A static data member is not part of the subobjects of a class. If a -static data member is declared \tcode{thread_local} there is one copy of -the member per thread. If a static data member is not declared -\tcode{thread_local} there is one copy of the data member that is shared by all -the objects of the class. +\begin{note} +\indextext{member function!constructor and}% +Some language constructs have special semantics when used during construction; +see~\ref{class.base.init} and~\ref{class.cdtor}. +\end{note} \pnum -\indextext{initialization!static member}% -\indextext{definition!static member}% -The declaration of a non-inline -static data member in its class definition -is not a definition and may be of an incomplete type other than -\cv{}~\tcode{void}. The definition for a static data -member that is not defined inline in the class definition -shall appear in a namespace scope enclosing the member's class -definition. -\indextext{operator use!scope resolution}% -In the definition at namespace scope, the name of the static -data member shall be qualified by its class name using the \tcode{::} -operator. The \grammarterm{initializer} expression in the definition of a -static data member is in the scope of its -class\iref{basic.scope.class}. +During the construction of an object, +if the value of the object or any of its subobjects is +accessed through a glvalue that is not obtained, directly or indirectly, from +the constructor's +\tcode{this} +pointer, the value of the object or subobject thus obtained is unspecified. \begin{example} \begin{codeblock} -class process { - static process* run_chain; - static process* running; +struct C; +void no_opt(C*); + +struct C { + int c; + C() : c(0) { no_opt(this); } }; -process* process::running = get_main(); -process* process::run_chain = running; -\end{codeblock} +const C cobj; -The static data member \tcode{run_chain} of class -\tcode{process} is defined in global scope; the notation -\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 -member \tcode{running} of class \tcode{process}. +void no_opt(C* cptr) { + int i = cobj.c * 100; // value of \tcode{cobj.c} is unspecified + cptr->c = 1; + cout << cobj.c * 100 // value of \tcode{cobj.c} is unspecified + << '\n'; +} + +extern struct D d; +struct D { + D(int a) : a(a), b(d.a) {} + int a, b; +}; +D d = D(1); // value of \tcode{d.b} is unspecified +\end{codeblock} \end{example} -\begin{note} -Once the static data member has been defined, it exists even if -no objects of its class have been created. +\rSec2[class.copy.ctor]{Copy/move constructors}% + +\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 +a +copy +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 arguments\iref{dcl.fct.default}. \begin{example} -In the example above, \tcode{run_chain} and \tcode{running} exist even -if no objects of class \tcode{process} are created by the program. +\tcode{X::X(const X\&)} +and +\tcode{X::X(X\&,int=1)} +are copy constructors. + +\begin{codeblock} +struct X { + X(int); + X(const X&, int = 1); +}; +X a(1); // calls \tcode{X(int);} +X b(a, 0); // calls \tcode{X(const X\&, int);} +X c = b; // calls \tcode{X(const X\&, int);} +\end{codeblock} \end{example} -\end{note} \pnum -If a non-volatile non-inline \tcode{const} static data member is -of integral or enumeration type, -its declaration in the class definition can specify a -\grammarterm{brace-or-equal-initializer} in which every -\grammarterm{initializer-clause} that is an \grammarterm{assignment-expression} -is a constant expression\iref{expr.const}. -The member shall still be defined in a namespace scope if -it is odr-used\iref{basic.def.odr} in the program and the -namespace scope definition shall not contain an \grammarterm{initializer}. -An inline static data member may be defined in the class definition -and may specify a \grammarterm{brace-or-equal-initializer}. If the -member is declared with the \tcode{constexpr} specifier, it may be -redeclared in namespace scope with no initializer (this usage is -deprecated; see \ref{depr.static_constexpr}). Declarations of other -static data members shall not specify a \grammarterm{brace-or-equal-initializer}. +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 +arguments\iref{dcl.fct.default}. +\begin{example} \tcode{Y::Y(Y\&\&)} is a move constructor. +\begin{codeblock} +struct Y { + Y(const Y&); + Y(Y&&); +}; +extern Y f(int); +Y d(f(1)); // calls \tcode{Y(Y\&\&)} +Y e = d; // calls \tcode{Y(const Y\&)} +\end{codeblock} +\end{example} \pnum \begin{note} -There shall be exactly one definition of a static data member -that is odr-used\iref{basic.def.odr} in a program; no diagnostic is required. +All forms of copy/move constructor may be declared for a class. +\begin{example} + +\begin{codeblock} +struct X { + X(const X&); + X(X&); // OK + X(X&&); + X(const X&&); // OK, but possibly not sensible +}; +\end{codeblock} +\end{example} \end{note} -Unnamed classes and classes contained directly -or indirectly within unnamed classes shall not contain static -data members. \pnum \begin{note} -Static data members of a class in namespace scope have the linkage of that class\iref{basic.link}. A local class cannot have static data members\iref{class.local}. +If a class +\tcode{X} +only has a copy constructor with a parameter of type +\tcode{X\&}, +an initializer of type +\tcode{const} +\tcode{X} +or +\tcode{volatile} +\tcode{X} +cannot initialize an object of type +(possibly +cv-qualified) +\tcode{X}. +\begin{example} + +\begin{codeblock} +struct X { + X(); // default constructor + X(X&); // copy constructor with a non-const parameter +}; +const X cx; +X x = cx; // error: \tcode{X::X(X\&)} cannot copy \tcode{cx} into \tcode{x} +\end{codeblock} +\end{example} +\end{note} + +\pnum +A declaration of a constructor for a class +\tcode{X} +is ill-formed if its first parameter is of type (optionally cv-qualified) +\tcode{X} +and either there are no other parameters or else all other parameters have +default arguments. +A member function template is never instantiated to +produce such a constructor signature. +\begin{example} +\begin{codeblock} +struct S { + template S(T); + S(); +}; + +S g; + +void h() { + S a(g); // does not instantiate the member template to produce \tcode{S::S(S)}; + // uses the implicitly declared copy constructor +} +\end{codeblock} +\end{example} + +\pnum +If the class definition does not explicitly declare a copy constructor, +a non-explicit one is declared \defnx{implicitly}{constructor!copy!implicitly declared}. +If the class definition declares a move +constructor or move assignment operator, the implicitly declared copy +constructor is defined as deleted; otherwise, it is defined as +defaulted\iref{dcl.fct.def}. +The latter case is deprecated if the class has a user-declared copy assignment +operator or a user-declared destructor. + +\pnum +The implicitly-declared copy constructor for a class +\tcode{X} +will have the form + +\begin{codeblock} +X::X(const X&) +\end{codeblock} + +if each potentially constructed subobject of a class type +\tcode{M} +(or array thereof) +has a copy constructor whose first parameter is of type +\tcode{const} +\tcode{M\&} +or +\tcode{const} +\tcode{volatile} +\tcode{M\&}.\footnote{This implies that the reference parameter of the +implicitly-declared copy constructor +cannot bind to a +\tcode{volatile} +lvalue; see~\ref{diff.special}.} +Otherwise, the implicitly-declared copy constructor will have the form + +\begin{codeblock} +X::X(X&) +\end{codeblock} + +\pnum +\indextext{constructor!move!implicitly declared}% +If the definition of a class \tcode{X} does not explicitly declare +a move constructor, a non-explicit one will be +implicitly declared as defaulted if and only if + +\begin{itemize} +\item +\tcode{X} does not have a user-declared copy constructor, + +\item +\tcode{X} does not have a user-declared copy assignment operator, + +\item +\tcode{X} does not have a user-declared move assignment operator, and + +\item +\tcode{X} does not have a user-declared destructor. +\end{itemize} + +\begin{note} When the move constructor is not implicitly declared or explicitly supplied, +expressions that otherwise would have invoked the move constructor may instead invoke +a copy constructor. \end{note} + +\pnum +The implicitly-declared move constructor for class \tcode{X} will have the form +\begin{codeblock} +X::X(X&&) +\end{codeblock} + +\pnum +An implicitly-declared copy/move constructor is an +inline public member of its class. +A defaulted copy/\brk{}move constructor for a class + \tcode{X} is defined as deleted\iref{dcl.fct.def.delete} if \tcode{X} has: +\begin{itemize} +\item a potentially constructed subobject type + \tcode{M} (or array thereof) that cannot be copied/moved because + overload resolution\iref{over.match}, as applied to find + \tcode{M}'s + corresponding constructor, results in an ambiguity or + a function that is deleted or inaccessible from the + defaulted constructor, + +\item a variant member whose corresponding constructor + as selected by overload resolution is non-trivial, + +\item any potentially constructed subobject of a type + with a destructor that is deleted or inaccessible from the defaulted + constructor, or, + +\item for the copy constructor, a non-static data member of rvalue reference type. +\end{itemize} + +A defaulted move constructor that is defined as deleted is ignored by overload +resolution~(\ref{over.match}, \ref{over.over}). +\begin{note} +A deleted move constructor would otherwise interfere with initialization from +an rvalue which can use the copy constructor instead. +\end{note} + +\pnum +\indextext{constructor!copy!trivial}% +\indextext{constructor!move!trivial}% +A copy/move constructor for class +\tcode{X} +is +trivial +if it is not user-provided and if: + +\begin{itemize} +\item +class +\tcode{X} +has no virtual functions\iref{class.virtual} +and no virtual base classes\iref{class.mi}, and + +\item +the constructor selected to copy/move each direct base class subobject is trivial, and + +\item +for each non-static data member of +\tcode{X} +that is of class type (or array thereof), +the constructor selected to copy/move that member is trivial; +\end{itemize} + +\indextext{constructor!move!non-trivial}% +otherwise the copy/move constructor is +\defnx{non-trivial}{constructor!copy!nontrivial}. + +\pnum +\indextext{constructor!copy!implicitly defined}% +\indextext{constructor!move!implicitly defined}% +A copy/move constructor +that is defaulted and not defined as deleted +is +\term{implicitly defined} +when it is odr-used\iref{basic.def.odr}, +when it is needed for constant evaluation\iref{expr.const}, or +when it is explicitly defaulted after its first declaration. +\begin{note} +The copy/move constructor is implicitly defined even if the implementation elided +its odr-use~(\ref{basic.def.odr}, \ref{class.temporary}). +\end{note} +If the implicitly-defined constructor would satisfy the requirements of a +constexpr constructor\iref{dcl.constexpr}, the implicitly-defined +constructor is \tcode{constexpr}. + +\pnum +Before the defaulted copy/move constructor for a class is +implicitly defined, +all non-user-provided copy/move constructors for its +potentially constructed subobjects +shall have been implicitly defined. +\begin{note} +An implicitly-declared copy/move constructor has an +implied exception specification\iref{except.spec}. +\end{note} + +\pnum +The implicitly-defined copy/move constructor for a non-union class +\tcode{X} +performs a memberwise copy/move of its bases and members. +\begin{note} Default member initializers of non-static data members are ignored. See also the example in~\ref{class.base.init}. \end{note} +The order of initialization is the same as the order of initialization of bases +and members in a user-defined constructor (see~\ref{class.base.init}). +Let \tcode{x} be either the parameter of the constructor or, for the move constructor, an +xvalue referring to the parameter. +Each base or non-static data member +is copied/moved in the manner appropriate to its type: + +\begin{itemize} +\item +if the member is an array, each element is +direct-initialized with the corresponding subobject of \tcode{x}; + +\item +if a member \tcode{m} has rvalue reference type \tcode{T\&\&}, it is direct-initialized with +\tcode{static_cast(x.m)}; + +\item +otherwise, the base or member is direct-initialized with the corresponding base or member of \tcode{x}. +\end{itemize} + +\indextext{initialization!virtual base class}% +Virtual base class subobjects shall be initialized only once by +the implicitly-defined copy/move constructor (see~\ref{class.base.init}). + +\pnum +The implicitly-defined copy/move constructor for a union +\tcode{X} copies the object representation\iref{basic.types} of \tcode{X}.% +\indextext{constructor!move|)}% +\indextext{constructor!copy|)} + +\rSec2[class.copy.assign]{Copy/move assignment operator}% + +\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\&}, +\tcode{volatile} \tcode{X\&} or \tcode{const} \tcode{volatile} +\tcode{X\&}.\footnote{Because a template assignment operator or an assignment +operator taking an rvalue reference parameter is never a copy assignment +operator, the presence of such an assignment operator does not suppress the +implicit declaration of a copy assignment operator. Such assignment operators +participate in overload resolution with other assignment operators, including +copy assignment operators, and, if selected, will be used to assign an object.} +\begin{note} +An overloaded assignment operator must be declared to have only one parameter; +see~\ref{over.ass}. +\end{note} +\begin{note} +More than one form of copy assignment operator may be declared for a class. +\end{note} +\begin{note} +If a class +\tcode{X} +only has a copy assignment operator with a parameter of type +\tcode{X\&}, +an expression of type const +\tcode{X} +cannot be assigned to an object of type +\tcode{X}. +\begin{example} + +\begin{codeblock} +struct X { + X(); + X& operator=(X&); +}; +const X cx; +X x; +void f() { + x = cx; // error: \tcode{X::operator=(X\&)} cannot assign \tcode{cx} into \tcode{x} +} +\end{codeblock} +\end{example} +\end{note} + +\pnum +If the class definition does not explicitly declare a copy assignment operator, +one is declared \defnx{implicitly}{assignment operator!copy!implicitly declared}. +If the class definition declares a move +constructor or move assignment operator, the implicitly declared copy +assignment operator is defined as deleted; otherwise, it is defined as +defaulted\iref{dcl.fct.def}. +The latter case is deprecated if the class has a user-declared copy constructor +or a user-declared destructor. +The implicitly-declared copy assignment operator for a class +\tcode{X} +will have the form + +\begin{codeblock} +X& X::operator=(const X&) +\end{codeblock} + +if + +\begin{itemize} +\item +each direct base class +\tcode{B} +of +\tcode{X} +has a copy assignment operator whose parameter is of type +\tcode{const} +\tcode{B\&}, +\tcode{const} +\tcode{volatile} +\tcode{B\&} +or +\tcode{B}, +and +\item +for all the non-static data members of +\tcode{X} +that are of a class type +\tcode{M} +(or array thereof), +each such class type has a copy assignment operator whose parameter is of type +\tcode{const} +\tcode{M\&}, +\tcode{const} +\tcode{volatile} +\tcode{M\&} +or +\tcode{M}.\footnote{This implies that the reference parameter of the +implicitly-declared copy assignment operator cannot bind to a +\tcode{volatile} +lvalue; see~\ref{diff.special}.} +\end{itemize} + +Otherwise, the implicitly-declared copy +assignment operator +will have the form + +\begin{codeblock} +X& X::operator=(X&) +\end{codeblock} + +\pnum +A user-declared move 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{const X\&\&}, \tcode{volatile X\&\&}, or +\tcode{const volatile X\&\&}. \begin{note} An overloaded assignment operator must be +declared to have only one parameter; see~\ref{over.ass}. \end{note}{} +\begin{note} More +than one form of move assignment operator may be declared for a class. \end{note} + +\pnum +\indextext{assignment operator!move!implicitly declared}% +If the definition of a class \tcode{X} does not explicitly declare a +move assignment operator, one +will be implicitly declared as defaulted if and only if + +\begin{itemize} +\item +\tcode{X} does not have a user-declared copy constructor, + +\item +\tcode{X} does not have a user-declared move constructor, + +\item +\tcode{X} does not have a user-declared copy assignment operator, and + +\item +\tcode{X} does not have a user-declared destructor. +\end{itemize} + +\begin{example} The class definition +\begin{codeblock} +struct S { + int a; + S& operator=(const S&) = default; +}; +\end{codeblock} + +will not have a default move assignment operator implicitly declared because the +copy assignment operator has been user-declared. The move assignment operator may +be explicitly defaulted. + +\begin{codeblock} +struct S { + int a; + S& operator=(const S&) = default; + S& operator=(S&&) = default; +}; +\end{codeblock} +\end{example} + +\pnum +The implicitly-declared move assignment operator for a class \tcode{X} will have the form +\begin{codeblock} +X& X::operator=(X&&); +\end{codeblock} + +\pnum +The implicitly-declared copy/move assignment operator for class +\tcode{X} +has the return type +\tcode{X\&}; +it returns the object for which the assignment operator is invoked, that is, +the object assigned to. +An implicitly-declared copy/move assignment operator is an +inline public member of its class. + +\pnum +A defaulted copy/move assignment operator for +class \tcode{X} is defined as deleted if \tcode{X} has: +\begin{itemize} +\item a variant member with a non-trivial corresponding assignment operator and + \tcode{X} is a union-like class, or + +\item a non-static data member of \tcode{const} non-class + type (or array thereof), or + +\item a non-static data member of reference type, or + +\item a direct non-static data member of class type \tcode{M} + (or array thereof) or a direct base class \tcode{M} + that cannot be copied/moved because overload resolution + \iref{over.match}, as applied to find \tcode{M}'s corresponding + assignment operator, results in an ambiguity or + a function that is deleted or inaccessible from the + defaulted assignment operator. +\end{itemize} + +A defaulted move assignment operator that is defined as deleted is ignored by +overload resolution~(\ref{over.match}, \ref{over.over}). + +\pnum +\indextext{assignment operator!copy!hidden}% +\indextext{assignment operator!move!hidden}% +Because a copy/move assignment operator is implicitly declared for a class +if not declared by the user, +a base class copy/move assignment operator is always hidden +by the corresponding assignment operator of a derived class\iref{over.ass}. +A +\grammarterm{using-declaration}\iref{namespace.udecl} that brings in from a base class an assignment operator +with a parameter type that could be that of a +copy/move assignment operator for the +derived class is not considered an explicit declaration of such an +operator and does not suppress the implicit declaration of the derived class +operator; +the operator introduced by the +\grammarterm{using-declaration} +is hidden by the implicitly-declared operator in the derived +class. + +\pnum +\indextext{assignment operator!copy!trivial}% +\indextext{assignment operator!move!trivial}% +A copy/move assignment operator for class +\tcode{X} +is +trivial +if it is not user-provided and if: + +\begin{itemize} +\item +class +\tcode{X} +has no virtual functions\iref{class.virtual} +and no virtual base classes\iref{class.mi}, and + +\item the assignment operator selected to copy/move each direct +base class subobject is trivial, and + +\item +for each non-static data member of +\tcode{X} +that is of class type (or array thereof), +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 +\defnx{non-trivial}{assignment operator!copy!non-trivial}. + +\pnum +\indextext{assignment operator!copy!implicitly defined}% +\indextext{assignment operator!move!implicitly defined}% +A copy/move assignment operator for a class \tcode{X} +that is defaulted and not defined as deleted +is +\term{implicitly defined} +when it is odr-used\iref{basic.def.odr} +(e.g., when it is selected by overload resolution +to assign to an object of its class type), +when it is needed for constant evaluation\iref{expr.const}, or +when it is explicitly defaulted after its first declaration. +The implicitly-defined copy/move assignment operator is \tcode{constexpr} if +\begin{itemize} +\item +\tcode{X} is a literal type, and + +\item +the assignment operator selected to copy/move each direct base class subobject +is a constexpr function, and + +\item +for each non-static data member of \tcode{X} that is of class type (or array +thereof), the assignment operator selected to copy/move that member is a +constexpr function. +\end{itemize} + +\pnum +Before the defaulted copy/move assignment operator for a class is +implicitly defined, +all non-user-provided copy/move assignment operators for +its direct base classes and +its non-static data members shall have been implicitly defined. +\begin{note} +An implicitly-declared copy/move assignment operator has an +implied exception specification\iref{except.spec}. +\end{note} + +\pnum +The implicitly-defined copy/move assignment operator for a +non-union class \tcode{X} performs memberwise copy/move assignment of its subobjects. The direct +base classes of \tcode{X} are assigned first, in the order of their declaration in the +\grammarterm{base-specifier-list}, and then the immediate non-static data members of +\tcode{X} are assigned, in the order in which they were declared in the class +definition. +Let \tcode{x} be either the parameter of the function or, for the move operator, an +xvalue referring to the parameter. +Each subobject is assigned in the manner appropriate to its type: + +\begin{itemize} +\item +if the subobject is of class type, +as if by a call to \tcode{operator=} with the subobject as the object expression +and the corresponding subobject of \tcode{x} as a single function argument +(as if by explicit qualification; that is, +ignoring any possible virtual overriding functions in more derived classes); +\item +if the subobject is an array, each element is assigned, +in the manner appropriate to the element type; +\item +if the subobject is of scalar type, +the built-in assignment operator is used. +\end{itemize} + +\indextext{assignment operator!copy!virtual bases and}% +It is unspecified whether subobjects representing virtual base classes +are assigned more than once by the implicitly-defined copy/move assignment +operator. +\begin{example} + +\begin{codeblock} +struct V { }; +struct A : virtual V { }; +struct B : virtual V { }; +struct C : B, A { }; +\end{codeblock} + +It is unspecified whether the virtual base class subobject +\tcode{V} +is assigned twice by the implicitly-defined copy/move assignment operator for +\tcode{C}. +\end{example} + +\pnum +The implicitly-defined copy assignment operator for a +union \tcode{X} copies the object representation\iref{basic.types} of \tcode{X}.% +\indextext{assignment operator!move|)}% +\indextext{assignment operator!copy|)} + +\rSec2[class.dtor]{Destructors}% +\indextext{destructor}% +\indextext{special member function|see{destructor}}% + +\pnum +In a declaration of a destructor, the \grammarterm{declarator} is a +function declarator\iref{dcl.fct} of the form + +\begin{ncbnf} +ptr-declarator \terminal{(} parameter-declaration-clause \terminal{)} \opt{noexcept-specifier} \opt{attribute-specifier-seq} +\end{ncbnf} + +where the \grammarterm{ptr-declarator} consists solely of an +\grammarterm{id-expression}, an optional \grammarterm{attribute-specifier-seq}, +and optional surrounding parentheses, and the \grammarterm{id-expression} has +one of the following forms: + +\begin{itemize} +\item +in a \grammarterm{member-declaration} that belongs to the +\grammarterm{member-specification} of a class or class template +but is not a friend +declaration\iref{class.friend}, the \grammarterm{id-expression} is +\tcode{\~}\grammarterm{class-name} and the \grammarterm{class-name} is the +injected-class-name\iref{class} of the immediately-enclosing entity or + +\item +in a declaration at namespace scope or in a friend declaration, the +\grammarterm{id-expression} is \grammarterm{nested-name-specifier} +\tcode{\~}\grammarterm{class-name} and the \grammarterm{class-name} names the +same class as the \grammarterm{nested-name-specifier}. +\end{itemize} + +The \grammarterm{class-name} shall not be a \grammarterm{typedef-name}. A +destructor shall take no arguments\iref{dcl.fct}. +Each \grammarterm{decl-specifier} of the \grammarterm{decl-specifier-seq} +of a destructor declaration (if any) shall be \tcode{friend}, \tcode{inline}, or +\tcode{virtual}. + +\pnum +A destructor is used to destroy objects of its class type. +\indextext{restriction!destructor}% +The address of a destructor shall not be taken. +\indextext{\idxcode{const}!destructor and}% +\indextext{\idxcode{volatile}!destructor and}% +A destructor can be invoked for a +\tcode{const}, +\tcode{volatile} +or +\tcode{const} +\tcode{volatile} +object. +\tcode{const} +and +\tcode{volatile} +semantics\iref{dcl.type.cv} are not applied on an object under destruction. +They stop being in effect when the destructor for the +most derived object\iref{intro.object} starts. + +\pnum +\begin{note} +A declaration of a destructor that does not have a \grammarterm{noexcept-specifier} +has the same exception specification as if it had been implicitly declared\iref{except.spec}. +\end{note} + +\pnum +\indextext{generated destructor|see{destructor, default}}% +\indextext{destructor!default}% +If a class has no user-declared +destructor, a destructor is implicitly +declared as defaulted\iref{dcl.fct.def}. +An implicitly-declared destructor is an +inline public member of its class. + +\pnum +A defaulted destructor for a class + \tcode{X} is defined as deleted if: +\begin{itemize} +\item \tcode{X} is a union-like class that has a variant + member with a non-trivial destructor, + +\item any potentially constructed subobject has class type + \tcode{M} (or array thereof) and + \tcode{M} has a deleted destructor or a destructor + that is inaccessible from the defaulted destructor, + +\item or, for a virtual destructor, lookup of the non-array deallocation + function results in an ambiguity or in a function that is deleted or + inaccessible from the defaulted destructor. +\end{itemize} + +\pnum +A destructor is trivial if it is not user-provided and if: + +\begin{itemize} +\item the destructor is not \tcode{virtual}, + +\item all of the direct base classes of its class have trivial destructors, and + +\item for all of the non-static data members of its class that are of class +type (or array thereof), each such class has a trivial destructor. +\end{itemize} + +Otherwise, the destructor is +\defnx{non-trivial}{destructor!non-trivial}. + +\pnum +A destructor +that is defaulted and not defined as deleted +is +\defnx{implicitly defined}{destructor!implicitly defined} +when it is odr-used\iref{basic.def.odr} +or when it is explicitly defaulted after its first declaration. + +\pnum +Before the +defaulted destructor for a class is implicitly defined, all the non-user-provided +destructors for its base classes and its non-static data members shall have been +implicitly defined. + +\pnum +\indextext{order of execution!destructor}% +\indextext{order of execution!base class destructor}% +\indextext{order of execution!member destructor}% +After executing the body of the destructor and destroying +any automatic objects allocated within the body, a +destructor for class +\tcode{X} +calls the destructors for +\tcode{X}'s +direct non-variant non-static data members, the destructors for +\tcode{X}'s +non-virtual direct base classes and, if +\tcode{X} +is the type of the most derived class\iref{class.base.init}, +its destructor calls the destructors for +\tcode{X}'s +virtual base classes. +All destructors are called as if they were referenced with a qualified name, +that is, ignoring any possible virtual overriding destructors in more +derived classes. +Bases and members are destroyed in the reverse order of the completion of +their constructor (see~\ref{class.base.init}). +A +\tcode{return} +statement\iref{stmt.return} in a destructor might not directly return to the +caller; before transferring control to the caller, the destructors for the +members and bases are called. +\indextext{order of execution!destructor and array}% +Destructors for elements of an array are called in reverse order of their +construction (see~\ref{class.init}). + +\pnum +\indextext{destructor!virtual}% +\indextext{destructor!pure virtual}% +A destructor can be declared +\tcode{virtual}\iref{class.virtual} +or pure +\tcode{virtual}\iref{class.abstract}; +if any objects of that class or any derived class are created in the program, +the destructor shall be defined. +If a class has a base class with a virtual destructor, its destructor +(whether user- or implicitly-declared) is virtual. + +\pnum +\begin{note} +\indextext{member function!destructor and}% +Some language constructs have special semantics when used during destruction; +see~\ref{class.cdtor}. +\end{note} + +\pnum +\indextext{destructor!implicit call}% +\indextext{destructor!program termination and}% +A destructor is invoked implicitly + +\begin{itemize} + +\item for a constructed object with static storage duration\iref{basic.stc.static} at program termination\iref{basic.start.term}, + +\item for a constructed object with thread storage duration\iref{basic.stc.thread} at thread exit, + +\item for a constructed object with automatic storage duration\iref{basic.stc.auto} when the block in which an object is created exits\iref{stmt.dcl}, + +\item for a constructed temporary object when its lifetime ends~(\ref{conv.rval}, \ref{class.temporary}). +\end{itemize} + +\indextext{\idxcode{delete}!destructor and}% +\indextext{destructor!explicit call}% +In each case, the context of the invocation is the context of the construction of +the object. A destructor may also be invoked implicitly through use of a +\grammarterm{delete-expression}\iref{expr.delete} for a constructed object allocated +by a \grammarterm{new-expression}\iref{expr.new}; the context of the invocation is the +\grammarterm{delete-expression}. +\begin{note} An array of class type contains several subobjects for each of which +the destructor is invoked. \end{note} +A destructor can also be invoked explicitly. A destructor is \term{potentially invoked} +if it is invoked or as specified in~\ref{expr.new}, \ref{dcl.init.aggr}, +\ref{class.base.init}, and~\ref{except.throw}. +A program is ill-formed if a destructor that is potentially invoked is deleted +or not accessible from the context of the invocation. + +\pnum +At the point of definition of a virtual destructor (including an implicit +definition\iref{class.dtor}), 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 +a deleted definition\iref{dcl.fct.def}, the program is ill-formed. +\begin{note} +This assures that a deallocation function corresponding to the dynamic type of an +object is available for the +\grammarterm{delete-expression}\iref{class.free}. +\end{note} + +\pnum +\indextext{destructor!explicit call}% +In an explicit destructor call, the destructor is specified by a +\tcode{\~{}} +followed by a +\grammarterm{type-name} or \grammarterm{decltype-specifier} +that denotes the destructor's class type. +The invocation of a destructor is subject to the usual rules for member +functions\iref{class.mfct}; +that is, if the object is not of the destructor's class type and +not of a class derived from the destructor's class type (including when +the destructor is invoked via a null pointer value), the program has +undefined behavior. +\begin{note} Invoking \tcode{delete} on a null pointer does not call the +destructor; see \ref{expr.delete}. \end{note} +\begin{example} + +\begin{codeblock} +struct B { + virtual ~B() { } +}; +struct D : B { + ~D() { } +}; + +D D_object; +typedef B B_alias; +B* B_ptr = &D_object; + +void f() { + D_object.B::~B(); // calls \tcode{B}'s destructor + B_ptr->~B(); // calls \tcode{D}'s destructor + B_ptr->~B_alias(); // calls \tcode{D}'s destructor + B_ptr->B_alias::~B(); // calls \tcode{B}'s destructor + B_ptr->B_alias::~B_alias(); // calls \tcode{B}'s destructor +} +\end{codeblock} +\end{example} +\begin{note} +An explicit destructor call must always be written using +a member access operator\iref{expr.ref} or a \grammarterm{qualified-id}\iref{expr.prim.id.qual}; +in particular, the +\grammarterm{unary-expression} +\tcode{\~{}X()} +in a member function is not an explicit destructor call\iref{expr.unary.op}. +\end{note} + +\pnum +\begin{note} +\indextext{object!destructor and placement of}% +Explicit calls of destructors are rarely needed. +One use of such calls is for objects placed at specific +addresses using a placement +\grammarterm{new-expression}. +Such use of explicit placement and destruction of objects can be necessary +to cope with dedicated hardware resources and for writing memory management +facilities. +For example, +\begin{codeblock} +void* operator new(std::size_t, void* p) { return p; } +struct X { + X(int); + ~X(); +}; +void f(X* p); + +void g() { // rare, specialized use: + char* buf = new char[sizeof(X)]; + X* p = new(buf) X(222); // use \tcode{buf[]} and initialize + f(p); + p->X::~X(); // cleanup +} +\end{codeblock} +\end{note} + +\pnum +Once a destructor is invoked for an object, the object no longer exists; +the behavior is undefined if the destructor is invoked +for an object whose lifetime has ended\iref{basic.life}. +\begin{example} +If the destructor for an automatic object is explicitly invoked, +and the block is subsequently left in a manner that would ordinarily +invoke implicit destruction of the object, the behavior is undefined. +\end{example} + +\pnum +\begin{note} +\indextext{fundamental type!destructor and}% +The notation for explicit call of a destructor can be used for any scalar type +name\iref{expr.pseudo}. +Allowing this makes it possible to write code without having to know if a +destructor exists for a given type. +For example: +\begin{codeblock} +typedef int I; +I* p; +p->I::~I(); +\end{codeblock} +\end{note} + +\rSec2[class.conv]{Conversions} + +\pnum +\indextext{conversion!class}% +\indextext{constructor, conversion by|see{conversion, user-defined}}% +\indextext{conversion function|see{conversion, user-defined}}% +\indextext{conversion!implicit}% +Type conversions of class objects can be specified by constructors and +by conversion functions. +These conversions are called +\defnx{user-defined conversions}{conversion!user-defined} +and are used for implicit type conversions\iref{conv}, +for initialization\iref{dcl.init}, +and for explicit type conversions~(\ref{expr.cast}, \ref{expr.static.cast}). + +\pnum +User-defined conversions are applied only where they are unambiguous~(\ref{class.member.lookup}, \ref{class.conv.fct}). +Conversions obey the access control rules\iref{class.access}. +Access control is applied after ambiguity resolution\iref{basic.lookup}. + +\pnum +\begin{note} +See~\ref{over.match} for a discussion of the use of conversions in function calls +as well as examples below. +\end{note} + +\pnum +\indextext{conversion!implicit user-defined}% +At most one user-defined conversion (constructor or conversion function) +is implicitly applied to a single value. +\begin{example} +\begin{codeblock} +struct X { + operator int(); +}; + +struct Y { + operator X(); +}; + +Y a; +int b = a; // error, \tcode{a.operator X().operator int()} not tried +int c = X(a); // OK: \tcode{a.operator X().operator int()} +\end{codeblock} +\end{example} + +\pnum +User-defined conversions are used implicitly only if they are unambiguous. +\indextext{name hiding!user-defined conversion and}% +A conversion function in a derived class does not hide a conversion function +in a base class unless the two functions convert to the same type. +Function overload resolution\iref{over.match.best} selects the best +conversion function to perform the conversion. +\begin{example} +\begin{codeblock} +struct X { + operator int(); +}; + +struct Y : X { + operator char(); +}; + +void f(Y& a) { + if (a) { // ill-formed: \tcode{X::operator int()} or \tcode{Y::operator char()} + } +} +\end{codeblock} +\end{example} + +\rSec3[class.conv.ctor]{Conversion by constructor}% +\indextext{conversion!user-defined}% + +\pnum +A constructor that is not explicit\iref{dcl.fct.spec} +specifies a conversion from +the types of its parameters (if any) +to the type of its class. +Such a constructor is called a +\defnx{converting constructor}{constructor!converting}. +\begin{example} + +\indextext{Jessie}% +\begin{codeblock} +struct X { + X(int); + X(const char*, int =0); + X(int, int); +}; + +void f(X arg) { + X a = 1; // \tcode{a = X(1)} + X b = "Jessie"; // \tcode{b = X("Jessie",0)} + a = 2; // \tcode{a = X(2)} + f(3); // \tcode{f(X(3))} + f({1, 2}); // \tcode{f(X(1,2))} +} +\end{codeblock} +\end{example} + +\pnum +\begin{note} +An explicit constructor constructs objects just like non-explicit +constructors, but does so only where the direct-initialization syntax\iref{dcl.init} +or where casts~(\ref{expr.static.cast}, \ref{expr.cast}) are explicitly +used; see also~\ref{over.match.copy}. +A default constructor may be an explicit constructor; such a constructor +will be used to perform default-initialization +or value-initialization\iref{dcl.init}. +\begin{example} +\begin{codeblock} +struct Z { + explicit Z(); + explicit Z(int); + explicit Z(int, int); +}; + +Z a; // OK: default-initialization performed +Z b{}; // OK: direct initialization syntax used +Z c = {}; // error: copy-list-initialization +Z a1 = 1; // error: no implicit conversion +Z a3 = Z(1); // OK: direct initialization syntax used +Z a2(1); // OK: direct initialization syntax used +Z* p = new Z(1); // OK: direct initialization syntax used +Z a4 = (Z)1; // OK: explicit cast used +Z a5 = static_cast(1); // OK: explicit cast used +Z a6 = { 3, 4 }; // error: no implicit conversion +\end{codeblock} +\end{example} +\end{note} + +\pnum +A non-explicit copy/move constructor\iref{class.copy.ctor} is +a converting constructor. +\begin{note} +An implicitly-declared copy/move constructor is not an explicit constructor; +it may be called for implicit type conversions. +\end{note} + +\rSec3[class.conv.fct]{Conversion functions}% +\indextext{function!conversion}% +\indextext{fundamental type conversion|see{conversion, user-defined}}% +\indextext{conversion!user-defined}% + +\pnum +A member function of a class \tcode{X} having no parameters with a name of the form + +\begin{bnf} +\nontermdef{conversion-function-id}\br + \terminal{operator} conversion-type-id +\end{bnf} + +\begin{bnf} +\nontermdef{conversion-type-id}\br + type-specifier-seq \opt{conversion-declarator} +\end{bnf} + +\begin{bnf} +\nontermdef{conversion-declarator}\br + ptr-operator \opt{conversion-declarator} +\end{bnf} + +specifies a conversion from +\tcode{X} +to the type specified by the +\grammarterm{conversion-type-id}. +Such functions are called \defnx{conversion functions}{conversion function}. +A \grammarterm{decl-specifier} in the \grammarterm{decl-specifier-seq} +of a conversion function (if any) shall be neither +a \grammarterm{defining-type-specifier} nor \tcode{static}. +\indextext{conversion!type of}% +The type of the conversion function\iref{dcl.fct} is +``function taking no parameter returning +\grammarterm{conversion-type-id}''. +A conversion function is never used to convert a (possibly cv-qualified) object +to the (possibly cv-qualified) same object type (or a reference to it), +to a (possibly cv-qualified) base class of that type (or a reference to it), +or to (possibly cv-qualified) void.\footnote{These conversions are considered +as standard conversions for the purposes of overload resolution~(\ref{over.best.ics}, \ref{over.ics.ref}) and therefore initialization\iref{dcl.init} and explicit casts\iref{expr.static.cast}. A conversion to \tcode{void} does not invoke any conversion function\iref{expr.static.cast}. +Even though never directly called to perform a conversion, +such conversion functions can be declared and can potentially +be reached through a call to a virtual conversion function in a base class.} +\begin{example} +\begin{codeblock} +struct X { + operator int(); + operator auto() -> short; // error: trailing return type +}; + +void f(X a) { + int i = int(a); + i = (int)a; + i = a; +} +\end{codeblock} +In all three cases the value assigned will be converted by +\tcode{X::operator int()}. +\end{example} + +\pnum +A conversion function may be explicit\iref{dcl.fct.spec}, in which case it is only considered as a user-defined conversion for direct-initialization\iref{dcl.init}. Otherwise, user-defined conversions are not restricted to use in assignments and initializations. +\begin{example} +\begin{codeblock} +class Y { }; +struct Z { + explicit operator Y() const; +}; + +void h(Z z) { + Y y1(z); // OK: direct-initialization + Y y2 = z; // ill-formed: copy-initialization + Y y3 = (Y)z; // OK: cast notation +} + +void g(X a, X b) { + int i = (a) ? 1+a : 0; + int j = (a&&b) ? a+b : i; + if (a) { + } +} +\end{codeblock} +\end{example} + +\pnum +The +\grammarterm{conversion-type-id} +shall not represent a function type nor an array type. +The +\grammarterm{conversion-type-id} +in a +\grammarterm{conversion-function-id} +is the longest sequence of +tokens that could possibly form a \grammarterm{conversion-type-id}. +\begin{note} +This prevents ambiguities between the declarator operator \tcode{*} and its expression +counterparts. +\begin{example} +\begin{codeblock} +&ac.operator int*i; // syntax error: + // parsed as: \tcode{\&(ac.operator int *)i} + // not as: \tcode{\&(ac.operator int)*i} +\end{codeblock} +The \tcode{*} is the pointer declarator and not the multiplication operator. +\end{example} +This rule also prevents ambiguities for attributes. +\begin{example} +\begin{codeblock} +operator int [[noreturn]] (); // error: \tcode{noreturn} attribute applied to a type +\end{codeblock} +\end{example} +\end{note} + +\pnum +\indextext{conversion!inheritance of user-defined}% +Conversion functions are inherited. + +\pnum +\indextext{conversion!virtual user-defined}% +Conversion functions can be virtual. + +\pnum +\indextext{conversion!deduced return type of user-defined}% +A conversion function template shall not have a +deduced return type\iref{dcl.spec.auto}. +\begin{example} +\begin{codeblock} +struct S { + operator auto() const { return 10; } // OK + template + operator auto() const { return 1.2; } // error: conversion function template +}; +\end{codeblock} +\end{example} + +\rSec2[class.static]{Static members}% +\indextext{member!static}% + +\pnum +A static member \tcode{s} of class \tcode{X} may be referred to +using the \grammarterm{qualified-id} expression \tcode{X::s}; it is not +necessary to use the class member access syntax\iref{expr.ref} to +refer to a static member. A static member may be +referred to using the class member access syntax, in which case the +object expression is evaluated. +\begin{example} + +\begin{codeblock} +struct process { + static void reschedule(); +}; +process& g(); + +void f() { + process::reschedule(); // OK: no object necessary + g().reschedule(); // \tcode{g()} is called +} +\end{codeblock} +\end{example} + +\pnum +A static member may be referred to directly in the scope of its +class or in the scope of a class derived\iref{class.derived} +from its class; in this case, the static member is referred to +as if a \grammarterm{qualified-id} expression was used, with the +\grammarterm{nested-name-specifier} of the \grammarterm{qualified-id} naming +the class scope from which the static member is referenced. +\begin{example} + +\begin{codeblock} +int g(); +struct X { + static int g(); +}; +struct Y : X { + static int i; +}; +int Y::i = g(); // equivalent to \tcode{Y::g();} +\end{codeblock} +\end{example} + +\pnum +If an \grammarterm{unqualified-id}\iref{expr.prim.id.unqual} is used in the +definition of a static member following the member's +\grammarterm{declarator-id}, and name lookup\iref{basic.lookup.unqual} +finds that the \grammarterm{unqualified-id} refers to a static +member, enumerator, or nested type of the member's class (or of a base +class of the member's class), the \grammarterm{unqualified-id} is +transformed into a \grammarterm{qualified-id} expression in which the +\grammarterm{nested-name-specifier} names the class scope from which the +member is referenced. +\begin{note} +See~\ref{expr.prim.id} for restrictions on the use of non-static data +members and non-static member functions. +\end{note} + + +\pnum +Static members obey the usual class member access rules\iref{class.access}. +When used in the declaration of a class +member, the \tcode{static} specifier shall only be used in the member +declarations that appear within the \grammarterm{member-specification} of +the class definition. +\begin{note} +It cannot be specified in member declarations that appear in namespace scope. +\end{note} + +\rSec3[class.static.mfct]{Static member functions} +\indextext{member function!static}% + +\pnum +\begin{note} +The rules described in~\ref{class.mfct} apply to static member +functions. +\end{note} + +\pnum +\begin{note} +A static member function does not have a \tcode{this} +pointer\iref{class.this}. +\end{note} +A static member function shall not be \tcode{virtual}. There +shall not be a static and a non-static member function with the +same name and the same parameter types\iref{over.load}. A +static member function shall not be declared \tcode{const}, +\tcode{volatile}, or \tcode{const volatile}. + +\rSec3[class.static.data]{Static data members} +\indextext{member data!static}% + +\pnum +A static data member is not part of the subobjects of a class. If a +static data member is declared \tcode{thread_local} there is one copy of +the member per thread. If a static data member is not declared +\tcode{thread_local} there is one copy of the data member that is shared by all +the objects of the class. + +\pnum +\indextext{initialization!static member}% +\indextext{definition!static member}% +The declaration of a non-inline +static data member in its class definition +is not a definition and may be of an incomplete type other than +\cv{}~\tcode{void}. The definition for a static data +member that is not defined inline in the class definition +shall appear in a namespace scope enclosing the member's class +definition. +\indextext{operator use!scope resolution}% +In the definition at namespace scope, the name of the static +data member shall be qualified by its class name using the \tcode{::} +operator. The \grammarterm{initializer} expression in the definition of a +static data member is in the scope of its +class\iref{basic.scope.class}. +\begin{example} + +\begin{codeblock} +class process { + static process* run_chain; + static process* running; +}; + +process* process::running = get_main(); +process* process::run_chain = running; +\end{codeblock} + +The static data member \tcode{run_chain} of class +\tcode{process} is defined in global scope; the notation +\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 +member \tcode{running} of class \tcode{process}. +\end{example} + +\begin{note} +Once the static data member has been defined, it exists even if +no objects of its class have been created. +\begin{example} +In the example above, \tcode{run_chain} and \tcode{running} exist even +if no objects of class \tcode{process} are created by the program. +\end{example} +\end{note} + +\pnum +If a non-volatile non-inline \tcode{const} static data member is +of integral or enumeration type, +its declaration in the class definition can specify a +\grammarterm{brace-or-equal-initializer} in which every +\grammarterm{initializer-clause} that is an \grammarterm{assignment-expression} +is a constant expression\iref{expr.const}. +The member shall still be defined in a namespace scope if +it is odr-used\iref{basic.def.odr} in the program and the +namespace scope definition shall not contain an \grammarterm{initializer}. +An inline static data member may be defined in the class definition +and may specify a \grammarterm{brace-or-equal-initializer}. If the +member is declared with the \tcode{constexpr} specifier, it may be +redeclared in namespace scope with no initializer (this usage is +deprecated; see \ref{depr.static_constexpr}). Declarations of other +static data members shall not specify a \grammarterm{brace-or-equal-initializer}. + +\pnum +\begin{note} +There shall be exactly one definition of a static data member +that is odr-used\iref{basic.def.odr} in a program; no diagnostic is required. +\end{note} +Unnamed classes and classes contained directly +or indirectly within unnamed classes shall not contain static +data members. + +\pnum +\begin{note} +Static data members of a class in namespace scope have the linkage of that class\iref{basic.link}. A local class cannot have static data members\iref{class.local}. \end{note} \pnum @@ -1300,530 +2921,4077 @@ \ref{basic.start.term}). \pnum -A static data member shall not be -\tcode{mutable}\iref{dcl.stc}. +A static data member shall not be +\tcode{mutable}\iref{dcl.stc}. + +\rSec2[class.bit]{Bit-fields}% +\indextext{bit-field} + +\pnum +A \grammarterm{member-declarator} of the form + +\begin{ncsimplebnf} +\opt{identifier} \opt{attribute-specifier-seq} \terminal{:} constant-expression \opt{brace-or-equal-initializer} +\end{ncsimplebnf} + +\indextext{\idxcode{:}!bit-field declaration}% +\indextext{declaration!bit-field}% +specifies a bit-field; +its length is set off from the bit-field name by a colon. The optional \grammarterm{attribute-specifier-seq} appertains to the entity being declared. The bit-field +attribute is not part of the type of the class member. The +\grammarterm{constant-expression} shall be an integral constant expression +with a value greater than or equal to zero. The +value of the integral constant expression may +be larger than the number of bits in the object +representation\iref{basic.types} of the bit-field's type; in such +cases the extra bits are padding bits\iref{basic.types}. +\indextext{allocation!implementation-defined bit-field}% +Allocation of bit-fields within a class object is +\impldef{allocation of bit-fields within a class object}. +\indextext{bit-field!implementation-defined alignment of}% +Alignment of bit-fields is \impldef{alignment of bit-fields within a class object}. +\indextext{layout!bit-field}% +Bit-fields are packed into some addressable allocation unit. +\begin{note} +Bit-fields straddle allocation units on some machines and not on others. +Bit-fields are assigned right-to-left on some machines, left-to-right on +others. +\end{note} + +\pnum +\indextext{bit-field!unnamed}% +A declaration for a bit-field that omits the \grammarterm{identifier} +declares an \defn{unnamed bit-field}. Unnamed bit-fields are not +members and cannot be initialized. +An unnamed bit-field shall not be declared with a cv-qualified type. +\begin{note} +An unnamed bit-field is useful for padding to conform to +externally-imposed layouts. +\end{note} +\indextext{bit-field!zero width of}% +\indextext{bit-field!alignment of}% +As a special case, an unnamed bit-field with a width of zero specifies +alignment of the next bit-field at an allocation unit boundary. Only +when declaring an unnamed bit-field may the value of the +\grammarterm{constant-expression} be equal to zero. + +\pnum +\indextext{bit-field!type of}% +A bit-field shall not be a static member. A bit-field shall have +integral or enumeration type\iref{basic.fundamental}. +\indextext{Boolean}% +A \tcode{bool} value can successfully be stored in a bit-field of any +nonzero size. +\indextext{bit-field!address of}% +The address-of operator \tcode{\&} shall not be applied to a bit-field, +so there are no pointers to bit-fields. +\indextext{restriction!bit-field}% +\indextext{restriction!address of bit-field}% +\indextext{restriction!pointer to bit-field}% +A non-const reference shall not be bound to a +bit-field\iref{dcl.init.ref}. +\begin{note} +If the initializer for a reference of type \tcode{const} \tcode{T\&} is +an lvalue that refers to a bit-field, the reference is bound to a +temporary initialized to hold the value of the bit-field; the reference +is not bound to the bit-field directly. See~\ref{dcl.init.ref}. +\end{note} + +\pnum +If the value \tcode{true} or \tcode{false} is stored into a bit-field of +type \tcode{bool} of any size (including a one bit bit-field), the +original \tcode{bool} value and the value of the bit-field shall compare +equal. If the value of an enumerator is stored into a bit-field of the +same enumeration type and the number of bits in the bit-field is large +enough to hold all the values of that enumeration type\iref{dcl.enum}, +the original enumerator value and the value of the bit-field shall +compare equal. +\begin{example} + +\begin{codeblock} +enum BOOL { FALSE=0, TRUE=1 }; +struct A { + BOOL b:1; +}; +A a; +void f() { + a.b = TRUE; + if (a.b == TRUE) // yields \tcode{true} + { @\commentellip@ } +} +\end{codeblock} +\end{example} + +\rSec2[class.nest]{Nested class declarations}% +\indextext{definition!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 \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. +\begin{note} +See~\ref{expr.prim.id} for restrictions on the use of non-static data +members and non-static member functions. +\end{note} + +\begin{example} +\begin{codeblock} +int x; +int y; + +struct enclose { + int x; + static int s; + + struct inner { + void f(int i) { + int a = sizeof(x); // OK: operand of sizeof is an unevaluated operand + x = i; // error: assign to \tcode{enclose::x} + s = i; // OK: assign to \tcode{enclose::s} + ::x = i; // OK: assign to global \tcode{x} + y = i; // OK: assign to global \tcode{y} + } + void g(enclose* p, int i) { + p->x = i; // OK: assign to \tcode{enclose::x} + } + }; +}; + +inner* p = 0; // error: \tcode{inner} not in scope +\end{codeblock} +\end{example} + +\pnum +Member functions and static data members of a nested class can be +defined in a namespace scope enclosing the definition of their class. +\begin{example} +\begin{codeblock} +struct enclose { + struct inner { + static int x; + void f(int i); + }; +}; + +int enclose::inner::x = 1; + +void enclose::inner::f(int i) { @\commentellip@ } +\end{codeblock} +\end{example} + +\pnum +If class \tcode{X} is defined in a namespace scope, a nested class +\tcode{Y} may be declared in class \tcode{X} and later defined in the +definition of class \tcode{X} or be later defined in a namespace scope +enclosing the definition of class \tcode{X}. +\begin{example} +\begin{codeblock} +class E { + class I1; // forward declaration of nested class + class I2; + class I1 { }; // definition of nested class +}; +class E::I2 { }; // definition of nested class +\end{codeblock} +\end{example} + +\pnum +\indextext{friend function!nested class}% +Like a member function, a friend function\iref{class.friend} defined +within a nested class is in the lexical scope of that class; it obeys +the same rules for name binding as a static member function of that +class\iref{class.static}, but it has no special access rights to +members of an enclosing class. + +\rSec2[class.nested.type]{Nested type names} +\indextext{type name!nested}% +\indextext{type name!nested!scope of}% + +\pnum +Type names obey exactly the same scope rules as other names. In +particular, type names defined within a class definition cannot be used +outside their class without qualification. +\begin{example} +\begin{codeblock} +struct X { + typedef int I; + class Y { @\commentellip@ }; + I a; +}; + +I b; // error +Y c; // error +X::Y d; // OK +X::I e; // OK +\end{codeblock} +\end{example}% +\indextext{class|)} + +\rSec1[class.union]{Unions}% +\indextext{\idxcode{union}} + +\pnum +In a union, +a non-static data member is \defnx{active}{active!union member} +if its name refers to an object +whose lifetime has begun and has not ended\iref{basic.life}. +At most one of the non-static data members of an object of union type +can be active at any +time, that is, the value of at most one of the non-static data members can be +stored in a union at any time. \begin{note} One special guarantee is made in order to +simplify the use of unions: If a standard-layout union contains several standard-layout +structs that share a common initial sequence\iref{class.mem}, and +if a non-static data member of an object of this standard-layout union type +is active and is one of the standard-layout structs, +it is permitted to inspect the common initial sequence +of any of the standard-layout struct members; +see~\ref{class.mem}. +\end{note} + +\pnum +The size of a union is sufficient to contain the largest +of its non-static data members. Each non-static data member is allocated +as if it were the sole member of a struct. +\begin{note} +A union object and its non-static data members are +pointer-interconvertible~(\ref{basic.compound}, \ref{expr.static.cast}). +As a consequence, all non-static data members of a +union object have the same address. +\end{note} + +\pnum +\indextext{member function!\idxcode{union}}% +\indextext{constructor!\idxcode{union}}% +\indextext{destructor!\idxcode{union}}% +A union can have member functions (including constructors and destructors), +\indextext{restriction!\idxcode{union}}% +but it shall not have virtual\iref{class.virtual} functions. A union shall not have +base classes. A union shall not be used as a base class. +\indextext{restriction!\idxcode{union}}% +If a union contains a non-static data member of +reference type the program is ill-formed. +\begin{note} Absent default member initializers\iref{class.mem}, +if any non-static data member of a union has a non-trivial +default constructor\iref{class.ctor}, +copy constructor, move constructor\iref{class.copy.ctor}, +copy assignment operator, move assignment operator\iref{class.copy.assign}, +or destructor\iref{class.dtor}, the corresponding member function +of the union must be user-provided or it will +be implicitly deleted\iref{dcl.fct.def.delete} for the union. \end{note} + +\pnum +\begin{example} Consider the following union: + +\begin{codeblock} +union U { + int i; + float f; + std::string s; +}; +\end{codeblock} + +Since \tcode{std::string}\iref{string.classes} declares non-trivial versions of all of the special +member functions, \tcode{U} will have an implicitly deleted default constructor, +copy/move constructor, +copy/move assignment operator, and destructor. +To use \tcode{U}, some or all of these member functions +must be user-provided.\end{example} + +\pnum +When the left operand of an assignment operator +involves a member access expression\iref{expr.ref} +that nominates a union member, +it may begin the lifetime of that union member, +as described below. +For an expression \tcode{E}, +define the set $S(\mathtt{E})$ +of subexpressions of \tcode{E} +as follows: +\begin{itemize} +\item +If \tcode{E} is of the form \tcode{A.B}, +$S(\mathtt{E})$ contains the elements of $S(\mathtt{A})$, +and also contains \tcode{A.B} +if \tcode{B} names a union member of a non-class, non-array type, +or of a class type with a trivial default constructor that is not deleted, +or an array of such types. +\item +If \tcode{E} is of the form \tcode{A[B]} +and is interpreted as a built-in array subscripting operator, +$S(\mathtt{E})$ is $S(\mathtt{A})$ if \tcode{A} is of array type, +$S(\mathtt{B})$ if \tcode{B} is of array type, +and empty otherwise. +\item +Otherwise, $S(\mathtt{E})$ is empty. +\end{itemize} +In an assignment expression of the form \tcode{E1 = E2} +that uses either the built-in assignment operator\iref{expr.ass} +or a trivial assignment operator\iref{class.copy.assign}, +for each element \tcode{X} of $S($\tcode{E1}$)$, +if modification of \tcode{X} would have undefined behavior under~\ref{basic.life}, +an object of the type of \tcode{X} is implicitly created +in the nominated storage; +no initialization is performed and +the beginning of its lifetime is sequenced after +the value computation of the left and right operands +and before the assignment. +\begin{note} +This ends the lifetime of the previously-active +member of the union, if any\iref{basic.life}. +\end{note} +\begin{example} +\begin{codeblock} +union A { int x; int y[4]; }; +struct B { A a; }; +union C { B b; int k; }; +int f() { + C c; // does not start lifetime of any union member + c.b.a.y[3] = 4; // OK: $S($\tcode{c.b.a.y[3]}$)$ contains \tcode{c.b} and \tcode{c.b.a.y}; + // creates objects to hold union members \tcode{c.b} and \tcode{c.b.a.y} + return c.b.a.y[3]; // OK: \tcode{c.b.a.y} refers to newly created object (see \ref{basic.life}) +} + +struct X { const int a; int b; }; +union Y { X x; int k; }; +void g() { + Y y = { { 1, 2 } }; // OK, \tcode{y.x} is active union member\iref{class.mem} + int n = y.x.a; + y.k = 4; // OK: ends lifetime of \tcode{y.x}, \tcode{y.k} is active member of union + y.x.b = n; // undefined behavior: \tcode{y.x.b} modified outside its lifetime, + // $S($\tcode{y.x.b}$)$ is empty because \tcode{X}'s default constructor is deleted, + // so union member \tcode{y.x}'s lifetime does not implicitly start +} +\end{codeblock} +\end{example} + +\pnum +\begin{note} In general, one must use explicit destructor calls and placement +\grammarterm{new-expression} to change the active member of a union. \end{note} +\begin{example} +Consider an object \tcode{u} of a \tcode{union} type \tcode{U} having non-static data members +\tcode{m} of type \tcode{M} and \tcode{n} of type \tcode{N}. If \tcode{M} has a non-trivial +destructor and \tcode{N} has a non-trivial constructor (for instance, if they declare or inherit +virtual functions), the active member of \tcode{u} can be safely switched from \tcode{m} to +\tcode{n} using the destructor and placement \grammarterm{new-expression} as follows: + +\begin{codeblock} +u.m.~M(); +new (&u.n) N; +\end{codeblock} +\end{example} + +\rSec2[class.union.anon]{Anonymous unions} +\indextext{\idxcode{union}!anonymous}% + +\pnum +A union of the form + +\begin{ncsimplebnf} +\terminal{union} \terminal{\{} member-specification \terminal{\}} \terminal{;} +\end{ncsimplebnf} + +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} +Nested types, anonymous unions, and functions cannot be declared within an anonymous +union. +\end{note} +The names of the members of an anonymous union shall be distinct from +the names of any other entity in the scope in which the anonymous union +is declared. For the purpose of name lookup, after the anonymous union +definition, the members of the anonymous union are considered to have +been defined in the scope in which the anonymous union is declared. +\indextext{initialization!\idxcode{union}}% +\begin{example} + +\begin{codeblock} +void f() { + union { int a; const char* p; }; + a = 1; + p = "Jennifer"; +} +\end{codeblock} + +Here \tcode{a} and \tcode{p} are used like ordinary (non-member) +variables, but since they are union members they have the same address. +\end{example} + +\pnum +\indextext{\idxcode{union}!global anonymous}% +\indextext{scope!anonymous \tcode{union} at namespace}% +Anonymous unions declared in a named namespace or in the global +namespace shall be declared \tcode{static}. Anonymous unions declared at +block scope shall be declared with any storage class allowed for a +block-scope variable, or with no storage class. A storage class is not +allowed in a declaration of an anonymous union in a class scope. +\indextext{access control!anonymous \tcode{union}}% +\indextext{restriction!anonymous \tcode{union}}% +An anonymous union shall not have private or protected +members\iref{class.access}. An anonymous union shall not have +member functions. + +\pnum +A union for which objects, pointers, or references are declared is not an anonymous union. +\begin{example} + +\begin{codeblock} +void f() { + union { int aa; char* p; } obj, *ptr = &obj; + aa = 1; // error + ptr->aa = 1; // OK +} +\end{codeblock} + +The assignment to plain \tcode{aa} is ill-formed since the member name +is not visible outside the union, and even if it were visible, it is not +associated with any particular object. +\end{example} +\begin{note} +Initialization of unions with no user-declared constructors is described +in~\ref{dcl.init.aggr}. +\end{note} + +\pnum +\indextext{class!union-like}% +\indextext{class!variant member of}% +A \defn{union-like class} is a union or a class that has an anonymous union as a direct +member. A union-like class \tcode{X} has a set of \defnx{variant members}{variant member}. +If \tcode{X} is a union, a non-static data member of \tcode{X} that is not an anonymous +union is a variant member of \tcode{X}. In addition, a non-static data member of an +anonymous union that is a member of \tcode{X} is also a variant member of \tcode{X}. +At most one variant member of a union may have a default member initializer. +\begin{example} +\begin{codeblock} +union U { + int x = 0; + union { + int k; + }; + union { + int z; + int y = 1; // error: initialization for second variant member of \tcode{U} + }; +}; +\end{codeblock} +\end{example} + +\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 \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 +access to names outside the function as does the enclosing function. +\begin{note} +A declaration in a local class +cannot odr-use\iref{basic.def.odr} +a local entity +from an +enclosing scope. +\end{note} +\begin{example} +\begin{codeblock} +int x; +void f() { + static int s; + int x; + const int N = 5; + extern int q(); + int arr[2]; + auto [y, z] = arr; + + struct local { + int g() { return x; } // error: odr-use of non-odr-usable variable \tcode{x} + int h() { return s; } // OK + int k() { return ::x; } // OK + int l() { return q(); } // OK + int m() { return N; } // OK: not an odr-use + int* n() { return &N; } // error: odr-use of non-odr-usable variable \tcode{N} + int p() { return y; } // error: odr-use of non-odr-usable structured binding \tcode{y} + }; +} + +local* p = 0; // error: \tcode{local} not in scope +\end{codeblock} +\end{example} + +\pnum +An enclosing function has no special access to members of the local +class; it obeys the usual access rules\iref{class.access}. +\indextext{member function!local class}% +Member functions of a local class shall be defined within their class +definition, if they are defined at all. + +\pnum +\indextext{nested class!local class}% +If class \tcode{X} is a local class a nested class \tcode{Y} may be +declared in class \tcode{X} and later defined in the definition of class +\tcode{X} or be later defined in the same scope as the definition of +class \tcode{X}. +\indextext{restriction!local class}% +A class nested within +a local class is a local class. + +\pnum +\indextext{restriction!static member local class}% +A local class shall not have static data members. + +\rSec1[class.derived]{Derived classes}% +\indextext{derived class|(} + +\indextext{virtual base class|see{base class, virtual}} +\indextext{virtual function|see{function, virtual}} +\indextext{dynamic binding|see{function, virtual}} + +\pnum +\indextext{base class}% +\indextext{inheritance}% +\indextext{multiple inheritance}% +A list of base classes can be specified in a class definition using +the notation: + +\begin{bnf} +\nontermdef{base-clause}\br + \terminal{:} base-specifier-list +\end{bnf} + + +\begin{bnf} +\nontermdef{base-specifier-list}\br + base-specifier \opt{\terminal{...}}\br + base-specifier-list \terminal{,} base-specifier \opt{\terminal{...}} +\end{bnf} + +\begin{bnf} +\nontermdef{base-specifier}\br + \opt{attribute-specifier-seq} class-or-decltype\br + \opt{attribute-specifier-seq} \terminal{virtual} \opt{access-specifier} class-or-decltype\br + \opt{attribute-specifier-seq} access-specifier \opt{\terminal{virtual}} class-or-decltype +\end{bnf} + +\begin{bnf} +\nontermdef{class-or-decltype}\br + \opt{nested-name-specifier} class-name\br + nested-name-specifier \terminal{template} simple-template-id\br + decltype-specifier +\end{bnf} + +\indextext{specifier access|see{access specifier}}% +% +\begin{bnf} +\nontermdef{access-specifier}\br + \terminal{private}\br + \terminal{protected}\br + \terminal{public} +\end{bnf} + +The optional \grammarterm{attribute-specifier-seq} appertains to the \grammarterm{base-specifier}. + +\pnum +\indextext{type!incomplete}% +A \grammarterm{class-or-decltype} shall denote +a class type that is not +an incompletely defined class\iref{class}. +The class denoted by the \grammarterm{class-or-decltype} of +a \grammarterm{base-specifier} is called a +\defnx{direct base class}{base class!direct} +for the class being defined. +\indextext{base class}% +\indextext{derivation|see{inheritance}}% +During the lookup for a base class name, non-type names are +ignored\iref{basic.scope.hiding}. If the name found is not a +\grammarterm{class-name}, the program is ill-formed. A class \tcode{B} is a +base class of a class \tcode{D} if it is a direct base class of +\tcode{D} or a direct base class of one of \tcode{D}'s base classes. +A class is an \defnx{indirect}{base class!indirect} base class of another if it is a base +class but not a direct base class. A class is said to be (directly or +indirectly) \term{derived} from its (direct or indirect) base +classes. +\begin{note} +See \ref{class.access} for the meaning of +\grammarterm{access-specifier}. +\end{note} +\indextext{access control!base class member}% +Unless redeclared in the derived class, members of a base class are also +considered to be members of the derived class. +Members of a base class other than constructors are said to be +\defnx{inherited}{inheritance} +by the derived class. Constructors of a base class +can also be inherited as described in~\ref{namespace.udecl}. +Inherited members can be referred to in +expressions in the same manner as other members of the derived class, +unless their names are hidden or ambiguous\iref{class.member.lookup}. +\indextext{operator!scope resolution}% +\begin{note} +The scope resolution operator \tcode{::}\iref{expr.prim.id.qual} can be used +to refer to a direct or indirect base member explicitly. This allows +access to a name that has been redeclared in the derived class. A +derived class can itself serve as a base class subject to access +control; see~\ref{class.access.base}. A pointer to a derived class can be +implicitly converted to a pointer to an accessible unambiguous base +class\iref{conv.ptr}. An lvalue of a derived class type can be bound +to a reference to an accessible unambiguous base +class\iref{dcl.init.ref}. +\end{note} + +\pnum +The \grammarterm{base-specifier-list} specifies the type of the +\term{base class subobjects} contained in an +object of the derived class type. +\begin{example} +\begin{codeblock} +struct Base { + int a, b, c; +}; +\end{codeblock} + +\begin{codeblock} +struct Derived : Base { + int b; +}; +\end{codeblock} + +\begin{codeblock} +struct Derived2 : Derived { + int c; +}; +\end{codeblock} + +Here, an object of class \tcode{Derived2} will have a subobject of class +\tcode{Derived} which in turn will have a subobject of class +\tcode{Base}. +\end{example} + +\pnum +A \grammarterm{base-specifier} followed by an ellipsis is a pack +expansion\iref{temp.variadic}. + +\pnum +The order in which the base class subobjects are allocated in the most +derived object\iref{intro.object} is unspecified. +\begin{note} +\indextext{directed acyclic graph|see{DAG}}% +\indextext{lattice|see{DAG, subobject}}% +A derived class and its base class subobjects can be represented by a +directed acyclic graph (DAG) where an arrow means ``directly derived +from''. An arrow need not have a physical representation in memory. +A DAG of subobjects is often referred to as a ``subobject lattice''. + +\begin{importgraphic} +{Directed acyclic graph} +{fig:dag} +{figdag.pdf} +\end{importgraphic} +\end{note} + +\pnum +\begin{note} +Initialization of objects representing base classes can be specified in +constructors; see~\ref{class.base.init}. +\end{note} + +\pnum +\begin{note} +A base class subobject might have a layout\iref{basic.stc} different +from the layout of a most derived object of the same type. A base class +subobject might have a polymorphic behavior\iref{class.cdtor} +different from the polymorphic behavior of a most derived object of the +same type. A base class subobject may be of zero size\iref{class}; +however, two subobjects that have the same class type and that belong to +the same most derived object must not be allocated at the same +address\iref{expr.eq}. +\end{note} + +\rSec2[class.mi]{Multiple base classes} +\indextext{multiple inheritance}% +\indextext{base class}% + +\pnum +A class can be derived from any number of base classes. +\begin{note} +The use of more than one direct base class is often called multiple inheritance. +\end{note} +\begin{example} +\begin{codeblock} +class A { @\commentellip@ }; +class B { @\commentellip@ }; +class C { @\commentellip@ }; +class D : public A, public B, public C { @\commentellip@ }; +\end{codeblock} +\end{example} + +\pnum +\indextext{layout!class object}% +\indextext{initialization!order of}% +\begin{note} +The order of derivation is not significant except as specified by the +semantics of initialization by constructor\iref{class.base.init}, +cleanup\iref{class.dtor}, and storage +layout~(\ref{class.mem}, \ref{class.access.spec}). +\end{note} + +\pnum +A class shall not be specified as a direct base class of a derived class +more than once. +\begin{note} +A class can be an indirect base class more than once and can be a direct +and an indirect base class. There are limited things that can be done +with such a class. The non-static data members and member functions of +the direct base class cannot be referred to in the scope of the derived +class. However, the static members, enumerations and types can be +unambiguously referred to. +\end{note} +\begin{example} +\begin{codeblock} +class X { @\commentellip@ }; +class Y : public X, public X { @\commentellip@ }; // ill-formed + +\end{codeblock} +\begin{codeblock} +class L { public: int next; @\commentellip@ }; +class A : public L { @\commentellip@ }; +class B : public L { @\commentellip@ }; +class C : public A, public B { void f(); @\commentellip@ }; // well-formed +class D : public A, public L { void f(); @\commentellip@ }; // well-formed +\end{codeblock} +\end{example} + +\pnum +\indextext{base class!virtual}% +A base class specifier that does not contain the keyword +\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\iref{intro.object} shall contain a +corresponding distinct base class subobject of that type. For each +distinct base class that is specified virtual, the most derived object +shall contain a single base class subobject of that type. + +\pnum +\begin{note} +For an object of class type \tcode{C}, each distinct occurrence of a +(non-virtual) base class \tcode{L} in the class lattice of \tcode{C} +corresponds one-to-one with a distinct \tcode{L} subobject within the +object of type \tcode{C}. Given the class \tcode{C} defined above, an +object of class \tcode{C} will have two subobjects of class \tcode{L} as +shown in Figure~\ref{fig:nonvirt}. + +\begin{importgraphic} +{Non-virtual base} +{fig:nonvirt} +{fignonvirt.pdf} +\end{importgraphic} + +In such lattices, explicit qualification can be used to specify which +subobject is meant. The body of function \tcode{C::f} could refer to the +member \tcode{next} of each \tcode{L} subobject: +\begin{codeblock} +void C::f() { A::next = B::next; } // well-formed +\end{codeblock} +Without the \tcode{A::} or \tcode{B::} qualifiers, the definition of +\tcode{C::f} above would be ill-formed because of +ambiguity\iref{class.member.lookup}. +\end{note} + +\pnum +\begin{note} +In contrast, consider the case with a virtual base class: +\begin{codeblock} +class V { @\commentellip@ }; +class A : virtual public V { @\commentellip@ }; +class B : virtual public V { @\commentellip@ }; +class C : public A, public B { @\commentellip@ }; +\end{codeblock} +\begin{importgraphic} +{Virtual base} +{fig:virt} +{figvirt.pdf} +\end{importgraphic} +For an object \tcode{c} of class type \tcode{C}, a single subobject of +type \tcode{V} is shared by every base class subobject of \tcode{c} that has a +\tcode{virtual} base class of type \tcode{V}. Given the class \tcode{C} +defined above, an object of class \tcode{C} will have one subobject of +class \tcode{V}, as shown in Figure~\ref{fig:virt}. +\indextext{DAG!multiple inheritance}% +\indextext{DAG!virtual base class}% +\end{note} + +\pnum +\begin{note} +A class can have both virtual and non-virtual base classes of a given +type. +\begin{codeblock} +class B { @\commentellip@ }; +class X : virtual public B { @\commentellip@ }; +class Y : virtual public B { @\commentellip@ }; +class Z : public B { @\commentellip@ }; +class AA : public X, public Y, public Z { @\commentellip@ }; +\end{codeblock} +For an object of class \tcode{AA}, all \tcode{virtual} occurrences of +base class \tcode{B} in the class lattice of \tcode{AA} correspond to a +single \tcode{B} subobject within the object of type \tcode{AA}, and +every other occurrence of a (non-virtual) base class \tcode{B} in the +class lattice of \tcode{AA} corresponds one-to-one with a distinct +\tcode{B} subobject within the object of type \tcode{AA}. Given the +class \tcode{AA} defined above, class \tcode{AA} has two subobjects of +class \tcode{B}: \tcode{Z}'s \tcode{B} and the virtual \tcode{B} shared +by \tcode{X} and \tcode{Y}, as shown in Figure~\ref{fig:virtnonvirt}. + +\indextext{DAG!virtual base class}% +\indextext{DAG!non-virtual base class}% +\indextext{DAG!multiple inheritance}% +\begin{importgraphic} +{Virtual and non-virtual base} +{fig:virtnonvirt} +{figvirtnonvirt.pdf} +\end{importgraphic} +\end{note} + +\rSec2[class.virtual]{Virtual functions}% +\indextext{function!virtual|(}% +\indextext{type!polymorphic}% + +\pnum +\begin{note} +Virtual functions support dynamic binding and object-oriented +programming. \end{note} A class that declares or inherits a virtual function is +called a \defnx{polymorphic class}{class!polymorphic}. + +\pnum +If a virtual member function \tcode{vf} is declared in a class +\tcode{Base} and in a class \tcode{Derived}, derived directly or +indirectly from \tcode{Base}, a member function \tcode{vf} with the same +name, parameter-type-list\iref{dcl.fct}, cv-qualification, and ref-qualifier +(or absence of same) as +\tcode{Base::vf} is declared, then \tcode{Derived::vf} is also virtual +(whether or not it is so declared) and it \term{overrides}\footnote{A function with the same name but a different parameter list\iref{over} +as a virtual function is not necessarily virtual and +does not override. The use of the \tcode{virtual} specifier in the +declaration of an overriding function is legal but redundant (has empty +semantics). Access control\iref{class.access} is not considered in +determining overriding.} +\tcode{Base::vf}. For convenience we say that any virtual function +overrides itself. +\indextext{overrider!final}% +A virtual member function \tcode{C::vf} of a class object \tcode{S} is a \defn{final +overrider} unless the most derived class\iref{intro.object} of which \tcode{S} is a +base class subobject (if any) declares or inherits another member function that overrides +\tcode{vf}. In a derived class, if a virtual member function of a base class subobject +has more than one final overrider the program is ill-formed. +\begin{example} +\begin{codeblock} +struct A { + virtual void f(); +}; +struct B : virtual A { + virtual void f(); +}; +struct C : B , virtual A { + using A::f; +}; + +void foo() { + C c; + c.f(); // calls \tcode{B::f}, the final overrider + c.C::f(); // calls \tcode{A::f} because of the using-declaration +} +\end{codeblock} +\end{example} + +\begin{example} +\begin{codeblock} +struct A { virtual void f(); }; +struct B : A { }; +struct C : A { void f(); }; +struct D : B, C { }; // OK: \tcode{A::f} and \tcode{C::f} are the final overriders + // for the \tcode{B} and \tcode{C} subobjects, respectively +\end{codeblock} +\end{example} + +\pnum +\begin{note} +A virtual member function does not have to be visible to be overridden, +for example, +\begin{codeblock} +struct B { + virtual void f(); +}; +struct D : B { + void f(int); +}; +struct D2 : D { + void f(); +}; +\end{codeblock} +the function \tcode{f(int)} in class \tcode{D} hides the virtual +function \tcode{f()} in its base class \tcode{B}; \tcode{D::f(int)} is +not a virtual function. However, \tcode{f()} declared in class +\tcode{D2} has the same name and the same parameter list as +\tcode{B::f()}, and therefore is a virtual function that overrides the +function \tcode{B::f()} even though \tcode{B::f()} is not visible in +class \tcode{D2}. +\end{note} + +\pnum +If a virtual function \tcode{f} in some class \tcode{B} is marked with the +\grammarterm{virt-specifier} \tcode{final} and in a class \tcode{D} derived from \tcode{B} +a function \tcode{D::f} overrides \tcode{B::f}, the program is ill-formed. \begin{example} +\begin{codeblock} +struct B { + virtual void f() const final; +}; + +struct D : B { + void f() const; // error: \tcode{D::f} attempts to override \tcode{final} \tcode{B::f} +}; +\end{codeblock} +\end{example} + +\pnum +If a virtual function is marked with the \grammarterm{virt-specifier} \tcode{override} and +does not override a member function of a base class, the program is ill-formed. \begin{example} +\begin{codeblock} +struct B { + virtual void f(int); +}; + +struct D : B { + virtual void f(long) override; // error: wrong signature overriding \tcode{B::f} + virtual void f(int) override; // OK +}; +\end{codeblock} +\end{example} + +\pnum +A virtual function shall not have a trailing \grammarterm{requires-clause}\iref{dcl.decl}. +\begin{example} +\begin{codeblock} +struct A { + virtual void f() requires true; // error: virtual function cannot be constrained\iref{temp.constr.decl} +}; +\end{codeblock} +\end{example} + +\pnum +Even though destructors are not inherited, a destructor in a derived +class overrides a base class destructor declared virtual; +see~\ref{class.dtor} and~\ref{class.free}. + +\pnum +The return type of an overriding function shall be either identical to +the return type of the overridden function or \defnx{covariant}{return type!covariant} with +the classes of the functions. If a function \tcode{D::f} overrides a +function \tcode{B::f}, the return types of the functions are covariant +if they satisfy the following criteria: +\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.% +} + +\item the class in the return type of \tcode{B::f} is the same class as +the class in the return type of \tcode{D::f}, or is an unambiguous and +accessible direct or indirect base class of the class in the return type +of \tcode{D::f} + +\item both pointers or references have the same cv-qualification and the +class type in the return type of \tcode{D::f} has the same +cv-qualification as or less cv-qualification than the class type in the +return type of \tcode{B::f}. +\end{itemize} + +\pnum +If the class type in the covariant return type of \tcode{D::f} differs from that of +\tcode{B::f}, the class type in the return type of \tcode{D::f} shall be +complete at the point of declaration of \tcode{D::f} or shall be the +class type \tcode{D}. When the overriding function is called as the +final overrider of the overridden function, its result is converted to +the type returned by the (statically chosen) overridden +function\iref{expr.call}. +\begin{example} +\begin{codeblock} +class B { }; +class D : private B { friend class Derived; }; +struct Base { + virtual void vf1(); + virtual void vf2(); + virtual void vf3(); + virtual B* vf4(); + virtual B* vf5(); + void f(); +}; + +struct No_good : public Base { + D* vf4(); // error: \tcode{B} (base class of \tcode{D}) inaccessible +}; + +class A; +struct Derived : public Base { + void vf1(); // virtual and overrides \tcode{Base::vf1()} + void vf2(int); // not virtual, hides \tcode{Base::vf2()} + char vf3(); // error: invalid difference in return type only + D* vf4(); // OK: returns pointer to derived class + A* vf5(); // error: returns pointer to incomplete class + void f(); +}; + +void g() { + Derived d; + Base* bp = &d; // standard conversion: + // \tcode{Derived*} to \tcode{Base*} + bp->vf1(); // calls \tcode{Derived::vf1()} + bp->vf2(); // calls \tcode{Base::vf2()} + bp->f(); // calls \tcode{Base::f()} (not virtual) + B* p = bp->vf4(); // calls \tcode{Derived::vf4()} and converts the + // result to \tcode{B*} + Derived* dp = &d; + D* q = dp->vf4(); // calls \tcode{Derived::vf4()} and does not + // convert the result to \tcode{B*} + dp->vf2(); // ill-formed: argument mismatch +} +\end{codeblock} +\end{example} + +\pnum +\begin{note} +The interpretation of the call of a virtual function depends on the type +of the object for which it is called (the dynamic type), whereas the +interpretation of a call of a non-virtual member function depends only +on the type of the pointer or reference denoting that object (the static +type)\iref{expr.call}. +\end{note} + +\pnum +\begin{note} +The \tcode{virtual} specifier implies membership, so a virtual function +cannot be a non-member\iref{dcl.fct.spec} function. Nor can a virtual +function be a static member, since a virtual function call relies on a +specific object for determining which function to invoke. A virtual +function declared in one class can be declared a friend~(\ref{class.friend}) in +another class. +\end{note} + +\pnum +\indextext{definition!virtual function}% +A virtual function declared in a class shall be defined, or declared +pure\iref{class.abstract} in that class, or both; no diagnostic is +required\iref{basic.def.odr}. +\indextext{friend!\tcode{virtual} and}% + +\pnum +\indextext{multiple inheritance!\tcode{virtual} and}% +\begin{example} +Here are some uses of virtual functions with multiple base classes: +\begin{codeblock} +struct A { + virtual void f(); +}; + +struct B1 : A { // note non-virtual derivation + void f(); +}; + +struct B2 : A { + void f(); +}; + +struct D : B1, B2 { // \tcode{D} has two separate \tcode{A} subobjects +}; + +void foo() { + D d; +//\tcode{ A* ap = \&d;} // would be ill-formed: ambiguous + B1* b1p = &d; + A* ap = b1p; + D* dp = &d; + ap->f(); // calls \tcode{D::B1::f} + dp->f(); // ill-formed: ambiguous +} +\end{codeblock} +In class \tcode{D} above there are two occurrences of class \tcode{A} +and hence two occurrences of the virtual member function \tcode{A::f}. +The final overrider of \tcode{B1::A::f} is \tcode{B1::f} and the final +overrider of \tcode{B2::A::f} is \tcode{B2::f}. +\end{example} + +\pnum +\begin{example} +The following example shows a function that does not have a unique final +overrider: +\begin{codeblock} +struct A { + virtual void f(); +}; + +struct VB1 : virtual A { // note virtual derivation + void f(); +}; + +struct VB2 : virtual A { + void f(); +}; + +struct Error : VB1, VB2 { // ill-formed +}; + +struct Okay : VB1, VB2 { + void f(); +}; +\end{codeblock} +Both \tcode{VB1::f} and \tcode{VB2::f} override \tcode{A::f} but there +is no overrider of both of them in class \tcode{Error}. This example is +therefore ill-formed. Class \tcode{Okay} is well-formed, however, +because \tcode{Okay::f} is a final overrider. +\end{example} + +\pnum +\begin{example} +The following example uses the well-formed classes from above. +\begin{codeblock} +struct VB1a : virtual A { // does not declare \tcode{f} +}; + +struct Da : VB1a, VB2 { +}; + +void foe() { + VB1a* vb1ap = new Da; + vb1ap->f(); // calls \tcode{VB2::f} +} +\end{codeblock} +\end{example} + +\pnum +\indextext{operator!scope resolution}% +\indextext{virtual function call}% +Explicit qualification with the scope operator\iref{expr.prim.id.qual} +suppresses the virtual call mechanism. +\begin{example} +\begin{codeblock} +class B { public: virtual void f(); }; +class D : public B { public: void f(); }; + +void D::f() { @\commentellip@ B::f(); } +\end{codeblock} + +Here, the function call in +\tcode{D::f} +really does call +\tcode{B::f} +and not +\tcode{D::f}. +\end{example} + +\pnum +A function with a deleted definition\iref{dcl.fct.def} shall +not override a function that does not have a deleted definition. Likewise, +a function that does not have a deleted definition shall not override a +function with a deleted definition.% +\indextext{function!virtual|)} + +\pnum +If an overriding function specifies contract conditions\iref{dcl.attr.contract}, +it shall specify the same list of contract conditions as +its overridden functions; +no diagnostic is required +if corresponding conditions will always evaluate to the same value. +Otherwise, it is considered to have +the list of contract conditions from one of its overridden functions; +the names in the contract conditions are bound, +and the semantic constraints are checked, +at the point where the contract conditions appear. +Given a virtual function \tcode{f} +with a contract condition that odr-uses \tcode{*this}\iref{basic.def.odr}, +the class of which \tcode{f} is a direct member +shall be be an unambiguous and accessible base class of any class +in which \tcode{f} is overridden. +If a function overrides more than one function, +all of the overridden functions shall have +the same list of contract conditions\iref{dcl.attr.contract}; +no diagnostic is required +if corresponding conditions will always evaluate to the same value. +\begin{example} +\begin{codeblock} +struct A { + virtual void g() [[expects: x == 0]]; + int x = 42; +}; + +int x = 42; +struct B { + virtual void g() [[expects: x == 0]]; +} + +struct C : A, B { + virtual void g(); // error: preconditions of overridden functions are not the same +}; +\end{codeblock} +\end{example} + +\rSec2[class.abstract]{Abstract classes}% + +\pnum +\begin{note} +The abstract class mechanism supports the notion of a general concept, +such as a \tcode{shape}, of which only more concrete variants, such as +\tcode{circle} and \tcode{square}, can actually be used. An abstract +class can also be used to define an interface for which derived classes +provide a variety of implementations. +\end{note} + +\pnum +A virtual function is specified as +a \defnx{pure virtual function}{function!virtual!pure} by using a +\grammarterm{pure-specifier}\iref{class.mem} in the function declaration +in the class definition. +\begin{note} +Such a function might be inherited: see below. +\end{note} +A class is an \defnx{abstract class}{class!abstract} +if it has at least one pure virtual function. +\begin{note} +An abstract class can be used only as a base class of some other class; +no objects of an abstract class can be created +except as subobjects of a class +derived from it~(\ref{basic.def}, \ref{class.mem}). +\end{note} +\indextext{definition!pure virtual function}% +A pure virtual function need be defined only if called with, or as if +with\iref{class.dtor}, the \grammarterm{qualified-id} +syntax\iref{expr.prim.id.qual}. +\begin{example} +\begin{codeblock} +class point { @\commentellip@ }; +class shape { // abstract class + point center; +public: + point where() { return center; } + void move(point p) { center=p; draw(); } + virtual void rotate(int) = 0; // pure virtual + virtual void draw() = 0; // pure virtual +}; +\end{codeblock} +\end{example} +\begin{note} +A function declaration cannot provide both a \grammarterm{pure-specifier} +and a definition +\end{note} +\begin{example} +\begin{codeblock} +struct C { + virtual void f() = 0 { }; // ill-formed +}; +\end{codeblock} +\end{example} + +\pnum +\begin{note} +An abstract class type cannot be used +as a parameter or return type of +a function being defined\iref{dcl.fct} or called\iref{expr.call}, +except as specified in \ref{dcl.type.simple}. +Further, an abstract class type cannot be used as +the type of an explicit type conversion~(\ref{expr.static.cast}, +\ref{expr.reinterpret.cast}, \ref{expr.const.cast}), +because the resulting prvalue would be of abstract class type\iref{basic.lval}. +However, pointers and references to abstract class types +can appear in such contexts. +\end{note} + +\pnum +\indextext{function!virtual!pure}% +A class is abstract if it contains or inherits at least one pure virtual +function for which the final overrider is pure virtual. +\begin{example} +\begin{codeblock} +class ab_circle : public shape { + int radius; +public: + void rotate(int) { } + // \tcode{ab_circle::draw()} is a pure virtual +}; +\end{codeblock} + +Since \tcode{shape::draw()} is a pure virtual function +\tcode{ab_circle::draw()} is a pure virtual by default. The alternative +declaration, +\begin{codeblock} +class circle : public shape { + int radius; +public: + void rotate(int) { } + void draw(); // a definition is required somewhere +}; +\end{codeblock} +would make class \tcode{circle} non-abstract and a definition of +\tcode{circle::draw()} must be provided. +\end{example} + +\pnum +\begin{note} +An abstract class can be derived from a class that is not abstract, and +a pure virtual function may override a virtual function which is not +pure. +\end{note} + +\pnum +\indextext{class!constructor and abstract}% +Member functions can be called from a constructor (or destructor) of an +abstract class; +\indextext{virtual function call!undefined pure}% +the effect of making a virtual call\iref{class.virtual} to a pure +virtual function directly or indirectly for the object being created (or +destroyed) from such a constructor (or destructor) is undefined.% +\indextext{derived class|)} + +\rSec1[class.member.lookup]{Member name lookup}% +\indextext{lookup!member name}% +\indextext{ambiguity!base class member}% +\indextext{ambiguity!member access} + +\pnum +Member name lookup determines the meaning of a name +(\grammarterm{id-expression}) in a class scope\iref{basic.scope.class}. +Name lookup can result in an \term{ambiguity}, in which case the +program is ill-formed. For an \grammarterm{id-expression}, name lookup +begins in the class scope of \tcode{this}; for a +\grammarterm{qualified-id}, name lookup begins in the scope of the +\grammarterm{nested-name-specifier}. Name lookup takes place before access +control~(\ref{basic.lookup}, \ref{class.access}). + +\pnum +The following steps define the result of name lookup for a member name +\tcode{f} in a class scope \tcode{C}. + +\pnum +The \term{lookup set} for \tcode{f} in \tcode{C}, called $S(f,C)$, +consists of two component sets: the \term{declaration set}, a set of +members named \tcode{f}; and the \term{subobject set}, a set of +subobjects where declarations of these members (possibly including +\grammarterm{using-declaration}{s}) were found. In the declaration set, +\grammarterm{using-declaration}{s} are replaced by the +set of designated members that are not hidden or overridden by members of the +derived class\iref{namespace.udecl}, +and type declarations (including injected-class-names) are +replaced by the types they designate. $S(f,C)$ is calculated as follows: + +\pnum +If \tcode{C} contains a declaration of the name \tcode{f}, the +declaration set contains every declaration of \tcode{f} declared in +\tcode{C} that satisfies the requirements of the language construct in +which the lookup occurs. +\begin{note} +Looking up a name in an +\grammarterm{elaborated-type-specifier}\iref{basic.lookup.elab} or +\grammarterm{base-specifier}\iref{class.derived}, for instance, +ignores all non-type declarations, while looking up a name in a +\grammarterm{nested-name-specifier}\iref{basic.lookup.qual} ignores +function, variable, and enumerator declarations. As another example, +looking up a name in a +\grammarterm{using-declaration}\iref{namespace.udecl} includes the +declaration of a class or enumeration that would ordinarily be hidden by +another declaration of that name in the same scope. +\end{note} +If the resulting declaration set is not empty, the subobject set +contains \tcode{C} itself, and calculation is complete. + +\pnum +Otherwise (i.e., \tcode{C} does not contain a declaration of \tcode{f} +or the resulting declaration set is empty), $S(f,C)$ is initially empty. +If \tcode{C} has base classes, calculate the lookup set for \tcode{f} in +each direct base class subobject $B_i$, and merge each such lookup set +$S(f,B_i)$ in turn into $S(f,C)$. + +\pnum +The following steps define the result of merging lookup set $S(f,B_i)$ +into the intermediate $S(f,C)$: + +\begin{itemize} +\item If each of the subobject members of $S(f,B_i)$ is a base class +subobject of at least one of the subobject members of $S(f,C)$, or if +$S(f,B_i)$ is empty, $S(f,C)$ is unchanged and the merge is complete. +Conversely, if each of the subobject members of $S(f,C)$ is a base class +subobject of at least one of the subobject members of $S(f,B_i)$, or if +$S(f,C)$ is empty, the new $S(f,C)$ is a copy of $S(f,B_i)$. + +\item Otherwise, if the declaration sets of $S(f,B_i)$ and $S(f,C)$ +differ, the merge is ambiguous: the new $S(f,C)$ is a lookup set with an +invalid declaration set and the union of the subobject sets. In +subsequent merges, an invalid declaration set is considered different +from any other. + +\item Otherwise, the new $S(f,C)$ is a lookup set with the shared set of +declarations and the union of the subobject sets. +\end{itemize} + +\pnum +The result of name lookup for \tcode{f} in \tcode{C} is the declaration +set of $S(f,C)$. If it is an invalid set, the program is ill-formed. +\begin{example} +\begin{codeblock} +struct A { int x; }; // S(x,A) = \{ \{ \tcode{A::x} \}, \{ \tcode{A} \} \} +struct B { float x; }; // S(x,B) = \{ \{ \tcode{B::x} \}, \{ \tcode{B} \} \} +struct C: public A, public B { }; // S(x,C) = \{ invalid, \{ \tcode{A} in \tcode{C}, \tcode{B} in \tcode{C} \} \} +struct D: public virtual C { }; // S(x,D) = S(x,C) +struct E: public virtual C { char x; }; // S(x,E) = \{ \{ \tcode{E::x} \}, \{ \tcode{E} \} \} +struct F: public D, public E { }; // S(x,F) = S(x,E) +int main() { + F f; + f.x = 0; // OK, lookup finds \tcode{E::x} +} +\end{codeblock} + +$S(x,F)$ is unambiguous because the \tcode{A} and \tcode{B} base +class subobjects of \tcode{D} are also base class subobjects of \tcode{E}, so +$S(x,D)$ is discarded in the first merge step. +\end{example} + +\pnum +\indextext{access control!overload resolution and}% +If the name of an overloaded function is unambiguously found, +overload resolution\iref{over.match} also takes place before access +control. +\indextext{overloading!resolution!scoping ambiguity}% +Ambiguities can often be resolved by qualifying a name with its class name. +\begin{example} +\begin{codeblock} +struct A { + int f(); +}; + +\end{codeblock} +\begin{codeblock} +struct B { + int f(); +}; + +\end{codeblock} +\begin{codeblock} +struct C : A, B { + int f() { return A::f() + B::f(); } +}; +\end{codeblock} +\end{example} + +\pnum +\begin{note} +A static member, a nested type or an enumerator defined in a base class +\tcode{T} can unambiguously be found even if an object has more than one +base class subobject of type \tcode{T}. Two base class subobjects share +the non-static member subobjects of their common virtual base classes. +\end{note} +\begin{example} +\begin{codeblock} +struct V { + int v; +}; +struct A { + int a; + static int s; + enum { e }; +}; +struct B : A, virtual V { }; +struct C : A, virtual V { }; +struct D : B, C { }; + +void f(D* pd) { + pd->v++; // OK: only one \tcode{v} (virtual) + pd->s++; // OK: only one \tcode{s} (static) + int i = pd->e; // OK: only one \tcode{e} (enumerator) + pd->a++; // error, ambiguous: two \tcode{a}{s} in \tcode{D} +} +\end{codeblock} +\end{example} + +\pnum +\begin{note} +\indextext{dominance!virtual base class}% +When virtual base classes are used, a hidden declaration can be reached +along a path through the subobject lattice that does not pass through +the hiding declaration. This is not an ambiguity. The identical use with +non-virtual base classes is an ambiguity; in that case there is no +unique instance of the name that hides all the others. +\end{note} +\begin{example} +\begin{codeblock} +struct V { int f(); int x; }; +struct W { int g(); int y; }; +struct B : virtual V, W { + int f(); int x; + int g(); int y; +}; +struct C : virtual V, W { }; + +struct D : B, C { void glorp(); }; +\end{codeblock} + +\begin{importgraphic} +{Name lookup} +{fig:name} +{figname.pdf} +\end{importgraphic} + +The names declared in \tcode{V} and the left-hand instance of \tcode{W} +are hidden by those in \tcode{B}, but the names declared in the +right-hand instance of \tcode{W} are not hidden at all. +\begin{codeblock} +void D::glorp() { + x++; // OK: \tcode{B::x} hides \tcode{V::x} + f(); // OK: \tcode{B::f()} hides \tcode{V::f()} + y++; // error: \tcode{B::y} and \tcode{C}'s \tcode{W::y} + g(); // error: \tcode{B::g()} and \tcode{C}'s \tcode{W::g()} +} +\end{codeblock} +\end{example} +\indextext{ambiguity!class conversion}% + +\pnum +An explicit or implicit conversion from a pointer to or +an expression designating an object +of a +derived class to a pointer or reference to one of its base classes shall +unambiguously refer to a unique object representing the base class. +\begin{example} +\begin{codeblock} +struct V { }; +struct A { }; +struct B : A, virtual V { }; +struct C : A, virtual V { }; +struct D : B, C { }; + +void g() { + D d; + B* pb = &d; + A* pa = &d; // error, ambiguous: \tcode{C}'s \tcode{A} or \tcode{B}'s \tcode{A}? + V* pv = &d; // OK: only one \tcode{V} subobject +} +\end{codeblock} +\end{example} + +\pnum +\begin{note} +Even if the result of name lookup is unambiguous, use of a name found in +multiple subobjects might still be +ambiguous~(\ref{conv.mem}, \ref{expr.ref}, \ref{class.access.base}).\end{note} +\begin{example} +\begin{codeblock} +struct B1 { + void f(); + static void f(int); + int i; +}; +struct B2 { + void f(double); +}; +struct I1: B1 { }; +struct I2: B1 { }; + +struct D: I1, I2, B2 { + using B1::f; + using B2::f; + void g() { + f(); // Ambiguous conversion of \tcode{this} + f(0); // Unambiguous (static) + f(0.0); // Unambiguous (only one \tcode{B2}) + int B1::* mpB1 = &D::i; // Unambiguous + int D::* mpD = &D::i; // Ambiguous conversion + } +}; +\end{codeblock}\end{example} + +\rSec1[class.access]{Member access control}% +\indextext{access control|(} + +\indextext{protection|see{access control}} +\indextext{\idxcode{private}|see{access control, \tcode{private}}} +\indextext{\idxcode{protected}|see{access control, \tcode{protected}}} +\indextext{\idxcode{public}|see{access control, \tcode{public}}} + +\pnum +A member of a class can be +\begin{itemize} +\item +\indextext{access control!\idxcode{private}}% +private; +that is, its name can be used only by members and friends +of the class in which it is declared. +\item +\indextext{access control!\idxcode{protected}}% +protected; +that is, its name can be used only by members and friends +of the class in which it is declared, by classes derived from that class, and by their +friends (see~\ref{class.protected}). +\item +\indextext{access control!\idxcode{public}}% +public; +that is, its name can be used anywhere without access restriction. +\end{itemize} + +\pnum +A member of a class can also access all the names to which the class has access. +A local class of a member function may access +the same names that the member function itself may access.\footnote{Access +permissions are thus transitive and cumulative to nested +and local classes.} + +\pnum +\indextext{access control!member name}% +\indextext{default access control|see{access control, default}}% +\indextext{access control!default}% +Members of a class defined with the keyword +\tcode{class} +are +\tcode{private} +by default. +Members of a class defined with the keywords +\tcode{struct} or \tcode{union} +are public by default. +\begin{example} + +\begin{codeblock} +class X { + int a; // \tcode{X::a} is private by default +}; + +struct S { + int a; // \tcode{S::a} is public by default +}; +\end{codeblock} +\end{example} + +\pnum +Access control is applied uniformly to all names, whether the names are +referred to from declarations or expressions. +\begin{note} +Access control applies to names nominated by +friend declarations\iref{class.friend} and +\grammarterm{using-declaration}{s}\iref{namespace.udecl}. +\end{note} +In the case of overloaded function names, access control is applied to +the function selected by overload resolution. +\begin{note} +Because access control applies to names, if access control is applied to a +typedef name, only the accessibility of the typedef name itself is considered. +The accessibility of the entity referred to by the typedef is not considered. +For example, + +\begin{codeblock} +class A { + class B { }; +public: + typedef B BB; +}; + +void f() { + A::BB x; // OK, typedef name \tcode{A::BB} is public + A::B y; // access error, \tcode{A::B} is private +} +\end{codeblock} +\end{note} + +\pnum +\begin{note} +Access to members and base classes is controlled, not their +visibility\iref{basic.scope.hiding}. +Names of members are still visible, and implicit conversions to base +classes are still considered, when those members and base classes are +inaccessible. +\end{note} +The interpretation of a given construct is +established without regard to access control. +If the interpretation +established makes use of inaccessible member names or base classes, +the construct is ill-formed. + +\pnum +All access controls in \ref{class.access} affect the ability to access a class member +name from the declaration of a particular +entity, including parts of the declaration preceding the name of the entity +being declared and, if the entity is a class, the definitions of members of +the class appearing outside the class's \grammarterm{member-specification}{.} +\begin{note} This access also applies to implicit references to constructors, +conversion functions, and destructors. \end{note} + +\pnum +\begin{example} +\begin{codeblock} +class A { + typedef int I; // private member + I f(); + friend I g(I); + static I x; + template struct Q; + template friend struct R; +protected: + struct B { }; +}; + +A::I A::f() { return 0; } +A::I g(A::I p = A::x); +A::I g(A::I p) { return 0; } +A::I A::x = 0; +template struct A::Q { }; +template struct R { }; + +struct D: A::B, A { }; +\end{codeblock} + +Here, all the uses of +\tcode{A::I} +are well-formed because +\tcode{A::f}, +\tcode{A::x}, and \tcode{A::Q} +are members of class +\tcode{A} +and +\tcode{g} +and \tcode{R} are friends of class +\tcode{A}. +This implies, for example, that access checking on the first use of +\tcode{A::I} +must be deferred until it is determined that this use of +\tcode{A::I} +is as the return type of a member of class +\tcode{A}. +Similarly, the use of \tcode{A::B} as a +\grammarterm{base-specifier} is well-formed because \tcode{D} +is derived from \tcode{A}, so checking of \grammarterm{base-specifier}{s} +must be deferred until the entire \grammarterm{base-specifier-list} has been seen. +\end{example} + +\pnum +\indextext{argument!access checking and default}% +\indextext{access control!default argument}% +The names in a default argument\iref{dcl.fct.default} are +bound at the point of declaration, and access is checked at that +point rather than at any points of use of the default argument. +Access checking for default arguments in function templates and in +member functions of class templates is performed as described in~\ref{temp.inst}. + +\pnum +The names in a default \grammarterm{template-argument}\iref{temp.param} +have their access checked in the context in which they appear rather than at any +points of use of the default \grammarterm{template-argument}. \begin{example} +\begin{codeblock} +class B { }; +template class C { +protected: + typedef T TT; +}; + +template +class D : public U { }; + +D >* d; // access error, \tcode{C::TT} is protected +\end{codeblock} +\end{example} + +\rSec2[class.access.spec]{Access specifiers}% +\indextext{access specifier} + +\pnum +Member declarations can be labeled by an +\grammarterm{access-specifier} +(\ref{class.derived}): + +\begin{ncsimplebnf} +access-specifier \terminal{:} \opt{member-specification} +\end{ncsimplebnf} + +An +\grammarterm{access-specifier} +specifies the access rules for members following it +until the end of the class or until another +\grammarterm{access-specifier} +is encountered. +\begin{example} + +\begin{codeblock} +class X { + int a; // \tcode{X::a} is private by default: \tcode{class} used +public: + int b; // \tcode{X::b} is public + int c; // \tcode{X::c} is public +}; +\end{codeblock} +\end{example} + +\pnum +Any number of access specifiers is allowed and no particular order is required. +\begin{example} + +\begin{codeblock} +struct S { + int a; // \tcode{S::a} is public by default: \tcode{struct} used +protected: + int b; // \tcode{S::b} is protected +private: + int c; // \tcode{S::c} is private +public: + int d; // \tcode{S::d} is public +}; +\end{codeblock} +\end{example} + +\pnum +\begin{note} The effect of access control on the order of allocation +of data members is described in~\ref{class.mem}.\end{note} + +\pnum +When a member is redeclared within its class definition, +the access specified at its redeclaration shall +be the same as at its initial declaration. +\begin{example} + +\begin{codeblock} +struct S { + class A; + enum E : int; +private: + class A { }; // error: cannot change access + enum E: int { e0 }; // error: cannot change access +}; +\end{codeblock} +\end{example} + +\pnum +\begin{note} +In a derived class, the lookup of a base class name will find the +injected-class-name instead of the name of the base class in the scope +in which it was declared. The injected-class-name might be less accessible +than the name of the base class in the scope in which it was declared. +\end{note} + +\begin{example} +\begin{codeblock} +class A { }; +class B : private A { }; +class C : public B { + A* p; // error: injected-class-name \tcode{A} is inaccessible + ::A* q; // OK +}; +\end{codeblock} +\end{example} + +\rSec2[class.access.base]{Accessibility of base classes and base class members}% +\indextext{access control!base class}% +\indextext{access specifier}% +\indextext{base class!\idxcode{private}}% +\indextext{base class!\idxcode{protected}}% +\indextext{base class!\idxcode{public}} + +\pnum +If a class is declared to be a base class\iref{class.derived} for another class using the +\tcode{public} +access specifier, the +public members of the base class are accessible as +public members of the derived class and +protected members of the base class are accessible as +protected members of the derived class. +If a class is declared to be a base class for another class using the +\tcode{protected} +access specifier, the +public and protected members of the base class are accessible as +protected members of the derived class. +If a class is declared to be a base class for another class using the +private +access specifier, the +public and protected +members of the base class are accessible as private +members of the derived class.\footnote{As specified previously in \ref{class.access}, +private members of a base class remain inaccessible even to derived classes +unless friend +declarations within the base class definition are used to grant access explicitly.} + +\pnum +In the absence of an +\grammarterm{access-specifier} +for a base class, +\tcode{public} +is assumed when the derived class is +defined with the \grammarterm{class-key} +\tcode{struct} +and +\tcode{private} +is assumed when the class is +defined with the \grammarterm{class-key} +\tcode{class}. +\begin{example} + +\begin{codeblock} +class B { @\commentellip@ }; +class D1 : private B { @\commentellip@ }; +class D2 : public B { @\commentellip@ }; +class D3 : B { @\commentellip@ }; // \tcode{B} private by default +struct D4 : public B { @\commentellip@ }; +struct D5 : private B { @\commentellip@ }; +struct D6 : B { @\commentellip@ }; // \tcode{B} public by default +class D7 : protected B { @\commentellip@ }; +struct D8 : protected B { @\commentellip@ }; +\end{codeblock} + +Here +\tcode{B} +is a public base of +\tcode{D2}, +\tcode{D4}, +and +\tcode{D6}, +a private base of +\tcode{D1}, +\tcode{D3}, +and +\tcode{D5}, +and a protected base of +\tcode{D7} +and +\tcode{D8}. +\end{example} + +\pnum +\begin{note} +A member of a private base class might be inaccessible as an inherited +member name, but accessible directly. +Because of the rules on pointer conversions\iref{conv.ptr} and explicit casts\iref{expr.cast}, a conversion from a pointer to a derived class to a pointer +to an inaccessible base class might be ill-formed if an implicit conversion +is used, but well-formed if an explicit cast is used. +For example, + +\begin{codeblock} +class B { +public: + int mi; // non-static member + static int si; // static member +}; +class D : private B { +}; +class DD : public D { + void f(); +}; + +void DD::f() { + mi = 3; // error: \tcode{mi} is private in \tcode{D} + si = 3; // error: \tcode{si} is private in \tcode{D} + ::B b; + b.mi = 3; // OK (\tcode{b.mi} is different from \tcode{this->mi}) + b.si = 3; // OK (\tcode{b.si} is different from \tcode{this->si}) + ::B::si = 3; // OK + ::B* bp1 = this; // error: \tcode{B} is a private base class + ::B* bp2 = (::B*)this; // OK with cast + bp2->mi = 3; // OK: access through a pointer to \tcode{B}. +} +\end{codeblock} +\end{note} + +\pnum +A base class +\tcode{B} +of +\tcode{N} +is +\defn{accessible} +at +\placeholder{R}, +if +\begin{itemize} +\item +an invented public member of +\tcode{B} +would be a public member of +\tcode{N}, or +\item +\placeholder{R} +occurs in a member or friend of class +\tcode{N}, +and an invented public member of +\tcode{B} +would be a private or protected member of +\tcode{N}, or +\item +\placeholder{R} +occurs in a member or friend of a class +\tcode{P} +derived from +\tcode{N}, +and an invented public member of +\tcode{B} +would be a private or protected member of +\tcode{P}, or +\item +there exists a class +\tcode{S} +such that +\tcode{B} +is a base class of +\tcode{S} +accessible at +\placeholder{R} +and +\tcode{S} +is a base class of +\tcode{N} +accessible at +\placeholder{R}. +\end{itemize} + +\begin{example} +\begin{codeblock} +class B { +public: + int m; +}; + +class S: private B { + friend class N; +}; + +class N: private S { + void f() { + B* p = this; // OK because class \tcode{S} satisfies the fourth condition above: \tcode{B} is a base class of \tcode{N} + // accessible in \tcode{f()} because \tcode{B} is an accessible base class of \tcode{S} and \tcode{S} is an accessible + // base class of \tcode{N}. + } +}; +\end{codeblock} +\end{example} + +\pnum +If a base class is accessible, one can implicitly convert a pointer to +a derived class to a pointer to that base class~(\ref{conv.ptr}, \ref{conv.mem}). +\begin{note} +It follows that +members and friends of a class +\tcode{X} +can implicitly convert an +\tcode{X*} +to a pointer to a private or protected immediate base class of +\tcode{X}. +\end{note} +The access to a member is affected by the class in which the member is +named. +This naming class is the class in which the member name was looked +up and found. +\begin{note} +This class can be explicit, e.g., when a +\grammarterm{qualified-id} +is used, or implicit, e.g., when a class member access operator\iref{expr.ref} is used (including cases where an implicit +``\tcode{this->}'' +is +added). +If both a class member access operator and a +\grammarterm{qualified-id} +are used to name the member (as in +\tcode{p->T::m}), +the class naming the member is the class denoted by the +\grammarterm{nested-name-specifier} +of the +\grammarterm{qualified-id} +(that is, +\tcode{T}). +\end{note} +A member +\tcode{m} +is accessible at the point +\placeholder{R} +when named in class +\tcode{N} +if +\begin{itemize} +\item +\tcode{m} +as a member of +\tcode{N} +is public, or +\item +\tcode{m} +as a member of +\tcode{N} +is private, and +\placeholder{R} +occurs in a member or friend of class +\tcode{N}, +or +\item +\tcode{m} +as a member of +\tcode{N} +is protected, and +\placeholder{R} +occurs in a member or friend of class +\tcode{N}, +or in a member of a class +\tcode{P} +derived from +\tcode{N}, +where +\tcode{m} +as a member of +\tcode{P} +is public, private, or protected, or +\item +there exists a base class +\tcode{B} +of +\tcode{N} +that is accessible at +\placeholder{R}, +and +\tcode{m} +is accessible at +\placeholder{R} +when named in class +\tcode{B}. +\begin{example} + +\begin{codeblock} +class B; +class A { +private: + int i; + friend void f(B*); +}; +class B : public A { }; +void f(B* p) { + p->i = 1; // OK: \tcode{B*} can be implicitly converted to \tcode{A*}, and \tcode{f} has access to \tcode{i} in \tcode{A} +} +\end{codeblock} +\end{example} +\end{itemize} + +\pnum +If a class member access operator, including an implicit +``\tcode{this->}'', +is used to access a non-static data member or non-static +member function, the reference is ill-formed if the +left operand (considered as a pointer in the +``\tcode{.}'' +operator case) cannot be implicitly converted to a +pointer to the naming class of the right operand. +\begin{note} +This requirement is in addition to the requirement that +the member be accessible as named. +\end{note} + +\rSec2[class.friend]{Friends}% +\indextext{friend function!access and}% +\indextext{access control!friend function} + +\pnum +A friend of a class is a function or class that is +given permission to use the private and protected member names from the class. +A class specifies its friends, if any, by way of friend declarations. +Such declarations give special access rights to the friends, but they +do not make the nominated friends members of the befriending class. +\begin{example} +The following example illustrates the differences between +members and friends: +\indextext{friend function!member function and}% + +\begin{codeblock} +class X { + int a; + friend void friend_set(X*, int); +public: + void member_set(int); +}; + +void friend_set(X* p, int i) { p->a = i; } +void X::member_set(int i) { a = i; } + +void f() { + X obj; + friend_set(&obj,10); + obj.member_set(10); +} +\end{codeblock} +\end{example} + +\pnum +\indextext{friend!class access and}% +Declaring a class to be a friend implies that the names of private and +protected members from the class granting friendship can be accessed in the +\grammarterm{base-specifier}{s} and member declarations of the befriended +class. \begin{example} + +\begin{codeblock} +class A { + class B { }; + friend class X; +}; + +struct X : A::B { // OK: \tcode{A::B} accessible to friend + A::B mx; // OK: \tcode{A::B} accessible to member of friend + class Y { + A::B my; // OK: \tcode{A::B} accessible to nested member of friend + }; +}; +\end{codeblock} +\end{example} +\begin{example} + +\begin{codeblock} +class X { + enum { a=100 }; + friend class Y; +}; + +class Y { + int v[X::a]; // OK, \tcode{Y} is a friend of \tcode{X} +}; + +class Z { + int v[X::a]; // error: \tcode{X::a} is private +}; +\end{codeblock} +\end{example} + +A class shall not be defined in a friend declaration. \begin{example} +\begin{codeblock} +class A { + friend class B { }; // error: cannot define class in friend declaration +}; +\end{codeblock} +\end{example} + +\pnum +A friend declaration that does not declare a function +shall have one of the following forms: + +\begin{ncsimplebnf} +\terminal{friend} elaborated-type-specifier \terminal{;}\br +\terminal{friend} simple-type-specifier \terminal{;}\br +\terminal{friend} typename-specifier \terminal{;} +\end{ncsimplebnf} + +\begin{note} A friend declaration may be the +\grammarterm{declaration} in a \grammarterm{template-declaration} +(\ref{temp}, \ref{temp.friend}).\end{note} If the +type specifier in a \tcode{friend} declaration designates a (possibly +cv-qualified) class type, that class is declared as a friend; otherwise, the +friend declaration is ignored. \begin{example} + +\begin{codeblock} +class C; +typedef C Ct; + +class X1 { + friend C; // OK: \tcode{class C} is a friend +}; + +class X2 { + friend Ct; // OK: \tcode{class C} is a friend + friend D; // error: no type-name \tcode{D} in scope + friend class D; // OK: elaborated-type-specifier declares new class +}; + +template class R { + friend T; +}; + +R rc; // \tcode{class C} is a friend of \tcode{R} +R Ri; // OK: \tcode{"friend int;"} is ignored +\end{codeblock} +\end{example} + +\pnum +\indextext{friend function!linkage of}% +A function first declared in a friend declaration +has the linkage of the namespace of which it is a member\iref{basic.link}. +Otherwise, the function retains its previous linkage\iref{dcl.stc}. + +\pnum +\indextext{declaration!overloaded name and \tcode{friend}}% +When a friend +declaration refers to an overloaded name or operator, only the function specified +by the parameter types becomes a friend. +A member function of a class +\tcode{X} +can be a friend of +a class +\tcode{Y}. +\indextext{member function!friend}% +\begin{example} + +\begin{codeblock} +class Y { + friend char* X::foo(int); + friend X::X(char); // constructors can be friends + friend X::~X(); // destructors can be friends +}; +\end{codeblock} +\end{example} + +\pnum +\indextext{friend function!inline}% +A function can be defined in a friend declaration of a class if and only if the +class is a non-local class\iref{class.local}, the function name is unqualified, +and the function has namespace scope. +\begin{example} + +\begin{codeblock} +class M { + friend void f() { } // definition of global \tcode{f}, a friend of \tcode{M}, + // not the definition of a member function +}; +\end{codeblock} +\end{example} + +\pnum +Such a function is implicitly an inline function\iref{dcl.inline}. +A friend +function defined in a class is in the (lexical) scope of the class in which it is defined. +A friend function defined outside the class is not\iref{basic.lookup.unqual}. + +\pnum +No +\grammarterm{storage-class-specifier} +shall appear in the +\grammarterm{decl-specifier-seq} +of a friend declaration. + +\pnum +\indextext{friend!access specifier and}% +A name nominated by a friend declaration shall be accessible in the scope of the +class containing the friend declaration. +The meaning of the friend declaration is the same whether the friend declaration +appears in the private, protected, or public\iref{class.mem} +portion of the class +\grammarterm{member-specification}. + +\pnum +\indextext{friend!inheritance and}% +Friendship is neither inherited nor transitive. +\begin{example} + +\begin{codeblock} +class A { + friend class B; + int a; +}; + +class B { + friend class C; +}; + +class C { + void f(A* p) { + p->a++; // error: \tcode{C} is not a friend of \tcode{A} despite being a friend of a friend + } +}; + +class D : public B { + void f(A* p) { + p->a++; // error: \tcode{D} is not a friend of \tcode{A} despite being derived from a friend + } +}; +\end{codeblock} +\end{example} + +\pnum +\indextext{local class!friend}% +\indextext{friend!local class and}% +If a friend declaration appears in a local class\iref{class.local} and the +name specified is an unqualified name, a prior declaration is looked +up without considering scopes that are outside the innermost enclosing +non-class scope. +For a friend function declaration, if there is no +prior declaration, the program is ill-formed. +For a friend class +declaration, if there is no prior declaration, the class that is +specified belongs to the innermost enclosing non-class scope, but if it is +subsequently referenced, its name is not found by name lookup +until a matching declaration is provided in the innermost enclosing +non-class scope. +\begin{example} + +\begin{codeblock} +class X; +void a(); +void f() { + class Y; + extern void b(); + class A { + friend class X; // OK, but \tcode{X} is a local class, not \tcode{::X} + friend class Y; // OK + friend class Z; // OK, introduces local class \tcode{Z} + friend void a(); // error, \tcode{::a} is not considered + friend void b(); // OK + friend void c(); // error + }; + X* px; // OK, but \tcode{::X} is found + Z* pz; // error, no \tcode{Z} is found +} +\end{codeblock} +\end{example} + +\rSec2[class.protected]{Protected member access} +\indextext{access control!\idxcode{protected}}% + +\pnum +An additional access check beyond those described earlier in \ref{class.access} +is applied when a non-static data member or non-static member function is a +protected member of its naming class\iref{class.access.base}.\footnote{This +additional check does not apply to other members, +e.g., static data members or enumerator member constants.} +As described earlier, access to a protected member is granted because the +reference occurs in a friend or member of some class \tcode{C}. If the access is +to form a pointer to member\iref{expr.unary.op}, the +\grammarterm{nested-name-specifier} shall denote \tcode{C} or a class derived from +\tcode{C}. All other accesses involve a (possibly implicit) object +expression\iref{expr.ref}. In this case, the class of the object expression shall be +\tcode{C} or a class derived from \tcode{C}. +\begin{example} + +\begin{codeblock} +class B { +protected: + int i; + static int j; +}; + +class D1 : public B { +}; + +class D2 : public B { + friend void fr(B*,D1*,D2*); + void mem(B*,D1*); +}; + +void fr(B* pb, D1* p1, D2* p2) { + pb->i = 1; // ill-formed + p1->i = 2; // ill-formed + p2->i = 3; // OK (access through a \tcode{D2}) + p2->B::i = 4; // OK (access through a \tcode{D2}, even though naming class is \tcode{B}) + int B::* pmi_B = &B::i; // ill-formed + int B::* pmi_B2 = &D2::i; // OK (type of \tcode{\&D2::i} is \tcode{int B::*}) + B::j = 5; // ill-formed (not a friend of naming class \tcode{B}) + D2::j = 6; // OK (because refers to static member) +} + +void D2::mem(B* pb, D1* p1) { + pb->i = 1; // ill-formed + p1->i = 2; // ill-formed + i = 3; // OK (access through \tcode{this}) + B::i = 4; // OK (access through \tcode{this}, qualification ignored) + int B::* pmi_B = &B::i; // ill-formed + int B::* pmi_B2 = &D2::i; // OK + j = 5; // OK (because \tcode{j} refers to static member) + B::j = 6; // OK (because \tcode{B::j} refers to static member) +} + +void g(B* pb, D1* p1, D2* p2) { + pb->i = 1; // ill-formed + p1->i = 2; // ill-formed + p2->i = 3; // ill-formed +} +\end{codeblock} +\end{example} + +\rSec2[class.access.virt]{Access to virtual functions}% +\indextext{access control!virtual function} + +\pnum +The access rules\iref{class.access} for a virtual function are determined by its declaration +and are not affected by the rules for a function that later overrides it. +\begin{example} + +\begin{codeblock} +class B { +public: + virtual int f(); +}; + +class D : public B { +private: + int f(); +}; + +void f() { + D d; + B* pb = &d; + D* pd = &d; + + pb->f(); // OK: \tcode{B::f()} is public, \tcode{D::f()} is invoked + pd->f(); // error: \tcode{D::f()} is private +} +\end{codeblock} +\end{example} + +\pnum +Access is checked at the call point using the type of the expression used +to denote the object for which the member function is called +(\tcode{B*} +in the example above). +The access of the member function in the class in which it was defined +(\tcode{D} +in the example above) is in general not known. -\rSec2[class.bit]{Bit-fields}% -\indextext{bit-field} +\rSec2[class.paths]{Multiple access}% +\indextext{access control!multiple access} \pnum -A \grammarterm{member-declarator} of the form +If a name can be reached by several paths through a multiple inheritance +graph, the access is that of the path that gives most access. +\begin{example} -\begin{ncsimplebnf} -\opt{identifier} \opt{attribute-specifier-seq} \terminal{:} constant-expression \opt{brace-or-equal-initializer} -\end{ncsimplebnf} +\begin{codeblock} +class W { public: void f(); }; +class A : private virtual W { }; +class B : public virtual W { }; +class C : public A, public B { + void f() { W::f(); } // OK +}; +\end{codeblock} -\indextext{\idxcode{:}!bit-field declaration}% -\indextext{declaration!bit-field}% -specifies a bit-field; -its length is set off from the bit-field name by a colon. The optional \grammarterm{attribute-specifier-seq} appertains to the entity being declared. The bit-field -attribute is not part of the type of the class member. The -\grammarterm{constant-expression} shall be an integral constant expression -with a value greater than or equal to zero. The -value of the integral constant expression may -be larger than the number of bits in the object -representation\iref{basic.types} of the bit-field's type; in such -cases the extra bits are padding bits\iref{basic.types}. -\indextext{allocation!implementation-defined bit-field}% -Allocation of bit-fields within a class object is -\impldef{allocation of bit-fields within a class object}. -\indextext{bit-field!implementation-defined alignment of}% -Alignment of bit-fields is \impldef{alignment of bit-fields within a class object}. -\indextext{layout!bit-field}% -Bit-fields are packed into some addressable allocation unit. +Since +\tcode{W::f()} +is available to +\tcode{C::f()} +along the public path through +\tcode{B}, +access is allowed. +\end{example} + +\rSec2[class.access.nest]{Nested classes}% +\indextext{access control!nested class}% +\indextext{member function!nested class} + +\pnum +A nested class is a member and as such has the same access rights as any other member. +The members of an enclosing class have no special access to members of a nested +class; the usual access rules\iref{class.access} shall be obeyed. +\begin{example} +\begin{codeblock} +class E { + int x; + class B { }; + + class I { + B b; // OK: \tcode{E::I} can access \tcode{E::B} + int y; + void f(E* p, int i) { + p->x = i; // OK: \tcode{E::I} can access \tcode{E::x} + } + }; + + int g(I* p) { + return p->y; // error: \tcode{I::y} is private + } +}; +\end{codeblock} +\end{example}% +\indextext{access control|)} + +\rSec1[class.init]{Initialization}% +\indextext{initialization!class object|(}% +\indextext{initialization!default constructor and}% +\indextext{initialization!constructor and} + +\pnum +When no initializer is specified for an object of (possibly +cv-qualified) class type (or array thereof), or the initializer has +the form +\tcode{()}, +the object is initialized as specified in~\ref{dcl.init}. + +\pnum +An object of class type (or array thereof) can be explicitly initialized; +see~\ref{class.expl.init} and~\ref{class.base.init}. + +\pnum +\indextext{order of execution!constructor and array}% +When an array of class objects is initialized +(either explicitly or implicitly) and the elements are initialized by constructor, +the constructor shall be called for each element of the array, +following the subscript order; see~\ref{dcl.array}. \begin{note} -Bit-fields straddle allocation units on some machines and not on others. -Bit-fields are assigned right-to-left on some machines, left-to-right on -others. +Destructors for the array elements are called in reverse order of their +construction. \end{note} +\rSec2[class.expl.init]{Explicit initialization}% +\indextext{initialization!explicit}% +\indextext{initialization!constructor and}% + \pnum -\indextext{bit-field!unnamed}% -A declaration for a bit-field that omits the \grammarterm{identifier} -declares an \defn{unnamed bit-field}. Unnamed bit-fields are not -members and cannot be initialized. -An unnamed bit-field shall not be declared with a cv-qualified type. +An object of class type can be initialized with a parenthesized +\grammarterm{expression-list}, +where the +\grammarterm{expression-list} +is construed as an argument list for a constructor +that is called to initialize the object. +Alternatively, a single +\grammarterm{assignment-expression} +can be specified as an +\grammarterm{initializer} +using the +\tcode{=} +form of initialization. +Either direct-initialization semantics or copy-initialization semantics apply; +see~\ref{dcl.init}. +\begin{example} +\begin{codeblock} +struct complex { + complex(); + complex(double); + complex(double,double); +}; + +complex sqrt(complex,complex); + +complex a(1); // initialized by calling \tcode{complex(double)} with argument \tcode{1} +complex b = a; // initialized as a copy of \tcode{a} +complex c = complex(1,2); // initialized by calling \tcode{complex(double,double)} with arguments \tcode{1} and \tcode{2} +complex d = sqrt(b,c); // initialized by calling \tcode{sqrt(complex,complex)} with \tcode{d} as its result object +complex e; // initialized by calling \tcode{complex()} +complex f = 3; // initialized by calling \tcode{complex(double)} with argument \tcode{3} +complex g = { 1, 2 }; // initialized by calling \tcode{complex(double, double)} with arguments \tcode{1} and \tcode{2} +\end{codeblock} +\end{example} \begin{note} -An unnamed bit-field is useful for padding to conform to -externally-imposed layouts. +\indextext{initialization!overloaded assignment and}% +Overloading of the assignment operator\iref{over.ass} +has no effect on initialization. \end{note} -\indextext{bit-field!zero width of}% -\indextext{bit-field!alignment of}% -As a special case, an unnamed bit-field with a width of zero specifies -alignment of the next bit-field at an allocation unit boundary. Only -when declaring an unnamed bit-field may the value of the -\grammarterm{constant-expression} be equal to zero. \pnum -\indextext{bit-field!type of}% -A bit-field shall not be a static member. A bit-field shall have -integral or enumeration type\iref{basic.fundamental}. -\indextext{Boolean}% -A \tcode{bool} value can successfully be stored in a bit-field of any -nonzero size. -\indextext{bit-field!address of}% -The address-of operator \tcode{\&} shall not be applied to a bit-field, -so there are no pointers to bit-fields. -\indextext{restriction!bit-field}% -\indextext{restriction!address of bit-field}% -\indextext{restriction!pointer to bit-field}% -A non-const reference shall not be bound to a -bit-field\iref{dcl.init.ref}. +\indextext{initialization!array of class objects}% +\indextext{constructor!array of class objects and}% +An object of class type can also be initialized by a +\grammarterm{braced-init-list}. List-initialization semantics apply; +see~\ref{dcl.init} and~\ref{dcl.init.list}. \begin{example} + +\begin{codeblock} +complex v[6] = { 1, complex(1,2), complex(), 2 }; +\end{codeblock} + +Here, +\tcode{complex::complex(double)} +is called for the initialization of +\tcode{v[0]} +and +\tcode{v[3]}, +\tcode{complex::complex(\brk{}double, double)} +is called for the initialization of +\tcode{v[1]}, +\tcode{complex::complex()} +is called for the initialization +\tcode{v[2]}, +\tcode{v[4]}, +and +\tcode{v[5]}. +For another example, + +\begin{codeblock} +struct X { + int i; + float f; + complex c; +} x = { 99, 88.8, 77.7 }; +\end{codeblock} + +Here, +\tcode{x.i} +is initialized with 99, +\tcode{x.f} +is initialized with 88.8, and +\tcode{complex::complex(double)} +is called for the initialization of +\tcode{x.c}. +\end{example} \begin{note} -If the initializer for a reference of type \tcode{const} \tcode{T\&} is -an lvalue that refers to a bit-field, the reference is bound to a -temporary initialized to hold the value of the bit-field; the reference -is not bound to the bit-field directly. See~\ref{dcl.init.ref}. +Braces can be elided in the +\grammarterm{initializer-list} +for any aggregate, even if the aggregate has members of a class type with +user-defined type conversions; see~\ref{dcl.init.aggr}. \end{note} \pnum -If the value \tcode{true} or \tcode{false} is stored into a bit-field of -type \tcode{bool} of any size (including a one bit bit-field), the -original \tcode{bool} value and the value of the bit-field shall compare -equal. If the value of an enumerator is stored into a bit-field of the -same enumeration type and the number of bits in the bit-field is large -enough to hold all the values of that enumeration type\iref{dcl.enum}, -the original enumerator value and the value of the bit-field shall -compare equal. +\begin{note} +If +\tcode{T} +is a class type with no default constructor, +any declaration of an object of type +\tcode{T} +(or array thereof) is ill-formed if no +\grammarterm{initializer} +is explicitly specified (see~\ref{class.init} and~\ref{dcl.init}). +\end{note} + +\pnum +\begin{note} +\indextext{order of execution!constructor and \tcode{static} objects}% +The order in which objects with static or thread storage duration +are initialized is described in~\ref{basic.start.dynamic} and~\ref{stmt.dcl}. +\end{note} + +\rSec2[class.base.init]{Initializing bases and members}% +\indextext{initialization!base class}% +\indextext{initialization!member} + +\pnum +In the definition of a constructor for a class, +initializers for direct and virtual base class subobjects and +non-static data members can be specified by a +\grammarterm{ctor-initializer}, +which has the form + +\begin{bnf} +\nontermdef{ctor-initializer}\br + \terminal{:} mem-initializer-list +\end{bnf} + +\begin{bnf} +\nontermdef{mem-initializer-list}\br + mem-initializer \opt{\terminal{...}}\br + mem-initializer-list \terminal{,} mem-initializer \opt{\terminal{...}} +\end{bnf} + +\begin{bnf} +\nontermdef{mem-initializer}\br + mem-initializer-id \terminal{(} \opt{expression-list} \terminal{)}\br + mem-initializer-id braced-init-list +\end{bnf} + +\begin{bnf} +\nontermdef{mem-initializer-id}\br + class-or-decltype\br + identifier +\end{bnf} + +\pnum +In a \grammarterm{mem-initializer-id} an initial unqualified +\grammarterm{identifier} is looked up in the scope of the constructor's class +and, if not found in that scope, it is looked up in the scope containing the +constructor's definition. +\begin{note} +If the constructor's class contains a member with the same name as a direct +or virtual base class of the class, a +\grammarterm{mem-initializer-id} +naming the member or base class and composed of a single identifier +refers to the class member. +A +\grammarterm{mem-initializer-id} +for the hidden base class may be specified using a qualified name. +\end{note} +Unless the +\grammarterm{mem-initializer-id} +names the constructor's class, +a non-static data member of the constructor's class, or +a direct or virtual base of that class, +the +\grammarterm{mem-initializer} +is ill-formed. + +\pnum +A +\grammarterm{mem-initializer-list} +can initialize a base class using any \grammarterm{class-or-decltype} that denotes that base class type. +\begin{example} + +\begin{codeblock} +struct A { A(); }; +typedef A global_A; +struct B { }; +struct C: public A, public B { C(); }; +C::C(): global_A() { } // mem-initializer for base \tcode{A} +\end{codeblock} +\end{example} + +\pnum +If a +\grammarterm{mem-initializer-id} +is ambiguous because it designates both a direct non-virtual base class and +an inherited virtual base class, the +\grammarterm{mem-initializer} +is ill-formed. +\begin{example} + +\begin{codeblock} +struct A { A(); }; +struct B: public virtual A { }; +struct C: public A, public B { C(); }; +C::C(): A() { } // ill-formed: which \tcode{A}? +\end{codeblock} +\end{example} + +\pnum +A +\grammarterm{ctor-initializer} +may initialize a variant member of the +constructor's class. +If a +\grammarterm{ctor-initializer} +specifies more than one +\grammarterm{mem-initializer} +for the same member or for the same base class, +the +\grammarterm{ctor-initializer} +is ill-formed. + +\pnum +A \grammarterm{mem-initializer-list} can delegate to another +constructor of the constructor's class using any +\grammarterm{class-or-decltype} that denotes the constructor's class itself. If a +\grammarterm{mem-initializer-id} designates the constructor's class, +it shall be the only \grammarterm{mem-initializer}; the constructor +is a \term{delegating constructor}, and the constructor selected by the +\grammarterm{mem-initializer} is the \term{target constructor}. +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 required. \begin{example} + +\begin{codeblock} +struct C { + C( int ) { } // \#1: non-delegating constructor + C(): C(42) { } // \#2: delegates to \#1 + C( char c ) : C(42.0) { } // \#3: ill-formed due to recursion with \#4 + C( double d ) : C('a') { } // \#4: ill-formed due to recursion with \#3 +}; +\end{codeblock} +\end{example} + +\pnum +\indextext{initialization!base class}% +\indextext{initialization!member object}% +The +\grammarterm{expression-list} +or \grammarterm{braced-init-list} +in a +\grammarterm{mem-initializer} +is used to initialize the +designated subobject (or, in the case of a delegating constructor, the complete class object) +according to the initialization rules of~\ref{dcl.init} for direct-initialization. +\begin{example} +\begin{codeblock} +struct B1 { B1(int); @\commentellip@ }; +struct B2 { B2(int); @\commentellip@ }; +struct D : B1, B2 { + D(int); + B1 b; + const int c; +}; + +D::D(int a) : B2(a+1), B1(a+2), c(a+3), b(a+4) { @\commentellip@ } +D d(10); +\end{codeblock} +\end{example} +\begin{note} +\setlength{\emergencystretch}{1em} +The initialization +performed by each \grammarterm{mem-initializer} +constitutes a full-expres\-sion\iref{intro.execution}. +Any expression in +a +\grammarterm{mem-initializer} +is evaluated as part of the full-expression that performs the initialization. +\end{note} +A \grammarterm{mem-initializer} where the \grammarterm{mem-initializer-id} denotes +a virtual base class is ignored during execution of a constructor of any class that is +not the most derived class. + +\pnum +A temporary expression bound to a reference member in a \grammarterm{mem-initializer} +is ill-formed. +\begin{example} +\begin{codeblock} +struct A { + A() : v(42) { } // error + const int& v; +}; +\end{codeblock} +\end{example} + +\pnum +In a non-delegating constructor, if +a given potentially constructed subobject is not designated by a +\grammarterm{mem-initializer-id} +(including the case where there is no +\grammarterm{mem-initializer-list} +because the constructor has no +\grammarterm{ctor-initializer}), +then + +\begin{itemize} +\item if the entity is a non-static data member that has +a default member initializer\iref{class.mem} and either + +\begin{itemize} +\item the constructor's class is a union\iref{class.union}, and no other variant +member of that union is designated by a \grammarterm{mem-initializer-id} or + +\item the constructor's class is not a union, and, if the entity is a member of an +anonymous union, no other member of that union is designated by a +\grammarterm{mem-initializer-id}, +\end{itemize} + +the entity is initialized from its default member initializer +as specified in~\ref{dcl.init}; + +\item otherwise, if the entity is an anonymous union or a variant member\iref{class.union.anon}, no initialization is performed; + +\item otherwise, the entity is default-initialized\iref{dcl.init}. +\end{itemize} + +\begin{note} An abstract class\iref{class.abstract} is never a most derived +class, thus its constructors never initialize virtual base classes, therefore the +corresponding \grammarterm{mem-initializer}{s} may be omitted. \end{note} +An attempt to initialize more than one non-static data member of a union renders the +program ill-formed. +\indextext{initialization!const member}% +\indextext{initialization!reference member}% +\begin{note} +After the call to a constructor for class +\tcode{X} +for an object with automatic or dynamic storage duration +has completed, if +the constructor was not invoked as part of value-initialization and +a member of +\tcode{X} +is neither initialized nor +given a value +during execution of the \grammarterm{compound-statement} of the body of the constructor, +the member has an indeterminate value. +\end{note} +\begin{example} +\begin{codeblock} +struct A { + A(); +}; + +struct B { + B(int); +}; + +struct C { + C() { } // initializes members as follows: + A a; // OK: calls \tcode{A::A()} + const B b; // error: \tcode{B} has no default constructor + int i; // OK: \tcode{i} has indeterminate value + int j = 5; // OK: \tcode{j} has the value \tcode{5} +}; +\end{codeblock} +\end{example} + +\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 +default member initializer is ignored. +\begin{example} Given +% The comment below is misrendered with an overly large space before 'effects' +% if left to listings (see NB US-26 (C++17 CD)) (possibly due to the ff +% ligature), so we fix it up manually. +\begin{codeblock} +struct A { + int i = /* some integer expression with side effects */ ; + A(int arg) : i(arg) { } + // ... +}; +\end{codeblock} + +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 +will not take place. +\end{example} + +\pnum +A temporary expression bound to a reference member from a +default member initializer is ill-formed. +\begin{example} +\begin{codeblock} +struct A { + A() = default; // OK + A(int v) : v(v) { } // OK + const int& v = 42; // OK +}; +A a1; // error: ill-formed binding of temporary to reference +A a2(1); // OK, unfortunately +\end{codeblock} +\end{example} + +\pnum +In a non-delegating constructor, the destructor for each potentially constructed +subobject of class type is potentially invoked\iref{class.dtor}. +\begin{note} This provision ensures that destructors can be called for fully-constructed +subobjects in case an exception is thrown\iref{except.ctor}. \end{note} + +\pnum +In a non-delegating constructor, initialization +proceeds in the following order: +\begin{itemize} +\item +\indextext{initialization!order of virtual base class}% +First, and only for the constructor of the most derived class\iref{intro.object}, +virtual base classes are initialized in the order they appear on a +depth-first left-to-right traversal of the directed acyclic graph of +base classes, +where ``left-to-right'' is the order of appearance of the base classes +in the derived class +\grammarterm{base-specifier-list}. +\item +\indextext{initialization!order of base class}% +Then, direct base classes are initialized in declaration order +as they appear in the +\grammarterm{base-specifier-list} +(regardless of the order of the +\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-initializer}{s}). +\item +Finally, the \grammarterm{compound-statement} of the constructor +body is executed. +\end{itemize} + +\begin{note} +The declaration order is mandated to ensure that base and member +subobjects are destroyed in the reverse order of initialization. +\end{note} + +\pnum +\begin{example} +\begin{codeblock} +struct V { + V(); + V(int); +}; + +struct A : virtual V { + A(); + A(int); +}; + +struct B : virtual V { + B(); + B(int); +}; + +struct C : A, B, virtual V { + C(); + C(int); +}; + +A::A(int i) : V(i) { @\commentellip@ } +B::B(int i) { @\commentellip@ } +C::C(int i) { @\commentellip@ } + +V v(1); // use \tcode{V(int)} +A a(2); // use \tcode{V(int)} +B b(3); // use \tcode{V()} +C c(4); // use \tcode{V()} +\end{codeblock} +\end{example} + +\pnum +\indextext{initializer!scope of member}% +Names in the +\grammarterm{expression-list} +or \grammarterm{braced-init-list} +of a +\grammarterm{mem-initializer} +are evaluated in the scope of the constructor for which the +\grammarterm{mem-initializer} +is specified. \begin{example} \begin{codeblock} -enum BOOL { FALSE=0, TRUE=1 }; -struct A { - BOOL b:1; +class X { + int a; + int b; + int i; + int j; +public: + const int& r; + X(int i): r(a), b(i), i(i), j(this->i) { } }; -A a; -void f() { - a.b = TRUE; - if (a.b == TRUE) // yields \tcode{true} - { @\commentellip@ } -} \end{codeblock} -\end{example} - -\rSec2[class.nest]{Nested class declarations}% -\indextext{definition!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 \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. +initializes +\tcode{X::r} +to refer to +\tcode{X::a}, +initializes +\tcode{X::b} +with the value of the constructor parameter +\tcode{i}, +initializes +\tcode{X::i} +with the value of the constructor parameter +\tcode{i}, +and initializes +\tcode{X::j} +with the value of +\tcode{X::i}; +this takes place each time an object of class +\tcode{X} +is created. +\end{example} \begin{note} -See~\ref{expr.prim.id} for restrictions on the use of non-static data -members and non-static member functions. +Because the +\grammarterm{mem-initializer} +are evaluated in the scope of the constructor, the +\tcode{this} +pointer can be used in the +\grammarterm{expression-list} +of a +\grammarterm{mem-initializer} +to refer to the object being initialized. \end{note} +\pnum +\indextext{initialization!member function call during}% +Member functions (including virtual member functions, \ref{class.virtual}) can be +called for an object under construction. +Similarly, an object under construction can be the operand of the +\tcode{typeid} +operator\iref{expr.typeid} or of a +\tcode{dynamic_cast}\iref{expr.dynamic.cast}. +However, if these operations are performed in a +\grammarterm{ctor-initializer} +(or in a function called directly or indirectly from a +\grammarterm{ctor-initializer}) +before all the +\grammarterm{mem-initializer}{s} +for base classes have completed, the program has undefined behavior. \begin{example} \begin{codeblock} -int x; -int y; +class A { +public: + A(int); +}; -struct enclose { - int x; - static int s; +class B : public A { + int j; +public: + int f(); + B() : A(f()), // undefined: calls member function but base \tcode{A} not yet initialized + j(f()) { } // well-defined: bases are all initialized +}; - struct inner { - void f(int i) { - int a = sizeof(x); // OK: operand of sizeof is an unevaluated operand - x = i; // error: assign to \tcode{enclose::x} - s = i; // OK: assign to \tcode{enclose::s} - ::x = i; // OK: assign to global \tcode{x} - y = i; // OK: assign to global \tcode{y} - } - void g(enclose* p, int i) { - p->x = i; // OK: assign to \tcode{enclose::x} - } - }; +class C { +public: + C(int); }; -inner* p = 0; // error: \tcode{inner} not in scope +class D : public B, C { + int i; +public: + D() : C(f()), // undefined: calls member function but base \tcode{C} not yet initialized + i(f()) { } // well-defined: bases are all initialized +}; \end{codeblock} \end{example} \pnum -Member functions and static data members of a nested class can be -defined in a namespace scope enclosing the definition of their class. +\begin{note} +\ref{class.cdtor} describes the result of virtual function calls, +\tcode{typeid} +and +\tcode{dynamic_cast}s +during construction for the well-defined cases; +that is, describes the +\term{polymorphic behavior} +of an object under construction. +\end{note} + +\pnum +\indextext{initializer!pack expansion}% +A \grammarterm{mem-initializer} followed by an ellipsis is +a pack expansion\iref{temp.variadic} that initializes the base +classes specified by a pack expansion in the \grammarterm{base-specifier-list} +for the class. \begin{example} + +\begin{codeblock} +template +class X : public Mixins... { +public: + X(const Mixins&... mixins) : Mixins(mixins)... { } +}; +\end{codeblock} + +\end{example} + +\rSec2[class.inhctor.init]{Initialization by inherited constructor}% +\indextext{initialization!by inherited constructor} + +\pnum +When a constructor for type \tcode{B} is invoked +to initialize an object of a different type \tcode{D} +(that is, when the constructor was inherited\iref{namespace.udecl}), +initialization proceeds as if a defaulted default constructor +were used to initialize the \tcode{D} object and +each base class subobject from which the constructor was inherited, +except that the \tcode{B} subobject is initialized +by the invocation of the inherited constructor. +The complete initialization is considered to be a single function call; +in particular, the initialization of the inherited constructor's parameters +is sequenced before the initialization of any part of the \tcode{D} object. \begin{example} \begin{codeblock} -struct enclose { - struct inner { - static int x; - void f(int i); - }; +struct B1 { + B1(int, ...) { } }; -int enclose::inner::x = 1; +struct B2 { + B2(double) { } +}; -void enclose::inner::f(int i) { @\commentellip@ } +int get(); + +struct D1 : B1 { + using B1::B1; // inherits \tcode{B1(int, ...)} + int x; + int y = get(); +}; + +void test() { + D1 d(2, 3, 4); // OK: \tcode{B1} is initialized by calling \tcode{B1(2, 3, 4)}, + // then \tcode{d.x} is default-initialized (no initialization is performed), + // then \tcode{d.y} is initialized by calling \tcode{get()} + D1 e; // error: \tcode{D1} has a deleted default constructor +} + +struct D2 : B2 { + using B2::B2; + B1 b; +}; + +D2 f(1.0); // error: \tcode{B1} has a deleted default constructor + +struct W { W(int); }; +struct X : virtual W { using W::W; X() = delete; }; +struct Y : X { using X::X; }; +struct Z : Y, virtual W { using Y::Y; }; +Z z(0); // OK: initialization of \tcode{Y} does not invoke default constructor of \tcode{X} + +template struct Log : T { + using T::T; // inherits all constructors from class \tcode{T} + ~Log() { std::clog << "Destroying wrapper" << std::endl; } +}; \end{codeblock} +Class template \tcode{Log} wraps any class and forwards all of its constructors, +while writing a message to the standard log +whenever an object of class \tcode{Log} is destroyed. \end{example} \pnum -If class \tcode{X} is defined in a namespace scope, a nested class -\tcode{Y} may be declared in class \tcode{X} and later defined in the -definition of class \tcode{X} or be later defined in a namespace scope -enclosing the definition of class \tcode{X}. +If the constructor was inherited from multiple base class subobjects +of type \tcode{B}, the program is ill-formed. \begin{example} \begin{codeblock} -class E { - class I1; // forward declaration of nested class - class I2; - class I1 { }; // definition of nested class +struct A { A(int); }; +struct B : A { using A::A; }; + +struct C1 : B { using B::B; }; +struct C2 : B { using B::B; }; + +struct D1 : C1, C2 { + using C1::C1; + using C2::C2; }; -class E::I2 { }; // definition of nested class + +struct V1 : virtual B { using B::B; }; +struct V2 : virtual B { using B::B; }; + +struct D2 : V1, V2 { + using V1::V1; + using V2::V2; +}; + +D1 d1(0); // ill-formed: ambiguous +D2 d2(0); // OK: initializes virtual \tcode{B} base class, which initializes the \tcode{A} base class + // then initializes the \tcode{V1} and \tcode{V2} base classes as if by a defaulted default constructor + +struct M { M(); M(int); }; +struct N : M { using M::M; }; +struct O : M {}; +struct P : N, O { using N::N; using O::O; }; +P p(0); // OK: use \tcode{M(0)} to initialize \tcode{N}{'s} base class, + // use \tcode{M()} to initialize \tcode{O}{'s} base class \end{codeblock} \end{example} \pnum -\indextext{friend function!nested class}% -Like a member function, a friend function\iref{class.friend} defined -within a nested class is in the lexical scope of that class; it obeys -the same rules for name binding as a static member function of that -class\iref{class.static}, but it has no special access rights to -members of an enclosing class. +When an object is initialized by an inherited constructor, +initialization of the object is complete +when the initialization of all subobjects is complete.% +\indextext{initialization!class object|)} -\rSec2[class.nested.type]{Nested type names} -\indextext{type name!nested}% -\indextext{type name!nested!scope of}% +\rSec2[class.cdtor]{Construction and destruction}% +\indextext{construction|(}% +\indextext{destruction|(}% \pnum -Type names obey exactly the same scope rules as other names. In -particular, type names defined within a class definition cannot be used -outside their class without qualification. +\indextext{construction!member access}% +\indextext{destruction!member access}% +For an object with a non-trivial constructor, referring to any non-static member +or base class of the object before the constructor begins execution results in +undefined behavior. For an object with a non-trivial destructor, referring to +any non-static member or base class of the object after the destructor finishes +execution results in undefined behavior. \begin{example} \begin{codeblock} -struct X { - typedef int I; - class Y { @\commentellip@ }; - I a; +struct X { int i; }; +struct Y : X { Y(); }; // non-trivial +struct A { int a; }; +struct B : public A { int j; Y y; }; // non-trivial + +extern B bobj; +B* pb = &bobj; // OK +int* p1 = &bobj.a; // undefined, refers to base class member +int* p2 = &bobj.y.i; // undefined, refers to member's member + +A* pa = &bobj; // undefined, upcast to a base class type +B bobj; // definition of \tcode{bobj} + +extern X xobj; +int* p3 = &xobj.i; // OK, \tcode{X} is a trivial class +X xobj; +\end{codeblock} +For another example, +\begin{codeblock} +struct W { int j; }; +struct X : public virtual W { }; +struct Y { + int* p; + X x; + Y() : p(&x.j) { // undefined, \tcode{x} is not yet constructed + } }; - -I b; // error -Y c; // error -X::Y d; // OK -X::I e; // OK \end{codeblock} -\end{example}% -\indextext{class|)} - -\rSec1[class.union]{Unions}% -\indextext{\idxcode{union}} - -\pnum -In a union, -a non-static data member is \defnx{active}{active!union member} -if its name refers to an object -whose lifetime has begun and has not ended\iref{basic.life}. -At most one of the non-static data members of an object of union type -can be active at any -time, that is, the value of at most one of the non-static data members can be -stored in a union at any time. \begin{note} One special guarantee is made in order to -simplify the use of unions: If a standard-layout union contains several standard-layout -structs that share a common initial sequence\iref{class.mem}, and -if a non-static data member of an object of this standard-layout union type -is active and is one of the standard-layout structs, -it is permitted to inspect the common initial sequence -of any of the standard-layout struct members; -see~\ref{class.mem}. -\end{note} +\end{example} \pnum -The size of a union is sufficient to contain the largest -of its non-static data members. Each non-static data member is allocated -as if it were the sole member of a struct. -\begin{note} -A union object and its non-static data members are -pointer-interconvertible~(\ref{basic.compound}, \ref{expr.static.cast}). -As a consequence, all non-static data members of a -union object have the same address. -\end{note} +\indextext{construction!pointer to member or base}% +\indextext{destruction!pointer to member or base}% +To explicitly or implicitly convert a pointer (a glvalue) referring to +an object of class +\tcode{X} +to a pointer (reference) to a direct or indirect base class +\tcode{B} +of +\tcode{X}, +the construction of +\tcode{X} +and the construction of all of its direct or indirect bases that directly or +indirectly derive from +\tcode{B} +shall have started and the destruction of these classes shall not have +completed, otherwise the conversion results in undefined behavior. +To form a pointer to (or access the value of) a direct non-static member of +an object +\tcode{obj}, +the construction of +\tcode{obj} +shall have started and its destruction shall not have completed, +otherwise the computation of the pointer value (or accessing the member +value) results in undefined behavior. +\begin{example} +\begin{codeblock} +struct A { }; +struct B : virtual A { }; +struct C : B { }; +struct D : virtual A { D(A*); }; +struct X { X(A*); }; -\pnum -\indextext{member function!\idxcode{union}}% -\indextext{constructor!\idxcode{union}}% -\indextext{destructor!\idxcode{union}}% -A union can have member functions (including constructors and destructors), -\indextext{restriction!\idxcode{union}}% -but it shall not have virtual\iref{class.virtual} functions. A union shall not have -base classes. A union shall not be used as a base class. -\indextext{restriction!\idxcode{union}}% -If a union contains a non-static data member of -reference type the program is ill-formed. -\begin{note} Absent default member initializers\iref{class.mem}, -if any non-static data member of a union has a non-trivial -default constructor\iref{class.ctor}, -copy constructor\iref{class.copy}, -move constructor\iref{class.copy}, -copy assignment operator\iref{class.copy}, -move assignment operator\iref{class.copy}, -or destructor\iref{class.dtor}, the corresponding member function -of the union must be user-provided or it will -be implicitly deleted\iref{dcl.fct.def.delete} for the union. \end{note} +struct E : C, D, X { + E() : D(this), // undefined: upcast from \tcode{E*} to \tcode{A*} might use path \tcode{E*} $\rightarrow$ \tcode{D*} $\rightarrow$ \tcode{A*} + // but \tcode{D} is not constructed -\pnum -\begin{example} Consider the following union: + // ``\tcode{D((C*)this)}\!'' would be defined: \tcode{E*} $\rightarrow$ \tcode{C*} is defined because \tcode{E()} has started, + // and \tcode{C*} $\rightarrow$ \tcode{A*} is defined because \tcode{C} is fully constructed -\begin{codeblock} -union U { - int i; - float f; - std::string s; + X(this) {} // defined: upon construction of \tcode{X}, \tcode{C/B/D/A} sublattice is fully constructed }; \end{codeblock} - -Since \tcode{std::string}\iref{string.classes} declares non-trivial versions of all of the special -member functions, \tcode{U} will have an implicitly deleted default constructor, -copy/move constructor, -copy/move assignment operator, and destructor. -To use \tcode{U}, some or all of these member functions -must be user-provided.\end{example} +\end{example} \pnum -When the left operand of an assignment operator -involves a member access expression\iref{expr.ref} -that nominates a union member, -it may begin the lifetime of that union member, -as described below. -For an expression \tcode{E}, -define the set $S(\mathtt{E})$ -of subexpressions of \tcode{E} -as follows: -\begin{itemize} -\item -If \tcode{E} is of the form \tcode{A.B}, -$S(\mathtt{E})$ contains the elements of $S(\mathtt{A})$, -and also contains \tcode{A.B} -if \tcode{B} names a union member of a non-class, non-array type, -or of a class type with a trivial default constructor that is not deleted, -or an array of such types. -\item -If \tcode{E} is of the form \tcode{A[B]} -and is interpreted as a built-in array subscripting operator, -$S(\mathtt{E})$ is $S(\mathtt{A})$ if \tcode{A} is of array type, -$S(\mathtt{B})$ if \tcode{B} is of array type, -and empty otherwise. -\item -Otherwise, $S(\mathtt{E})$ is empty. -\end{itemize} -In an assignment expression of the form \tcode{E1 = E2} -that uses either the built-in assignment operator\iref{expr.ass} -or a trivial assignment operator\iref{class.copy}, -for each element \tcode{X} of $S($\tcode{E1}$)$, -if modification of \tcode{X} would have undefined behavior under~\ref{basic.life}, -an object of the type of \tcode{X} is implicitly created -in the nominated storage; -no initialization is performed and -the beginning of its lifetime is sequenced after -the value computation of the left and right operands -and before the assignment. -\begin{note} -This ends the lifetime of the previously-active -member of the union, if any\iref{basic.life}. -\end{note} +\indextext{virtual function call!constructor and}% +\indextext{virtual function call!destructor and}% +\indextext{construction!virtual function call}% +\indextext{destruction!virtual function call}% +Member functions, including virtual functions\iref{class.virtual}, can be called +during construction or destruction\iref{class.base.init}. +When a virtual function is called directly or indirectly from a constructor +or from a destructor, +including during the construction or destruction of the class's non-static data +members, +and the object to which the call applies is the object (call it \tcode{x}) under construction or +destruction, +the function called is the +final overrider in the constructor's or destructor's class and not one +overriding it in a more-derived class. +If the virtual function call uses an explicit class member access\iref{expr.ref} +and the object expression refers to +the complete object of \tcode{x} or one of that object's base class subobjects +but not \tcode{x} or one of its base class subobjects, the behavior +is undefined. \begin{example} + \begin{codeblock} -union A { int x; int y[4]; }; -struct B { A a; }; -union C { B b; int k; }; -int f() { - C c; // does not start lifetime of any union member - c.b.a.y[3] = 4; // OK: $S($\tcode{c.b.a.y[3]}$)$ contains \tcode{c.b} and \tcode{c.b.a.y}; - // creates objects to hold union members \tcode{c.b} and \tcode{c.b.a.y} - return c.b.a.y[3]; // OK: \tcode{c.b.a.y} refers to newly created object (see \ref{basic.life}) -} +struct V { + virtual void f(); + virtual void g(); +}; -struct X { const int a; int b; }; -union Y { X x; int k; }; -void g() { - Y y = { { 1, 2 } }; // OK, \tcode{y.x} is active union member\iref{class.mem} - int n = y.x.a; - y.k = 4; // OK: ends lifetime of \tcode{y.x}, \tcode{y.k} is active member of union - y.x.b = n; // undefined behavior: \tcode{y.x.b} modified outside its lifetime, - // $S($\tcode{y.x.b}$)$ is empty because \tcode{X}'s default constructor is deleted, - // so union member \tcode{y.x}'s lifetime does not implicitly start +struct A : virtual V { + virtual void f(); +}; + +struct B : virtual V { + virtual void g(); + B(V*, A*); +}; + +struct D : A, B { + virtual void f(); + virtual void g(); + D() : B((A*)this, this) { } +}; + +B::B(V* v, A* a) { + f(); // calls \tcode{V::f}, not \tcode{A::f} + g(); // calls \tcode{B::g}, not \tcode{D::g} + v->g(); // \tcode{v} is base of \tcode{B}, the call is well-defined, calls \tcode{B::g} + a->f(); // undefined behavior, \tcode{a}'s type not a base of \tcode{B} } \end{codeblock} \end{example} \pnum -\begin{note} In general, one must use explicit destructor calls and placement -\grammarterm{new-expression} to change the active member of a union. \end{note} -\begin{example} -Consider an object \tcode{u} of a \tcode{union} type \tcode{U} having non-static data members -\tcode{m} of type \tcode{M} and \tcode{n} of type \tcode{N}. If \tcode{M} has a non-trivial -destructor and \tcode{N} has a non-trivial constructor (for instance, if they declare or inherit -virtual functions), the active member of \tcode{u} can be safely switched from \tcode{m} to -\tcode{n} using the destructor and placement \grammarterm{new-expression} as follows: +\indextext{construction!\idxcode{typeid} operator}% +\indextext{destruction!\idxcode{typeid} operator}% +\indextext{\idxcode{typeid}!construction and}% +\indextext{\idxcode{typeid}!destruction and}% +The +\tcode{typeid} +operator\iref{expr.typeid} can be used during construction or destruction\iref{class.base.init}. +When +\tcode{typeid} +is used in a constructor (including the +\grammarterm{mem-initializer} or default member initializer\iref{class.mem} +for a non-static data member) +or in a destructor, or used in a function called (directly or indirectly) from +a constructor or destructor, if the operand of +\tcode{typeid} +refers to the object under construction or destruction, +\tcode{typeid} +yields the +\tcode{std::type_info} +object representing the constructor or destructor's class. +If the operand of +\tcode{typeid} +refers to the object under construction or destruction and the static type of +the operand is neither the constructor or destructor's class nor one of its +bases, the behavior is undefined. +\pnum +\indextext{construction!dynamic cast and}% +\indextext{destruction!dynamic cast and}% +\indextext{cast!dynamic!construction and}% +\indextext{cast!dynamic!destruction and}% +\tcode{dynamic_cast}s\iref{expr.dynamic.cast} can be used during construction +or destruction\iref{class.base.init}. When a +\tcode{dynamic_cast} +is used in a constructor (including the +\grammarterm{mem-initializer} or default member initializer +for a non-static data member) +or in a destructor, or used in a function called (directly or indirectly) from +a constructor or destructor, if the operand of the +\tcode{dynamic_cast} +refers to the object under construction or destruction, this object is +considered to be a most derived object that has the type of the constructor or +destructor's class. +If the operand of the +\tcode{dynamic_cast} +refers to the object under construction or destruction and the static type of +the operand is not a pointer to or object of the constructor or destructor's +own class or one of its bases, the +\tcode{dynamic_cast} +results in undefined behavior. +\begin{example} \begin{codeblock} -u.m.~M(); -new (&u.n) N; +struct V { + virtual void f(); +}; + +struct A : virtual V { }; + +struct B : virtual V { + B(V*, A*); +}; + +struct D : A, B { + D() : B((A*)this, this) { } +}; + +B::B(V* v, A* a) { + typeid(*this); // \tcode{type_info} for \tcode{B} + typeid(*v); // well-defined: \tcode{*v} has type \tcode{V}, a base of \tcode{B} yields \tcode{type_info} for \tcode{B} + typeid(*a); // undefined behavior: type \tcode{A} not a base of \tcode{B} + dynamic_cast(v); // well-defined: \tcode{v} of type \tcode{V*}, \tcode{V} base of \tcode{B} results in \tcode{B*} + dynamic_cast(a); // undefined behavior, \tcode{a} has type \tcode{A*}, \tcode{A} not a base of \tcode{B} +} \end{codeblock} \end{example} +\indextext{destruction|)}% +\indextext{construction|)}% -\rSec2[class.union.anon]{Anonymous unions} -\indextext{\idxcode{union}!anonymous}% +\rSec2[class.copy.elision]{Copy/move elision}% \pnum -A union of the form - -\begin{ncsimplebnf} -\terminal{union} \terminal{\{} member-specification \terminal{\}} \terminal{;} -\end{ncsimplebnf} +\indextext{temporary!elimination of}% +\indextext{elision!copy constructor|see{constructor, copy, elision}}% +\indextext{elision!move constructor|see{constructor, move, elision}}% +\indextext{constructor!copy!elision}% +\indextext{constructor!move!elision}% +When certain criteria are met, an implementation is +allowed to omit the copy/move construction of a class object, +even if the constructor selected for the copy/move operation and/or the +destructor for the object have +\indextext{side effects}% +side effects. In such cases, the +implementation treats the source and target of the +omitted copy/move operation as simply two different ways of +referring to the same object. If the first parameter of the +selected constructor is an rvalue reference to the object's type, +the destruction of that object occurs when the target would have been destroyed; +otherwise, the destruction occurs at the later of the times when the +two objects would have been destroyed without the +optimization.\footnote{Because only one object is destroyed instead of two, +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}}% +\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 +eliminate multiple copies): -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{itemize} +\item in a \tcode{return} statement in a function with a class return type, +when the \grammarterm{expression} is the name of a non-volatile +automatic object (other than a function parameter or a variable +introduced by the \grammarterm{exception-declaration} of a +\grammarterm{handler}\iref{except.handle}) +with the same type (ignoring cv-qualification) as +the function return type, the copy/move operation can be +omitted by constructing the automatic object directly +into the function call's return object + +\item in a \grammarterm{throw-expression}\iref{expr.throw}, when the operand +is the name of a non-volatile automatic object +(other than a function or catch-clause parameter) +whose scope does not extend beyond the end of the innermost enclosing +\grammarterm{try-block} (if there is one), the copy/move operation from the +operand to the exception object\iref{except.throw} can be omitted by +constructing the automatic object directly into the exception object + +\item when the \grammarterm{exception-declaration} of an +exception handler\iref{except} declares an object of the same +type (except for cv-qualification) as the exception +object\iref{except.throw}, the copy operation can be omitted by treating +the \grammarterm{exception-declaration} as an alias for the exception +object if the meaning of the program will be unchanged except for the execution +of constructors and destructors for the object declared by the +\grammarterm{exception-declaration}. +\begin{note} There cannot be a move from the exception object because it is +always an lvalue. \end{note} +\end{itemize} +Copy elision is required +where an expression is evaluated in a context +requiring a constant expression\iref{expr.const} +and in constant initialization\iref{basic.start.static}. \begin{note} -Nested types, anonymous unions, and functions cannot be declared within an anonymous -union. +Copy elision might not be performed +if the same expression +is evaluated in another context. \end{note} -The names of the members of an anonymous union shall be distinct from -the names of any other entity in the scope in which the anonymous union -is declared. For the purpose of name lookup, after the anonymous union -definition, the members of the anonymous union are considered to have -been defined in the scope in which the anonymous union is declared. -\indextext{initialization!\idxcode{union}}% -\begin{example} +\pnum +\begin{example} \begin{codeblock} -void f() { - union { int a; const char* p; }; - a = 1; - p = "Jennifer"; +class Thing { +public: + Thing(); + ~Thing(); + Thing(const Thing&); +}; + +Thing f() { + Thing t; + return t; } -\end{codeblock} -Here \tcode{a} and \tcode{p} are used like ordinary (non-member) -variables, but since they are union members they have the same address. +Thing t2 = f(); + +struct A { + void *p; + constexpr A(): p(this) {} +}; + +constexpr A g() { + A a; + return a; +} + +constexpr A a; // well-formed, \tcode{a.p} points to \tcode{a} +constexpr A b = g(); // well-formed, \tcode{b.p} points to \tcode{b} + +void h() { + A c = g(); // well-formed, \tcode{c.p} may point to \tcode{c} or to an ephemeral temporary +} +\end{codeblock} +Here the criteria for elision can +eliminate +the copying of the local automatic object +\tcode{t} +into the result object for the function call +\tcode{f()}, +which is the global object +\tcode{t2}. +Effectively, the construction of the local object +\tcode{t} +can be viewed as directly initializing the global +object +\tcode{t2}, +and that object's destruction will occur at program +exit. +Adding a move constructor to \tcode{Thing} has the same effect, but it is the +move construction from the local automatic object to \tcode{t2} that is elided. \end{example} \pnum -\indextext{\idxcode{union}!global anonymous}% -\indextext{scope!anonymous \tcode{union} at namespace}% -Anonymous unions declared in a named namespace or in the global -namespace shall be declared \tcode{static}. Anonymous unions declared at -block scope shall be declared with any storage class allowed for a -block-scope variable, or with no storage class. A storage class is not -allowed in a declaration of an anonymous union in a class scope. -\indextext{access control!anonymous \tcode{union}}% -\indextext{restriction!anonymous \tcode{union}}% -An anonymous union shall not have private or protected -members\iref{class.access}. An anonymous union shall not have -member functions. +In the following copy-initialization contexts, a move operation might be used instead of a copy operation: +\begin{itemize} +\item If the \grammarterm{expression} in a \tcode{return} statement\iref{stmt.return} +is a (possibly parenthesized) \grammarterm{id-expression} +that names an object with automatic storage duration declared in the body +or \grammarterm{parameter-declaration-clause} of the innermost enclosing +function or \grammarterm{lambda-expression}, or + +\item if the operand of a \grammarterm{throw-expression}\iref{expr.throw} +is the name of a non-volatile automatic object +(other than a function or catch-clause parameter) +whose scope does not extend beyond the end of the innermost enclosing +\grammarterm{try-block} (if there is one), +\end{itemize} +overload resolution to select the constructor +for the copy is first performed as if the object were designated by an +rvalue. +If the first overload resolution fails or was not performed, +or if the type of the first parameter of the selected +constructor is not an rvalue reference to the object's type (possibly cv-qualified), +overload resolution is performed again, considering the object as an lvalue. +\begin{note} +This two-stage overload resolution must be performed regardless +of whether copy elision will occur. It determines the constructor to be called if +elision is not performed, and the selected constructor must be accessible even if +the call is elided. +\end{note} \pnum -A union for which objects, pointers, or references are declared is not an anonymous union. \begin{example} - \begin{codeblock} -void f() { - union { int aa; char* p; } obj, *ptr = &obj; - aa = 1; // error - ptr->aa = 1; // OK +class Thing { +public: + Thing(); + ~Thing(); + Thing(Thing&&); +private: + Thing(const Thing&); +}; + +Thing f(bool b) { + Thing t; + if (b) + throw t; // OK: \tcode{Thing(Thing\&\&)} used (or elided) to throw \tcode{t} + return t; // OK: \tcode{Thing(Thing\&\&)} used (or elided) to return \tcode{t} } -\end{codeblock} -The assignment to plain \tcode{aa} is ill-formed since the member name -is not visible outside the union, and even if it were visible, it is not -associated with any particular object. +Thing t2 = f(false); // OK: no extra copy/move performed, \tcode{t2} constructed by call to \tcode{f} + +struct Weird { + Weird(); + Weird(Weird&); +}; + +Weird g() { + Weird w; + return w; // OK: first overload resolution fails, second overload resolution selects \tcode{Weird(Weird\&)} +} +\end{codeblock} \end{example} + +\rSec1[class.compare]{Comparisons}% + +\rSec2[class.compare.default]{Defaulted comparison operator functions}% + +\pnum +A defaulted comparison operator function (\ref{expr.spaceship}, \ref{expr.rel}, \ref{expr.eq}) +for some class \tcode{C} +shall be a non-template function +declared in the \grammarterm{member-specification} of \tcode{C} +that is +\begin{itemize} +\item a non-static member of \tcode{C} having one parameter of type \tcode{const C\&}, or +\item a friend of \tcode{C} having two parameters of type \tcode{const C\&}. +\end{itemize} + +\pnum +\indextext{structural comparison operator|see{operator, structural comparison}}% +A three-way comparison operator for a class type \tcode{C} +is a \defnx{structural comparison operator}{operator!structural comparison} +if it is defined as defaulted in the definition of \tcode{C}, +and all three-way comparison operators it invokes +are structural comparison operators. +\indextext{strong structural equality|see{equality, strong structural}}% +A type \tcode{T} +has \defnx{strong structural equality}{equality!strong structural} +if, for a glvalue \tcode{x} of type \tcode{const T}, +\tcode{x <=> x} is a valid expression +of type \tcode{std::strong_ordering} or \tcode{std::strong_equality} +and either does not invoke a three-way comparison operator +or invokes a structural comparison operator. + +\rSec2[class.spaceship]{Three-way comparison} +\indextext{operator!three-way comparison!defaulted}% + +\pnum +The direct base class subobjects of \tcode{C}, +in the order of their declaration in the \grammarterm{base-specifier-list} of \tcode{C}, +followed by the non-static data members of \tcode{C}, +in the order of their declaration in the \grammarterm{member-specification} of \tcode{C}, +form a list of subobjects. +In that list, any subobject of array type is recursively expanded +to the sequence of its elements, in the order of increasing subscript. +Let $\tcode{x}_i$ be an lvalue denoting the $i^\text{th}$ element +in the expanded list of subobjects for an object \tcode{x} +(of length $n$), +where $\tcode{x}_i$ is +formed by a sequence of +derived-to-base conversions\iref{over.best.ics}, +class member access expressions\iref{expr.ref}, and +array subscript expressions\iref{expr.sub} applied to \tcode{x}. +The type of the expression $\tcode{x}_i$ \tcode{<=>} $\tcode{x}_i$ +is denoted by $\tcode{R}_i$. +It is unspecified +whether virtual base class subobjects are compared more than once. + +\pnum +If the declared return type +of a defaulted three-way comparison operator function +is \tcode{auto}, +then the return type is deduced as +the common comparison type (see below) of +$\tcode{R}_0$, $\tcode{R}_1$, $\dotsc$, $\tcode{R}_{n-1}$. \begin{note} -Initialization of unions with no user-declared constructors is described -in~\ref{dcl.init.aggr}. +Otherwise, +the program will be ill-formed +if the expression $\tcode{x}_i$ \tcode{<=>} $\tcode{x}_i$ +is not implicitly convertible to the declared return type for any $i$. \end{note} +If the return type is deduced as \tcode{void}, +the operator function is defined as deleted. + +\pnum +The return value \tcode{V} of type \tcode{R} +of the defaulted three-way comparison operator function +with parameters \tcode{x} and \tcode{y} of the same type +is determined by comparing corresponding elements +$\tcode{x}_i$ and $\tcode{y}_i$ +in the expanded lists of subobjects for \tcode{x} and \tcode{y} +until the first index $i$ +where $\tcode{x}_i$ \tcode{<=>} $\tcode{y}_i$ +yields a result value $\tcode{v}_i$ where $\tcode{v}_i \mathrel{\tcode{!=}} 0$, +contextually converted to \tcode{bool}, yields \tcode{true}; +\tcode{V} is $\tcode{v}_i$ converted to \tcode{R}. +If no such index exists, \tcode{V} is +\tcode{std::strong_ordering::equal} converted to \tcode{R}. + +\pnum +The \defn{common comparison type} \tcode{U} +of a possibly-empty list of $n$ types +$\tcode{T}_0$, $\tcode{T}_1$, $\dotsc$, $\tcode{T}_{n-1}$ +is defined as follows: + +\begin{itemize} +\item +If any $\tcode{T}_i$ +is not a comparison category type\iref{cmp.categories}, +\tcode{U} is \tcode{void}. + +\item +Otherwise, if +at least one $\tcode{T}_i$ is \tcode{std::weak_equality}, or +at least one $\tcode{T}_i$ is \tcode{std::strong_equality} and +at least one $\tcode{T}_j$ is \tcode{std::partial_ordering} or + \tcode{std::weak_ordering}, +\tcode{U} is \tcode{std::weak_equality}\iref{cmp.weakeq}. + +\item +Otherwise, if at least one $\tcode{T}_i$ is \tcode{std::strong_equality}, +\tcode{U} is \tcode{std::strong_equality}\iref{cmp.strongeq}. + +\item +Otherwise, if at least one $\tcode{T}_i$ is \tcode{std::partial_ordering}, +\tcode{U} is \tcode{std::partial_ordering}\iref{cmp.partialord}. + +\item +Otherwise, if at least one $\tcode{T}_i$ is \tcode{std::weak_ordering}, +\tcode{U} is \tcode{std::weak_ordering}\iref{cmp.weakord}. + +\item +Otherwise, \tcode{U} is \tcode{std::strong_ordering}\iref{cmp.strongord}. +\begin{note} +In particular, this is the result when $n$ is 0. +\end{note} +\end{itemize} + +\rSec2[class.rel.eq]{Other comparison operators} +\indextext{operator!relational!defaulted}% +\indextext{operator!equality!defaulted}% +\indextext{operator!inequality!defaulted}% + +\pnum +A defaulted relational\iref{expr.rel} or equality\iref{expr.eq} operator function +for some operator \tcode{@} +shall have a declared return type \tcode{bool}. + +\pnum +The operator function with parameters \tcode{x} and \tcode{y} +is defined as deleted if + +\begin{itemize} +\item +overload resolution\iref{over.match}, +as applied to \tcode{x <=> y} +(also considering synthesized candidates with reversed order of parameters\iref{over.match.oper}), +results in an ambiguity +or a function that is deleted or inaccessible from the operator function, +or + +\item +the operator \tcode{@} +cannot be applied to the return type of \tcode{x <=> y} or \tcode{y <=> x}. +\end{itemize} + +Otherwise, the operator function yields +\tcode{x <=> y @ 0} +if an \tcode{operator<=>} +with the original order of parameters was selected, or +\tcode{0 @ y <=> x} +otherwise. \pnum -\indextext{class!union-like}% -\indextext{class!variant member of}% -A \defn{union-like class} is a union or a class that has an anonymous union as a direct -member. A union-like class \tcode{X} has a set of \defnx{variant members}{variant member}. -If \tcode{X} is a union, a non-static data member of \tcode{X} that is not an anonymous -union is a variant member of \tcode{X}. In addition, a non-static data member of an -anonymous union that is a member of \tcode{X} is also a variant member of \tcode{X}. -At most one variant member of a union may have a default member initializer. \begin{example} \begin{codeblock} -union U { - int x = 0; - union { - int k; - }; - union { - int z; - int y = 1; // error: initialization for second variant member of \tcode{U} - }; +struct C { + friend std::strong_equality operator<=>(const C&, const C&); + friend bool operator==(const C& x, const C& y) = default; // OK, returns \tcode{x <=> y == 0} + bool operator<(const C&) = default; // OK, function is deleted }; \end{codeblock} \end{example} -\rSec1[class.local]{Local class declarations} -\indextext{declaration!local class}% -\indextext{definition!local class}% -\indextext{class!local|see{local class}}% +\rSec1[class.free]{Free store}% +\indextext{free store}% + +\pnum +\indextext{\idxcode{new}!type of} +Any allocation function for a class +\tcode{T} +is a static member (even if not explicitly declared +\tcode{static}). \pnum -A class can be declared within a function definition; such a class is -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 -access to names outside the function as does the enclosing function. -\begin{note} -A declaration in a local class -cannot odr-use\iref{basic.def.odr} -a local entity -from an -enclosing scope. -\end{note} \begin{example} \begin{codeblock} -int x; -void f() { - static int s; - int x; - const int N = 5; - extern int q(); - int arr[2]; - auto [y, z] = arr; +class Arena; +struct B { + void* operator new(std::size_t, Arena*); +}; +struct D1 : B { +}; - struct local { - int g() { return x; } // error: odr-use of non-odr-usable variable \tcode{x} - int h() { return s; } // OK - int k() { return ::x; } // OK - int l() { return q(); } // OK - int m() { return N; } // OK: not an odr-use - int* n() { return &N; } // error: odr-use of non-odr-usable variable \tcode{N} - int p() { return y; } // error: odr-use of non-odr-usable structured binding \tcode{y} - }; +Arena* ap; +void foo(int i) { + new (ap) D1; // calls \tcode{B::operator new(std::size_t, Arena*)} + new D1[i]; // calls \tcode{::operator new[](std::size_t)} + new D1; // ill-formed: \tcode{::operator new(std::size_t)} hidden } +\end{codeblock} +\end{example} -local* p = 0; // error: \tcode{local} not in scope +\pnum +\indextext{\idxcode{delete}}% +When an object is deleted with a +\grammarterm{delete-expression}\iref{expr.delete}, +a deallocation function +\indextext{function!deallocation}% +(\tcode{operator delete()} +\indextext{\idxcode{operator delete}}% +for non-array objects or +\tcode{operator delete[]()} +\indextext{\idxcode{operator delete}}% +for arrays) is (implicitly) called to reclaim the storage occupied by +the object\iref{basic.stc.dynamic.deallocation}. + +\pnum +Class-specific deallocation function lookup is a part of general deallocation +function lookup\iref{expr.delete} and occurs as follows. +If the \grammarterm{delete-expression} +is used to deallocate a class object whose static type has a virtual +destructor, the deallocation function is the one selected at the point +of definition of the dynamic type's virtual +destructor\iref{class.dtor}.\footnote{A similar provision is not needed for +the array version of \tcode{operator} \tcode{delete} because~\ref{expr.delete} +requires that in this situation, the static type of the object to be deleted be +the same as its dynamic type. +} +Otherwise, if the +\grammarterm{delete-expression} +is used to deallocate an object of class +\tcode{T} +or array thereof, +the deallocation function's name is looked up in the scope of +\tcode{T}. +If this lookup fails to find the name, general deallocation function +lookup\iref{expr.delete} continues. +If the result of the lookup is ambiguous or inaccessible, or if the lookup +selects a placement deallocation function, the program is ill-formed. + +\pnum +\indextext{\idxcode{delete}!type of}% +Any deallocation function for a class +\tcode{X} +is a static member (even if not explicitly declared +\tcode{static}). +\begin{example} +\begin{codeblock} +class X { + void operator delete(void*); + void operator delete[](void*, std::size_t); +}; + +class Y { + void operator delete(void*, std::size_t); + void operator delete[](void*); +}; \end{codeblock} \end{example} \pnum -An enclosing function has no special access to members of the local -class; it obeys the usual access rules\iref{class.access}. -\indextext{member function!local class}% -Member functions of a local class shall be defined within their class -definition, if they are defined at all. +Since member allocation and deallocation functions are +\tcode{static} +they cannot be virtual. +\begin{note} +However, when the +\grammarterm{cast-expression} +of a +\grammarterm{delete-expression} +refers to an object of class type, +because the deallocation function actually called is looked up in the scope of +the class that is the dynamic type of the object +if the destructor is virtual, the effect is the same in that case. +For example, +\begin{codeblock} +struct B { + virtual ~B(); + void operator delete(void*, std::size_t); +}; + +struct D : B { + void operator delete(void*); +}; + +struct E : B { + void log_deletion(); + void operator delete(E *p, std::destroying_delete_t) { + p->log_deletion(); + p->~E(); + ::operator delete(p); + } +}; + +void f() { + B* bp = new D; + delete bp; // 1: uses \tcode{D::operator delete(void*)} + bp = new E; + delete bp; // 2: uses \tcode{E::operator delete(E*, std::destroying_delete_t)} +} +\end{codeblock} +Here, storage for the object of class +\tcode{D} +is deallocated by +\tcode{D::operator delete()}, +and +the object of class \tcode{E} is destroyed +and its storage is deallocated +by \tcode{E::operator delete()}, +due to the virtual destructor. +\end{note} +\begin{note} +Virtual destructors have no effect on the deallocation function actually +called when the +\grammarterm{cast-expression} +of a +\grammarterm{delete-expression} +refers to an array of objects of class type. +For example, +\begin{codeblock} +struct B { + virtual ~B(); + void operator delete[](void*, std::size_t); +}; + +struct D : B { + void operator delete[](void*, std::size_t); +}; + +void f(int i) { + D* dp = new D[i]; + delete [] dp; // uses \tcode{D::operator delete[](void*, std::size_t)} + B* bp = new D[i]; + delete[] bp; // undefined behavior +} +\end{codeblock} +\end{note} \pnum -\indextext{nested class!local class}% -If class \tcode{X} is a local class a nested class \tcode{Y} may be -declared in class \tcode{X} and later defined in the definition of class -\tcode{X} or be later defined in the same scope as the definition of -class \tcode{X}. -\indextext{restriction!local class}% -A class nested within -a local class is a local class. +Access to the deallocation function is checked statically. +Hence, even though a different one might actually be executed, +the statically visible deallocation function is required to be accessible. +\begin{example} +For the call on line ``// 1'' above, +if +\tcode{B::operator delete()} +had been private, the delete expression would have been ill-formed. +\end{example} \pnum -\indextext{restriction!static member local class}% -A local class shall not have static data members. +\begin{note} +If a deallocation function has no explicit \grammarterm{noexcept-specifier}, it +has a non-throwing exception specification\iref{except.spec}. +\end{note} diff --git a/source/compatibility.tex b/source/compatibility.tex index 1686a25c86..6947f19b6f 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -248,7 +248,7 @@ \howwide Common. -\diffref{expr.post.incr}, \ref{expr.pre.incr} +\diffrefs{expr.post.incr}{expr.pre.incr} \change Decrement operator is not allowed with \tcode{bool} operand. \rationale Feature with surprising semantics. @@ -256,7 +256,7 @@ a \tcode{bool} lvalue (for instance, via the C typedef in \tcode{}) is ill-formed in this International Standard. -\diffref{expr.sizeof}, \ref{expr.cast} +\diffrefs{expr.sizeof}{expr.cast} \change Types must be defined in declarations, not in expressions.\\ In C, a sizeof expression or cast expression may define a new type. For example, @@ -274,7 +274,7 @@ \howwide Seldom. -\diffref{expr.cond}, \ref{expr.ass}, \ref{expr.comma} +\diffrefs{expr.cond}{expr.ass}, \ref{expr.comma} \indextext{conversion!lvalue-to-rvalue}% \indextext{rvalue!lvalue conversion to}% \indextext{lvalue}% @@ -305,7 +305,7 @@ \rSec2[diff.stat]{\ref{stmt.stmt}: statements} -\diffref{stmt.switch}, \ref{stmt.goto} +\diffrefs{stmt.switch}{stmt.goto} \change It is now invalid to jump past a declaration with explicit or implicit initializer (except across entire block not entered). \rationale Constructors used in initializers may allocate @@ -790,7 +790,7 @@ \rSec2[diff.special]{\ref{special}: special member functions} -\diffref{class.copy} +\diffref{class.copy.ctor} \change Copying volatile objects. The implicitly-declared copy constructor and @@ -993,7 +993,7 @@ \rSec2[diff.cpp03.special]{\ref{special}: special member functions} -\diffref{class.ctor}, \ref{class.dtor}, \ref{class.copy} +\diffrefs{class.ctor}{class.dtor}, \ref{class.copy.ctor}, \ref{class.copy.assign} \change Implicitly-declared special member functions are defined as deleted when the implicit definition would have been ill-formed. \rationale Improves template argument deduction failure. @@ -1085,13 +1085,9 @@ and \tcode{}. In addition the following C compatibility headers are new: -\tcode{}, \tcode{}, \tcode{}, -\tcode{}, -\tcode{}, \tcode{}, -\tcode{}, and \tcode{}. Valid \CppIII{} code that \tcode{\#include}{s} headers with these names may be @@ -1123,40 +1119,6 @@ \rSec2[diff.cpp03.language.support]{\ref{language.support}: language support library} -\diffref{new.delete.single} -\change Linking \tcode{new} and \tcode{delete} operators. -\rationale The two throwing single-object signatures of \tcode{operator new} and -\tcode{operator delete} are now specified to form the base functionality for -the other operators. This clarifies that replacing just these two signatures -changes others, even if they are not explicitly changed. -\effect -Valid \CppIII{} code that replaces global \tcode{new} or \tcode{delete} -operators may execute differently in this International Standard. For -example, the following program should write \tcode{"custom deallocation"} twice, -once for the single-object delete and once for the array delete. - -\begin{codeblock} -#include -#include -#include - -void* operator new(std::size_t size) throw(std::bad_alloc) { - return std::malloc(size); -} - -void operator delete(void* ptr) throw() { - std::puts("custom deallocation"); - std::free(ptr); -} - -int main() { - int* i = new int; - delete i; // single-object delete - int* a = new int[3]; - delete [] a; // array delete -} -\end{codeblock} - \diffref{new.delete.single} \change \tcode{operator new} may throw exceptions other than \tcode{std::bad_alloc}. @@ -1165,6 +1127,10 @@ Valid \CppIII{} code that assumes that global \tcode{operator new} only throws \tcode{std::bad_alloc} may execute differently in this International Standard. +Valid \CppIII{} code that replaces the global replaceable \tcode{operator new} +is ill-formed in this International Standard, +because the exception specification of \tcode{throw(std::bad_alloc)} +was removed. \rSec2[diff.cpp03.diagnostics]{\ref{diagnostics}: diagnostics library} @@ -1185,8 +1151,8 @@ that interacts with newer \Cpp{} code using regions declared reachable may have different runtime behavior. -\diffref{refwrap}, \ref{arithmetic.operations}, \ref{comparisons}, -\ref{logical.operations}, \ref{bitwise.operations}, \ref{depr.negators} +\diffrefs{refwrap}{arithmetic.operations}, \ref{comparisons}, +\ref{logical.operations}, \ref{bitwise.operations} \change Standard function object types no longer derived from \tcode{std::unary_function} or \tcode{std::binary_function}. \rationale Superseded by new feature; \tcode{unary_function} and @@ -1247,7 +1213,7 @@ Valid \CppIII{} code that attempts to explicitly instantiate a container using a user-defined type with no default constructor may fail to compile. -\diffref{sequence.reqmts}, \ref{associative.reqmts} +\diffrefs{sequence.reqmts}{associative.reqmts} \change Signature changes: from \tcode{void} return types. \rationale Old signature threw away useful information that may be expensive to recalculate. @@ -1264,7 +1230,7 @@ (e.g., code that creates a pointer to member function that points to one of these functions) will fail to compile with this International Standard. -\diffref{sequence.reqmts}, \ref{associative.reqmts} +\diffrefs{sequence.reqmts}{associative.reqmts} \change Signature changes: from \tcode{iterator} to \tcode{const_iterator} parameters. \rationale Overspecification. @@ -1285,7 +1251,7 @@ Valid \CppIII{} code that uses these functions may fail to compile with this International Standard. -\diffref{sequence.reqmts}, \ref{associative.reqmts} +\diffrefs{sequence.reqmts}{associative.reqmts} \change Signature changes: \tcode{resize}. \rationale Performance, compatibility with move semantics. \effect @@ -1319,7 +1285,7 @@ \rSec2[diff.cpp03.input.output]{\ref{input.output}: input/output library} -\diffref{istream::sentry}, \ref{ostream::sentry}, \ref{iostate.flags} +\diffrefs{istream::sentry}{ostream::sentry}, \ref{iostate.flags} \change Specify use of \tcode{explicit} in existing boolean conversion functions. \rationale Clarify intentions, avoid workarounds. \effect @@ -1543,7 +1509,7 @@ \rSec2[diff.cpp14.expr]{\ref{expr}: expressions} -\diffref{expr.post.incr}, \ref{expr.pre.incr} +\diffrefs{expr.post.incr}{expr.pre.incr} \change Remove increment operator with \tcode{bool} operand. \rationale Obsolete feature with occasionally surprising semantics. @@ -1552,7 +1518,7 @@ Note that this might occur when the lvalue has a type given by a template parameter. -\diffref{expr.new}, \ref{expr.delete} +\diffrefs{expr.new}{expr.delete} \change Dynamic allocation mechanism for over-aligned types. \rationale Simplify use of over-aligned types. \effect In \CppXIV{} code that uses a \grammarterm{new-expression} @@ -1800,6 +1766,7 @@ \rSec2[diff.cpp14.depr]{\ref{depr}: compatibility features} +\nodiffref \change The class templates \tcode{auto_ptr}, @@ -1818,6 +1785,7 @@ \effect Valid \CppXIV{} code that uses these class templates and function templates may fail to compile in this International Standard. +\nodiffref \change Remove old iostreams members [depr.ios.members]. \rationale Redundant feature for compatibility with pre-standard code @@ -1872,8 +1840,72 @@ if those entities are only referenced in contexts that do not result in an odr-use. +\rSec2[diff.cpp17.dcl.decl]{\ref{dcl.decl}: declarators} + +\diffref{dcl.init.aggr} +\change A class that has user-declared constructors is never an aggregate. +\rationale Remove potentially error-prone aggregate initialization +which may apply notwithstanding the declared constructors of a class. +\effect Valid \CppXVII{} code that aggregate-initializes +a type with a user-declared constructor +may be ill-formed or have different semantics +in this International Standard. +\begin{codeblock} +struct A { // not an aggregate; previously an aggregate + A() = delete; +}; + +struct B { // not an aggregate; previously an aggregate + B() = default; + int i = 0; +}; + +struct C { // not an aggregate; previously an aggregate + C(C&&) = default; + int a, b; +}; + +A a{}; // ill-formed; previously well-formed +B b = {1}; // ill-formed; previously well-formed +auto* c = new C{2, 3}; // ill-formed; previously well-formed + +struct Y; + +struct X { + operator Y(); +}; + +struct Y { // not an aggregate; previously an aggregate + Y(const Y&) = default; + X x; +}; + +Y y{X{}}; // copy constructor call; previously aggregate-initialization +\end{codeblock} + \rSec2[diff.cpp17.special]{\ref{special}: special member functions} +\diffrefs{class.ctor}{class.conv.fct} +\change +The class name can no longer be used parenthesized +immediately after an \tcode{explicit} \grammarterm{decl-specifier} +in a constructor declaration. +The \grammarterm{conversion-function-id} can no longer be used parenthesized +immediately after an \tcode{explicit} \grammarterm{decl-specifier} +in a conversion function declaration. +\rationale +Necessary for new functionality. +\effect +Valid \CppXVII{} code may fail to compile +in this International Standard. For example: +\begin{codeblock} +struct S { + explicit (S)(const S&); // ill-formed; previously well-formed + explicit (operator int)(); // ill-formed; previously well-formed + explicit(true) (S)(int); // OK +}; +\end{codeblock} + \diffrefs{class.ctor}{class.dtor} \change A \grammarterm{simple-template-id} @@ -1923,6 +1955,26 @@ } \end{codeblock} +\rSec2[diff.cpp17.except]{\ref{except}: exception handling} + +\diffref{except.spec} +\change Remove \tcode{throw()} exception specification. +\rationale +Removal of obsolete feature that has been replaced by \tcode{noexcept}. +\effect +A valid \CppXVII{} function declaration, member function declaration, function +pointer declaration, or function reference declaration that uses \tcode{throw()} +for its exception specification will be rejected as ill-formed in this +International Standard. It should simply be replaced with \tcode{noexcept} for no +change of meaning since \CppXVII{}. +\begin{note} +There is no way to write a function declaration +that is non-throwing in this International Standard +and is also non-throwing in \CppIII{} +except by using the preprocessor to generate +a different token sequence in each case. +\end{note} + \rSec2[diff.cpp17.library]{\ref{library}: library introduction} \diffref{headers} @@ -1930,13 +1982,140 @@ \rationale New functionality. \effect The following \Cpp{} headers are new: +\tcode{}, \tcode{}, +\tcode{}, +\tcode{}, \tcode{}, \tcode{}, and \tcode{}. Valid \CppXVII{} code that \tcode{\#include}{s} headers with these names may be invalid in this International Standard. +\diffref{headers} +\change Remove vacuous \Cpp{} header files. +\rationale +The empty headers implied a false requirement to achieve C compatibility with the \Cpp{} headers. +\effect +A valid \CppXVII{} program that \tcode{\#include}{s} any of the following headers may fail to compile: +\tcode{}, +\tcode{}, +\tcode{}, +\tcode{}, and +\tcode{}. +To retain the same behavior: +\begin{itemize} +\item +a \tcode{\#include} of \tcode{} can be replaced by +a \tcode{\#include} of \tcode{}\iref{complex.syn}, +\item +a \tcode{\#include} of \tcode{} can be replaced by +a \tcode{\#include} of \tcode{}\iref{cmath.syn} and +a \tcode{\#include} of \tcode{}, +and +\item +a \tcode{\#include} of +\tcode{}, +\tcode{}, or +\tcode{} +can simply be removed. +\end{itemize} + +\rSec2[diff.cpp17.containers]{\ref{containers}: containers library} + +\diffrefs{forwardlist}{list} +\change +Return types of \tcode{remove}, \tcode{remove_if}, and \tcode{unique} +changed from \tcode{void} to \tcode{container::size_type}. +\rationale Improve efficiency and convenience of finding number of removed elements. +\effect +Code that depends on the return types might have different semantics in this International Standard. +Translation units compiled against this version of \Cpp{} may be incompatible with +translation units compiled against \CppXVII{}, either failing to link or having undefined behavior. + +\rSec2[diff.cpp17.depr]{\ref{depr}: compatibility features} + +\nodiffref +\change Remove \tcode{uncaught_exception}. +\rationale +The function did not have a clear specification when multiple exceptions were +active, and has been superseded by \tcode{uncaught_exceptions}. +\effect +A valid \CppXVII{} program that calls \tcode{std::uncaught_exception} may fail +to compile. It might be revised to use \tcode{std::uncaught_exceptions} instead, +for clear and portable semantics. + +\nodiffref +\change Remove support for adaptable function API. +\rationale +The deprecated support relied on a limited convention that could not be +extended to support the general case or new language features. It has been +superseded by direct language support with \tcode{decltype}, and by the +\tcode{std::bind} and \tcode{std::not_fn} function templates. +\effect +A valid \CppXVII{} program that relies on the presence of \tcode{result_type}, +\tcode{argument_type}, \tcode{first_argument_type}, or +\tcode{second_argument_type} in a standard library class may fail to compile. A +valid \CppXVII{} program that calls \tcode{not1} or \tcode{not2}, or uses the +class templates \tcode{unary_negate} or \tcode{binary_negate}, may fail to +compile. + +\nodiffref +\change Remove redundant members from \tcode{std::allocator}. +\rationale +\tcode{std::allocator} was overspecified, encouraging direct usage in user containers +rather than relying on \tcode{std::allocator_traits}, leading to poor containers. +\effect +A valid \CppXVII{} program that directly makes use of the \tcode{pointer}, +\tcode{const_pointer}, \tcode{reference}, \tcode{const_reference}, +\tcode{rebind}, \tcode{address}, \tcode{construct}, \tcode{destroy}, or +\tcode{max_size} members of \tcode{std::allocator}, or that directly calls +\tcode{allocate} with an additional hint argument, may fail to compile. + +\nodiffref +\change Remove \tcode{raw_storage_iterator}. +\rationale +The iterator encouraged use of algorithms that might throw exceptions, but did +not return the number of elements successfully constructed that might need to +be destroyed in order to avoid leaks. +\effect +A valid \CppXVII{} program that uses this iterator class may fail to compile. + +\nodiffref +\change Remove temporary buffers API. +\rationale +The temporary buffer facility was intended to provide an efficient optimization +for small memory requests, but there is little evidence this was achieved in +practice, while requiring the user to provide their own exception-safe wrappers +to guard use of the facility in many cases. +\effect +A valid \CppXVII{} program that calls \tcode{get_temporary_buffer} or +\tcode{return_temporary_buffer} may fail to compile. + +\nodiffref +\change Remove \tcode{shared_ptr::unique}. +\rationale +The result of a call to this member function is not reliable in the presence of +multiple threads and weak pointers. The member function \tcode{use_count} is +similarly unreliable, but has a clearer contract in such cases, and remains +available for well defined use in single-threaded cases. +\effect +A valid \CppXVII{} program that calls \tcode{unique} on a \tcode{shared_ptr} +object may fail to compile. + +\diffref{depr.meta.types} +\change Remove deprecated type traits. +\rationale +The traits had unreliable or awkward interfaces. The \tcode{is_literal_type} +trait provided no way to detect which subset of constructors and member +functions of a type were declared \tcode{constexpr}. The \tcode{result_of} +trait had a surprising syntax that could not report the result of a regular +function type. It has been superseded by the \tcode{invoke_result} trait. +\effect +A valid \CppXVII{} program that relies on the \tcode{is_literal_type} or +\tcode{result_of} type traits, on the \tcode{is_literal_type_v} variable template, +or on the \tcode{result_of_t} alias template may fail to compile. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \rSec1[diff.library]{C standard library} \indextext{library!C standard}% @@ -1955,27 +2134,17 @@ in~\ref{depr.c.headers}, but their use is deprecated in \Cpp{}. \pnum -There are no \Cpp{} headers for the C headers +There are no \Cpp{} headers for the C standard library's headers \tcode{}\indextext{\idxhdr{stdatomic.h}!absence thereof}, \tcode{}\indextext{\idxhdr{stdnoreturn.h}!absence thereof}, and \tcode{}\indextext{\idxhdr{threads.h}!absence thereof}, -nor are the C headers themselves part of \Cpp{}. - -\pnum -The \Cpp{} headers \tcode{}\indexhdr{ccomplex}\iref{depr.ccomplex.syn} -and \tcode{}\indexhdr{ctgmath}\iref{depr.ctgmath.syn}, as well -as their corresponding C headers \tcode{}\indexhdr{complex.h} -and \tcode{}\indexhdr{tgmath.h}, do not contain any of the -content from the C standard library and instead merely include other headers -from the \Cpp{} standard library. +nor are these headers from the C standard library headers themselves part of \Cpp{}. \pnum -The headers \tcode{}\indexhdr{ciso646}, -\tcode{}\indexhdr{cstdalign}\iref{depr.cstdalign.syn}, -and \tcode{}\indexhdr{cstdbool}\iref{depr.cstdbool.syn} -are meaningless in \Cpp{}. Use of -the \Cpp{} headers \tcode{}, \tcode{}, \tcode{}, -and \tcode{} is deprecated\iref{depr.c.headers}. +The C headers \tcode{}\indexhdr{complex.h} and +\tcode{}\indexhdr{tgmath.h} do not contain any of the content from +the C standard library and instead merely include other headers from the \Cpp{} +standard library. \rSec2[diff.mods.to.definitions]{Modifications to definitions} @@ -2027,27 +2196,27 @@ and \tcode{xor_eq} are keywords in this International -Standard\iref{lex.key}. -They do not appear as macro names defined in -\tcode{}. -\indexhdr{ciso646}% +Standard\iref{lex.key}, +and are not introduced as macros +by \tcode{}\iref{depr.iso646.h.syn}. \rSec3[diff.header.stdalign.h]{Header \tcode{}} \indexhdr{stdalign.h}% \pnum The token \tcode{alignas} is a keyword in this International -Standard\iref{lex.key}. It does not appear as a macro name defined -in \tcode{}\indexhdr{cstdalign}\iref{depr.cstdalign.syn}. +Standard\iref{lex.key}, +and is not introduced as a macro +by \tcode{}\iref{depr.stdalign.h.syn}. \rSec3[diff.header.stdbool.h]{Header \tcode{}} \indexhdr{stdbool.h}% \pnum The tokens \tcode{bool}, \tcode{true}, and \tcode{false} -are keywords in this International Standard\iref{lex.key}. -They do not appear as macro names defined in -\tcode{}\indexhdr{cstdbool}\iref{depr.cstdbool.syn}. +are keywords in this International Standard\iref{lex.key}, +and are not introduced as macros +by \tcode{}\iref{depr.stdbool.h.syn}. \rSec3[diff.null]{Macro \tcode{NULL}} diff --git a/source/concepts.tex b/source/concepts.tex new file mode 100644 index 0000000000..defd96dcb7 --- /dev/null +++ b/source/concepts.tex @@ -0,0 +1,1166 @@ +%!TEX root = std.tex +\rSec0[concepts]{Concepts library} + +\rSec1[concepts.general]{General} + +\pnum +This Clause describes library components that \Cpp{} programs may use to perform +compile-time validation of template arguments and perform function dispatch +based on properties of types. The purpose of these concepts is to establish +a foundation for equational reasoning in programs. + +\pnum +The following subclauses describe language-related concepts, comparison +concepts, object concepts, and callable concepts as summarized in +\tref{concepts.lib.summary}. + +\begin{libsumtab}{Fundamental concepts library summary}{tab:concepts.lib.summary} +\ref{concepts.lang} & Language-related concepts & \tcode{} \\ +\ref{concepts.compare} & Comparison concepts & \\ +\ref{concepts.object} & Object concepts & \\ +\ref{concepts.callable} & Callable concepts & \\ +\end{libsumtab} + +\rSec1[concepts.equality]{Equality preservation} + +\pnum +An expression is \defnx{equality-preserving}{expression!equality-preserving} if, +given equal inputs, the expression results in equal outputs. The inputs to an +expression are the set of the expression's operands. The output of an expression +is the expression's result and all operands modified by the expression. + +\pnum +Not all input values need be valid for a given expression; e.g., for integers +\tcode{a} and \tcode{b}, the expression \tcode{a / b} is not well-defined when +\tcode{b} is \tcode{0}. This does not preclude the expression \tcode{a / b} +being equality-preserving. The \term{domain} of an expression is the set of +input values for which the expression is required to be well-defined. + +\pnum +Expressions required by this document to be equality-preserving are further +required to be stable: two evaluations of such an expression with the same input +objects are required to have equal outputs absent any explicit intervening +modification of those input objects. +\begin{note} +This requirement allows generic code to reason about the current values of +objects based on knowledge of the prior values as observed via +equality-preserving expressions. It effectively forbids spontaneous changes to +an object, changes to an object from another thread of execution, changes to an +object as side effects of non-modifying expressions, and changes to an object as +side effects of modifying a distinct object if those changes could be observable +to a library function via an equality-preserving expression that is required to +be valid for that object. +\end{note} + +\pnum +Expressions declared in a \grammarterm{requires-expression} in this document are +required to be equality-preserving, except for those annotated with the comment +``not required to be equality-preserving.'' An expression so annotated +may be equality-preserving, but is not required to be so. + +\pnum +An expression that may alter the value of one or more of its inputs in a manner +observable to equality-preserving expressions is said to modify those inputs. +This document uses a notational convention to specify which expressions declared +in a \grammarterm{requires-expression} modify which inputs: except where +otherwise specified, an expression operand that is a non-constant lvalue or +rvalue may be modified. Operands that are constant lvalues or rvalues are +required to not be modified. + +\pnum +Where a \grammarterm{requires-expression} declares an expression that is +non-modifying for some constant lvalue operand, additional variations of that +expression that accept a non-constant lvalue or (possibly constant) rvalue for +the given operand are also required except where such an expression variation is +explicitly required with differing semantics. These +\term{implicit expression variations} are required to meet the semantic +requirements of the declared expression. The extent to which an implementation +validates the syntax of the variations is unspecified. + +\pnum +\begin{example} +\begin{codeblock} +template concept C = requires(T a, T b, const T c, const T d) { + c == d; // \#1 + a = std::move(b); // \#2 + a = c; // \#3 +}; +\end{codeblock} + +For the above example: +\begin{itemize} +\item +Expression \#1 does not modify either of its operands, \#2 modifies both of its +operands, and \#3 modifies only its first operand \tcode{a}. + +\item +Expression \#1 implicitly requires additional expression variations that meet +the requirements for \tcode{c == d} (including non-modification), as if the +expressions +\begin{codeblock} + c == b; + c == std::move(d); c == std::move(b); +std::move(c) == d; std::move(c) == b; +std::move(c) == std::move(d); std::move(c) == std::move(b); + + a == d; a == b; + a == std::move(d); a == std::move(b); +std::move(a) == d; std::move(a) == b; +std::move(a) == std::move(d); std::move(a) == std::move(b); +\end{codeblock} +had been declared as well. + +\item +Expression \#3 implicitly requires additional expression variations that meet +the requirements for \tcode{a = c} (including non-modification of the second +operand), as if the expressions \tcode{a = b} and \tcode{a = std::move(c)} had +been declared. Expression \#3 does not implicitly require an expression +variation with a non-constant rvalue second operand, since expression \#2 +already specifies exactly such an expression explicitly. +\end{itemize} +\end{example} + +\pnum +\begin{example} +The following type \tcode{T} meets the explicitly stated syntactic requirements +of concept \tcode{C} above but does not meet the additional implicit +requirements: + +\begin{codeblock} +struct T { + bool operator==(const T&) const { return true; } + bool operator==(T&) = delete; +}; +\end{codeblock} + +\tcode{T} fails to meet the implicit requirements of \tcode{C}, so \tcode{C} +is not satisfied. Since implementations are not required to validate the syntax +of implicit requirements, it is unspecified whether an implementation diagnoses +as ill-formed a program that requires \tcode{C}. +\end{example} + +\rSec1[concepts.syn]{Header \tcode{} synopsis} + +\indexlibrary{\idxhdr{concepts}}% +\begin{codeblock} +namespace std { + // \ref{concepts.lang}, language-related concepts + // \ref{concept.same}, concept \libconcept{Same} + template + concept Same = @\seebelow@; + + // \ref{concept.derivedfrom}, concept \libconcept{DerivedFrom} + template + concept DerivedFrom = @\seebelow@; + + // \ref{concept.convertibleto}, concept \libconcept{ConvertibleTo} + template + concept ConvertibleTo = @\seebelow@; + + // \ref{concept.commonref}, concept \libconcept{CommonReference} + template + concept CommonReference = @\seebelow@; + + // \ref{concept.common}, concept \libconcept{Common} + template + concept Common = @\seebelow@; + + // \ref{concepts.integral}, integral concepts + template + concept Integral = @\seebelow@; + template + concept SignedIntegral = @\seebelow@; + template + concept UnsignedIntegral = @\seebelow@; + + // \ref{concept.assignable}, concept \libconcept{Assignable} + template + concept Assignable = @\seebelow@; + + // \ref{concept.swappable}, concept \libconcept{Swappable} + template + concept Swappable = @\seebelow@; + template + concept SwappableWith = @\seebelow@; + + // \ref{concept.destructible}, concept \libconcept{Destructible} + template + concept Destructible = @\seebelow@; + + // \ref{concept.constructible}, concept \libconcept{Constructible} + template + concept Constructible = @\seebelow@; + + // \ref{concept.defaultconstructible}, concept \libconcept{DefaultConstructible} + template + concept DefaultConstructible = @\seebelow@; + + // \ref{concept.moveconstructible}, concept \libconcept{MoveConstructible} + template + concept MoveConstructible = @\seebelow@; + + // \ref{concept.copyconstructible}, concept \libconcept{CopyConstructible} + template + concept CopyConstructible = @\seebelow@; + + // \ref{concepts.compare}, comparison concepts + // \ref{concept.boolean}, concept \libconcept{Boolean} + template + concept Boolean = @\seebelow@; + + // \ref{concept.equalitycomparable}, concept \libconcept{EqualityComparable} + template + concept EqualityComparable = @\seebelow@; + template + concept EqualityComparableWith = @\seebelow@; + + // \ref{concept.stricttotallyordered}, concept \libconcept{StrictTotallyOrdered} + template + concept StrictTotallyOrdered = @\seebelow@; + template + concept StrictTotallyOrderedWith = @\seebelow@; + + // \ref{concepts.object}, object concepts + template + concept Movable = @\seebelow@; + template + concept Copyable = @\seebelow@; + template + concept Semiregular = @\seebelow@; + template + concept Regular = @\seebelow@; + + // \ref{concepts.callable}, callable concepts + // \ref{concept.invocable}, concept \libconcept{Invocable} + template + concept Invocable = @\seebelow@; + + // \ref{concept.regularinvocable}, concept \libconcept{RegularInvocable} + template + concept RegularInvocable = @\seebelow@; + + // \ref{concept.predicate}, concept \libconcept{Predicate} + template + concept Predicate = @\seebelow@; + + // \ref{concept.relation}, concept \libconcept{Relation} + template + concept Relation = @\seebelow@; + + // \ref{concept.strictweakorder}, concept \libconcept{StrictWeakOrder} + template + concept StrictWeakOrder = @\seebelow@; +} +\end{codeblock} + +\rSec1[concepts.lang]{Language-related concepts} + +\rSec2[concepts.lang.general]{General} + +\pnum +This subclause contains the definition of concepts corresponding to language +features. These concepts express relationships between types, type +classifications, and fundamental type properties. + +\rSec2[concept.same]{Concept \libconcept{Same}} + +\indexlibrary{\idxcode{Same}}% +\begin{itemdecl} +template + concept Same = is_same_v; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\tcode{\libconcept{Same}} subsumes \tcode{\libconcept{Same}} and +vice versa. +\end{itemdescr} + +\rSec2[concept.derivedfrom]{Concept \libconcept{DerivedFrom}} + +\indexlibrary{\idxcode{DerivedFrom}}% +\begin{itemdecl} +template + concept DerivedFrom = + is_base_of_v && + is_convertible_v; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\begin{note} +\tcode{\libconcept{DerivedFrom}} is satisfied if and only if +\tcode{Derived} is publicly and unambiguously derived from \tcode{Base}, or +\tcode{Derived} and \tcode{Base} are the same class type ignoring cv-qualifiers. +\end{note} +\end{itemdescr} + +\rSec2[concept.convertibleto]{Concept \libconcept{ConvertibleTo}} + +\pnum +The \libconcept{ConvertibleTo} concept requires an expression of a particular +type and value category to be both implicitly and explicitly convertible to some +other type. The implicit and explicit conversions are required to produce equal +results. + +\indexlibrary{\idxcode{ConvertibleTo}}% +\begin{itemdecl} +template + concept ConvertibleTo = + is_convertible_v && + requires(From (&f)()) { + static_cast(f()); + }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{test} be the invented function: +\begin{codeblock} +To test(From (&f)()) { + return f(); +} +\end{codeblock} +and let \tcode{f} be a function with no arguments and return type \tcode{From} +such that \tcode{f()} is equality-preserving. +\tcode{\libconcept{ConvertibleTo}} is satisfied only if: + +\begin{itemize} +\item +\tcode{To} is not an object or reference-to-object type, or +\tcode{static_cast(f())} is equal to \tcode{test(f)}. + +\item +\tcode{From} is not a reference-to-object type, or + +\begin{itemize} +\item +If \tcode{From} is an rvalue reference to a non const-qualified type, the +resulting state of the object referenced by \tcode{f()} after either above +expression is valid but unspecified\iref{lib.types.movedfrom}. + +\item +Otherwise, the object referred to by \tcode{f()} is not modified by either above +expression. +\end{itemize} +\end{itemize} +\end{itemdescr} + + +\rSec2[concept.commonref]{Concept \libconcept{CommonReference}} + +\pnum +For two types \tcode{T} and \tcode{U}, if \tcode{common_reference_t} +is well-formed and denotes a type \tcode{C} such that both +\tcode{\libconcept{ConvertibleTo}} +and +\tcode{\libconcept{ConvertibleTo}} +are satisfied, then \tcode{T} and \tcode{U} share a +\term{common reference type}, \tcode{C}. +\begin{note} +\tcode{C} could be the same as \tcode{T}, or \tcode{U}, or it could be a +different type. \tcode{C} may be a reference type. +\end{note} + +\indexlibrary{\idxcode{CommonReference}}% +\begin{itemdecl} +template + concept CommonReference = + Same, common_reference_t> && + ConvertibleTo> && + ConvertibleTo>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{C} be \tcode{common_reference_t}. Let \tcode{t} be a +function whose return type is \tcode{T}, and let \tcode{u} be a function +whose return type is \tcode{U}. \tcode{\libconcept{CommonReference}} is +satisfied only if: +\begin{itemize} +\item \tcode{C(t())} equals \tcode{C(t())} if and only if \tcode{t()} is an + equality-preserving expression\iref{concepts.equality}. +\item \tcode{C(u())} equals \tcode{C(u())} if and only if \tcode{u()} is an + equality-preserving expression. +\end{itemize} + +\pnum +\begin{note} +Users can customize the behavior of \libconcept{CommonReference} by specializing +the \tcode{basic_common_reference} class template\iref{meta.trans.other}. +\end{note} +\end{itemdescr} + +\rSec2[concept.common]{Concept \libconcept{Common}} + +\pnum +If \tcode{T} and \tcode{U} can both be explicitly converted to some third type, +\tcode{C}, then \tcode{T} and \tcode{U} share a \term{common type}, +\tcode{C}. +\begin{note} +\tcode{C} could be the same as \tcode{T}, or \tcode{U}, or it could be a +different type. \tcode{C} might not be unique. +\end{note} + +\indexlibrary{\idxcode{Common}}% +\begin{itemdecl} +template + concept Common = + Same, common_type_t> && + ConvertibleTo> && + ConvertibleTo> && + CommonReference< + add_lvalue_reference_t, + add_lvalue_reference_t> && + CommonReference< + add_lvalue_reference_t>, + common_reference_t< + add_lvalue_reference_t, + add_lvalue_reference_t>>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{C} be \tcode{common_type_t}. Let +\tcode{t} be a function whose return type is \tcode{T}, and let \tcode{u} be a +function whose return type is \tcode{U}. \tcode{\libconcept{Common}} is +satisfied only if: +\begin{itemize} +\item \tcode{C(t())} equals \tcode{C(t())} if and only if + \tcode{t()} is an equality-preserving + expression\iref{concepts.equality}. +\item \tcode{C(u())} equals \tcode{C(u())} if and only if + \tcode{u()} is an equality-preserving + expression\iref{concepts.equality}. +\end{itemize} + +\pnum +\begin{note} +Users can customize the behavior of \libconcept{Common} by specializing the +\tcode{common_type} class template\iref{meta.trans.other}. +\end{note} + +\end{itemdescr} + +\rSec2[concepts.integral]{Integral concepts} + +\indexlibrary{\idxcode{Integral}}% +\indexlibrary{\idxcode{SignedIntegral}}% +\indexlibrary{\idxcode{UnsignedIntegral}}% +\begin{itemdecl} +template + concept Integral = is_integral_v; +template + concept SignedIntegral = Integral && is_signed_v; +template + concept UnsignedIntegral = Integral && !SignedIntegral; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\begin{note} +\tcode{\libconcept{SignedIntegral}} can be satisfied even by types that are +not signed integral types\iref{basic.fundamental}; for example, \tcode{char}. +\end{note} + +\pnum +\begin{note} +\tcode{\libconcept{UnsignedIntegral}} can be satisfied even by types that are +not unsigned integral types\iref{basic.fundamental}; for example, \tcode{bool}. +\end{note} +\end{itemdescr} + +\rSec2[concept.assignable]{Concept \libconcept{Assignable}} + +\indexlibrary{\idxcode{Assignable}}% +\begin{itemdecl} +template + concept Assignable = + is_lvalue_reference_v && + CommonReference&, const remove_reference_t&> && + requires(LHS lhs, RHS&& rhs) { + lhs = std::forward(rhs); + requires Same(rhs)), LHS>; + }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let: +\begin{itemize} +\item \tcode{lhs} be an lvalue that refers to an object \tcode{lcopy} such that + \tcode{decltype((lhs))} is \tcode{LHS}, +\item \tcode{rhs} be an expression such that \tcode{decltype((rhs))} is + \tcode{RHS}, and +\item \tcode{rcopy} be a distinct object that is equal to \tcode{rhs}. +\end{itemize} +\tcode{\libconcept{Assignable}} is satisfied only if + +\begin{itemize} +\item \tcode{addressof(lhs = rhs) == addressof(lcopy)}. + +\item After evaluating \tcode{lhs = rhs}: + +\begin{itemize} +\item \tcode{lhs} is equal to \tcode{rcopy}, unless \tcode{rhs} is a non-const +xvalue that refers to \tcode{lcopy}. + +\item If \tcode{rhs} is a non-\tcode{const} xvalue, the resulting state of the +object to which it refers is valid but unspecified\iref{lib.types.movedfrom}. + +\item Otherwise, if \tcode{rhs} is a glvalue, the object to which it refers is + not modified. +\end{itemize} +\end{itemize} + +\pnum +\begin{note} +Assignment need not be a total function\iref{structure.requirements}; +in particular, if assignment to an object \tcode{x} can result in a modification +of some other object \tcode{y}, then \tcode{x = y} is likely not in the domain +of \tcode{=}. +\end{note} +\end{itemdescr} + +\rSec2[concept.swappable]{Concept \libconcept{Swappable}} + +\indexlibrary{\idxcode{Swappable}}% +\begin{itemdecl} +template + concept Swappable = is_swappable_v; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{a1} and \tcode{a2} denote distinct equal objects of type \tcode{T}, +and let \tcode{b1} and \tcode{b2} similarly denote distinct equal objects of +type \tcode{T}. \tcode{\libconcept{Swappable}} is satisfied only if after +evaluating either \tcode{swap(a1, b1)} or \tcode{swap(b1, a1)} in the context +described below, \tcode{a1} is equal to \tcode{b2} and \tcode{b1} is equal to +\tcode{a2}. + +\pnum +The context in which \tcode{swap(a1, b1)} or \tcode{swap(b1, a1)} is evaluated +shall ensure that a binary non-member function named \tcode{swap} is selected via +overload resolution\iref{over.match} on a candidate set that includes: +\begin{itemize} +\item the two \tcode{swap} function templates defined in + \tcode{}\iref{utility} and +\item the lookup set produced by argument-dependent + lookup\iref{basic.lookup.argdep}. +\end{itemize} +\end{itemdescr} + +\indexlibrary{\idxcode{SwappableWith}}% +\begin{itemdecl} +template + concept SwappableWith = + is_swappable_with_v && is_swappable_with_v && + CommonReference&, const remove_reference_t&> && + is_swappable_with_v && is_swappable_with_v; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let: +\begin{itemize} +\item \tcode{t1} and \tcode{t2} denote distinct equal objects of type + \tcode{remove_cvref_t}, +\item $E_t$ be an expression that denotes \tcode{t1} such that + \tcode{decltype(($E_t$))} is \tcode{T}, +\item \tcode{u1} and \tcode{u2} similarly denote distinct equal objects of type + \tcode{remove_cvref_t}, +\item $E_u$ be an expression that denotes \tcode{u1} such that + \tcode{decltype(($E_u$))} is \tcode{U}, and +\item \tcode{C} be + % This comfortably fits on one line as a codeblock, but overfills the page as + % tcode. :( + \begin{codeblock} + common_reference_t&, const remove_reference_t&> + \end{codeblock} +\end{itemize} +\tcode{\libconcept{SwappableWith}} is satisfied only if after evaluating +either \tcode{swap($E_t$, $E_u$)} or \tcode{swap($E_u$, $E_t$)} in the context +described above, \tcode{C(t1)} is equal to \tcode{C(u2)} and \tcode{C(u1)} is +equal to \tcode{C(t2)}. + +\pnum +The context in which \tcode{swap($E_t$, $E_u$)} or \tcode{swap($E_u$, $E_t$)} +is evaluated shall ensure that a binary non-member function named \tcode{swap} is +selected via overload resolution\iref{over.match} on a candidate set that +includes: +\begin{itemize} +\item the two \tcode{swap} function templates defined in + \tcode{}\iref{utility} and +\item the lookup set produced by argument-dependent + lookup\iref{basic.lookup.argdep}. +\end{itemize} +\end{itemdescr} + +\pnum +\begin{example} +User code can ensure that the evaluation of \tcode{swap} calls +is performed in an appropriate context under the various conditions as follows: +\begin{codeblock} +#include +#include +#include + +template U> +void value_swap(T&& t, U&& u) { + using std::swap; + swap(std::forward(t), std::forward(u)); // OK: uses ``swappable with'' conditions + // for rvalues and lvalues +} + +template +void lv_swap(T& t1, T& t2) { + using std::swap; + swap(t1, t2); // OK: uses swappable conditions for +} // lvalues of type \tcode{T} + +namespace N { + struct A { int m; }; + struct Proxy { A* a; }; + Proxy proxy(A& a) { return Proxy{ &a }; } + + void swap(A& x, Proxy p) { + std::swap(x.m, p.a->m); // OK: uses context equivalent to swappable + // conditions for fundamental types + } + void swap(Proxy p, A& x) { swap(x, p); } // satisfy symmetry constraint +} + +int main() { + int i = 1, j = 2; + lv_swap(i, j); + assert(i == 2 && j == 1); + + N::A a1 = { 5 }, a2 = { -5 }; + value_swap(a1, proxy(a2)); + assert(a1.m == -5 && a2.m == 5); +} +\end{codeblock} +\end{example} + +\rSec2[concept.destructible]{Concept \libconcept{Destructible}} + +\pnum +The \libconcept{Destructible} concept specifies properties of all types, +instances of which can be destroyed at the end of their lifetime, or reference +types. + +\indexlibrary{\idxcode{Destructible}}% +\begin{itemdecl} +template + concept Destructible = is_nothrow_destructible_v; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\begin{note} +Unlike the \oldconcept{Destructible} requirements~(\tref{destructible}), this +concept forbids destructors that are potentially throwing, even if a particular +invocation of the destructor does not actually throw. +\end{note} +\end{itemdescr} + +\rSec2[concept.constructible]{Concept \libconcept{Constructible}} + +\pnum +The \libconcept{Constructible} concept constrains the initialization of a +variable of a given type with a particular set of argument types. + +\indexlibrary{\idxcode{Constructible}}% +\begin{itemdecl} +template + concept Constructible = Destructible && is_constructible_v; +\end{itemdecl} + +\rSec2[concept.defaultconstructible]{Concept \libconcept{DefaultConstructible}} + +\indexlibrary{\idxcode{DefaultConstructible}}% +\begin{itemdecl} +template + concept DefaultConstructible = Constructible; +\end{itemdecl} + +\rSec2[concept.moveconstructible]{Concept \libconcept{MoveConstructible}} + +\indexlibrary{\idxcode{MoveConstructible}}% +\begin{itemdecl} +template + concept MoveConstructible = Constructible && ConvertibleTo; +\end{itemdecl} + +\begin{itemdescr} +\pnum +If \tcode{T} is an object type, then let \tcode{rv} be an rvalue of type +\tcode{T} and \tcode{u2} a distinct object of type \tcode{T} equal to +\tcode{rv}. \tcode{\libconcept{MoveConstructible}} is satisfied only if + +\begin{itemize} +\item After the definition \tcode{T u = rv;}, \tcode{u} is equal to \tcode{u2}. + +\item \tcode{T(rv)} is equal to \tcode{u2}. + +\item If \tcode{T} is not \tcode{const}, \tcode{rv}'s resulting state is valid +but unspecified\iref{lib.types.movedfrom}; otherwise, it is unchanged. +\end{itemize} +\end{itemdescr} + +\rSec2[concept.copyconstructible]{Concept \libconcept{CopyConstructible}} + +\indexlibrary{\idxcode{CopyConstructible}}% +\begin{itemdecl} +template + concept CopyConstructible = + MoveConstructible && + Constructible && ConvertibleTo && + Constructible && ConvertibleTo && + Constructible && ConvertibleTo; +\end{itemdecl} + +\begin{itemdescr} +\pnum +If \tcode{T} is an object type, then let \tcode{v} be an lvalue of type +(possibly \tcode{const}) \tcode{T} or an rvalue of type \tcode{const T}. +\tcode{\libconcept{CopyConstructible}} is satisfied only if + +\begin{itemize} +\item After the definition \tcode{T u = v;}, \tcode{u} is equal to \tcode{v}. + +\item \tcode{T(v)} is equal to \tcode{v}. +\end{itemize} + +\end{itemdescr} + +\rSec1[concepts.compare]{Comparison concepts} + +\rSec2[concepts.compare.general]{General} + +\pnum +This subclause describes concepts that establish relationships and orderings +on values of possibly differing object types. + +\rSec2[concept.boolean]{Concept \libconcept{Boolean}} + +\pnum +The \libconcept{Boolean} concept specifies the requirements on a type that is +usable in Boolean contexts. + +\indexlibrary{\idxcode{Boolean}}% +\begin{itemdecl} +template + concept Boolean = + Movable> && // (see \ref{concepts.object}) + requires(const remove_reference_t& b1, + const remove_reference_t& b2, const bool a) { + requires ConvertibleTo&, bool>; + !b1; requires ConvertibleTo; + b1 && a; requires Same; + b1 || a; requires Same; + b1 && b2; requires Same; + a && b2; requires Same; + b1 || b2; requires Same; + a || b2; requires Same; + b1 == b2; requires ConvertibleTo; + b1 == a; requires ConvertibleTo; + a == b2; requires ConvertibleTo; + b1 != b2; requires ConvertibleTo; + b1 != a; requires ConvertibleTo; + a != b2; requires ConvertibleTo; + }; +\end{itemdecl} + +\pnum +Let \tcode{b1} and \tcode{b2} be lvalues of type +\tcode{const remove_reference_t}. +\tcode{\libconcept{Boolean}} is satisfied only if + +\begin{itemize} +\item \tcode{bool(b1) == !bool(!b1)}. +\item \tcode{(b1 \&\& b2)}, \tcode{(b1 \&\& bool(b2))}, and + \tcode{(bool(b1) \&\& b2)} are all equal to + \tcode{(bool(b1) \&\& bool(b2))}, and have the same short-circuit + evaluation. +\item \tcode{(b1 || b2)}, \tcode{(b1 || bool(b2))}, and + \tcode{(bool(b1) || b2)} are all equal to + \tcode{(bool(b1) || bool(b2))}, and have the same short-circuit + evaluation. +\item \tcode{bool(b1 == b2)}, \tcode{bool(b1 == bool(b2))}, and + \tcode{bool(bool(b1) == b2)} are all equal to + \tcode{(bool(b1) == bool(b2))}. +\item \tcode{bool(b1 != b2)}, \tcode{bool(b1 != bool(b2))}, and + \tcode{bool(bool(b1) != b2)} are all equal to + \tcode{(bool(b1) != bool(b2))}. +\end{itemize} + +\pnum +\begin{example} +The types \tcode{bool}, \tcode{true_type}\iref{meta.type.synop}, and +\tcode{bitset<$N$>::reference}\iref{template.bitset} are \libconcept{Boolean} +types. Pointers, smart pointers, and types with only explicit conversions to +\tcode{bool} are not \libconcept{Boolean} types. +\end{example} + +\rSec2[concept.equalitycomparable]{Concept \libconcept{EqualityComparable}} + +\begin{itemdecl} +template + concept @\placeholder{weakly-equality-comparable-with}@ = // \expos + requires(const remove_reference_t& t, + const remove_reference_t& u) { + t == u; requires Boolean; + t != u; requires Boolean; + u == t; requires Boolean; + u != t; requires Boolean; + }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{t} and \tcode{u} be lvalues of types +\tcode{const remove_reference_t} and +\tcode{const remove_reference_t} respectively. +\tcode{\placeholder{weakly-equality-comparable-with}} +is satisfied only if: +\begin{itemize} +\item \tcode{t == u}, \tcode{u == t}, \tcode{t != u}, and \tcode{u != t} + have the same domain. +\item \tcode{bool(u == t) == bool(t == u)}. +\item \tcode{bool(t != u) == !bool(t == u)}. +\item \tcode{bool(u != t) == bool(t != u)}. +\end{itemize} +\end{itemdescr} + +\indexlibrary{\idxcode{EqualityComparable}}% +\begin{itemdecl} +template + concept EqualityComparable = @\placeholder{weakly-equality-comparable-with}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{a} and \tcode{b} be objects of type \tcode{T}. +\tcode{\libconcept{EqualityComparable}} is satisfied only if +\tcode{bool(a == b)} is \tcode{true} when \tcode{a} is equal to +\tcode{b}\iref{concepts.equality}, and \tcode{false} otherwise. + +\pnum +\begin{note} +The requirement that the expression \tcode{a == b} is equality-preserving +implies that \tcode{==} is transitive and symmetric. +\end{note} +\end{itemdescr} + +\indexlibrary{\idxcode{EqualityComparableWith}}% +\begin{itemdecl} +template + concept EqualityComparableWith = + EqualityComparable && EqualityComparable && + CommonReference&, const remove_reference_t&> && + EqualityComparable< + common_reference_t< + const remove_reference_t&, + const remove_reference_t&>> && + @\placeholder{weakly-equality-comparable-with}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{t} be an lvalue of type \tcode{const remove_reference_t}, +\tcode{u} be an lvalue of type \tcode{const remove_reference_t}, +and \tcode{C} be: +\begin{codeblock} +common_reference_t&, const remove_reference_t&> +\end{codeblock} +\tcode{\libconcept{EqualityComparableWith}} is satisfied only if +\tcode{bool(t == u) == bool(C(t) == C(u))}. +\end{itemdescr} + +\rSec2[concept.stricttotallyordered]{Concept \libconcept{StrictTotallyOrdered}} + +\indexlibrary{\idxcode{StrictTotallyOrdered}}% +\begin{itemdecl} +template + concept StrictTotallyOrdered = + EqualityComparable && + requires(const remove_reference_t& a, + const remove_reference_t& b) { + a < b; requires Boolean; + a > b; requires Boolean b)>; + a <= b; requires Boolean; + a >= b; requires Boolean= b)>; + }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{a}, \tcode{b}, and \tcode{c} be lvalues of type +\tcode{const remove_reference_t}. +\tcode{\libconcept{StrictTotallyOrdered}} is satisfied only if + +\begin{itemize} +\item Exactly one of \tcode{bool(a < b)}, \tcode{bool(a > b)}, or + \tcode{bool(a == b)} is \tcode{true}. +\item If \tcode{bool(a < b)} and \tcode{bool(b < c)}, then + \tcode{bool(a < c)}. +\item \tcode{bool(a > b) == bool(b < a)}. +\item \tcode{bool(a <= b) == !bool(b < a)}. +\item \tcode{bool(a >= b) == !bool(a < b)}. +\end{itemize} + +\end{itemdescr} + +\begin{itemdecl} +template + concept StrictTotallyOrderedWith = + StrictTotallyOrdered && StrictTotallyOrdered && + CommonReference&, const remove_reference_t&> && + StrictTotallyOrdered< + common_reference_t< + const remove_reference_t&, + const remove_reference_t&>> && + EqualityComparableWith && + requires(const remove_reference_t& t, + const remove_reference_t& u) { + t < u; requires Boolean; + t > u; requires Boolean u)>; + t <= u; requires Boolean; + t >= u; requires Boolean= u)>; + u < t; requires Boolean; + u > t; requires Boolean t)>; + u <= t; requires Boolean; + u >= t; requires Boolean= t)>; + }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{t} be an lvalue of type \tcode{const remove_reference_t}, +\tcode{u} be an lvalue of type \tcode{const remove_reference_t}, +and \tcode{C} be: +\begin{codeblock} +common_reference_t&, const remove_reference_t&> +\end{codeblock} +\tcode{\libconcept{StrictTotallyOrderedWith}} is satisfied only if + +\begin{itemize} +\item \tcode{bool(t < u) == bool(C(t) < C(u)).} +\item \tcode{bool(t > u) == bool(C(t) > C(u)).} +\item \tcode{bool(t <= u) == bool(C(t) <= C(u)).} +\item \tcode{bool(t >= u) == bool(C(t) >= C(u)).} +\item \tcode{bool(u < t) == bool(C(u) < C(t)).} +\item \tcode{bool(u > t) == bool(C(u) > C(t)).} +\item \tcode{bool(u <= t) == bool(C(u) <= C(t)).} +\item \tcode{bool(u >= t) == bool(C(u) >= C(t)).} +\end{itemize} +\end{itemdescr} + +\rSec1[concepts.object]{Object concepts} + +\pnum +This subclause describes concepts that specify the basis of the +value-oriented programming style on which the library is based. + +\indexlibrary{\idxcode{Movable}}% +\indexlibrary{\idxcode{Copyable}}% +\indexlibrary{\idxcode{Semiregular}}% +\indexlibrary{\idxcode{Regular}}% +\begin{itemdecl} +template + concept Movable = is_object_v && MoveConstructible && Assignable && Swappable; +template + concept Copyable = CopyConstructible && Movable && Assignable; +template + concept Semiregular = Copyable && DefaultConstructible; +template + concept Regular = Semiregular && EqualityComparable; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\begin{note} +The \libconcept{Semiregular} concept is satisfied by types that behave similarly +to built-in types like \tcode{int}, except that they might not +be comparable with \tcode{==}. +\end{note} + +\pnum +\begin{note} +The \libconcept{Regular} concept is satisfied by types that behave similarly to +built-in types like \tcode{int} and that are comparable with +\tcode{==}. +\end{note} +\end{itemdescr} + +\rSec1[concepts.callable]{Callable concepts} + +\rSec2[concepts.callable.general]{General} + +\pnum +The concepts in this subclause describe the requirements on function +objects\iref{function.objects} and their arguments. + +\rSec2[concept.invocable]{Concept \libconcept{Invocable}} + +\pnum +The \libconcept{Invocable} concept specifies a relationship between a callable +type\iref{func.def} \tcode{F} and a set of argument types \tcode{Args...} which +can be evaluated by the library function \tcode{invoke}\iref{func.invoke}. + +\indexlibrary{\idxcode{Invocable}}% +\begin{itemdecl} +template + concept Invocable = requires(F&& f, Args&&... args) { + invoke(std::forward(f), std::forward(args)...); // not required to be equality-preserving + }; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\begin{example} +A function that generates random numbers can satisfy \libconcept{Invocable}, +since the \tcode{invoke} function call expression is not required to be +equality-preserving\iref{concepts.equality}. +\end{example} +\end{itemdescr} + +\rSec2[concept.regularinvocable]{Concept \libconcept{RegularInvocable}} + +\indexlibrary{\idxcode{RegularInvocable}}% +\begin{itemdecl} +template + concept RegularInvocable = Invocable; +\end{itemdecl} + +\begin{itemdescr} +\pnum +The \tcode{invoke} function call expression shall be equality-preserving and +shall not modify the function object or the +arguments\iref{concepts.equality}. +\begin{note} +This requirement supersedes the annotation in the definition of +\libconcept{Invocable}. +\end{note} + +\pnum +\begin{example} +A random number generator does not satisfy +\libconcept{RegularInvocable}. +\end{example} + +\pnum +\begin{note} +The distinction between \libconcept{Invocable} and \libconcept{RegularInvocable} +is purely semantic. +\end{note} +\end{itemdescr} + +\rSec2[concept.predicate]{Concept \libconcept{Predicate}} + +\indexlibrary{\idxcode{Predicate}}% +\begin{itemdecl} +template + concept Predicate = RegularInvocable && Boolean>; +\end{itemdecl} + +\rSec2[concept.relation]{Concept \libconcept{Relation}} + +\indexlibrary{\idxcode{Relation}}% +\begin{itemdecl} +template + concept Relation = + Predicate && Predicate && + CommonReference&, const remove_reference_t&> && + Predicate&, const remove_reference_t&>, + common_reference_t&, const remove_reference_t&>> && + Predicate && Predicate; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let +\begin{itemize} +\item \tcode{r} be an expression such that \tcode{decltype((r))} is \tcode{R}, +\item \tcode{t} be an expression such that \tcode{decltype((t))} is \tcode{T}, +\item \tcode{u} be an expression such that \tcode{decltype((u))} is \tcode{U}, + and +\item \tcode{C} be + \begin{codeblock} + common_reference_t&, + const remove_reference_t&> + \end{codeblock} +\end{itemize} +\tcode{\libconcept{Relation}} is satisfied only if + +\begin{itemize} +\item \tcode{bool(r(t, u)) == bool(r(C(t), C(u))).} +\item \tcode{bool(r(u, t)) == bool(r(C(u), C(t))).} +\end{itemize} +\end{itemdescr} + +\rSec2[concept.strictweakorder]{Concept \libconcept{StrictWeakOrder}} + +\indexlibrary{\idxcode{Relation}}% +\begin{itemdecl} +template + concept StrictWeakOrder = Relation; +\end{itemdecl} + +\begin{itemdescr} +\pnum +A \libconcept{Relation} satisfies \libconcept{StrictWeakOrder} only if +it imposes a \term{strict weak ordering} on its arguments. + +\pnum +The term +\term{strict} +refers to the +requirement of an irreflexive relation (\tcode{!comp(x, x)} for all \tcode{x}), +and the term +\term{weak} +to requirements that are not as strong as +those for a total ordering, +but stronger than those for a partial +ordering. +If we define +\tcode{equiv(a, b)} +as +\tcode{!comp(a, b) \&\& !comp(b, a)}, +then the requirements are that +\tcode{comp} +and +\tcode{equiv} +both be transitive relations: + +\begin{itemize} +\item +\tcode{comp(a, b) \&\& comp(b, c)} +implies +\tcode{comp(a, c)} +\item +\tcode{equiv(a, b) \&\& equiv(b, c)} +implies +\tcode{equiv(a, c)} +\end{itemize} + +\pnum +\begin{note} +Under these conditions, it can be shown that +\begin{itemize} +\item +\tcode{equiv} +is an equivalence relation, +\item +\tcode{comp} +induces a well-defined relation on the equivalence +classes determined by +\tcode{equiv}, and +\item +the induced relation is a strict total ordering. +\end{itemize} +\end{note} +\end{itemdescr} diff --git a/source/config.tex b/source/config.tex index cf1a7b3242..61f9e82bbc 100644 --- a/source/config.tex +++ b/source/config.tex @@ -1,8 +1,8 @@ %!TEX root = std.tex %%-------------------------------------------------- %% Version numbers -\newcommand{\docno}{N4750} -\newcommand{\prevdocno}{N4741} +\newcommand{\docno}{N4762} +\newcommand{\prevdocno}{N4750} \newcommand{\cppver}{201703L} %% Release date diff --git a/source/containers.tex b/source/containers.tex index 6fc9d17954..6c2e03ba0d 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -98,7 +98,7 @@ \tcode{X::value_type} & \tcode{T} & & - \requires\ \tcode{T} is \tcode{Erasable} from \tcode{X} (see~\ref{container.requirements.general}, below) & + \requires\ \tcode{T} is \oldconcept{Erasable} from \tcode{X} (see~\ref{container.requirements.general}, below) & compile time \\ \rowsep \tcode{X::reference} & @@ -155,7 +155,7 @@ \tcode{X(a)} & & & - \requires \tcode{T} is \tcode{CopyInsertable} + \requires \tcode{T} is \oldconcept{CopyInsertable} into \tcode{X} (see below).\br \postconditions \tcode{a == X(a)}. & linear \\ \rowsep @@ -163,7 +163,7 @@ \tcode{X u = a;} & & & - \requires \tcode{T} is \tcode{CopyInsertable} + \requires \tcode{T} is \oldconcept{CopyInsertable} into \tcode{X} (see below).\br \postconditions \tcode{u == a} & linear \\ \rowsep @@ -217,7 +217,7 @@ convertible to \tcode{bool} & \tcode{==} is an equivalence relation. \tcode{equal(\brk{}a.begin(), a.end(), b.begin(), b.end())} & - \requires\ \tcode{T} is \tcode{EqualityCompar\-a\-ble} & + \requires\ \tcode{T} is \oldconcept{\-Equal\-ity\-Compar\-a\-ble} & Constant if \tcode{a.size() != b.size()}, linear otherwise \\ \rowsep @@ -318,7 +318,7 @@ All other constructors for these container types take a \tcode{const allocator_type\&} argument. \begin{note} If an invocation of a constructor uses the default value of an optional -allocator argument, then the \tcode{Allocator} type must support value-initialization. +allocator argument, then the allocator type must support value-initialization. \end{note} A copy of this allocator is used for any memory allocation and element construction performed, by these constructors and by all member functions, @@ -527,8 +527,8 @@ \begin{itemize} \item -\tcode{T} is \defnx{\tcode{DefaultInsertable} into \tcode{X}} -{DefaultInsertable into X@\tcode{DefaultInsertable} into \tcode{X}} +\tcode{T} is \defnx{\oldconcept{DefaultInsertable} into \tcode{X}} +{\oldconcept{DefaultInsertable} into X@\oldconcept{DefaultInsertable} into \tcode{X}} means that the following expression is well-formed: \begin{codeblock} allocator_traits::construct(m, p) @@ -544,8 +544,8 @@ allocated within \tcode{X}. \item -\tcode{T} is \defnx{\tcode{MoveInsertable} into \tcode{X}} -{MoveInsertable into X@\tcode{MoveInsertable} into \tcode{X}} +\tcode{T} is \defnx{\oldconcept{MoveInsertable} into \tcode{X}} +{\oldconcept{MoveInsertable} into X@\oldconcept{MoveInsertable} into \tcode{X}} means that the following expression is well-formed: \begin{codeblock} @@ -556,9 +556,9 @@ \begin{note} \tcode{rv} remains a valid object. Its state is unspecified \end{note} \item -\tcode{T} is \defnx{\tcode{CopyInsertable} into \tcode{X}} -{CopyInsertable into X@\tcode{CopyInsertable} into \tcode{X}} -means that, in addition to \tcode{T} being \tcode{MoveInsertable} into +\tcode{T} is \defnx{\oldconcept{CopyInsertable} into \tcode{X}} +{\oldconcept{CopyInsertable} into X@\oldconcept{CopyInsertable} into \tcode{X}} +means that, in addition to \tcode{T} being \oldconcept{MoveInsertable} into \tcode{X}, the following expression is well-formed: \begin{codeblock} allocator_traits::construct(m, p, v) @@ -568,8 +568,8 @@ \item \tcode{T} is -\defnx{\tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}} -{EmplaceConstructible into X from args@\tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}}, +\defnx{\oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}} +{\oldconcept{EmplaceConstructible} into X from args@\oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}}, for zero or more arguments \tcode{args}, means that the following expression is well-formed: \begin{codeblock} @@ -578,8 +578,8 @@ \item \tcode{T} is -\defnx{\tcode{Erasable} from \tcode{X}} -{Erasable from X@\tcode{Erasable} from \tcode{X}} +\defnx{\oldconcept{Erasable} from \tcode{X}} +{\oldconcept{Erasable} from X@\oldconcept{Erasable} from \tcode{X}} means that the following expression is well-formed: \begin{codeblock} allocator_traits::destroy(m, p) @@ -632,7 +632,7 @@ \tcode{X()}\br \tcode{X u;} & & - \requires\ \tcode{A} is \tcode{DefaultConstructible}.\br + \requires\ \tcode{A} is \oldconcept{DefaultConstructible}.\br \postconditions \tcode{u.empty()} returns \tcode{true}, \tcode{u.get_allocator() == A()} & constant \\ \rowsep @@ -649,7 +649,7 @@ \tcode{X(t, m)}\br \tcode{X u(t, m);} & & -\requires\ \tcode{T} is \tcode{CopyInsertable} into \tcode{X}.\br +\requires\ \tcode{T} is \oldconcept{CopyInsertable} into \tcode{X}.\br \postconditions \tcode{u == t}, \tcode{u.get_allocator() == m} & linear \\ \rowsep @@ -666,7 +666,7 @@ \tcode{X u(rv, m);} & & \requires\ \tcode{T} is - \tcode{MoveInsertable} into \tcode{X}.\br + \oldconcept{MoveInsertable} into \tcode{X}.\br \postconditions \tcode{u} shall have the same elements, or copies of the elements, that \tcode{rv} had before this construction, \tcode{u.get_allocator() == m} & @@ -675,8 +675,8 @@ \tcode{a = t} & \tcode{X\&} & \requires\ \tcode{T} is - \tcode{CopyInsertable} into \tcode{X} - and \tcode{CopyAssignable}.\br + \oldconcept{CopyInsertable} into \tcode{X} + and \oldconcept{CopyAssignable}.\br \postconditions \tcode{a == t} & linear \\ \rowsep @@ -687,8 +687,8 @@ \tcode{::propagate_on_container_-}\br \tcode{move_assignment::value} is\br \tcode{false}, \tcode{T} is - \tcode{MoveInsertable} into \tcode{X} and - \tcode{MoveAssignable}. All existing elements of \tcode{a} + \oldconcept{MoveInsertable} into \tcode{X} and + \oldconcept{MoveAssignable}. All existing elements of \tcode{a} are either move assigned to or destroyed.\br \postconditions \tcode{a} shall be equal to the value that \tcode{rv} had before this assignment. & @@ -823,18 +823,18 @@ \tcode{X u(n, t);} & & \requires\ \tcode{T} shall be - \tcode{CopyInsertable} into \tcode{X}.\br + \oldconcept{CopyInsertable} into \tcode{X}.\br \postconditions \tcode{distance(begin(), end()) == n}\br Constructs a sequence container with \tcode{n} copies of \tcode{t} \\ \rowsep \tcode{X(i, j)}\br \tcode{X u(i, j);} & & - \requires\ \tcode{T} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i}. + \requires\ \tcode{T} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}. For \tcode{vector}, if the iterator does - not meet the forward iterator requirements\iref{forward.iterators}, \tcode{T} + not meet the \oldconcept{\-Forward\-Iterator} requirements\iref{forward.iterators}, \tcode{T} shall also be - \tcode{MoveInsertable} into \tcode{X}. + \oldconcept{MoveInsertable} into \tcode{X}. Each iterator in the range \range{i}{j} shall be dereferenced exactly once.\br \postconditions \tcode{distance(begin(), end()) ==} \tcode{distance(i, j)}\br @@ -847,8 +847,8 @@ \tcode{a = il} & \tcode{X\&} & \requires\ \tcode{T} is - \tcode{CopyInsertable} into \tcode{X} - and \tcode{CopyAssignable}. + \oldconcept{CopyInsertable} into \tcode{X} + and \oldconcept{CopyAssignable}. Assigns the range \range{il.begin()}{il.end()} into \tcode{a}. All existing elements of \tcode{a} are either assigned to or destroyed.\br \returns\ \tcode{*this}. @@ -856,9 +856,9 @@ \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}, + \requires\ \tcode{T} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}. For \tcode{vector} and \tcode{deque}, \tcode{T} is also - \tcode{MoveInsertable} into \tcode{X} and \tcode{MoveAssignable}. + \oldconcept{MoveInsertable} into \tcode{X} and \oldconcept{MoveAssignable}. \effects\ Inserts an object of type \tcode{T} constructed with \tcode{std::forward<\brk{}Args\brk{}>(\brk{}args)...} before \tcode{p}. \begin{note} \tcode{args} may directly or indirectly refer to @@ -868,29 +868,29 @@ \tcode{a.insert(p,t)} & \tcode{iterator} & \requires\ \tcode{T} shall be - \tcode{CopyInsertable} into \tcode{X}. For \tcode{vector} and \tcode{deque}, - \tcode{T} shall also be \tcode{CopyAssignable}.\br + \oldconcept{CopyInsertable} into \tcode{X}. For \tcode{vector} and \tcode{deque}, + \tcode{T} shall also be \oldconcept{CopyAssignable}.\br \effects\ Inserts a copy of \tcode{t} before \tcode{p}. \\ \rowsep \tcode{a.insert(p,rv)} & \tcode{iterator} & \requires\ \tcode{T} shall be - \tcode{MoveInsertable} into \tcode{X}. For \tcode{vector} and \tcode{deque}, - \tcode{T} shall also be \tcode{MoveAssignable}.\br + \oldconcept{MoveInsertable} into \tcode{X}. For \tcode{vector} and \tcode{deque}, + \tcode{T} shall also be \oldconcept{MoveAssignable}.\br \effects\ Inserts a copy of \tcode{rv} before \tcode{p}. \\ \rowsep \tcode{a.insert(p,n,t)} & \tcode{iterator} & \requires\ \tcode{T} shall be - \tcode{CopyInsertable} into \tcode{X} - and \tcode{CopyAssignable}.\br + \oldconcept{CopyInsertable} into \tcode{X} + and \oldconcept{CopyAssignable}.\br Inserts \tcode{n} copies of \tcode{t} before \tcode{p}. \\ \rowsep \tcode{a.insert(p,i,j)} & \tcode{iterator} & - \requires\ \tcode{T} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i}. + \requires\ \tcode{T} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}. For \tcode{vector} and \tcode{deque}, \tcode{T} shall also be - \tcode{MoveInsertable} into \tcode{X}, \tcode{MoveConstructible}, \tcode{MoveAssignable}, + \oldconcept{MoveInsertable} into \tcode{X}, \oldconcept{MoveConstructible}, \oldconcept{MoveAssignable}, and swappable\iref{swappable.requirements}. Each iterator in the range \range{i}{j} shall be dereferenced exactly once.\br \requires \tcode{i} and \tcode{j} are not iterators into \tcode{a}.\br @@ -903,13 +903,13 @@ \tcode{a.erase(q)} & \tcode{iterator} & \requires\ For \tcode{vector} and \tcode{deque}, - \tcode{T} shall be \tcode{MoveAssignable}.\br + \tcode{T} shall be \oldconcept{MoveAssignable}.\br \effects\ Erases the element pointed to by \tcode{q}. \\ \rowsep \tcode{a.erase(q1,q2)} & \tcode{iterator} & \requires\ For \tcode{vector} and \tcode{deque}, - \tcode{T} shall be \tcode{MoveAssignable}.\br + \tcode{T} shall be \oldconcept{MoveAssignable}.\br \effects\ Erases the elements in the range \tcode{[q1, q2)}. \\ \rowsep \tcode{a.clear()} & @@ -921,11 +921,11 @@ \tcode{a.assign(i,j)} & \tcode{void} & - \requires\ \tcode{T} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i} + \requires\ \tcode{T} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i} and assignable from \tcode{*i}. For \tcode{vector}, if the iterator does not meet the forward iterator requirements\iref{forward.iterators}, \tcode{T} shall also be - \tcode{MoveInsertable} into \tcode{X}.\br + \oldconcept{MoveInsertable} into \tcode{X}.\br Each iterator in the range \range{i}{j} shall be dereferenced exactly once.\br \requires \tcode{i}, \tcode{j} are not iterators into \tcode{a}.\br Replaces elements in \tcode{a} with a copy of \tcode{[i, j)}.\br @@ -941,8 +941,8 @@ \tcode{a.assign(n,t)} & \tcode{void} & \requires\ \tcode{T} shall be - \tcode{CopyInsertable} into \tcode{X} - and \tcode{CopyAssignable}.\br + \oldconcept{CopyInsertable} into \tcode{X} + and \oldconcept{CopyAssignable}.\br \requires \tcode{t} is not a reference into \tcode{a}.\br Replaces elements in \tcode{a} with \tcode{n} copies of \tcode{t}.\br Invalidates all references, pointers and iterators @@ -1082,7 +1082,7 @@ \tcode{a.emplace_\-front(args)} & \tcode{reference} & Prepends an object of type \tcode{T} constructed with \tcode{std::forward<\brk{}Args\brk{}>(\brk{}args)...}.\br - \requires\ \tcode{T} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br + \requires\ \tcode{T} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br \returns{} \tcode{a.front()}. & \tcode{deque}, \tcode{forward_list}, @@ -1092,9 +1092,9 @@ \tcode{a.emplace_\-back(args)} & \tcode{reference} & Appends an object of type \tcode{T} constructed with \tcode{std::forward<\brk{}Args\brk{}>(\brk{}args)...}.\br - \requires\ \tcode{T} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}. For \tcode{vector}, \tcode{T} + \requires\ \tcode{T} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}. For \tcode{vector}, \tcode{T} shall also be - \tcode{MoveInsertable} into \tcode{X}.\br + \oldconcept{MoveInsertable} into \tcode{X}.\br \returns{} \tcode{a.back()}. & \tcode{deque}, \tcode{list}, @@ -1105,7 +1105,7 @@ \tcode{void} & Prepends a copy of \tcode{t}.\br \requires\ \tcode{T} shall be - \tcode{CopyInsertable} into \tcode{X}. + \oldconcept{CopyInsertable} into \tcode{X}. & \tcode{deque}, \tcode{forward_list}, @@ -1116,7 +1116,7 @@ \tcode{void} & Prepends a copy of \tcode{rv}.\br \requires\ \tcode{T} shall be - \tcode{MoveInsertable} into \tcode{X}. + \oldconcept{MoveInsertable} into \tcode{X}. & \tcode{deque}, \tcode{forward_list}, @@ -1127,7 +1127,7 @@ \tcode{void} & Appends a copy of \tcode{t}.\br \requires\ \tcode{T} shall be - \tcode{CopyInsertable} into \tcode{X}. + \oldconcept{CopyInsertable} into \tcode{X}. & \tcode{basic_string}, \tcode{deque}, @@ -1139,7 +1139,7 @@ \tcode{void} & Appends a copy of \tcode{rv}.\br \requires\ \tcode{T} shall be - \tcode{MoveInsertable} into \tcode{X}. + \oldconcept{MoveInsertable} into \tcode{X}. & \tcode{basic_string}, \tcode{deque}, @@ -1575,9 +1575,9 @@ \tcode{map} and \tcode{multimap}, the requirements placed on \tcode{value_type} in \tref{containers.allocatoraware} apply instead to \tcode{key_type} and \tcode{mapped_type}. \begin{note} For example, in some cases \tcode{key_type} and \tcode{mapped_type} -are required to be \tcode{CopyAssignable} even though the associated +are required to be \oldconcept{CopyAssignable} even though the associated \tcode{value_type}, \tcode{pair}, is not -\tcode{CopyAssignable}. \end{note} +\oldconcept{CopyAssignable}. \end{note} \pnum In \tref{containers.associative.requirements}, @@ -1620,6 +1620,15 @@ \tcode{m} denotes an allocator of a type convertible to \tcode{A}, and \tcode{nh} denotes a non-const rvalue of type \tcode{X::node_type}. +% Local command to index names as members of all ordered containers. +\newcommand{\indexordmem}[1]{% +\indexlibrary{\idxcode{#1}!ordered associative containers}% +\indexlibrary{\idxcode{set}!\idxcode{#1}}% +\indexlibrary{\idxcode{map}!\idxcode{#1}}% +\indexlibrary{\idxcode{multiset}!\idxcode{#1}}% +\indexlibrary{\idxcode{multimap}!\idxcode{#1}}% +} + \begin{libreqtab4b} {Associative container requirements (in addition to container)} {tab:containers.associative.requirements} @@ -1645,17 +1654,17 @@ \tcode{X::value_type} (\tcode{set} and \tcode{multiset} only) & \tcode{Key} & - \requires\ \tcode{value_type} is \tcode{Erasable} from \tcode{X} & + \requires\ \tcode{value_type} is \oldconcept{Erasable} from \tcode{X} & compile time \\ \rowsep \tcode{X::value_type} (\tcode{map} and \tcode{multimap} only) & \tcode{pair} & - \requires\ \tcode{value_type} is \tcode{Erasable} from \tcode{X} & + \requires\ \tcode{value_type} is \oldconcept{Erasable} from \tcode{X} & compile time \\ \rowsep \tcode{X::key_compare} & \tcode{Compare} & - \requires\ \tcode{key_compare} is \tcode{CopyConstructible}. & + \requires\ \tcode{key_compare} is \oldconcept{CopyConstructible}. & compile time \\ \rowsep \tcode{X::value_compare} & @@ -1681,7 +1690,7 @@ \tcode{X()}\br\tcode{X u;} & & - \requires\ \tcode{key_compare} is \tcode{DefaultConstructible}.\br + \requires\ \tcode{key_compare} is \oldconcept{DefaultConstructible}.\br \effects\ Constructs an empty container. Uses \tcode{Compare()} as a comparison object & constant \\ \rowsep @@ -1689,7 +1698,7 @@ \tcode{X(i,j,c)}\br \tcode{X~u(i,j,c);} & & - \requires\ \tcode{value_type} is \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br + \requires\ \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br \effects\ Constructs an empty container and inserts elements from the range \tcode{[i, j)} into it; uses \tcode{c} as a comparison object. & $N \log N$ in general, where $N$ has the value \tcode{distance(i, j)}; @@ -1697,8 +1706,8 @@ \tcode{X(i,j)}\br\tcode{X~u(i,j);} & & - \requires\ \tcode{key_compare} is \tcode{DefaultConstructible}. - \tcode{value_type} is \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br + \requires\ \tcode{key_compare} is \oldconcept{DefaultConstructible}. + \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br \effects\ Same as above, but uses \tcode{Compare()} as a comparison object. & same as above \\ \rowsep @@ -1715,8 +1724,8 @@ \tcode{a = il} & \tcode{X\&} & \requires\ \tcode{value_type} is - \tcode{CopyInsertable} into \tcode{X} - and \tcode{CopyAssignable}.\br + \oldconcept{CopyInsertable} into \tcode{X} + and \oldconcept{CopyAssignable}.\br \effects Assigns the range \range{il.begin()}{il.end()} into \tcode{a}. All existing elements of \tcode{a} are either assigned to or destroyed. & $N \log N$ in general, where $N$ has the value \tcode{il.size() + a.size()}; @@ -1735,7 +1744,7 @@ \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 + \requires\ \tcode{value_type} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br \effects\ Inserts a \tcode{value_type} object \tcode{t} constructed with \tcode{std::forward<\brk{}Args\brk{}>(\brk{}args)...} if and only if there is no element in the container with key equivalent to the key of \tcode{t}. @@ -1747,7 +1756,7 @@ \tcode{a_eq.\brk{}emplace(\brk{}args)} & \tcode{iterator} & - \requires\ \tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br + \requires\ \tcode{value_type} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br \effects\ Inserts a \tcode{value_type} object \tcode{t} constructed with \tcode{std::forward<\brk{}Args\brk{}>(\brk{}args)...} and returns the iterator pointing to the newly inserted element. @@ -1767,9 +1776,9 @@ \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 + \requires\ If \tcode{t} is a non-const rvalue, \tcode{value_type} shall be + \oldconcept{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} shall be + \oldconcept{CopyInsertable} into \tcode{X}.\br \effects\ Inserts \tcode{t} if and only if there is no element in the container with key equivalent to the key of \tcode{t}. The \tcode{bool} component of the returned pair is \tcode{true} if and only if the insertion @@ -1780,9 +1789,9 @@ \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 - \tcode{CopyInsertable} into \tcode{X}.\br + \requires\ If \tcode{t} is a non-const rvalue, \tcode{value_type} shall be + \oldconcept{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} shall be + \oldconcept{CopyInsertable} into \tcode{X}.\br \effects\ Inserts \tcode{t} and returns the iterator pointing to the newly inserted element. If a range containing elements equivalent to @@ -1792,9 +1801,9 @@ \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 - \tcode{CopyInsertable} into \tcode{X}.\br + \requires\ If \tcode{t} is a non-const rvalue, \tcode{value_type} shall be + \oldconcept{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} shall be + \oldconcept{CopyInsertable} into \tcode{X}.\br \effects\ Inserts \tcode{t} if and only if there is no element with key equivalent to the key of \tcode{t} in containers with unique keys; always inserts \tcode{t} in containers with equivalent keys. Always @@ -1806,7 +1815,7 @@ \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{value_type} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br \requires \tcode{i}, \tcode{j} are not iterators into \tcode{a}. inserts each element from the range \range{i}{j} if and only if there is no element with key equivalent to the key of that element in containers @@ -1948,6 +1957,19 @@ \tcode{!c(r, ke) \&\& !c(ke, r)} & $\log (\tcode{a_tran.size()}) + \tcode{a_tran.count(ke)}$ \\ \rowsep +\indexordmem{contains}% +\tcode{b.}\br + \tcode{contains(k)} & + \tcode{bool} & + equivalent to \tcode{b.find(k) != b.end()} & + logarithmic \\ \rowsep + +\tcode{a_tran.}\br + \tcode{con\-tains(ke)} & + \tcode{bool} & + equivalent to \tcode{a_tran.find(ke) != a_tran.end()} & + logarithmic \\ \rowsep + \tcode{b.lower_bound(k)} & \tcode{iterator}; \tcode{const_iterator} for constant \tcode{b}. & returns an iterator pointing to the first element with @@ -2044,9 +2066,11 @@ its constructor. \pnum -The member function templates \tcode{find}, \tcode{count}, \tcode{lower_bound}, -\tcode{upper_bound}, and \tcode{equal_range} shall not participate in overload -resolution unless the \grammarterm{qualified-id} \tcode{Compare::is_transparent} is valid +The member function templates +\tcode{find}, \tcode{count}, \tcode{contains}, +\tcode{lower_bound}, \tcode{upper_bound}, and \tcode{equal_range} +shall not participate in overload resolution unless +the \grammarterm{qualified-id} \tcode{Compare::is_transparent} is valid and denotes a type\iref{temp.deduct}. \pnum @@ -2107,7 +2131,7 @@ \pnum Each unordered associative container is parameterized by \tcode{Key}, -by a function object type \tcode{Hash} that meets the \tcode{Hash} +by a function object type \tcode{Hash} that meets the \oldconcept{Hash} requirements\iref{hash.requirements} and acts as a hash function for argument values of type \tcode{Key}, and by a binary predicate \tcode{Pred} that induces an equivalence relation on values of type \tcode{Key}. @@ -2192,9 +2216,9 @@ \tcode{unordered_map} and \tcode{unordered_multimap}, the requirements placed on \tcode{value_type} in \tref{containers.allocatoraware} apply instead to \tcode{key_type} and \tcode{mapped_type}. \begin{note} For example, \tcode{key_type} and \tcode{mapped_type} -are sometimes required to be \tcode{CopyAssignable} even though the associated +are sometimes required to be \oldconcept{CopyAssignable} even though the associated \tcode{value_type}, \tcode{pair}, is not -\tcode{CopyAssignable}. \end{note} +\oldconcept{CopyAssignable}. \end{note} \pnum \indextext{unordered associative containers}% @@ -2261,12 +2285,12 @@ \tcode{X::value_type} (\tcode{unordered_set} and \tcode{unordered_multiset} only) & \tcode{Key} & - \requires\ \tcode{value_type} is \tcode{Erasable} from \tcode{X} & + \requires\ \tcode{value_type} is \oldconcept{Erasable} from \tcode{X} & compile time \\ \rowsep \tcode{X::value_type} (\tcode{unordered_map} and \tcode{unordered_multimap} only) & \tcode{pair} & - \requires\ \tcode{value_type} is \tcode{Erasable} from \tcode{X} & + \requires\ \tcode{value_type} is \oldconcept{Erasable} from \tcode{X} & compile time \\ \rowsep \indexunordmem{hasher}% @@ -2280,7 +2304,7 @@ \indexunordmem{key_equal}% \tcode{X::key_equal} & \tcode{Pred} -& \requires\ \tcode{Pred} is \tcode{CopyConstructible}.\br +& \requires\ \tcode{Pred} is \oldconcept{CopyConstructible}.\br \tcode{Pred} shall be a binary predicate that takes two arguments of type \tcode{Key}. \tcode{Pred} is an equivalence relation.% & compile time @@ -2326,7 +2350,7 @@ % \tcode{X(n, hf)}\br \tcode{X a(n, hf);} & \tcode{X} -& \requires\ \tcode{key_equal} is \tcode{DefaultConstructible}.\br +& \requires\ \tcode{key_equal} is \oldconcept{DefaultConstructible}.\br \effects\ Constructs an empty container with at least \tcode{n} buckets, using \tcode{hf} as the hash function and \tcode{key_equal()} as the key equality predicate. @@ -2335,7 +2359,7 @@ % \tcode{X(n)}\br \tcode{X a(n);} & \tcode{X} -& \requires\ \tcode{hasher} and \tcode{key_equal} are \tcode{DefaultConstructible}.\br +& \requires\ \tcode{hasher} and \tcode{key_equal} are \oldconcept{DefaultConstructible}.\br \effects\ Constructs an empty container with at least \tcode{n} buckets, using \tcode{hasher()} as the hash function and \tcode{key_equal()} as the key equality predicate. @@ -2344,7 +2368,7 @@ % \tcode{X()}\br \tcode{X a;} & \tcode{X} -& \requires\ \tcode{hasher} and \tcode{key_equal} are \tcode{DefaultConstructible}.\br +& \requires\ \tcode{hasher} and \tcode{key_equal} are \oldconcept{DefaultConstructible}.\br \effects\ Constructs an empty container with an unspecified number of buckets, using \tcode{hasher()} as the hash function and \tcode{key_equal()} as the key equality predicate. @@ -2353,7 +2377,7 @@ % \tcode{X(i, j, n, hf, eq)}\br \tcode{X a(i, j, n, hf, eq);} & \tcode{X} -& \requires\ \tcode{value_type} is \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br +& \requires\ \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br \effects\ Constructs an empty container with at least \tcode{n} buckets, using \tcode{hf} as the hash function and \tcode{eq} as the key equality predicate, and inserts elements from \tcode{[i, j)} into it. @@ -2363,8 +2387,8 @@ % \tcode{X(i, j, n, hf)}\br \tcode{X a(i, j, n, hf);} & \tcode{X} -& \requires\ \tcode{key_equal} is \tcode{DefaultConstructible}. - \tcode{value_type} is \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br +& \requires\ \tcode{key_equal} is \oldconcept{DefaultConstructible}. + \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br \effects\ Constructs an empty container with at least \tcode{n} buckets, using \tcode{hf} as the hash function and \tcode{key_equal()} as the key equality predicate, and inserts elements from \tcode{[i, j)} into it. @@ -2374,8 +2398,8 @@ % \tcode{X(i, j, n)}\br \tcode{X a(i, j, n);} & \tcode{X} -& \requires\ \tcode{hasher} and \tcode{key_equal} are \tcode{DefaultConstructible}. - \tcode{value_type} is \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br +& \requires\ \tcode{hasher} and \tcode{key_equal} are \oldconcept{DefaultConstructible}. + \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br \effects\ Constructs an empty container with at least \tcode{n} buckets, using \tcode{hasher()} as the hash function and \tcode{key_equal()} as the key equality predicate, and inserts elements from \tcode{[i, j)} @@ -2386,8 +2410,8 @@ % \tcode{X(i, j)}\br \tcode{X a(i, j);} & \tcode{X} -& \requires\ \tcode{hasher} and \tcode{key_equal} are \tcode{DefaultConstructible}. - \tcode{value_type} is \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br +& \requires\ \tcode{hasher} and \tcode{key_equal} are \oldconcept{DefaultConstructible}. + \tcode{value_type} is \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br \effects\ Constructs an empty container with an unspecified number of buckets, using \tcode{hasher()} as the hash function and \tcode{key_equal()} as the key equality predicate, and inserts elements @@ -2439,8 +2463,8 @@ \tcode{a = il} & \tcode{X\&} & \requires\ \tcode{value_type} is -\tcode{CopyInsertable} into \tcode{X} -and \tcode{CopyAssignable}.\br +\oldconcept{CopyInsertable} into \tcode{X} +and \oldconcept{CopyAssignable}.\br \effects\ Assigns the range \range{il.begin()}{il.end()} into \tcode{a}. All existing elements of \tcode{a} are either assigned to or destroyed. & Same as \tcode{a = X(il)}. @@ -2463,7 +2487,7 @@ \tcode{a_uniq.} \tcode{emplace(args)} & \tcode{pair} & - \requires\ \tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br + \requires\ \tcode{value_type} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br \effects\ Inserts a \tcode{value_type} object \tcode{t} constructed with \tcode{std::forward<\brk{}Args\brk{}>(\brk{}args)...} if and only if there is no element in the container with key equivalent to the key of \tcode{t}. @@ -2476,7 +2500,7 @@ \tcode{a_eq.}\tcode{emplace(args)} & \tcode{iterator} & - \requires\ \tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br + \requires\ \tcode{value_type} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br \effects\ Inserts a \tcode{value_type} object \tcode{t} constructed with \tcode{std::forward<\brk{}Args>(\brk{}args)...} and returns the iterator pointing to the newly inserted element. & @@ -2485,7 +2509,7 @@ \tcode{a.emplace_hint(p, args)} & \tcode{iterator} & - \requires\ \tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br + \requires\ \tcode{value_type} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{args}.\br \effects\ Equivalent to \tcode{a.emplace(} \tcode{std::forward<\brk{}Args>(\brk{}args)...)}. Return value is an iterator pointing to the element with the key equivalent to the newly inserted element. The \tcode{const_iterator} \tcode{p} @@ -2497,9 +2521,9 @@ \indexunordmem{insert}% \tcode{a_uniq.insert(t)} & \tcode{pair} -& \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 +& \requires\ If \tcode{t} is a non-const rvalue, \tcode{value_type} shall be + \oldconcept{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} shall be + \oldconcept{CopyInsertable} into \tcode{X}.\br \effects\ Inserts \tcode{t} if and only if there is no element in the container with key equivalent to the key of \tcode{t}. The \tcode{bool} component of the returned pair indicates whether the insertion @@ -2510,9 +2534,9 @@ % \tcode{a_eq.insert(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 - \tcode{CopyInsertable} into \tcode{X}.\br +& \requires\ If \tcode{t} is a non-const rvalue, \tcode{value_type} shall be + \oldconcept{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} shall be + \oldconcept{CopyInsertable} into \tcode{X}.\br \effects\ Inserts \tcode{t}, and returns an iterator pointing to the newly inserted element. & Average case \bigoh{1}, worst case \bigoh{\tcode{a_eq.}\br\tcode{size()}}. @@ -2520,9 +2544,9 @@ % \tcode{a.insert(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 - \tcode{CopyInsertable} into \tcode{X}.\br +& \requires\ If \tcode{t} is a non-const rvalue, \tcode{value_type} shall be + \oldconcept{MoveInsertable} into \tcode{X}; otherwise, \tcode{value_type} shall be + \oldconcept{CopyInsertable} into \tcode{X}.\br \effects Equivalent to \tcode{a.insert(t)}. Return value is an iterator pointing to the element with the key equivalent to that of \tcode{t}. The iterator \tcode{p} is a hint pointing to where the search should @@ -2532,7 +2556,7 @@ % \tcode{a.insert(i, j)} & \tcode{void} -& \requires\ \tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br +& \requires\ \tcode{value_type} shall be \oldconcept{EmplaceConstructible} into \tcode{X} from \tcode{*i}.\br \requires \tcode{i} and \tcode{j} are not iterators in \tcode{a}.\br \effects Equivalent to \tcode{a.insert(t)} for each element in \tcode{[i,j)}.% & Average case \bigoh{N}, where $N$ is \tcode{distance(i, j)}. @@ -2672,6 +2696,13 @@ & Average case \bigoh{\tcode{b.count(k)}}, worst case \bigoh{\tcode{b.size()}}. \\ \rowsep % +\indexunordmem{contains}% +\tcode{b.contains(k)} +& \tcode{bool} +& Equivalent to \tcode{b.find(k) != b.end()}% +& Average case \bigoh{1}, worst case \bigoh{\tcode{b.size()}}. +\\ \rowsep +% \indexunordmem{equal_range}% \tcode{b.equal_range(k)} & \tcode{pair}; \br @@ -2713,7 +2744,7 @@ \tcode{b.bucket_size(n)} & \tcode{size_type} & \requires \tcode{n} shall be in the range \tcode{[0, b.bucket_count())}. - Returns the number of elements in the $\texttt{n}^{\textrm{ th}}$ bucket.% + Returns the number of elements in the $\tcode{n}^\text{th}$ bucket.% & \bigoh{\tcode{b.bucket_}\-\tcode{size(n)}} \\ \rowsep % @@ -2934,17 +2965,17 @@ template struct array; template - bool operator==(const array& x, const array& y); + constexpr bool operator==(const array& x, const array& y); template - bool operator!=(const array& x, const array& y); + constexpr bool operator!=(const array& x, const array& y); template - bool operator< (const array& x, const array& y); + constexpr bool operator< (const array& x, const array& y); template - bool operator> (const array& x, const array& y); + constexpr bool operator> (const array& x, const array& y); template - bool operator<=(const array& x, const array& y); + constexpr bool operator<=(const array& x, const array& y); template - bool operator>=(const array& x, const array& y); + constexpr bool operator>=(const array& x, const array& y); template void swap(array& x, array& y) noexcept(noexcept(x.swap(y))); @@ -3222,11 +3253,11 @@ \indextext{requirements!container}% The conditions for an aggregate\iref{dcl.init.aggr} shall be met. Class \tcode{array} relies on the implicitly-declared special -member functions~(\ref{class.ctor}, \ref{class.dtor}, and \ref{class.copy}) to +member functions~(\ref{class.ctor}, \ref{class.dtor}, and \ref{class.copy.ctor}) to conform to the container requirements table in~\ref{container.requirements}. In addition to the requirements specified in the container requirements table, the implicit move constructor and move assignment operator for \tcode{array} -require that \tcode{T} be \tcode{MoveConstructible} or \tcode{MoveAssignable}, +require that \tcode{T} be \oldconcept{MoveConstructible} or \oldconcept{MoveAssignable}, respectively. \begin{itemdecl} @@ -3537,7 +3568,7 @@ \tcode{n} default-inserted elements using the specified allocator. \pnum -\requires \tcode{T} shall be \tcode{DefaultInsertable} into \tcode{*this}. +\requires \tcode{T} shall be \oldconcept{DefaultInsertable} into \tcode{*this}. \pnum \complexity Linear in \tcode{n}. @@ -3557,7 +3588,7 @@ using the specified allocator. \pnum -\requires \tcode{T} shall be \tcode{CopyInsertable} into \tcode{*this}. +\requires \tcode{T} shall be \oldconcept{CopyInsertable} into \tcode{*this}. \pnum \complexity @@ -3597,7 +3628,7 @@ appends \tcode{sz - size()} default-inserted elements to the sequence. \pnum -\requires \tcode{T} shall be \tcode{MoveInsertable} and \tcode{DefaultInsertable} into \tcode{*this}. +\requires \tcode{T} shall be \oldconcept{MoveInsertable} and \oldconcept{DefaultInsertable} into \tcode{*this}. \end{itemdescr} \indexlibrary{\idxcode{resize}!\idxcode{deque}}% @@ -3613,7 +3644,7 @@ \pnum \requires \tcode{T} shall be -\tcode{CopyInsertable} into \tcode{*this}. +\oldconcept{CopyInsertable} into \tcode{*this}. \end{itemdescr} \indexlibrarymember{shrink_to_fit}{deque}% @@ -3623,7 +3654,7 @@ \begin{itemdescr} \pnum -\requires \tcode{T} shall be \tcode{MoveInsertable} into \tcode{*this}. +\requires \tcode{T} shall be \oldconcept{MoveInsertable} into \tcode{*this}. \pnum \effects \tcode{shrink_to_fit} is a non-binding request to reduce memory use @@ -3631,7 +3662,7 @@ \begin{note} The request is non-binding to allow latitude for implementation-specific optimizations. \end{note} If an exception is thrown other than by the move constructor -of a non-\tcode{CopyInsertable} \tcode{T} there are no effects. +of a non-\oldconcept{CopyInsertable} \tcode{T} there are no effects. \pnum \complexity Linear in the size of the sequence. @@ -3684,7 +3715,7 @@ If an exception is thrown while inserting a single element at either end, there are no effects. Otherwise, if an exception is thrown by the move constructor of a -non-\tcode{CopyInsertable} +non-\oldconcept{CopyInsertable} \tcode{T}, the effects are unspecified. \pnum @@ -3852,11 +3883,11 @@ void splice_after(const_iterator position, forward_list&& x, const_iterator first, const_iterator last); - void remove(const T& value); - template void remove_if(Predicate pred); + size_type remove(const T& value); + template size_type remove_if(Predicate pred); - void unique(); - template void unique(BinaryPredicate binary_pred); + size_type unique(); + template size_type unique(BinaryPredicate binary_pred); void merge(forward_list& x); void merge(forward_list&& x); @@ -3913,7 +3944,7 @@ default-inserted elements using the specified allocator. \pnum -\requires \tcode{T} shall be \tcode{DefaultInsertable} into \tcode{*this}. +\requires \tcode{T} shall be \oldconcept{DefaultInsertable} into \tcode{*this}. \pnum \complexity Linear in \tcode{n}. @@ -3929,7 +3960,7 @@ \effects Constructs a \tcode{forward_list} object with \tcode{n} copies of \tcode{value} using the specified allocator. \pnum -\requires \tcode{T} shall be \tcode{CopyInsertable} into \tcode{*this}. +\requires \tcode{T} shall be \oldconcept{CopyInsertable} into \tcode{*this}. \pnum \complexity Linear in \tcode{n}. @@ -4171,7 +4202,7 @@ elements at the end of the list. \pnum -\requires \tcode{T} shall be \tcode{DefaultInsertable} into \tcode{*this}. +\requires \tcode{T} shall be \oldconcept{DefaultInsertable} into \tcode{*this}. \end{itemdescr} \begin{itemdecl} @@ -4185,7 +4216,7 @@ copies of \tcode{c} at the end of the list. \pnum -\requires \tcode{T} shall be \tcode{CopyInsertable} into \tcode{*this}. +\requires \tcode{T} shall be \oldconcept{CopyInsertable} into \tcode{*this}. \end{itemdescr} @@ -4297,17 +4328,20 @@ \indexlibrarymember{remove}{forward_list}% \indexlibrarymember{remove_if}{forward_list}% \begin{itemdecl} -void remove(const T& value); -template void remove_if(Predicate pred); +size_type remove(const T& value); +template size_type remove_if(Predicate pred); \end{itemdecl} \begin{itemdescr} \pnum -\effects Erases all the elements in the list referred by a list iterator \tcode{i} for +\effects Erases all the elements in the list referred to by a list iterator \tcode{i} for which the following conditions hold: \tcode{*i == value} (for \tcode{remove()}), \tcode{pred(*i)} is \tcode{true} (for \tcode{remove_if()}). Invalidates only the iterators and references to the erased elements. +\pnum +\returns The number of elements erased. + \pnum \throws Nothing unless an exception is thrown by the equality comparison or the predicate. @@ -4322,8 +4356,8 @@ \indexlibrarymember{unique}{forward_list}% \begin{itemdecl} -void unique(); -template void unique(BinaryPredicate pred); +size_type unique(); +template size_type unique(BinaryPredicate pred); \end{itemdecl} \begin{itemdescr} @@ -4334,6 +4368,9 @@ *(i - 1))} (for the version with a predicate argument) holds. Invalidates only the iterators and references to the erased elements. +\pnum +\returns The number of elements erased. + \pnum \throws Nothing unless an exception is thrown by the equality comparison or the predicate. @@ -4543,12 +4580,12 @@ void splice(const_iterator position, list& x, const_iterator first, const_iterator last); void splice(const_iterator position, list&& x, const_iterator first, const_iterator last); - void remove(const T& value); - template void remove_if(Predicate pred); + size_type remove(const T& value); + template size_type remove_if(Predicate pred); - void unique(); + size_type unique(); template - void unique(BinaryPredicate binary_pred); + size_type unique(BinaryPredicate binary_pred); void merge(list& x); void merge(list&& x); @@ -4607,7 +4644,7 @@ \tcode{n} default-inserted elements using the specified allocator. \pnum -\requires \tcode{T} shall be \tcode{DefaultInsertable} into \tcode{*this}. +\requires \tcode{T} shall be \oldconcept{DefaultInsertable} into \tcode{*this}. \pnum \complexity @@ -4632,7 +4669,7 @@ using the specified allocator. \pnum -\requires \tcode{T} shall be \tcode{CopyInsertable} into \tcode{*this}. +\requires \tcode{T} shall be \oldconcept{CopyInsertable} into \tcode{*this}. \pnum \complexity @@ -4684,7 +4721,7 @@ \pnum \requires \tcode{T} shall be -\tcode{DefaultInsertable} into \tcode{*this}. +\oldconcept{DefaultInsertable} into \tcode{*this}. \end{itemdescr} \indexlibrary{\idxcode{resize}!\idxcode{list}}% @@ -4709,7 +4746,7 @@ \end{codeblock} \pnum -\requires \tcode{T} shall be \tcode{CopyInsertable} into \tcode{*this}. +\requires \tcode{T} shall be \oldconcept{CopyInsertable} into \tcode{*this}. \end{itemdescr} \rSec3[list.modifiers]{Modifiers} @@ -4930,17 +4967,20 @@ \indexlibrary{\idxcode{remove}!\idxcode{list}}% \begin{itemdecl} -void remove(const T& value); -template void remove_if(Predicate pred); +size_type remove(const T& value); +template size_type remove_if(Predicate pred); \end{itemdecl} \begin{itemdescr} \pnum \effects -Erases all the elements in the list referred by a list iterator \tcode{i} for which the +Erases all the elements in the list referred to by a list iterator \tcode{i} for which the following conditions hold: \tcode{*i == value}, \tcode{pred(*i) != false}. Invalidates only the iterators and references to the erased elements. +\pnum +\returns The number of elements erased. + \pnum \throws Nothing unless an exception is thrown by @@ -4960,8 +5000,8 @@ \indexlibrary{\idxcode{unique}!\idxcode{list}}% \begin{itemdecl} -void unique(); -template void unique(BinaryPredicate binary_pred); +size_type unique(); +template size_type unique(BinaryPredicate binary_pred); \end{itemdecl} \begin{itemdescr} @@ -4974,6 +5014,9 @@ \tcode{unique} with a predicate argument) holds. Invalidates only the iterators and references to the erased elements. +\pnum +\returns The number of elements erased. + \pnum \throws Nothing unless an exception is thrown by @@ -5231,7 +5274,7 @@ \indexlibrary{\idxcode{vector}!constructor} \begin{itemdecl} -explicit vector(const Allocator&); +explicit vector(const Allocator&) noexcept; \end{itemdecl} \begin{itemdescr} @@ -5254,7 +5297,7 @@ default-inserted elements using the specified allocator. \pnum -\requires \tcode{T} shall be \tcode{DefaultInsertable} into \tcode{*this}. +\requires \tcode{T} shall be \oldconcept{DefaultInsertable} into \tcode{*this}. \pnum \complexity Linear in \tcode{n}. @@ -5273,7 +5316,7 @@ \pnum \requires \tcode{T} shall be -\tcode{CopyInsertable} into \tcode{*this}. +\oldconcept{CopyInsertable} into \tcode{*this}. \pnum \complexity Linear in \tcode{n}. @@ -5336,7 +5379,7 @@ \begin{itemdescr} \pnum -\requires \tcode{T} shall be \tcode{MoveInsertable} into \tcode{*this}. +\requires \tcode{T} shall be \oldconcept{MoveInsertable} into \tcode{*this}. \pnum \effects @@ -5354,7 +5397,7 @@ Reallocation happens at this point if and only if the current capacity is less than the argument of \tcode{reserve()}. If an exception is thrown -other than by the move constructor of a non-\tcode{CopyInsertable} type, +other than by the move constructor of a non-\oldconcept{CopyInsertable} type, there are no effects. \pnum @@ -5387,7 +5430,7 @@ \begin{itemdescr} \pnum -\requires \tcode{T} shall be \tcode{MoveInsertable} into \tcode{*this}. +\requires \tcode{T} shall be \oldconcept{MoveInsertable} into \tcode{*this}. \pnum \effects \tcode{shrink_to_fit} is a non-binding request to reduce @@ -5397,7 +5440,7 @@ It does not increase \tcode{capacity()}, but may reduce \tcode{capacity()} 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. +of a non-\oldconcept{CopyInsertable} \tcode{T} there are no effects. \pnum \complexity Linear in the size of the sequence. @@ -5442,10 +5485,10 @@ \pnum \requires \tcode{T} shall be -\tcode{MoveInsertable} and \tcode{DefaultInsertable} into \tcode{*this}. +\oldconcept{MoveInsertable} and \oldconcept{DefaultInsertable} into \tcode{*this}. \pnum -\remarks If an exception is thrown other than by the move constructor of a non-\tcode{CopyInsertable} +\remarks If an exception is thrown other than by the move constructor of a non-\oldconcept{CopyInsertable} \tcode{T} there are no effects. \end{itemdescr} @@ -5462,7 +5505,7 @@ \pnum \requires \tcode{T} shall be -\tcode{CopyInsertable} into \tcode{*this}. +\oldconcept{CopyInsertable} into \tcode{*this}. \pnum \remarks If an exception is thrown there are no effects. @@ -5517,9 +5560,9 @@ \tcode{T} or by any \tcode{InputIterator} operation there are no effects. If an exception is thrown while inserting a single element at the end and -\tcode{T} is \tcode{CopyInsertable} or \tcode{is_nothrow_move_constructible_v} +\tcode{T} is \oldconcept{CopyInsertable} or \tcode{is_nothrow_move_constructible_v} is \tcode{true}, there are no effects. -Otherwise, if an exception is thrown by the move constructor of a non-\tcode{CopyInsertable} +Otherwise, if an exception is thrown by the move constructor of a non-\oldconcept{CopyInsertable} \tcode{T}, the effects are unspecified. \pnum @@ -5585,6 +5628,7 @@ friend class vector; reference() noexcept; public: + reference(const reference&) = default; ~reference(); operator bool() const noexcept; reference& operator=(const bool x) noexcept; @@ -6104,6 +6148,9 @@ size_type count(const key_type& x) const; template size_type count(const K& x) const; + bool contains(const key_type& x) const; + template bool contains(const K& x) const; + iterator lower_bound(const key_type& x); const_iterator lower_bound(const key_type& x) const; template iterator lower_bound(const K& x); @@ -6274,7 +6321,7 @@ \begin{itemdescr} \pnum \requires -\tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{map} +\tcode{value_type} shall be \oldconcept{EmplaceConstructible} into \tcode{map} from \tcode{piecewise_construct}, \tcode{for\-ward_as_tuple(k)}, \tcode{forward_as_tuple(std::forward(args)...)}. @@ -6312,7 +6359,7 @@ \begin{itemdescr} \pnum \requires -\tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{map} +\tcode{value_type} shall be \oldconcept{EmplaceConstructible} into \tcode{map} from \tcode{piecewise_construct}, \tcode{for\-ward_as_tuple(std::move(k))}, \tcode{forward_as_tuple(std::forward(args)...)}. @@ -6351,7 +6398,7 @@ \pnum \requires \tcode{is_assignable_v} shall be \tcode{true}. -\tcode{value_type} shall be \tcode{Emplace\-Constructible} into \tcode{map} +\tcode{value_type} shall be \oldconcept{Emplace\-Constructible} into \tcode{map} from \tcode{k}, \tcode{forward(obj)}. \pnum @@ -6388,7 +6435,7 @@ \pnum \requires \tcode{is_assignable_v} shall be \tcode{true}. -\tcode{value_type} shall be \tcode{Emplace\-Constructible} into \tcode{map} +\tcode{value_type} shall be \oldconcept{Emplace\-Constructible} into \tcode{map} from \tcode{move(k)}, \tcode{forward(obj)}. \pnum @@ -6596,6 +6643,9 @@ size_type count(const key_type& x) const; template size_type count(const K& x) const; + bool contains(const key_type& x) const; + template bool contains(const K& x) const; + iterator lower_bound(const key_type& x); const_iterator lower_bound(const key_type& x) const; template iterator lower_bound(const K& x); @@ -6875,6 +6925,9 @@ size_type count(const key_type& x) const; template size_type count(const K& x) const; + bool contains(const key_type& x) const; + template bool contains(const K& x) const; + iterator lower_bound(const key_type& x); const_iterator lower_bound(const key_type& x) const; template iterator lower_bound(const K& x); @@ -7126,6 +7179,9 @@ size_type count(const key_type& x) const; template size_type count(const K& x) const; + bool contains(const key_type& x) const; + template bool contains(const K& x) const; + iterator lower_bound(const key_type& x); const_iterator lower_bound(const key_type& x) const; template iterator lower_bound(const K& x); @@ -7536,6 +7592,7 @@ iterator find(const key_type& k); const_iterator find(const key_type& k) const; size_type count(const key_type& k) const; + bool contains(const key_type& k) const; pair equal_range(const key_type& k); pair equal_range(const key_type& k) const; @@ -7762,7 +7819,7 @@ \begin{itemdescr} \pnum \requires -\tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{unordered_map} +\tcode{value_type} shall be \oldconcept{EmplaceConstructible} into \tcode{unordered_map} from \tcode{piecewise_con\-struct}, \tcode{forward_as_tuple(k)}, \tcode{forward_as_tuple(std::forward(args)...)}. @@ -7800,7 +7857,7 @@ \begin{itemdescr} \pnum \requires -\tcode{value_type} shall be \tcode{EmplaceConstructible} into \tcode{unordered_map} +\tcode{value_type} shall be \oldconcept{EmplaceConstructible} into \tcode{unordered_map} from \tcode{piecewise_con\-struct}, \tcode{forward_as_tuple(std::move(k))}, \tcode{forward_as_tuple(std::forward(args)...)}. @@ -7839,7 +7896,7 @@ \pnum \requires \tcode{is_assignable_v} shall be \tcode{true}. -\tcode{value_type} shall be \tcode{Emplace\-Constructible} into \tcode{unordered_map} +\tcode{value_type} shall be \oldconcept{Emplace\-Constructible} into \tcode{unordered_map} from \tcode{k}, \tcode{std::forward(obj)}. \pnum @@ -7876,7 +7933,7 @@ \pnum \requires \tcode{is_assignable_v} shall be \tcode{true}. -\tcode{value_type} shall be \tcode{Emplace\-Constructible} into \tcode{unordered_map} +\tcode{value_type} shall be \oldconcept{Emplace\-Constructible} into \tcode{unordered_map} from \tcode{std::move(k)}, \tcode{std::forward(obj)}. \pnum @@ -8064,6 +8121,7 @@ iterator find(const key_type& k); const_iterator find(const key_type& k) const; size_type count(const key_type& k) const; + bool contains(const key_type& k) const; pair equal_range(const key_type& k); pair equal_range(const key_type& k) const; @@ -8390,6 +8448,7 @@ iterator find(const key_type& k); const_iterator find(const key_type& k) const; size_type count(const key_type& k) const; + bool contains(const key_type& k) const; pair equal_range(const key_type& k); pair equal_range(const key_type& k) const; @@ -8678,6 +8737,7 @@ iterator find(const key_type& k); const_iterator find(const key_type& k) const; size_type count(const key_type& k) const; + bool contains(const key_type& k) const; pair equal_range(const key_type& k); pair equal_range(const key_type& k) const; @@ -8932,8 +8992,9 @@ Container c; public: + queue() : queue(Container()) {} explicit queue(const Container&); - explicit queue(Container&& = Container()); + explicit queue(Container&&); template explicit queue(const Alloc&); template queue(const Container&, const Alloc&); template queue(Container&&, const Alloc&); @@ -8983,7 +9044,7 @@ \end{itemdescr} \begin{itemdecl} -explicit queue(Container&& cont = Container()); +explicit queue(Container&& cont); \end{itemdecl} \begin{itemdescr} @@ -9181,8 +9242,10 @@ Compare comp; public: + priority_queue() : priority_queue(Compare()) {} + explicit priority_queue(const Compare& x) : priority_queue(x, Container()) {} priority_queue(const Compare& x, const Container&); - explicit priority_queue(const Compare& x = Compare(), Container&& = Container()); + priority_queue(const Compare& x, Container&&); template priority_queue(InputIterator first, InputIterator last, const Compare& x, const Container&); @@ -9239,7 +9302,7 @@ \indexlibrary{\idxcode{priority_queue}!constructor}% \begin{itemdecl} priority_queue(const Compare& x, const Container& y); -explicit priority_queue(const Compare& x = Compare(), Container&& y = Container()); +priority_queue(const Compare& x, Container&& y); \end{itemdecl} \begin{itemdescr} @@ -9477,8 +9540,9 @@ Container c; public: + stack() : stack(Container()) {} explicit stack(const Container&); - explicit stack(Container&& = Container()); + explicit stack(Container&&); template explicit stack(const Alloc&); template stack(const Container&, const Alloc&); template stack(Container&&, const Alloc&); @@ -9525,7 +9589,7 @@ \indexlibrary{\idxcode{stack}!constructor}% \begin{itemdecl} -explicit stack(Container&& cont = Container()); +explicit stack(Container&& cont); \end{itemdecl} \begin{itemdescr} @@ -9691,8 +9755,6 @@ \pnum The header \tcode{} defines the view \tcode{span}. -A \tcode{span} is a view over a contiguous sequence of objects, -the storage of which is owned by some other object. \rSec2[span.syn]{Header \tcode{} synopsis}% \indexhdr{span}% @@ -9752,7 +9814,12 @@ the program is ill-formed. \pnum -The iterator type for span is a random access iterator and a contiguous iterator. +The iterator types \tcode{span::iterator} and \tcode{span::const_iterator} are +random access iterators\iref{random.access.iterators}, +contiguous iterators\iref{iterator.requirements.general}, and +constexpr iterators\iref{iterator.requirements.general}. +All requirements on container iterators\iref{container.requirements} apply to +\tcode{span::iterator} and \tcode{span::const_iterator} as well. \pnum All member functions of \tcode{span} have constant time complexity. @@ -9772,8 +9839,8 @@ using reference = element_type&; using iterator = @\impdefx{type of \tcode{span::iterator}}@; using const_iterator = @\impdefx{type of \tcode{span::const_iterator}}@; - using reverse_iterator = reverse_iterator; - using const_reverse_iterator = reverse_iterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; static constexpr index_type extent = Extent; // \ref{span.cons}, constructors, copy, and assignment @@ -9856,10 +9923,6 @@ constexpr span() noexcept; \end{itemdecl} \begin{itemdescr} -\pnum -\effects -Constructs an empty \tcode{span}. - \pnum \postconditions \tcode{size() == 0 \&\& data() == nullptr}. @@ -9883,12 +9946,12 @@ \pnum \effects Constructs a \tcode{span} that is a view over the range \range{ptr}{ptr + count}. -If \tcode{count} is 0 then an empty span is constructed. \pnum \postconditions \tcode{size() == count \&\& data() == ptr}. +\pnum \throws Nothing. \end{itemdescr} @@ -9907,7 +9970,6 @@ \pnum \effects Constructs a span that is a view over the range \range{first}{last}. -If \tcode{last - first == 0} then an empty \tcode{span} is constructed. \pnum \postconditions diff --git a/source/conversions.tex b/source/conversions.tex deleted file mode 100644 index 13e028ae23..0000000000 --- a/source/conversions.tex +++ /dev/null @@ -1,609 +0,0 @@ -%!TEX root = std.tex -\rSec0[conv]{Standard conversions} - -\indextext{implicit conversion|see{conversion, implicit}} -\indextext{contextually converted to bool|see{conversion, contextual}} -\indextext{rvalue!lvalue conversion to|see{conversion, lvalue-to-rvalue}}% - -\pnum -\indextext{conversion!standard|(}% -\indextext{conversion!implicit}% -Standard conversions are implicit conversions with built-in meaning. -\ref{conv} enumerates the full set of such conversions. A -\defnx{standard conversion sequence}{conversion sequence!standard} is a sequence of standard -conversions in the following order: - -\begin{itemize} -\item Zero or one conversion from the following set: lvalue-to-rvalue -conversion, array-to-pointer conversion, and function-to-pointer -conversion. - -\item Zero or one conversion from the following set: integral -promotions, floating-point promotion, integral conversions, floating-point -conversions, floating-integral conversions, pointer conversions, -pointer-to-member conversions, and boolean conversions. - -\item Zero or one function pointer conversion. - -\item Zero or one qualification conversion. -\end{itemize} - -\begin{note} -A standard conversion sequence can be empty, i.e., it can consist of no -conversions. \end{note} A standard conversion sequence will be applied to -an expression if necessary to convert it to a required destination type. - -\pnum -\begin{note} -Expressions with a given type will be implicitly converted to other -types in several contexts: - -\begin{itemize} -\item When used as operands of operators. The operator's requirements -for its operands dictate the destination type\iref{expr.compound}. - -\item When used in the condition of an \tcode{if} statement\iref{stmt.if} or -iteration statement\iref{stmt.iter}. The destination type is -\tcode{bool}. - -\item When used in the expression of a \tcode{switch} statement\iref{stmt.switch}. -The destination type is integral. - -\item When used as the source expression for an initialization (which -includes use as an argument in a function call and use as the expression -in a \tcode{return} statement). The type of the entity being initialized -is (generally) the destination type. -See~\ref{dcl.init}, \ref{dcl.init.ref}. -\end{itemize} -\end{note} - -\pnum -An expression \tcode{e} can be -\defnx{implicitly converted}{conversion!implicit} to a type \tcode{T} if and only if the -declaration \tcode{T t=e;} is well-formed, for some invented temporary -variable \tcode{t}\iref{dcl.init}. - -\pnum -Certain language constructs require that an expression be converted to a Boolean -value. An expression \tcode{e} appearing in such a context is said to be -\defnx{contextually converted to \tcode{bool}}{conversion!contextual to \tcode{bool}} and is well-formed if and only if -the declaration \tcode{bool t(e);} is well-formed, for some invented temporary -variable \tcode{t}\iref{dcl.init}. - -\pnum -Certain language constructs require conversion to a value having -one of a specified set of types appropriate to the construct. An -expression \tcode{e} of class type \tcode{E} appearing in such a -context is said to be -\indextext{conversion!contextual}% -\defn{contextually implicitly converted} to a specified type \tcode{T} and is -well-formed if and only if \tcode{e} can be implicitly converted to a type \tcode{T} -that is determined as follows: -\tcode{E} is searched for non-explicit conversion functions -whose return type is \cv{} \tcode{T} or reference to \cv{} -\tcode{T} such that \tcode{T} is allowed by the context. -There shall be exactly one such \tcode{T}. - -\pnum -The effect of any implicit -conversion is the same as performing the corresponding declaration and initialization -and then using the temporary variable as the result of the conversion. -The result is an lvalue if \tcode{T} is an lvalue reference -type or an rvalue reference to function type\iref{dcl.ref}, -an xvalue if \tcode{T} is an rvalue reference to object type, -and a prvalue otherwise. The expression \tcode{e} -is used as a glvalue if and only if the initialization uses it as a glvalue. - -\pnum -\begin{note} -For class types, user-defined conversions are considered as well; -see~\ref{class.conv}. In general, an implicit conversion -sequence\iref{over.best.ics} consists of a standard conversion -sequence followed by a user-defined conversion followed by another -standard conversion sequence. -\end{note} - -\pnum -\begin{note} -There are some contexts where certain conversions are suppressed. For -example, the lvalue-to-rvalue conversion is not done on the operand of -the unary \tcode{\&} operator. Specific exceptions are given in the -descriptions of those operators and contexts. -\end{note} - -\rSec1[conv.lval]{Lvalue-to-rvalue conversion} - -\pnum -\indextext{conversion!lvalue-to-rvalue}% -\indextext{type!incomplete}% -A glvalue\iref{basic.lval} of a non-function, non-array type \tcode{T} -can be converted to -a prvalue.\footnote{For historical reasons, this conversion is called the ``lvalue-to-rvalue'' -conversion, even though that name does not accurately reflect the taxonomy -of expressions described in~\ref{basic.lval}.} -If \tcode{T} is an incomplete type, a -program that necessitates this conversion is ill-formed. If \tcode{T} -is a non-class type, the type of the prvalue is -the cv-unqualified version of \tcode{T}. Otherwise, the type of the -prvalue is \tcode{T}.% -\footnote{In \Cpp{} class and array prvalues can have cv-qualified types. -This differs from ISO C, in which non-lvalues never have -cv-qualified types.} - -\pnum -When an lvalue-to-rvalue conversion -is applied to an expression \tcode{e}, and either -\begin{itemize} -\item \tcode{e} is not potentially evaluated, or -\item the evaluation of \tcode{e} results in the evaluation of a member - \tcode{ex} of the set of potential results of \tcode{e}, and \tcode{ex} - names a variable \tcode{x} that is not odr-used by - \tcode{ex}\iref{basic.def.odr}, -\end{itemize} -the value contained in the referenced object is not accessed. -\begin{example} -\begin{codeblock} -struct S { int n; }; -auto f() { - S x { 1 }; - constexpr S y { 2 }; - return [&](bool b) { return (b ? y : x).n; }; -} -auto g = f(); -int m = g(false); // undefined behavior due to access of \tcode{x.n} outside its lifetime -int n = g(true); // OK, does not access \tcode{y.n} -\end{codeblock} -\end{example} - -\pnum -The result of the conversion is determined according to the -following rules: - -\begin{itemize} - -\item If \tcode{T} is \cv{}~\tcode{std::nullptr_t}, the result is a -null pointer constant\iref{conv.ptr}. -\begin{note} -Since no value is fetched from memory, -there is no side effect for a volatile access\iref{intro.execution}, and -an inactive member of a union\iref{class.union} may be accessed. -\end{note} - -\item Otherwise, if \tcode{T} has a class -type, the conversion copy-initializes the result object from -the glvalue. - -\item Otherwise, if the object to which the glvalue refers contains an invalid -pointer value~(\ref{basic.stc.dynamic.deallocation}, -\ref{basic.stc.dynamic.safety}), the behavior is -\impldef{lvalue-to-rvalue conversion of an invalid pointer value}. - -\item Otherwise, the value contained in the object indicated by the -glvalue is the prvalue result. - -\end{itemize} - -\pnum -\begin{note} -See also~\ref{basic.lval}.\end{note} - -\rSec1[conv.array]{Array-to-pointer conversion} - -\pnum -\indextext{conversion!array-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}''. -The temporary materialization conversion\iref{conv.rval} is applied. -The result is a pointer to the first element of the array. - -\rSec1[conv.func]{Function-to-pointer conversion} - -\pnum -\indextext{conversion!function-to-pointer}% -An lvalue of function type \tcode{T} can be converted to a prvalue of -type ``pointer to \tcode{T}''. The result is a pointer to the -function.\footnote{This conversion never applies to non-static member functions because an -lvalue that refers to a non-static member function cannot be obtained.} - -\pnum -\begin{note} -See~\ref{over.over} for additional rules for the case where the function -is overloaded. -\end{note} - -\rSec1[conv.rval]{Temporary materialization conversion} -\indextext{conversion!temporary materialization}% - -\pnum -A prvalue of type \tcode{T} can be converted to an xvalue of type \tcode{T}. -This conversion initializes a temporary object\iref{class.temporary} of type \tcode{T} from the prvalue -by evaluating the prvalue with the temporary object as its result object, -and produces an xvalue denoting the temporary object. -\tcode{T} shall be a complete type. -\begin{note} -If \tcode{T} is a class type (or array thereof), -it must have an accessible and non-deleted destructor; -see~\ref{class.dtor}. -\end{note} -\begin{example} -\begin{codeblock} -struct X { int n; }; -int k = X().n; // OK, \tcode{X()} prvalue is converted to xvalue -\end{codeblock} -\end{example} - -\rSec1[conv.qual]{Qualification conversions} - -\indextext{conversion!qualification|(}% -\pnum -A \defn{cv-decomposition} of a type \tcode{T} -is a sequence of -$\cv{}_i$ and $P_i$ -such that \tcode{T} is -\begin{indented} -``$\cv{}_0$ $P_0$ $\cv{}_1$ $P_1$ $\cdots$ $\cv{}_{n-1}$ $P_{n-1}$ $\cv{}_n$ \tcode{U}'' for $n > 0$, -\end{indented} -where -each $\cv{}_i$ is a set of cv-qualifiers\iref{basic.type.qualifier}, and -each $P_i$ is -``pointer to''\iref{dcl.ptr}, -``pointer to member of class $C_i$ of type''\iref{dcl.mptr}, -``array of $N_i$'', or -``array of unknown bound of''\iref{dcl.array}. -If $P_i$ designates an array, -the cv-qualifiers $\cv{}_{i+1}$ on the element type are also taken as -the cv-qualifiers $\cv{}_i$ of the array. -\begin{example} -The type denoted by the \grammarterm{type-id} \tcode{const int **} -has two cv-decompositions, -taking \tcode{U} as ``\tcode{int}'' and as ``pointer to \tcode{const int}''. -\end{example} -The $n$-tuple of cv-qualifiers after the first one -in the longest cv-decomposition of \tcode{T}, that is, -$\cv{}_1, \cv{}_2, \dotsc, \cv{}_n$, is called the -\defn{cv-qualification signature} of \tcode{T}. - -\pnum -\indextext{type!similar|see{similar types}}% -Two types $\tcode{T}_1$ and $\tcode{T}_2$ are \defnx{similar}{similar types} if -they have cv-decompositions with the same $n$ -such that corresponding $P_i$ components are the same -and the types denoted by \tcode{U} are the same. - -\pnum -A prvalue expression of type $\tcode{T}_1$ -can be converted to type $\tcode{T}_2$ -if the following conditions are satisfied, -% NB: forbid line break between 'where' and 'cv' -% to stop superscript j from running into -% descender of p on the previous line. -where~$\cv{}_i^j$ denotes the cv-qualifiers in the cv-qualification signature of $\tcode{T}_j$:% -\footnote{These rules ensure that const-safety is preserved by the conversion.} - -\begin{itemize} -\item $\tcode{T}_1$ and $\tcode{T}_2$ are similar. - -\item For every $i > 0$, if \tcode{const} is in $\cv{}_i^1$ then \tcode{const} is in $\cv{}_i^2$, and similarly for \tcode{volatile}. - -\item If the $\cv{}_i^1$ and $\cv{}_i^2$ are different, -then \tcode{const} is in every $\cv{}_k^2$ for $0 < k < i$. -\end{itemize} - -\begin{note} -If a program could assign a pointer of type \tcode{T**} to a pointer of -type \tcode{const} \tcode{T**} (that is, if line \#1 below were -allowed), a program could inadvertently modify a const object -(as it is done on line \#2). For example, - -\begin{codeblock} -int main() { - const char c = 'c'; - char* pc; - const char** pcc = &pc; // \#1: not allowed - *pcc = &c; - *pc = 'C'; // \#2: modifies a const object -} -\end{codeblock} -\end{note} - -\pnum -\begin{note} -A prvalue of type ``pointer to \cvqual{cv1} \tcode{T}'' can be -converted to a prvalue of type ``pointer to \cvqual{cv2} \tcode{T}'' if -``\cvqual{cv2} \tcode{T}'' is more cv-qualified than ``\cvqual{cv1} -\tcode{T}''. -A prvalue of type ``pointer to member of \tcode{X} of type \cvqual{cv1} -\tcode{T}'' can be converted to a prvalue of type ``pointer to member -of \tcode{X} of type \cvqual{cv2} \tcode{T}'' if ``\cvqual{cv2} -\tcode{T}'' is more cv-qualified than ``\cvqual{cv1} \tcode{T}''. -\end{note} - -\pnum -\begin{note} -Function types (including those used in pointer to member function -types) are never cv-qualified\iref{dcl.fct}. -\end{note} -\indextext{conversion!qualification|)} - -\rSec1[conv.prom]{Integral promotions} - -\pnum -\indextext{promotion!integral}% -A prvalue of an integer type other than \tcode{bool}, \tcode{char16_t}, -\tcode{char32_t}, or \tcode{wchar_t} whose integer conversion -rank\iref{conv.rank} is less than the rank of \tcode{int} can be -converted to a prvalue of type \tcode{int} if \tcode{int} can represent -all the values of the source type; otherwise, the source prvalue can be -converted to a prvalue of type \tcode{unsigned int}. - -\pnum -\indextext{type!underlying!\idxcode{wchar_t}}% -\indextext{type!underlying!\idxcode{char16_t}}% -\indextext{type!underlying!\idxcode{char32_t}}% -A prvalue of type \tcode{char16_t}, \tcode{char32_t}, or -\tcode{wchar_t}\iref{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 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 -to a prvalue of its underlying type. - -\pnum -\indextext{type!underlying!enumeration}% -A prvalue of an unscoped enumeration type whose underlying type is not -fixed\iref{dcl.enum} can be converted to a prvalue of the first of the following -types that can represent all the values of the enumeration (i.e., the values in the -range $b_\text{min}$ to $b_\text{max}$ as described in~\ref{dcl.enum}): \tcode{int}, -\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\iref{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 -A prvalue of an unscoped enumeration type whose underlying type is -fixed\iref{dcl.enum} can be converted to a prvalue of its underlying type. Moreover, -if integral promotion can be applied to its underlying type, a prvalue of an unscoped -enumeration type whose underlying type is fixed can also be converted to a prvalue of -the promoted underlying type. - -\pnum -A prvalue for an integral bit-field\iref{class.bit} can be converted -to a prvalue of type \tcode{int} if \tcode{int} can represent all the -values of the bit-field; otherwise, it can be converted to -\tcode{unsigned int} if \tcode{unsigned int} can represent all the -values of the bit-field. If the bit-field is larger yet, no integral -promotion applies to it. If the bit-field has an enumerated type, it is -treated as any other value of that type for promotion purposes. - -\pnum -\indextext{promotion!bool to int}% -A prvalue of type \tcode{bool} can be converted to a prvalue of type -\tcode{int}, with \tcode{false} becoming zero and \tcode{true} becoming -one. - -\pnum -These conversions are called \defnx{integral promotions}{integral promotion}. - -\rSec1[conv.fpprom]{Floating-point promotion} - -\pnum -\indextext{promotion!floating-point}% -A prvalue of type \tcode{float} can be converted to a prvalue of type -\tcode{double}. The value is unchanged. - -\pnum -This conversion is called \defn{floating-point promotion}. - -\rSec1[conv.integral]{Integral conversions} - -\pnum -\indextext{conversion!integral}% -A prvalue of an integer type can be converted to a prvalue of another -integer type. A prvalue of an unscoped enumeration type can be converted to -a prvalue of an integer type. - -\pnum -\indextext{conversion!to unsigned}% -If the destination type is unsigned, the resulting value is the least -unsigned integer congruent to the source integer (modulo $2^n$ where $n$ -is the number of bits used to represent the unsigned type). -\indextext{signed integer representation!two's complement}% -\begin{note} -In a two's complement representation, this conversion is conceptual and -there is no change in the bit pattern (if there is no truncation). -\end{note} - -\pnum -\indextext{conversion!to signed}% -If the destination type is signed, the value is unchanged if it can be -represented in the destination type; otherwise, -the value is \impldef{value of result of unsigned to signed conversion}. - -\pnum -\indextext{conversion!bool@\tcode{bool}}% -If the destination type is \tcode{bool}, see~\ref{conv.bool}. If the -source type is \tcode{bool}, the value \tcode{false} is converted to -zero and the value \tcode{true} is converted to one. - -\pnum -The conversions allowed as integral promotions are excluded from the set -of integral conversions. - -\rSec1[conv.double]{Floating-point conversions} - -\pnum -\indextext{conversion!floating-point}% -A prvalue of floating-point type can be converted to a prvalue of -another floating-point type. If the source value can be exactly -represented in the destination type, the result of the conversion is -that exact representation. If the source value is between two adjacent -destination values, the result of the conversion is an -\impldef{result of inexact floating-point conversion} choice of either of those values. -Otherwise, the behavior is undefined. - -\pnum -The conversions allowed as floating-point promotions are excluded from -the set of floating-point conversions. - -\rSec1[conv.fpint]{Floating-integral conversions} - -\pnum -\indextext{conversion!floating to integral}% -A prvalue of a floating-point type can be converted to a prvalue of an -integer type. The conversion truncates; that is, the fractional part is -discarded. -\indextext{value!undefined unrepresentable integral}% -The behavior is undefined if the truncated value cannot be represented -in the destination type. -\begin{note} -If the destination type is \tcode{bool}, see~\ref{conv.bool}. -\end{note} - -\pnum -\indextext{conversion!integral to floating}% -\indextext{truncation}% -\indextext{rounding}% -A prvalue of an integer type or of an unscoped enumeration type can be converted to -a prvalue of a floating-point type. The result is exact if possible. If the value being -converted is in the range of values that can be represented but the value cannot be -represented exactly, it is an \impldef{value of result of inexact integer to -floating-point conversion} choice of either the next lower or higher representable -value. \begin{note} Loss of precision occurs if the integral value cannot be represented -exactly as a value of the floating-point type. \end{note} If the value being converted is -outside the range of values that can be represented, the behavior is undefined. If the -source type is \tcode{bool}, the value \tcode{false} is converted to zero and the value -\tcode{true} is converted to one. - -\rSec1[conv.ptr]{Pointer conversions} - -\pnum -\indextext{conversion!pointer}% -\indextext{null pointer conversion|see{conversion, null pointer}}% -\indextext{pointer!zero|see{value, null pointer}}% -\indextext{value!null pointer}% -A \defnx{null pointer constant}{constant!null pointer} is an integer literal\iref{lex.icon} with -value zero -or a prvalue of type \tcode{std::nullptr_t}. A null pointer constant can be -converted to a pointer type; the -result is the null pointer value of that type\iref{basic.compound} and is -distinguishable from every other value of -object pointer or function pointer -type. -Such a conversion is called a \defnx{null pointer conversion}{conversion!null pointer}. -Two null pointer values of the same type shall compare -equal. The conversion of a null pointer constant to a pointer to -cv-qualified type is a single conversion, and not the sequence of a -pointer conversion followed by a qualification -conversion\iref{conv.qual}. A null pointer constant of integral type -can be converted to a prvalue of type \tcode{std::nullptr_t}. -\begin{note} The resulting prvalue is not a null pointer value. \end{note} - -\pnum -A prvalue of type ``pointer to \cv{} \tcode{T}'', where \tcode{T} -is an object type, can be converted to a prvalue of type ``pointer to -\cv{} \tcode{void}''. -The pointer value\iref{basic.compound} is unchanged by this conversion. - -\pnum -A prvalue of type ``pointer to \cv{} \tcode{D}'', where \tcode{D} -is a class type, can be converted to a prvalue of type ``pointer to -\cv{} \tcode{B}'', where \tcode{B} is a base class\iref{class.derived} -of \tcode{D}. If \tcode{B} is an -inaccessible\iref{class.access} or -ambiguous\iref{class.member.lookup} base class of \tcode{D}, a program -that necessitates this conversion is ill-formed. The result of the -conversion is a pointer to the base class subobject of the derived class -object. The null pointer value is converted to the null pointer value of -the destination type. - -\rSec1[conv.mem]{Pointer-to-member conversions} - -\pnum -\indextext{conversion!pointer-to-member}% -\indextext{null member pointer conversion|see{conversion, null member pointer}}% -\indextext{constant!null pointer}% -A null pointer constant\iref{conv.ptr} can be converted to a -pointer-to-member -type; the result is the \defnx{null member pointer value}{value!null member pointer} -of that type and is distinguishable from any pointer to member not -created from a null pointer constant. -Such a conversion is called a \defnx{null member pointer conversion}{conversion!null member pointer}. -Two null member pointer values of -the same type shall compare equal. The conversion of a null pointer -constant to a pointer to member of cv-qualified type is a single -conversion, and not the sequence of a pointer-to-member conversion -followed by a qualification conversion\iref{conv.qual}. - -\pnum -A prvalue of type ``pointer to member of \tcode{B} of type \cv{} -\tcode{T}'', where \tcode{B} is a class type, can be converted to -a prvalue of type ``pointer to member of \tcode{D} of type \cv{} -\tcode{T}'', where \tcode{D} is a derived class\iref{class.derived} -of \tcode{B}. If \tcode{B} is an -inaccessible\iref{class.access}, -ambiguous\iref{class.member.lookup}, or virtual\iref{class.mi} base -class of \tcode{D}, or a base class of a virtual base class of -\tcode{D}, a program that necessitates this conversion is ill-formed. -The result of the conversion refers to the same member as the pointer to -member before the conversion took place, but it refers to the base class -member as if it were a member of the derived class. The result refers to -the member in \tcode{D}'s instance of \tcode{B}. Since the result has -type ``pointer to member of \tcode{D} of type \cv{} \tcode{T}'', -indirection through it with a \tcode{D} object is valid. The result is the same -as if indirecting through the pointer to member of \tcode{B} with the -\tcode{B} subobject of \tcode{D}. The null member pointer value is -converted to the null member pointer value of the destination -type.\footnote{The rule for conversion of pointers to members (from pointer to member -of base to pointer to member of derived) appears inverted compared to -the rule for pointers to objects (from pointer to derived to pointer to -base)~(\ref{conv.ptr}, \ref{class.derived}). This inversion is -necessary to ensure type safety. Note that a pointer to member is not -an object pointer or a function pointer -and the rules for conversions -of such pointers do not apply to pointers to members. -\indextext{conversion!pointer-to-member!\idxcode{void*}}% -In particular, a pointer to member cannot be converted to a -\tcode{void*}.} - -\rSec1[conv.fctptr]{Function pointer conversions} - -\pnum -\indextext{conversion!function pointer}% -A prvalue of type ``pointer to \tcode{noexcept} function'' -can be converted to a prvalue of type ``pointer to function''. -The result is a pointer to the function. -A prvalue of type ``pointer to member of type \tcode{noexcept} function'' -can be converted to a prvalue of type ``pointer to member of type function''. -The result designates the member function. - -\begin{example} -\begin{codeblock} - void (*p)(); - void (**pp)() noexcept = &p; // error: cannot convert to pointer to \tcode{noexcept} function - - struct S { typedef void (*p)(); operator p(); }; - void (*q)() noexcept = S(); // error: cannot convert to pointer to \tcode{noexcept} function -\end{codeblock} -\end{example} - -\rSec1[conv.bool]{Boolean conversions} - -\pnum -\indextext{conversion!boolean}% -A prvalue of arithmetic, unscoped enumeration, pointer, or pointer-to-member -type can be converted to a prvalue of type \tcode{bool}. A zero value, null -pointer value, or null member pointer value is converted to \tcode{false}; any -other value is converted to \tcode{true}. For -direct-initialization\iref{dcl.init}, a prvalue of type -\tcode{std::nullptr_t} can be converted to a prvalue of type -\tcode{bool}; the resulting value is \tcode{false}. - -\indextext{conversion!standard|)} diff --git a/source/declarations.tex b/source/declarations.tex index 79355c3324..5708b855cf 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -499,6 +499,12 @@ \begin{bnf} \nontermdef{function-specifier}\br \terminal{virtual}\br + explicit-specifier +\end{bnf} + +\begin{bnf} +\nontermdef{explicit-specifier}\br + \terminal{explicit} \terminal{(} constant-expression \terminal{)}\br \terminal{explicit} \end{bnf} @@ -510,10 +516,22 @@ \pnum \indextext{specifier!\idxcode{explicit}}% -The \tcode{explicit} specifier shall be used only in the declaration of +An \grammarterm{explicit-specifier} shall be used only in the declaration of a constructor or conversion function within its class definition; see~\ref{class.conv.ctor} and~\ref{class.conv.fct}. +\pnum +In an \grammarterm{explicit-specifier}, +the \grammarterm{constant-expression}, if supplied, shall be a +contextually converted constant expression of type \tcode{bool}\iref{expr.const}. +The \grammarterm{explicit-specifier} \tcode{explicit} +without a \grammarterm{constant-expression} is equivalent to +the \grammarterm{explicit-specifier} \tcode{explicit(true)}. +If the constant expression evaluates to \tcode{true}, +the function is explicit. Otherwise, the function is not explicit. +A \tcode{(} token that follows \tcode{explicit} is parsed as +part of the \grammarterm{explicit-specifier}. + \rSec2[dcl.typedef]{The \tcode{typedef} specifier}% \indextext{specifier!\idxcode{typedef}} @@ -770,9 +788,6 @@ requirements: \begin{itemize} -\item -it shall not be virtual\iref{class.virtual}; - \item its return type shall be a literal type; @@ -930,7 +945,7 @@ a call to a constexpr function can appear in a constant expression\iref{expr.const} and \item -copy elision is mandatory in a constant expression\iref{class.copy}. +copy elision is mandatory in a constant expression\iref{class.copy.elision}. \end{itemize} \pnum @@ -1348,7 +1363,7 @@ \tcode{void} & ``\tcode{void}'' \\ \tcode{auto} & placeholder for a type to be deduced\\ \tcode{decltype(auto)} & placeholder for a type to be deduced\\ -\tcode{decltype(}\grammartermnc{expression}\tcode{)} +\tcode{decltype(}\grammarterm{expression}\tcode{)} & the type as defined below\\ \end{simpletypetable} @@ -1371,6 +1386,12 @@ \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} +naming a non-type \grammarterm{template-parameter}\iref{temp.param}, +\tcode{decltype(e)} is the type of the \grammarterm{template-parameter} +after performing any necessary type deduction +(\ref{dcl.spec.auto}, \ref{dcl.type.class.deduct}); + \item otherwise, if \tcode{e} is an unparenthesized \grammarterm{id-expression} or an unparenthesized class @@ -1413,7 +1434,7 @@ If the operand of a \grammarterm{decltype-specifier} is a prvalue, the temporary materialization conversion is not applied\iref{conv.rval} and no result object is provided for the prvalue. -The type of the prvalue may be incomplete. +The type of the prvalue may be incomplete or an abstract class type. \begin{note} As a result, storage is not allocated for the prvalue and it is not destroyed. Thus, a class type is not instantiated @@ -1876,9 +1897,11 @@ in the \grammarterm{type-specifier-seq} in the \grammarterm{new-type-id} or \grammarterm{type-id} of a \grammarterm{new-expression}\iref{expr.new}, -or as the \grammarterm{simple-type-specifier} -in an explicit type conversion (functional notation)\iref{expr.type.conv}. +in an explicit type conversion (functional notation)\iref{expr.type.conv}, +or +as the \grammarterm{type-specifier} in the \grammarterm{parameter-declaration} +of a \grammarterm{template-parameter}\iref{temp.param}. A placeholder for a deduced class type shall not appear in any other context. @@ -1900,217 +1923,4428 @@ \end{example} \indextext{specifier|)}% -\rSec1[dcl.enum]{Enumeration declarations}% -\indextext{enumeration}% -\indextext{\idxcode{\{\}}!enum declaration@\tcode{enum} declaration}% -\indextext{\idxcode{enum}!type of} +\rSec1[dcl.decl]{Declarators}% +\indextext{declarator|(} + +\indextext{initialization!class object|seealso{constructor}}% +\indextext{\idxcode{*}|see{declarator, pointer}} +\indextext{\idxcode{\&}|see{declarator, reference}}% +\indextext{\idxcode{::*}|see{declarator, pointer-to-member}}% +\indextext{\idxcode{[]}|see{declarator, array}}% +\indextext{\idxcode{()}|see{declarator, function}}% \pnum -An enumeration is a distinct type\iref{basic.compound} with named -constants. Its name becomes an \grammarterm{enum-name} within its scope. +A declarator declares a single variable, function, or type, within a declaration. +The +\grammarterm{init-declarator-list} +appearing in a declaration +is a comma-separated sequence of declarators, +each of which can have an initializer. \begin{bnf} -\nontermdef{enum-name}\br - identifier +\nontermdef{init-declarator-list}\br + init-declarator\br + init-declarator-list \terminal{,} init-declarator \end{bnf} \begin{bnf} -\nontermdef{enum-specifier}\br - enum-head \terminal{\{} \opt{enumerator-list} \terminal{\}}\br - enum-head \terminal{\{} enumerator-list \terminal{, \}} +\nontermdef{init-declarator}\br + declarator \opt{initializer}\br + declarator requires-clause \end{bnf} +\pnum +The three components of a +\grammarterm{simple-declaration} +are the +attributes\iref{dcl.attr}, the +specifiers +(\grammarterm{decl-specifier-seq}; +\ref{dcl.spec}) and the declarators +(\grammarterm{init-declarator-list}). +The specifiers indicate the type, storage class or other properties of +the entities being declared. +The declarators specify the names of these entities +and (optionally) modify the type of the specifiers with operators such as +\tcode{*} +(pointer +to) +and +\tcode{()} +(function returning). +Initial values can also be specified in a declarator; +initializers are discussed in~\ref{dcl.init} and~\ref{class.init}. + +\pnum +Each +\grammarterm{init-declarator} +in a declaration is analyzed separately as if it was in a declaration by itself. +\begin{note} +A declaration with several declarators is usually equivalent to the corresponding +sequence of declarations each with a single declarator. That is +\begin{codeblock} +T D1, D2, ... Dn; +\end{codeblock} +is usually equivalent to +\begin{codeblock} +T D1; T D2; ... T Dn; +\end{codeblock} +where \tcode{T} is a \grammarterm{decl-specifier-seq} +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-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 { @\commentellip@ }; +S S, T; // declare two instances of \tcode{struct S} +\end{codeblock} +which is not equivalent to +\begin{codeblock} +struct S { @\commentellip@ }; +S S; +S T; // error +\end{codeblock} +Another exception is when \tcode{T} is \tcode{auto}\iref{dcl.spec.auto}, +for example: +\begin{codeblock} +auto i = 1, j = 2.0; // error: deduced types for \tcode{i} and \tcode{j} do not match +\end{codeblock} +as opposed to +\begin{codeblock} +auto i = 1; // OK: \tcode{i} deduced to have type \tcode{int} +auto j = 2.0; // OK: \tcode{j} deduced to have type \tcode{double} +\end{codeblock} +\end{note} + +\pnum +The optional \grammarterm{requires-clause}\iref{temp} in an +\grammarterm{init-declarator} or \grammarterm{member-declarator} +shall not be present when the declarator does not declare a +function\iref{dcl.fct}. +% +\indextext{trailing requires-clause@trailing \textit{requires-clause}|see{\textit{requires-clause}, trailing}}% +When present after a declarator, the \grammarterm{requires-clause} +is called the \defnx{trailing \grammarterm{requires-clause}}{% +\idxgram{requires-clause}!trailing}. +The trailing \grammarterm{requires-clause} introduces the +\grammarterm{constraint-expression} that results from interpreting +its \grammarterm{constraint-logical-or-expression} as a +\grammarterm{constraint-expression}. +% +\begin{example} +\begin{codeblock} +void f1(int a) requires true; // OK +auto f2(int a) -> bool requires true; // OK +auto f3(int a) requires true -> bool; // error: \grammarterm{requires-clause} precedes \grammarterm{trailing-return-type} +void (*pf)() requires true; // error: constraint on a variable +void g(int (*)() requires true); // error: constraint on a \grammarterm{parameter-declaration} + +auto* p = new void(*)(char) requires true; // error: not a function declaration +\end{codeblock} +\end{example} + +\pnum +Declarators have the syntax + \begin{bnf} -\nontermdef{enum-head}\br - enum-key \opt{attribute-specifier-seq} \opt{enum-head-name} \opt{enum-base} +\nontermdef{declarator}\br + ptr-declarator\br + noptr-declarator parameters-and-qualifiers trailing-return-type \end{bnf} \begin{bnf} -\nontermdef{enum-head-name}\br - \opt{nested-name-specifier} identifier +\nontermdef{ptr-declarator}\br + noptr-declarator\br + ptr-operator ptr-declarator \end{bnf} \begin{bnf} -\nontermdef{opaque-enum-declaration}\br - enum-key \opt{attribute-specifier-seq} \opt{nested-name-specifier} identifier \opt{enum-base} \terminal{;} +\nontermdef{noptr-declarator}\br + declarator-id \opt{attribute-specifier-seq}\br + noptr-declarator parameters-and-qualifiers\br + noptr-declarator \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq}\br + \terminal{(} ptr-declarator \terminal{)} \end{bnf} \begin{bnf} -\nontermdef{enum-key}\br - \terminal{enum}\br - \terminal{enum class}\br - \terminal{enum struct} +\nontermdef{parameters-and-qualifiers}\br + \terminal{(} parameter-declaration-clause \terminal{)} \opt{cv-qualifier-seq}\br + \bnfindent\opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq} \end{bnf} \begin{bnf} -\nontermdef{enum-base}\br - \terminal{:} type-specifier-seq +\nontermdef{trailing-return-type}\br + \terminal{->} type-id \end{bnf} \begin{bnf} -\nontermdef{enumerator-list}\br - enumerator-definition\br - enumerator-list \terminal{,} enumerator-definition +\nontermdef{ptr-operator}\br + \terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq}\br + \terminal{\&} \opt{attribute-specifier-seq}\br + \terminal{\&\&} \opt{attribute-specifier-seq}\br + nested-name-specifier \terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq} \end{bnf} \begin{bnf} -\nontermdef{enumerator-definition}\br - enumerator\br - enumerator \terminal{=} constant-expression +\nontermdef{cv-qualifier-seq}\br + cv-qualifier \opt{cv-qualifier-seq} \end{bnf} \begin{bnf} -\nontermdef{enumerator}\br - identifier \opt{attribute-specifier-seq} +\nontermdef{cv-qualifier}\br + \terminal{const}\br + \terminal{volatile} \end{bnf} -The optional \grammarterm{attribute-specifier-seq} in the \grammarterm{enum-head} and -the \grammarterm{opaque-enum-declaration} appertains to the enumeration; the attributes -in that \grammarterm{attribute-specifier-seq} are thereafter considered attributes of the -enumeration whenever it is named. -A \tcode{:} following -``\tcode{enum} \opt{\grammarterm{nested-name-specifier}} \grammarterm{identifier}'' -within the \grammarterm{decl-specifier-seq} of a \grammarterm{member-declaration} -is parsed as part of an \grammarterm{enum-base}. -\begin{note} This resolves a potential ambiguity between the declaration of an enumeration -with an \grammarterm{enum-base} and the declaration of an unnamed bit-field of enumeration -type. \begin{example} +\begin{bnf} +\nontermdef{ref-qualifier}\br + \terminal{\&}\br + \terminal{\&\&} +\end{bnf} + +\begin{bnf} +\nontermdef{declarator-id}\br + \opt{\terminal{...}} id-expression +\end{bnf} + +\rSec2[dcl.name]{Type names} + +\pnum +\indextext{type name}% +To specify type conversions explicitly, +\indextext{operator!cast}% +and as an argument of +\tcode{sizeof}, +\tcode{alignof}, +\tcode{new}, +or +\tcode{typeid}, +the name of a type shall be specified. +This can be done with a +\grammarterm{type-id}, +which is syntactically a declaration for a variable or function +of that type that omits the name of the entity. + +\begin{bnf} +\nontermdef{type-id}\br + type-specifier-seq \opt{abstract-declarator} +\end{bnf} + +\begin{bnf} +\nontermdef{defining-type-id}\br + defining-type-specifier-seq \opt{abstract-declarator} +\end{bnf} + +\begin{bnf} +\nontermdef{abstract-declarator}\br + ptr-abstract-declarator\br + \opt{noptr-abstract-declarator} parameters-and-qualifiers trailing-return-type\br + abstract-pack-declarator +\end{bnf} + +\begin{bnf} +\nontermdef{ptr-abstract-declarator}\br + noptr-abstract-declarator\br + ptr-operator \opt{ptr-abstract-declarator} +\end{bnf} + +\begin{bnf} +\nontermdef{noptr-abstract-declarator}\br + \opt{noptr-abstract-declarator} parameters-and-qualifiers\br + \opt{noptr-abstract-declarator} \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq}\br + \terminal{(} ptr-abstract-declarator \terminal{)} +\end{bnf} + +\begin{bnf} +\nontermdef{abstract-pack-declarator}\br + noptr-abstract-pack-declarator\br + ptr-operator abstract-pack-declarator +\end{bnf} + +\begin{bnf} +\nontermdef{noptr-abstract-pack-declarator}\br + noptr-abstract-pack-declarator parameters-and-qualifiers\br + noptr-abstract-pack-declarator \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq}\br + \terminal{...} +\end{bnf} +It is possible to identify uniquely the location in the +\grammarterm{abstract-declarator} +where the identifier would appear if the construction were a declarator +in a declaration. +The named type is then the same as the type of the +hypothetical identifier. +\begin{example} \begin{codeblock} - struct S { - enum E : int {}; - enum E : int {}; // error: redeclaration of enumeration - }; +int // \tcode{int i} +int * // \tcode{int *pi} +int *[3] // \tcode{int *p[3]} +int (*)[3] // \tcode{int (*p3i)[3]} +int *() // \tcode{int *f()} +int (*)(double) // \tcode{int (*pf)(double)} \end{codeblock} - +name respectively the types +``\tcode{int}'', +``pointer to +\tcode{int}'', +``array of 3 pointers to +\tcode{int}'', +``pointer to array of 3 +\tcode{int}'', +``function of (no parameters) returning pointer to +\tcode{int}'', +and ``pointer to a function of +(\tcode{double}) +returning +\tcode{int}''. \end{example} + +\pnum +A type can also be named (often more easily) by using a +\tcode{typedef}\iref{dcl.typedef}. + +\rSec2[dcl.ambig.res]{Ambiguity resolution}% +\indextext{ambiguity!declaration versus cast}% +\indextext{declaration!parentheses in} + +\pnum +The ambiguity arising from the similarity between a function-style cast and +a declaration mentioned in~\ref{stmt.ambig} can also occur in the context of a declaration. +In that context, the choice is between a function declaration with +a redundant set of parentheses around a parameter name and an object declaration +with a function-style cast as the initializer. +Just as for the ambiguities mentioned in~\ref{stmt.ambig}, +the resolution is to consider any construct that could possibly +be a declaration a declaration. +\begin{note} +A declaration can be explicitly disambiguated by adding parentheses +around the argument. +The ambiguity can be avoided by use of copy-initialization or +list-initialization syntax, or by use of a non-function-style cast. \end{note} -If an \grammarterm{opaque-enum-declaration} contains -a \grammarterm{nested-name-specifier}, -the declaration shall be an explicit specialization\iref{temp.expl.spec}. +\begin{example} +\begin{codeblock} +struct S { + S(int); +}; + +void foo(double a) { + S w(int(a)); // function declaration + S x(int()); // function declaration + S y((int(a))); // object declaration + S y((int)a); // object declaration + S z = int(a); // object declaration +} +\end{codeblock} +\end{example} \pnum -\indextext{constant!enumeration}% -\indextext{enumeration}% -The enumeration type declared with an \grammarterm{enum-key} -of only \tcode{enum} is an \defnx{unscoped enumeration}{enumeration!unscoped}, -and its \grammarterm{enumerator}{s} are \defnx{unscoped enumerators}{enumerator!unscoped}. -The \grammarterm{enum-key}{s} \tcode{enum class} and -\tcode{enum struct} are semantically equivalent; an enumeration -type declared with one of these is a \defnx{scoped enumeration}{enumeration!scoped}, -and its \grammarterm{enumerator}{s} are \defnx{scoped enumerators}{enumerator!scoped}. -The optional \grammarterm{identifier} shall not be omitted in the declaration of a scoped enumeration. -The \grammarterm{type-specifier-seq} of an \grammarterm{enum-base} -shall name an integral type; any cv-qualification is ignored. -An \grammarterm{opaque-enum-declaration} declaring an unscoped enumeration shall -not omit the \grammarterm{enum-base}. -The identifiers in an \grammarterm{enumerator-list} are declared as -constants, and can appear wherever constants are required. -\indextext{enumerator!value of}% -An \grammarterm{enumerator-definition} with \tcode{=} gives the associated -\grammarterm{enumerator} the value indicated by the -\grammarterm{constant-expression}. -If the first \grammarterm{enumerator} -has no \grammarterm{initializer}, the value of the corresponding constant -is zero. An \grammarterm{enumerator-definition} without an -\grammarterm{initializer} gives the \grammarterm{enumerator} the value -obtained by increasing the value of the previous \grammarterm{enumerator} -by one. +An ambiguity can arise from the similarity between a function-style +cast and a +\grammarterm{type-id}. +The resolution is that any construct that could possibly be a +\grammarterm{type-id} +in its syntactic context shall be considered a +\grammarterm{type-id}. \begin{example} \begin{codeblock} -enum { a, b, c=0 }; -enum { d, e, f=e+2 }; +template struct X {}; +template struct Y {}; +X a; // type-id +X b; // expression (ill-formed) +Y c; // type-id (ill-formed) +Y d; // expression + +void foo(signed char a) { + sizeof(int()); // type-id (ill-formed) + sizeof(int(a)); // expression + sizeof(int(unsigned(a))); // type-id (ill-formed) + + (int())+1; // type-id (ill-formed) + (int(a))+1; // expression + (int(unsigned(a)))+1; // type-id (ill-formed) +} \end{codeblock} - -defines \tcode{a}, \tcode{c}, and \tcode{d} to be zero, \tcode{b} and -\tcode{e} to be \tcode{1}, and \tcode{f} to be \tcode{3}. \end{example} -The optional \grammarterm{attribute-specifier-seq} in an -\grammarterm{enumerator} appertains to that enumerator. \pnum -An \grammarterm{opaque-enum-declaration} is either a redeclaration -of an enumeration in the current scope or a declaration of a new enumeration. -\begin{note} An enumeration declared by an -\grammarterm{opaque-enum-declaration} has a fixed underlying type and is a -complete type. The list of enumerators can be provided in a later redeclaration -with an \grammarterm{enum-specifier}. \end{note} A scoped enumeration -shall not be later redeclared as unscoped or with a different underlying type. -An unscoped enumeration shall not be later redeclared as scoped and each -redeclaration shall include an \grammarterm{enum-base} specifying the same -underlying type as in the original declaration. +Another ambiguity arises in 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 +pointer to function and the declaration of a parameter with redundant +parentheses around the +\grammarterm{declarator-id}. +The resolution is to consider the +\grammarterm{type-name} +as a +\grammarterm{simple-type-specifier} +rather than a +\grammarterm{declarator-id}. +\begin{example} -\pnum -If the \grammarterm{enum-key} is followed by a -\grammarterm{nested-name-specifier}, the \grammarterm{enum-specifier} shall -refer to an enumeration that was previously declared directly in the class or -namespace to which the \grammarterm{nested-name-specifier} refers (i.e., neither -inherited nor introduced by a \grammarterm{using-declaration}), and the -\grammarterm{enum-specifier} shall appear in a namespace enclosing the previous -declaration. +\begin{codeblock} +class C { }; +void f(int(C)) { } // \tcode{void f(int(*fp)(C c)) \{ \}} + // not: \tcode{void f(int C) \{ \}} -\pnum -\indextext{\idxcode{enum}!type of}% -\indextext{\idxcode{enum}!underlying type|see{type, underlying}}% -Each enumeration defines a type that is different from all other types. -Each enumeration also has an \defnx{underlying type}{type!underlying!enumeration}. -The underlying type can be explicitly specified using an \grammarterm{enum-base}. -For a scoped enumeration type, the underlying type is \tcode{int} if it is not -explicitly specified. In both of these cases, the underlying type is said to be -\defnx{fixed}{type!underlying!fixed}. -Following the closing brace of an \grammarterm{enum-specifier}, each -enumerator has the type of its enumeration. -If the underlying type is fixed, the type of each enumerator -prior to the closing brace is the underlying -type -and the \grammarterm{constant-expression} in the \grammarterm{enumerator-definition} -shall be a converted constant expression of the underlying -type\iref{expr.const}. -If the underlying -type is not fixed, -the type of each enumerator prior to the closing brace is determined as -follows: +int g(C); -\begin{itemize} -\item If an -initializer is specified for an enumerator, the -\grammarterm{constant-expression} shall be an integral constant -expression\iref{expr.const}. If the expression has -unscoped enumeration type, the enumerator has the underlying type of that -enumeration type, otherwise it has the same type as the expression. +void foo() { + f(1); // error: cannot convert \tcode{1} to function pointer + f(g); // OK +} +\end{codeblock} -\item If no initializer is specified for the -first enumerator, its type is an unspecified signed integral type. +For another example, -\item Otherwise -the type of the enumerator is the same as that of the -preceding enumerator unless the incremented value is not representable -in that type, in which case the type is an unspecified integral type -sufficient to contain the incremented value. If no such type exists, the program -is ill-formed. -\end{itemize} +\begin{codeblock} +class C { }; +void h(int *(C[10])); // \tcode{void h(int *(*_fp)(C _parm[10]));} + // not: \tcode{void h(int *C[10]);} +\end{codeblock} +\end{example} + +\rSec2[dcl.meaning]{Meaning of declarators}% +\indextext{declarator!meaning of|(} + +\pnum +\indextext{declaration!type}% +A declarator contains exactly one +\grammarterm{declarator-id}; +it names the identifier that is declared. +An +\grammarterm{unqualified-id} +occurring in +a +\grammarterm{declarator-id} +shall be a simple +\grammarterm{identifier} +except for the declaration of some special functions~(\ref{class.ctor}, +\ref{class.conv}, \ref{class.dtor}, \ref{over.oper}) and +for the declaration of template specializations +or partial specializations\iref{temp.spec}. +When the +\grammarterm{declarator-id} +is qualified, the declaration shall refer to a previously declared member +of the class or namespace to which the qualifier refers (or, +in the case of a namespace, +of an element of the inline namespace +set of that namespace\iref{namespace.def}) or to a specialization thereof; the member +shall not merely have been introduced by a +\grammarterm{using-declaration} +in the scope of the class or namespace nominated by the +\grammarterm{nested-name-specifier} +of the +\grammarterm{declarator-id}. +The \grammarterm{nested-name-specifier} of a qualified \grammarterm{declarator-id} shall not +begin with a \grammarterm{decltype-specifier}. +\begin{note} +If the qualifier is the global +\tcode{::} +scope resolution operator, the +\grammarterm{declarator-id} +refers to a name declared in the global namespace scope. +\end{note} +The optional \grammarterm{attribute-specifier-seq} following a \grammarterm{declarator-id} appertains to the entity that is declared. \pnum -An enumeration whose underlying type is fixed is an incomplete type from its -point of declaration\iref{basic.scope.pdecl} to immediately after its -\grammarterm{enum-base} (if any), at which point it becomes a complete type. -An enumeration whose underlying type is not fixed is an incomplete type from -its point of declaration to immediately after the closing \tcode{\}} of its -\grammarterm{enum-specifier}, at which point it becomes a complete type. +A +\tcode{static}, +\tcode{thread_local}, +\tcode{extern}, +\tcode{mutable}, +\tcode{friend}, +\tcode{inline}, +\tcode{virtual}, +\tcode{constexpr}, +or +\tcode{typedef} +specifier +or an \grammarterm{explicit-specifier} +applies directly to each \grammarterm{declarator-id} +in an \grammarterm{init-declarator-list} or \grammarterm{member-declarator-list}; +the type specified for each \grammarterm{declarator-id} depends on +both the \grammarterm{decl-specifier-seq} and its \grammarterm{declarator}. \pnum -For an enumeration whose underlying type is not fixed, -the underlying type -is an -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 -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 -underlying type is as if the enumeration had a single enumerator with +Thus, a declaration of a particular identifier has the form + +\begin{codeblock} +T D +\end{codeblock} + +where +\tcode{T} +is of the form \opt{\grammarterm{attribute-specifier-seq}} +\grammarterm{decl-specifier-seq} +and +\tcode{D} +is a declarator. +Following is a recursive procedure for determining +the type specified for the contained +\grammarterm{declarator-id} +by such a declaration. + +\pnum +First, the +\grammarterm{decl-specifier-seq} +determines a type. +In a declaration + +\begin{codeblock} +T D +\end{codeblock} + +the +\grammarterm{decl-specifier-seq} +\tcode{T} +determines the type +\tcode{T}. +\begin{example} +In the declaration + +\begin{codeblock} +int unsigned i; +\end{codeblock} + +the type specifiers +\tcode{int} +\tcode{unsigned} +determine the type +``\tcode{unsigned int}''\iref{dcl.type.simple}. +\end{example} + +\pnum +In a declaration +\opt{\grammarterm{attribute-specifier-seq}} +\tcode{T} +\tcode{D} +where +\tcode{D} +is an unadorned identifier the type of this identifier is +``\tcode{T}''. + +\pnum +In a declaration +\tcode{T} +\tcode{D} +where +\tcode{D} +has the form + +\begin{ncsimplebnf} +\terminal{(} \terminal{D1} \terminal{)} +\end{ncsimplebnf} + +the type of the contained +\grammarterm{declarator-id} +is the same as that of the contained +\grammarterm{declarator-id} +in the declaration +\begin{codeblock} +T D1 +\end{codeblock} +\indextext{declaration!parentheses in}% +Parentheses do not alter the type of the embedded +\grammarterm{declarator-id}, +but they can alter the binding of complex declarators. + +\rSec3[dcl.ptr]{Pointers}% +\indextext{declarator!pointer}% + +\pnum +In a declaration +\tcode{T} +\tcode{D} +where +\tcode{D} +has the form + +\begin{ncsimplebnf} +\terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq} \terminal{D1} +\end{ncsimplebnf} + +and the type of the identifier in the declaration +\tcode{T} +\tcode{D1} +is ``\placeholder{derived-declarator-type-list} +\tcode{T}'', +then the type of the identifier of +\tcode{D} +is ``\placeholder{derived-declarator-type-list} \grammarterm{cv-qualifier-seq} pointer to +\tcode{T}''. +\indextext{declaration!pointer}% +\indextext{declaration!constant pointer}% +The +\grammarterm{cv-qualifier}{s} +apply to the pointer and not to the object pointed to. +Similarly, the optional \grammarterm{attribute-specifier-seq}\iref{dcl.attr.grammar} appertains to the pointer and not to the object pointed to. + +\pnum +\begin{example} +The declarations +\begin{codeblock} +const int ci = 10, *pc = &ci, *const cpc = pc, **ppc; +int i, *p, *const cp = &i; +\end{codeblock} + +declare +\tcode{ci}, +a constant integer; +\tcode{pc}, +a pointer to a constant integer; +\tcode{cpc}, +a constant pointer to a constant integer; +\tcode{ppc}, +a pointer to a pointer to a constant integer; +\tcode{i}, +an integer; +\tcode{p}, +a pointer to integer; and +\tcode{cp}, +a constant pointer to integer. +The value of +\tcode{ci}, +\tcode{cpc}, +and +\tcode{cp} +cannot be changed after initialization. +The value of +\tcode{pc} +can be changed, and so can the object pointed to by +\tcode{cp}. +Examples of +some correct operations are + +\begin{codeblock} +i = ci; +*cp = ci; +pc++; +pc = cpc; +pc = p; +ppc = &pc; +\end{codeblock} + +Examples of ill-formed operations are + +\begin{codeblock} +ci = 1; // error +ci++; // error +*pc = 2; // error +cp = &ci; // error +cpc++; // error +p = pc; // error +ppc = &p; // error +\end{codeblock} + +Each is unacceptable because it would either change the value of an object declared +\tcode{const} +or allow it to be changed through a cv-unqualified pointer later, for example: + +\begin{codeblock} +*ppc = &ci; // OK, but would make \tcode{p} point to \tcode{ci} because of previous error +*p = 5; // clobber \tcode{ci} +\end{codeblock} +\end{example} + +\pnum +See also~\ref{expr.ass} and~\ref{dcl.init}. + +\pnum +\begin{note} +Forming a pointer to reference type is ill-formed; see~\ref{dcl.ref}. +Forming a function pointer type is ill-formed if the function type has +\grammarterm{cv-qualifier}{s} or a \grammarterm{ref-qualifier}; +see~\ref{dcl.fct}. +Since the address of a bit-field\iref{class.bit} cannot be taken, +a pointer can never point to a bit-field. +\end{note} + +\rSec3[dcl.ref]{References}% +\indextext{declarator!reference} + +\pnum +In a declaration +\tcode{T} +\tcode{D} +where +\tcode{D} +has either of the forms + +\begin{ncsimplebnf} +\terminal{\&} \opt{attribute-specifier-seq} \terminal{D1}\br +\terminal{\&\&} \opt{attribute-specifier-seq} \terminal{D1} +\end{ncsimplebnf} + +and the type of the identifier in the declaration +\tcode{T} +\tcode{D1} +is ``\placeholder{derived-declarator-type-list} +\tcode{T}'', +then the type of the identifier of +\tcode{D} +is ``\placeholder{derived-declarator-type-list} reference to +\tcode{T}''. +The optional \grammarterm{attribute-specifier-seq} appertains to the reference type. +Cv-qualified references are ill-formed except when the cv-qualifiers +are introduced through the use of a +\grammarterm{typedef-name}~(\ref{dcl.typedef}, \ref{temp.param}) or +\grammarterm{decltype-specifier}\iref{dcl.type.simple}, +in which case the cv-qualifiers are ignored. +\begin{example} + +\begin{codeblock} +typedef int& A; +const A aref = 3; // ill-formed; lvalue reference to non-\tcode{const} initialized with rvalue +\end{codeblock} + +The type of +\tcode{aref} +is ``lvalue reference to \tcode{int}'', +not ``lvalue reference to \tcode{const int}''. +\end{example} +\begin{note} +A reference can be thought of as a name of an object. +\end{note} +\indextext{\idxcode{void\&}}% +A declarator that specifies the type +``reference to \cv{}~\tcode{void}'' +is ill-formed. + + +\pnum +A reference type that is declared using \tcode{\&} is called an +\defn{lvalue reference}, and a reference type that +is declared using \tcode{\&\&} is called an +\defn{rvalue reference}. Lvalue references and +rvalue references are distinct types. Except where explicitly noted, they are +semantically equivalent and commonly referred to as references. + +\pnum +\indextext{declaration!reference}% +\indextext{parameter!reference}% +\begin{example} + +\begin{codeblock} +void f(double& a) { a += 3.14; } +// ... +double d = 0; +f(d); +\end{codeblock} + +declares +\tcode{a} +to be a reference parameter of +\tcode{f} +so the call +\tcode{f(d)} +will add +\tcode{3.14} +to +\tcode{d}. + +\begin{codeblock} +int v[20]; +// ... +int& g(int i) { return v[i]; } +// ... +g(3) = 7; +\end{codeblock} + +declares the function +\tcode{g()} +to return a reference to an integer so +\tcode{g(3)=7} +will assign +\tcode{7} +to the fourth element of the array +\tcode{v}. +For another example, + +\begin{codeblock} +struct link { + link* next; +}; + +link* first; + +void h(link*& p) { // \tcode{p} is a reference to pointer + p->next = first; + first = p; + p = 0; +} + +void k() { + link* q = new link; + h(q); +} +\end{codeblock} + +declares +\tcode{p} +to be a reference to a pointer to +\tcode{link} +so +\tcode{h(q)} +will leave +\tcode{q} +with the value zero. +See also~\ref{dcl.init.ref}. +\end{example} + +\pnum +It is unspecified whether or not +a reference requires storage\iref{basic.stc}. + +\pnum +\indextext{restriction!reference}% +There shall be no references to references, +no arrays of references, and no pointers to references. +\indextext{initialization!reference}% +The declaration of a reference shall contain an +\grammarterm{initializer}\iref{dcl.init.ref} +except when the declaration contains an explicit +\tcode{extern} +specifier\iref{dcl.stc}, +is a class member\iref{class.mem} declaration within a class definition, +or is the declaration of a parameter or a return type\iref{dcl.fct}; see~\ref{basic.def}. +A reference shall be initialized to refer to a valid object or function. +\begin{note} +\indextext{reference!null}% +In particular, a null reference cannot exist in a well-defined program, +because the only way to create such a reference would be to bind it to +the ``object'' obtained by indirection through a null pointer, +which causes undefined behavior. +As described in~\ref{class.bit}, a reference cannot be bound directly +to a bit-field. +\end{note} + +\pnum +\indextext{reference collapsing}% +If a \grammarterm{typedef-name}~(\ref{dcl.typedef}, \ref{temp.param}) +or a \grammarterm{decltype-specifier}\iref{dcl.type.simple} denotes a type \tcode{TR} that +is a reference to a type \tcode{T}, an attempt to create the type ``lvalue reference to \cv{}~\tcode{TR}'' +creates the type ``lvalue reference to \tcode{T}'', while an attempt to create +the type ``rvalue reference to \cv{}~\tcode{TR}'' creates the type \tcode{TR}. +\begin{note} This rule is known as reference collapsing. \end{note} +\begin{example} + +\begin{codeblock} +int i; +typedef int& LRI; +typedef int&& RRI; + +LRI& r1 = i; // \tcode{r1} has the type \tcode{int\&} +const LRI& r2 = i; // \tcode{r2} has the type \tcode{int\&} +const LRI&& r3 = i; // \tcode{r3} has the type \tcode{int\&} + +RRI& r4 = i; // \tcode{r4} has the type \tcode{int\&} +RRI&& r5 = 5; // \tcode{r5} has the type \tcode{int\&\&} + +decltype(r2)& r6 = i; // \tcode{r6} has the type \tcode{int\&} +decltype(r2)&& r7 = i; // \tcode{r7} has the type \tcode{int\&} +\end{codeblock} +\end{example} + +\pnum +\begin{note} Forming a reference to function type is ill-formed if the function +type has \grammarterm{cv-qualifier}{s} or a \grammarterm{ref-qualifier}; +see~\ref{dcl.fct}. +\end{note} + +\rSec3[dcl.mptr]{Pointers to members}% +\indextext{declarator!pointer-to-member}% +\indextext{pointer to member}% + +\pnum +In a declaration +\tcode{T} +\tcode{D} +where +\tcode{D} +has the form + +\begin{ncsimplebnf} +nested-name-specifier \terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq} \terminal{D1} +\end{ncsimplebnf} + +and the +\grammarterm{nested-name-specifier} +denotes a class, +and the type of the identifier in the declaration +\tcode{T} +\tcode{D1} +is ``\placeholder{derived-declarator-type-list} +\tcode{T}'', +then the type of the identifier of +\tcode{D} +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}\iref{dcl.attr.grammar} appertains to the +pointer-to-member. + +\pnum +\begin{example} +\begin{codeblock} +struct X { + void f(int); + int a; +}; +struct Y; + +int X::* pmi = &X::a; +void (X::* pmf)(int) = &X::f; +double X::* pmd; +char Y::* pmc; +\end{codeblock} + +declares +\tcode{pmi}, +\tcode{pmf}, +\tcode{pmd} +and +\tcode{pmc} +to be a pointer to a member of +\tcode{X} +of type +\tcode{int}, +a pointer to a member of +\tcode{X} +of type +\tcode{void(int)}, +a pointer to a member of +\tcode{X} +of type +\tcode{double} +and a pointer to a member of +\tcode{Y} +of type +\tcode{char} +respectively. +The declaration of +\tcode{pmd} +is well-formed even though +\tcode{X} +has no members of type +\tcode{double}. +Similarly, the declaration of +\tcode{pmc} +is well-formed even though +\tcode{Y} +is an incomplete type. +\tcode{pmi} +and +\tcode{pmf} +can be used like this: +\begin{codeblock} +X obj; +// ... +obj.*pmi = 7; // assign \tcode{7} to an integer member of \tcode{obj} +(obj.*pmf)(7); // call a function member of \tcode{obj} with the argument \tcode{7} +\end{codeblock} +\end{example} + +\pnum +A pointer to member shall not point to a static member +of a class\iref{class.static}, +a member with reference type, +or +``\cv{}~\tcode{void}''. + +\begin{note} +See also~\ref{expr.unary} and~\ref{expr.mptr.oper}. +The type ``pointer to member'' is distinct from the type ``pointer'', +that is, a pointer to member is declared only by the pointer-to-member +declarator syntax, and never by the pointer declarator syntax. +There is no ``reference-to-member'' type in \Cpp{}. +\end{note} + +\rSec3[dcl.array]{Arrays}% +\indextext{declarator!array} + +\pnum +In a declaration +\tcode{T} +\tcode{D} +where +\tcode{D} +has the form + +\begin{ncsimplebnf} +\terminal{D1 [} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq} +\end{ncsimplebnf} + +and the type of the identifier in the declaration +\tcode{T} +\tcode{D1} +is +``\placeholder{derived-declarator-type-list} +\tcode{T}'', +then the type of the identifier of +\tcode{D} +is an array type; if the type of the identifier of \tcode{D} +contains the \tcode{auto} \grammarterm{type-specifier}, +the program is ill-formed. +\tcode{T} +is called the array +\term{element type}; +this type shall not be a reference type, \cv{}~\tcode{void}, +or a function type. +\indextext{declaration!array}% +If the +\grammarterm{constant-expression}\iref{expr.const} +is present, it shall be a converted constant +expression of type \tcode{std::size_t} and +its value shall be greater than zero. +The constant expression specifies the +\indextext{array!bound}% +\indextext{bound, of array}% +\term{bound} +of (number of elements in) the array. +If the value of the constant expression is +\tcode{N}, +the array has +\tcode{N} +elements numbered +\tcode{0} +to +\tcode{N-1}, +and the type of the identifier of +\tcode{D} +is ``\placeholder{derived-declarator-type-list} array of +\tcode{N} +\tcode{T}''. +An object of array type contains a contiguously allocated non-empty set of +\tcode{N} +subobjects of type +\tcode{T}. +Except as noted below, if +the constant expression is omitted, the type of the identifier of +\tcode{D} +is ``\placeholder{derived-declarator-type-list} array of unknown bound of +\tcode{T}'', +an incomplete object type. +The type ``\placeholder{derived-declarator-type-list} array of +\tcode{N} +\tcode{T}'' +is a different type from the type +``\placeholder{derived-declarator-type-list} array of unknown bound of +\tcode{T}'', +see~\ref{basic.types}. +Any type of the form +``\grammarterm{cv-qualifier-seq} array of +\tcode{N} +\tcode{T}'' +is adjusted to +``array of +\tcode{N} +\grammarterm{cv-qualifier-seq} +\tcode{T}'', +and similarly for +``array of unknown bound of +\tcode{T}''. +The optional \grammarterm{attribute-specifier-seq} appertains to the array. +\begin{example} + +\begin{codeblock} +typedef int A[5], AA[2][3]; +typedef const A CA; // type is ``array of 5 \tcode{const int}'' +typedef const AA CAA; // type is ``array of 2 array of 3 \tcode{const int}'' +\end{codeblock} +\end{example} +\begin{note} +An +``array of +\tcode{N} +\grammarterm{cv-qualifier-seq} +\tcode{T}'' +has cv-qualified type; see~\ref{basic.type.qualifier}. +\end{note} + +\pnum +An array can be constructed from one of the fundamental types +(except +\tcode{void}), +from a pointer, +from a pointer to member, from a class, +from an enumeration type, +or from another array. + +\pnum +\indextext{declarator!multidimensional array}% +When several ``array of'' specifications are adjacent, a +multidimensional array +type is created; +only the first of +the constant expressions that specify the bounds +of the arrays may be omitted. +In addition to declarations in which an incomplete object type is allowed, +an array bound may be omitted in some cases in the declaration of a function +parameter\iref{dcl.fct}. +An array bound may also be omitted +when the declarator is followed by an +\grammarterm{initializer}\iref{dcl.init}, +when a declarator for a static data member is followed by a +\grammarterm{brace-or-equal-initializer}\iref{class.mem}, +or in an explicit type conversion\iref{expr.type.conv}. +In these cases, the bound is calculated from the number +\indextext{array size!default}% +of initial elements (say, +\tcode{N}) +supplied\iref{dcl.init.aggr}, +and the type of the identifier of +\tcode{D} +is ``array of +\tcode{N} +\tcode{T}''. +Furthermore, if there is a preceding declaration of the entity in the same +scope in which the bound was specified, an omitted array bound is taken to +be the same as in that earlier declaration, and similarly for the definition +of a static data member of a class. + +\pnum +\begin{example} +\begin{codeblock} +float fa[17], *afp[17]; +\end{codeblock} +declares an array of +\tcode{float} +numbers and an array of +pointers to +\tcode{float} +numbers. +\end{example} + +\pnum +\begin{example} +\begin{codeblock} +int x3d[3][5][7]; +\end{codeblock} +declares an array of three elements, +each of which is an array of five elements, +each of which is an array of seven integers. +The overall array can be viewed as a +three-dimensional array of integers, +with rank $3 \times 5 \times 7$. +Any of the expressions +\tcode{x3d}, +\tcode{x3d[i]}, +\tcode{x3d[i][j]}, +\tcode{x3d[i][j][k]} +can reasonably appear in an expression. +The expression +\tcode{x3d[i]} +is equivalent to +\tcode{*(x3d + i)}; +in that expression, +\tcode{x3d} +is subject to the array-to-pointer conversion\iref{conv.array} +and is first converted to +a pointer to a 2-dimensional +array with rank +$5 \times 7$ +that points to the first element of \tcode{x3d}. +Then \tcode{i} is added, +which on typical implementations involves multiplying +\tcode{i} by the +length of the object to which the pointer points, +which is \tcode{sizeof(int)}$ \times 5 \times 7$. +The result of the addition and indirection is +an lvalue denoting +the $\tcode{i}^\text{th}$ array element of +\tcode{x3d} +(an array of five arrays of seven integers). +If there is another subscript, +the same argument applies again, so +\tcode{x3d[i][j]} is +an lvalue denoting +the $\tcode{j}^\text{th}$ array element of +the $\tcode{i}^\text{th}$ array element of +\tcode{x3d} +(an array of seven integers), and +\tcode{x3d[i][j][k]} is +an lvalue denoting +the $\tcode{k}^\text{th}$ array element of +the $\tcode{j}^\text{th}$ array element of +the $\tcode{i}^\text{th}$ array element of +\tcode{x3d} +(an integer). +\end{example} +\begin{note} +The first subscript in the declaration helps determine +the amount of storage consumed by an array +but plays no other part in subscript calculations. +\end{note} + +\pnum +\begin{example} +\begin{codeblock} +extern int x[10]; +struct S { + static int y[10]; +}; + +int x[]; // OK: bound is 10 +int S::y[]; // OK: bound is 10 + +void f() { + extern int x[]; + int i = sizeof(x); // error: incomplete object type +} +\end{codeblock} +\end{example} + +\pnum +\begin{note} +Conversions affecting expressions of array type are described in~\ref{conv.array}. +\end{note} + +\pnum +\begin{note} +The subscript operator can be overloaded for a class\iref{over.sub}. +For the operator's built-in meaning, see \ref{expr.sub}. +\end{note} + +\rSec3[dcl.fct]{Functions}% +\indextext{declarator!function|(} + +\pnum +\indextext{type!function}% +In a declaration +\tcode{T} +\tcode{D} +where +\tcode{D} +has the form +\begin{ncsimplebnf} +\terminal{D1 (} parameter-declaration-clause \terminal{)} \opt{cv-qualifier-seq}\br +\bnfindent\opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq} +\end{ncsimplebnf} +and the type of the contained +\grammarterm{declarator-id} +in the declaration +\tcode{T} +\tcode{D1} +is +``\placeholder{derived-declarator-type-list} +\tcode{T}'', +the type of the +\grammarterm{declarator-id} +in +\tcode{D} +is +``\placeholder{derived-declarator-type-list} +\opt{\tcode{noexcept}} +function of +(\grammarterm{parameter-declaration-clause}) +\opt{\grammarterm{cv-qualifier-seq}} \opt{\grammarterm{ref-qualifier}} +returning \tcode{T}'', +where the optional \tcode{noexcept} is present +if and only if +the exception specification\iref{except.spec} is non-throwing. +The optional \grammarterm{attribute-specifier-seq} +appertains to the function type. + +\pnum +In a declaration +\tcode{T} +\tcode{D} +where +\tcode{D} +has the form + +\begin{ncsimplebnf} +\terminal{D1 (} parameter-declaration-clause \terminal{)} \opt{cv-qualifier-seq}\br +\bnfindent\opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq} trailing-return-type +\end{ncsimplebnf} + +and the type of the contained +\grammarterm{declarator-id} +in the declaration +\tcode{T} +\tcode{D1} +is +``\placeholder{derived-declarator-type-list} \tcode{T}'', +\tcode{T} shall be the single \grammarterm{type-specifier} \tcode{auto}. +The type of the +\grammarterm{declarator-id} +in +\tcode{D} +is +``\placeholder{derived-declarator-type-list} +\opt{\tcode{noexcept}} +function of +(\grammarterm{parameter-declaration-clause}) +\opt{\grammarterm{cv-qualifier-seq}} \opt{\grammarterm{ref-qualifier}} +returning \tcode{U}'', +where \tcode{U} is the type specified by +the \grammarterm{trailing-return-type}, and +where the optional \tcode{noexcept} is present if and only if +the exception specification is non-throwing. +The optional \grammarterm{attribute-specifier-seq} +appertains to the function type. + +\pnum +\indextext{type!function}% +A type of either form is a \term{function type}.\footnote{As indicated by syntax, cv-qualifiers are a significant component in function return types.} + +\indextext{declaration!function}% +\begin{bnf} +\nontermdef{parameter-declaration-clause}\br + \opt{parameter-declaration-list} \opt{\terminal{...}}\br + parameter-declaration-list \terminal{, ...} +\end{bnf} + +\begin{bnf} +\nontermdef{parameter-declaration-list}\br + parameter-declaration\br + parameter-declaration-list \terminal{,} parameter-declaration +\end{bnf} + +\begin{bnf} +\nontermdef{parameter-declaration}\br + \opt{attribute-specifier-seq} decl-specifier-seq declarator\br + \opt{attribute-specifier-seq} decl-specifier-seq declarator \terminal{=} initializer-clause\br + \opt{attribute-specifier-seq} decl-specifier-seq \opt{abstract-declarator}\br + \opt{attribute-specifier-seq} decl-specifier-seq \opt{abstract-declarator} \terminal{=} initializer-clause +\end{bnf} + +The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{parameter-declaration} +appertains to the parameter. + +\pnum +\indextext{declaration!parameter}% +The +\grammarterm{parameter-declaration-clause} +determines the arguments that can be specified, and their processing, when the function is called. +\begin{note} +\indextext{conversion!argument}% +The +\grammarterm{parameter-declaration-clause} +is used to convert the arguments specified on the function call; +see~\ref{expr.call}. +\end{note} +\indextext{argument list!empty}% +If the +\grammarterm{parameter-declaration-clause} +is empty, the function takes no arguments. +A parameter list consisting of a single unnamed parameter of +non-dependent type \tcode{void} is equivalent to an empty parameter +list. +\indextext{parameter!\idxcode{void}}% +Except for this special case, a parameter shall not have type \term{cv} +\tcode{void}. +If the +\grammarterm{parameter-declaration-clause} +\indextext{argument type!unknown}% +\indextext{\idxcode{...}|see{ellipsis}}% +\indextext{declaration!ellipsis in function}% +\indextext{argument list!variable}% +\indextext{parameter list!variable}% +terminates with an ellipsis or a function parameter +pack\iref{temp.variadic}, the number of arguments shall be equal +to or greater than the number of parameters that do not have a default +argument and are not function parameter packs. +Where syntactically correct and where ``\tcode{...}'' is not +part of an \grammarterm{abstract-declarator}, +``\tcode{, ...}'' +is synonymous with +``\tcode{...}''. +\begin{example} +The declaration + +\begin{codeblock} +int printf(const char*, ...); +\end{codeblock} + +declares a function that can be called with varying numbers and types of arguments. + +\begin{codeblock} +printf("hello world"); +printf("a=%d b=%d", a, b); +\end{codeblock} + +However, the first argument must be of a type +that can be converted to a +\tcode{const} +\tcode{char*} +\end{example} +\begin{note} +The standard header +\tcode{} +\indexhdr{cstdarg}% +contains a mechanism for accessing arguments passed using the ellipsis +(see~\ref{expr.call} and~\ref{support.runtime}). +\end{note} + +\pnum +\indextext{type!function}% +The type of a function is determined using the following rules. +The type of each parameter (including function parameter packs) is +determined from its own +\grammarterm{decl-specifier-seq} +and +\grammarterm{declarator}. +After determining the type of each parameter, any parameter +\indextext{array!parameter of type}% +of type ``array of \tcode{T}'' or +\indextext{function!parameter of type}% +of function type \tcode{T} +is adjusted to be ``pointer to \tcode{T}''. +After producing the list of parameter types, +any top-level +\grammarterm{cv-qualifier}{s} +modifying a parameter type are deleted +when forming the function type. +The resulting list of transformed parameter types +and the presence or absence of the ellipsis or a function parameter pack +is the function's +\defn{parameter-type-list}. +\begin{note} This transformation does not affect the types of the parameters. +For example, \tcode{int(*)(const int p, decltype(p)*)} and +\tcode{int(*)(int, const int*)} are identical types. \end{note} + +\pnum +A function type with a \grammarterm{cv-qualifier-seq} or a +\grammarterm{ref-qualifier} (including a type named by +\grammarterm{typedef-name}~(\ref{dcl.typedef}, \ref{temp.param})) +shall appear only as: +\begin{itemize} +\item the function type for a non-static member function, + +\item the function type to which a pointer to member refers, + +\item the top-level function type of a function typedef declaration +or \grammarterm{alias-declaration}, + +\item the \grammarterm{type-id} in the default argument of a +\grammarterm{type-parameter}\iref{temp.param}, or + +\item the \grammarterm{type-id} of a \grammarterm{template-argument} for a +\grammarterm{type-parameter}\iref{temp.arg.type}. +\end{itemize} +\begin{example} + +\begin{codeblock} +typedef int FIC(int) const; +FIC f; // ill-formed: does not declare a member function +struct S { + FIC f; // OK +}; +FIC S::*pm = &S::f; // OK +\end{codeblock} +\end{example} + +\pnum +The effect of a +\grammarterm{cv-qualifier-seq} +in a function declarator is not the same as +adding cv-qualification on top of the function type. +In the latter case, the cv-qualifiers are ignored. +\begin{note} A function type that has a \grammarterm{cv-qualifier-seq} is not a +cv-qualified type; there are no cv-qualified function types. \end{note} +\begin{example} + +\begin{codeblock} +typedef void F(); +struct S { + const F f; // OK: equivalent to: \tcode{void f();} +}; +\end{codeblock} +\end{example} + +\pnum +The return type, the parameter-type-list, the \grammarterm{ref-qualifier}, +the \grammarterm{cv-qualifier-seq}, and +the exception specification, +but not the default arguments\iref{dcl.fct.default} +or the trailing \grammarterm{requires-clause}\iref{dcl.decl}, +are part of the function type. +\begin{note} +Function types are checked during the assignments and initializations of +pointers to functions, references to functions, and pointers to member functions. +\end{note} + +\pnum +\begin{example} +The declaration + +\begin{codeblock} +int fseek(FILE*, long, int); +\end{codeblock} + +declares a function taking three arguments of the specified types, +and returning +\tcode{int}\iref{dcl.type}. +\end{example} + +\pnum +\indextext{overloading}% +A single name can be used for several different functions in a single scope; +this is function overloading\iref{over}. +All declarations for a function shall have equivalent return types, +parameter-type-lists, and \grammarterm{requires-clause}{s}\iref{temp.over.link}. + +\pnum +\indextext{function return type|see{return type}}% +\indextext{return type}% +Functions shall not have a return type of type array or function, +although they may have a return type of type pointer or reference to such things. +There shall be no arrays of functions, although there can be arrays of pointers +to functions. + +\pnum +Types shall not be defined in return or parameter types. + +\pnum +\indextext{typedef!function}% +A typedef of function type may be used to declare a function but shall not be +used to define a function\iref{dcl.fct.def}. +\begin{example} + +\begin{codeblock} +typedef void F(); +F fv; // OK: equivalent to \tcode{void fv();} +F fv { } // ill-formed +void fv() { } // OK: definition of \tcode{fv} +\end{codeblock} +\end{example} + +\pnum +An identifier can optionally be provided as a parameter name; +if present in a function definition\iref{dcl.fct.def}, it names a parameter. +\begin{note} +In particular, parameter names are also optional in function definitions +and names used for a parameter in different declarations and the definition +of a function need not be the same. +If a parameter name is present in a function declaration that is not a definition, +it cannot be used outside of +its function declarator because that is the extent of its potential scope\iref{basic.scope.param}. +\end{note} + +\pnum +\begin{example} +The declaration + +\begin{codeblock} +int i, + *pi, + f(), + *fpi(int), + (*pif)(const char*, const char*), + (*fpif(int))(int); +\end{codeblock} + +declares an integer +\tcode{i}, +a pointer +\tcode{pi} +to an integer, +a function +\tcode{f} +taking no arguments and returning an integer, +a function +\tcode{fpi} +taking an integer argument and returning a pointer to an integer, +a pointer +\tcode{pif} +to a function which +takes two pointers to constant characters and returns an integer, +a function +\tcode{fpif} +taking an integer argument and returning a pointer to a function that takes an integer argument and returns an integer. +It is especially useful to compare +\tcode{fpi} +and +\tcode{pif}. +The binding of +\tcode{*fpi(int)} +is +\tcode{*(fpi(int))}, +so the declaration suggests, +and the same construction in an expression +requires, the calling of a function +\tcode{fpi}, +and then using indirection through the (pointer) result +to yield an integer. +In the declarator +\tcode{(*pif)(const char*, const char*)}, +the extra parentheses are necessary to indicate that indirection through +a pointer to a function yields a function, which is then called. +\end{example} +\begin{note} +Typedefs and \grammarterm{trailing-return-type}{s} are sometimes convenient when the return type of a function is complex. +For example, +the function +\tcode{fpif} +above could have been declared + +\begin{codeblock} +typedef int IFUNC(int); +IFUNC* fpif(int); +\end{codeblock} + +or + +\begin{codeblock} +auto fpif(int)->int(*)(int); +\end{codeblock} + +A \grammarterm{trailing-return-type} is most useful for a type that would be more complicated to specify before the \grammarterm{declarator-id}: + +\begin{codeblock} +template auto add(T t, U u) -> decltype(t + u); +\end{codeblock} + +rather than + +\begin{codeblock} +template decltype((*(T*)0) + (*(U*)0)) add(T t, U u); +\end{codeblock} +\end{note} + +\pnum +A \term{non-template function} is a function that is not a function template +specialization. \begin{note} A function template is not a function. \end{note} + +\pnum +A \grammarterm{declarator-id} or \grammarterm{abstract-declarator} +containing an ellipsis shall only +be used in a \grammarterm{parameter-declaration}. +When it is part of a +\grammarterm{parameter-declaration-clause}, +the \grammarterm{parameter-declaration} declares a +function parameter pack\iref{temp.variadic}. +Otherwise, the \grammarterm{parameter-declaration} is part of a +\grammarterm{template-parameter-list} and declares a +template parameter pack; see~\ref{temp.param}. +A function parameter pack is a pack expansion\iref{temp.variadic}. +\begin{example} + +\begin{codeblock} +template void f(T (* ...t)(int, int)); + +int add(int, int); +float subtract(int, int); + +void g() { + f(add, subtract); +} +\end{codeblock} +\end{example} + +\pnum +There is a syntactic ambiguity when an ellipsis occurs at the end +of a \grammarterm{parameter-declaration-clause} without a preceding +comma. In this case, the ellipsis is parsed as part of the +\grammarterm{abstract-declarator} if the type of the parameter either names +a template parameter pack that has not been expanded or contains \tcode{auto}; +otherwise, it is +parsed as part of the \grammarterm{parameter-declaration-clause}.\footnote{One can explicitly disambiguate the parse either by +introducing a comma (so the ellipsis will be parsed as part of the +\grammarterm{parameter-declaration-clause}) or by introducing a name for the +parameter (so the ellipsis will be parsed as part of the +\grammarterm{declarator-id}).}% +\indextext{declarator!function|)} + +\rSec3[dcl.fct.default]{Default arguments}% +\indextext{declaration!default argument|(} + +\pnum +If an \grammarterm{initializer-clause}{} is specified in a +\grammarterm{parameter-declaration}{} this +\grammarterm{initializer-clause}{} +is used as a default argument. +\begin{note} +Default arguments will be used in calls +where trailing arguments are missing\iref{expr.call}. +\end{note} + +\pnum +\indextext{argument!example of default}% +\begin{example} +The declaration + +\begin{codeblock} +void point(int = 3, int = 4); +\end{codeblock} + +declares a function that can be called with zero, one, or two arguments of type +\tcode{int}. +It can be called in any of these ways: + +\begin{codeblock} +point(1,2); point(1); point(); +\end{codeblock} + +The last two calls are equivalent to +\tcode{point(1,4)} +and +\tcode{point(3,4)}, +respectively. +\end{example} + +\pnum +A default argument shall be specified only in the +\grammarterm{parameter-declaration-clause} +of a function declaration +or \grammarterm{lambda-declarator} +or in a +\grammarterm{template-parameter}\iref{temp.param}; +in the latter case, the \grammarterm{initializer-clause} shall be an +\grammarterm{assignment-expression}. +A default argument shall not be specified for +a template parameter pack or +a function parameter pack. +If it is specified in a +\grammarterm{parameter-declaration-clause}, +it shall not occur within a +\grammarterm{declarator} +or +\grammarterm{abstract-declarator} +of a +\grammarterm{parameter-declaration}.\footnote{This means that default +arguments cannot appear, +for example, in declarations of pointers to functions, +references to functions, or +\tcode{typedef} +declarations. +} + +\pnum +For non-template functions, default arguments can be added in later +declarations of a +function in the same scope. +Declarations in different +scopes have completely distinct sets of default arguments. +That +is, declarations in inner scopes do not acquire default +arguments from declarations in outer scopes, and vice versa. +In +a given function declaration, each parameter subsequent to a +parameter with a default argument shall have a default argument +supplied in this or a previous declaration, +unless the parameter was expanded from a parameter pack, +or shall be a function parameter pack. +A default argument +shall not be redefined by a later declaration (not even to the +same value). +\begin{example} + +\begin{codeblock} +void g(int = 0, ...); // OK, ellipsis is not a parameter so it can follow + // a parameter with a default argument +void f(int, int); +void f(int, int = 7); +void h() { + f(3); // OK, calls \tcode{f(3, 7)} + void f(int = 1, int); // error: does not use default from surrounding scope +} +void m() { + void f(int, int); // has no defaults + f(4); // error: wrong number of arguments + void f(int, int = 5); // OK + f(4); // OK, calls \tcode{f(4, 5);} + void f(int, int = 5); // error: cannot redefine, even to same value +} +void n() { + f(6); // OK, calls \tcode{f(6, 7)} +} +template struct C { + void f(int n = 0, T...); +}; +C c; // OK, instantiates declaration \tcode{void C::f(int n = 0, int)} +\end{codeblock} +\end{example} +For a given inline function defined in different translation units, +the accumulated sets of default arguments at the end of the +translation units shall be the same; +see~\ref{basic.def.odr}. +If a friend declaration specifies a default argument expression, +that declaration shall be a definition and shall be the only +declaration of the function or function template in the translation unit. + +\pnum +\indextext{argument!type checking of default}% +\indextext{argument!binding of default}% +\indextext{argument!evaluation of default}% +The default argument has the +same semantic constraints as the initializer in a +declaration of a variable of the parameter type, using the +copy-initialization semantics\iref{dcl.init}. +The names in the +default argument are bound, and the semantic constraints are checked, +at the point where the default argument appears. +Name lookup and checking of semantic constraints for default +arguments in function templates and in member functions of +class templates are performed as described in~\ref{temp.inst}. +\begin{example} +In the following code, +\indextext{argument!example of default}% +\tcode{g} +will be called with the value +\tcode{f(2)}: + +\begin{codeblock} +int a = 1; +int f(int); +int g(int x = f(a)); // default argument: \tcode{f(::a)} + +void h() { + a = 2; + { + int a = 3; + g(); // \tcode{g(f(::a))} + } +} +\end{codeblock} +\end{example} +\begin{note} +In member function declarations, +names in default arguments are looked up +as described in~\ref{basic.lookup.unqual}. +Access checking applies to names in default arguments as +described in \ref{class.access}. +\end{note} + +\pnum +Except for member functions of class templates, the +default arguments in a member function definition that appears +outside of the class definition +are added to the set of default arguments provided by the +member function declaration in the class definition; +the program is ill-formed if a default constructor\iref{class.ctor}, +copy or move constructor\iref{class.copy.ctor}, or +copy or move assignment operator\iref{class.copy.assign} +is so declared. +Default arguments for a member function of a class template +shall be specified on the initial declaration of the member +function within the class template. +\begin{example} +\begin{codeblock} +class C { + void f(int i = 3); + void g(int i, int j = 99); +}; + +void C::f(int i = 3) {} // error: default argument already specified in class scope +void C::g(int i = 88, int j) {} // in this translation unit, \tcode{C::g} can be called with no argument +\end{codeblock} +\end{example} + +\pnum +\begin{note} +A local variable cannot be odr-used\iref{basic.def.odr} +in a default argument. +\end{note} +\begin{example} +\begin{codeblock} +void f() { + int i; + extern void g(int x = i); // error + extern void h(int x = sizeof(i)); // OK + // ... +} +\end{codeblock} +\end{example} + +\pnum +\begin{note} +The keyword +\tcode{this} +may not appear in a default argument of a member function; +see~\ref{expr.prim.this}. +\begin{example} + +\begin{codeblock} +class A { + void f(A* p = this) { } // error +}; +\end{codeblock} +\end{example} +\end{note} + +\pnum +\indextext{argument!evaluation of default}% +A default argument is evaluated each time the function is called +with no argument for the corresponding parameter. +\indextext{argument!scope of default}% +A parameter shall not appear as a potentially-evaluated expression +in a default argument. +\indextext{argument and name hiding!default}% +Parameters of a function declared before a default argument +are in scope and can hide namespace and class member names. +\begin{example} +\begin{codeblock} +int a; +int f(int a, int b = a); // error: parameter \tcode{a} used as default argument +typedef int I; +int g(float I, int b = I(2)); // error: parameter \tcode{I} found +int h(int a, int b = sizeof(a)); // OK, unevaluated operand +\end{codeblock} +\end{example} +A non-static member shall not appear in a default argument unless it appears as +the \grammarterm{id-expression} of a class member access expression\iref{expr.ref} or +unless it is used to form a pointer to member\iref{expr.unary.op}. +\begin{example} +The declaration of +\tcode{X::mem1()} +in the following example is ill-formed because no object is supplied for the +non-static member +\tcode{X::a} +used as an initializer. +\begin{codeblock} +int b; +class X { + int a; + int mem1(int i = a); // error: non-static member \tcode{a} used as default argument + int mem2(int i = b); // OK; use \tcode{X::b} + static int b; +}; +\end{codeblock} +The declaration of +\tcode{X::mem2()} +is meaningful, however, since no object is needed to access the static member +\tcode{X::b}. +Classes, objects, and members are described in \ref{class}. +\end{example} +A default argument is not part of the +type of a function. +\begin{example} +\begin{codeblock} +int f(int = 0); + +void h() { + int j = f(1); + int k = f(); // OK, means \tcode{f(0)} +} + +int (*p1)(int) = &f; +int (*p2)() = &f; // error: type mismatch +\end{codeblock} +\end{example} +When a declaration of a function is introduced by way of a +\grammarterm{using-declaration}\iref{namespace.udecl}, +any default argument information associated +with the declaration is made known as well. +If the function is redeclared +thereafter in the namespace with additional default arguments, +the additional arguments are also known at any point following +the redeclaration where the +\grammarterm{using-declaration} +is in scope. + +\pnum +\indextext{argument and virtual function!default}% +A virtual function call\iref{class.virtual} uses the default +arguments in the declaration of the virtual function determined +by the static type of the pointer or reference denoting the +object. +An overriding function in a derived class does not +acquire default arguments from the function it overrides. +\begin{example} + +\begin{codeblock} +struct A { + virtual void f(int a = 7); +}; +struct B : public A { + void f(int a); +}; +void m() { + B* pb = new B; + A* pa = pb; + pa->f(); // OK, calls \tcode{pa->B::f(7)} + pb->f(); // error: wrong number of arguments for \tcode{B::f()} +} +\end{codeblock} +\end{example}% +\indextext{declaration!default argument|)}% +\indextext{declarator!meaning of|)} + +\rSec1[dcl.init]{Initializers}% +\indextext{initialization|(} + +\pnum +The process of initialization described in this subclause applies to +all initializations regardless of syntactic context, including the +initialization of a function parameter\iref{expr.call}, the +initialization of a return value\iref{stmt.return}, or when an +initializer follows a declarator. + +\begin{bnf} +\nontermdef{initializer}\br + brace-or-equal-initializer\br + \terminal{(} expression-list \terminal{)} +\end{bnf} + +\begin{bnf} +\nontermdef{brace-or-equal-initializer}\br + \terminal{=} initializer-clause\br + braced-init-list +\end{bnf} + +\begin{bnf} +\nontermdef{initializer-clause}\br + assignment-expression\br + braced-init-list +\end{bnf} + +\begin{bnf} +\nontermdef{braced-init-list}\br + \terminal{\{} initializer-list \opt{\terminal{,}} \terminal{\}}\br + \terminal{\{} designated-initializer-list \opt{\terminal{,}} \terminal{\}}\br + \terminal{\{} \terminal{\}} +\end{bnf} + +\begin{bnf} +\nontermdef{initializer-list}\br + initializer-clause \opt{\terminal{...}}\br + initializer-list \terminal{,} initializer-clause \opt{\terminal{...}} +\end{bnf} + +\begin{bnf} +\nontermdef{designated-initializer-list}\br + designated-initializer-clause\br + designated-initializer-list \terminal{,} designated-initializer-clause +\end{bnf} + +\begin{bnf} +\nontermdef{designated-initializer-clause}\br + designator brace-or-equal-initializer +\end{bnf} + +\begin{bnf} +\nontermdef{designator}\br + \terminal{.} identifier +\end{bnf} + +\begin{bnf} +\nontermdef{expr-or-braced-init-list}\br + expression\br + braced-init-list +\end{bnf} + +\begin{note} +The rules in this subclause apply even if the grammar permits only +the \grammarterm{brace-or-equal-initializer} form +of \grammarterm{initializer} in a given context. +\end{note} + +\pnum +Except for objects declared with the \tcode{constexpr} specifier, for which see~\ref{dcl.constexpr}, +an \grammarterm{initializer} in the definition of a variable can consist of +arbitrary +\indextext{initialization!automatic object}% +\indextext{initialization!static object@\tcode{static} object}% +expressions involving literals and previously declared +variables and functions, +regardless of the variable's storage duration. +\begin{example} + +\begin{codeblock} +int f(int); +int a = 2; +int b = f(a); +int c(b); +\end{codeblock} +\end{example} + +\pnum +\begin{note} +Default arguments are more restricted; see~\ref{dcl.fct.default}. +\end{note} + +\pnum +\begin{note} +The order of initialization of variables with static storage duration is described in~\ref{basic.start} +and~\ref{stmt.dcl}. +\end{note} + +\pnum +A declaration of a block-scope variable with external or internal +linkage that has an \grammarterm{initializer} is ill-formed. + +\pnum +\indextext{initialization!static object@\tcode{static} object}% +\indextext{initialization!default}% +\indextext{variable!indeterminate uninitialized}% +\indextext{initialization!zero-initialization}% +To +\defnx{zero-initialize}{zero-initialization} +an object or reference of type +\tcode{T} +means: + +\begin{itemize} +\item +if +\tcode{T} +is a scalar type\iref{basic.types}, the +object +is initialized to the value obtained by converting the integer literal \tcode{0} +(zero) to +\tcode{T};\footnote{As specified in~\ref{conv.ptr}, converting an integer +literal whose value is +\tcode{0} +to a pointer type results in a null pointer value. +} + +\item +if +\tcode{T} +is a (possibly cv-qualified) non-union class type, +its padding bits\iref{basic.types} are initialized to zero bits and +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; + +\item +if +\tcode{T} +is a (possibly cv-qualified) union type, +its padding bits\iref{basic.types} are initialized to zero bits and +the +object's first non-static named +data member +is zero-initialized; + +\item +if +\tcode{T} +is an array type, +each element is zero-initialized; +\item +if +\tcode{T} +is a reference type, no initialization is performed. +\end{itemize} + +\pnum +To +\defnx{default-initialize}{default-initialization} +an object of type +\tcode{T} +means: + +\begin{itemize} +\item +If +\tcode{T} +is a (possibly cv-qualified) class type\iref{class}, +constructors are considered. The applicable constructors are +enumerated\iref{over.match.ctor}, and the best one for the +\grammarterm{initializer} \tcode{()} is chosen through +overload resolution\iref{over.match}. The constructor thus selected +is called, with an empty argument list, to initialize the object. + +\item +If +\tcode{T} +is an array type, each element is default-initialized. + +\item +Otherwise, +no initialization is performed. +\end{itemize} + +A class type \tcode{T} is \defn{const-default-constructible} if +default-initialization of \tcode{T} would invoke +a user-provided constructor of \tcode{T} (not inherited from a base class) +or if + +\begin{itemize} +\item +each direct non-variant non-static data member \tcode{M} of \tcode{T} +has a default member initializer +or, if \tcode{M} is of class type \tcode{X} (or array thereof), +\tcode{X} is const-default-constructible, +\item +if \tcode{T} is a union with at least one non-static data member, +exactly one variant member has a default member initializer, +\item +if \tcode{T} is not a union, +for each anonymous union member with at least one non-static data member (if any), +exactly one non-static data member has a default member initializer, and +\item +each potentially constructed base class of \tcode{T} is const-default-constructible. +\end{itemize} + +If a program calls for the default-initialization of an object of a +const-qualified type \tcode{T}, +\tcode{T} shall be a const-default-constructible class type or array thereof. + +\pnum +To +\defnx{value-initialize}{value-initialization} +an object of type +\tcode{T} +means: + +\begin{itemize} +\item +if +\tcode{T} +is a (possibly cv-qualified) class type\iref{class} with +either no default constructor\iref{class.ctor} or a default +constructor that is user-provided or deleted, then the object is default-initialized; + +\item +if +\tcode{T} +is a (possibly cv-qualified) class type without a +user-provided or deleted default constructor, +then the object is zero-initialized and the semantic constraints for +default-initialization are checked, and if \tcode{T} has a +non-trivial default constructor, the object is default-initialized; + +\item +if +\tcode{T} +is an array type, then each element is value-initialized; + +\item +otherwise, the object is zero-initialized. +\end{itemize} + +\pnum +A program that calls for default-initialization +or value-initialization +of an entity +of reference type is ill-formed. + +\pnum +\begin{note} Every +object of static storage duration is +zero-initialized at program startup before any other initialization +takes place. +In some cases, additional initialization is done later. +\end{note} + +\pnum +An object whose initializer is an empty set of parentheses, i.e., +\tcode{()}, +shall be +value-initialized. + +\indextext{ambiguity!function declaration}% +\begin{note} +Since +\tcode{()} +is not permitted by the syntax for +\grammarterm{initializer}, + +\begin{codeblock} +X a(); +\end{codeblock} + +is not the declaration of an object of class +\tcode{X}, +but the declaration of a function taking no argument and returning an +\tcode{X}. +The form +\tcode{()} +is permitted in certain other initialization contexts~(\ref{expr.new}, +\ref{expr.type.conv}, \ref{class.base.init}). +\end{note} + +\pnum +\indextext{value!indeterminate}% +\indextext{indeterminate value}% +If no initializer is specified for an object, the object is default-initialized. +When storage for an object with automatic or dynamic storage duration +is obtained, the object has an \term{indeterminate value}, and if +no initialization is performed for the object, that object retains an +indeterminate value until that value is replaced\iref{expr.ass}. +\begin{note} Objects with static or thread storage duration are zero-initialized, +see~\ref{basic.start.static}. \end{note} +If an indeterminate value is produced by an evaluation, the behavior is +undefined except in the following cases: + +\begin{itemize} +\item +If an indeterminate value of +unsigned narrow character type\iref{basic.fundamental} +or \tcode{std::byte} type\iref{cstddef.syn} +is produced by the evaluation of: +\begin{itemize} +\item the second or third operand of a conditional expression\iref{expr.cond}, +\item the right operand of a comma expression\iref{expr.comma}, +\item the operand of a cast or conversion~(\ref{conv.integral}, +\ref{expr.type.conv}, \ref{expr.static.cast}, \ref{expr.cast}) to an +unsigned narrow character type +or \tcode{std::byte} type\iref{cstddef.syn}, or +\item a discarded-value expression\iref{expr.prop}, +\end{itemize} +then the result of the operation is 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 right +operand of a simple assignment operator\iref{expr.ass} whose first operand +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 +If an indeterminate value of unsigned narrow character type is produced by the +evaluation of the initialization expression when initializing an object of +unsigned narrow character type, that object is initialized to an indeterminate +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} + int f(bool b) { + unsigned char c; + unsigned char d = c; // OK, \tcode{d} has an indeterminate value + int e = d; // undefined behavior + return b ? d : 0; // undefined behavior if \tcode{b} is \tcode{true} + } +\end{codeblock} +\end{example} + +\pnum +\indextext{initialization!class member}% +An initializer for a static member is in the scope of the member's class. +\begin{example} +\begin{codeblock} +int a; + +struct X { + static int a; + static int b; +}; + +int X::a = 1; +int X::b = a; // \tcode{X::b = X::a} +\end{codeblock} +\end{example} + +\pnum +If the entity being initialized does not have class type, the +\grammarterm{expression-list} in a +parenthesized initializer shall be a single expression. + +\pnum +\indextext{initialization!copy}% +\indextext{initialization!direct}% +The initialization that occurs in the \tcode{=} form of a +\grammarterm{brace-or-equal-initializer} or +\grammarterm{condition}\iref{stmt.select}, +as well as in argument passing, function return, +throwing an exception\iref{except.throw}, +handling an exception\iref{except.handle}, +and aggregate member initialization\iref{dcl.init.aggr}, +is called +\defn{copy-initialization}. +\begin{note} +Copy-initialization may invoke a move\iref{class.copy.ctor}. +\end{note} + +\pnum +The initialization that occurs +\begin{itemize} +\item for an \grammarterm{initializer} that is a +parenthesized \grammarterm{expression-list} or a \grammarterm{braced-init-list}, +\item for a \grammarterm{new-initializer}\iref{expr.new}, +\item in a \tcode{static_cast} expression\iref{expr.static.cast}, +\item in a functional notation type conversion\iref{expr.type.conv}, and +\item in the \grammarterm{braced-init-list} form of a \grammarterm{condition} +\end{itemize} +is called +\defn{direct-initialization}. + +\pnum +The semantics of initializers are as follows. +The +\indextext{type!destination}% +\term{destination type} +is the type of the object or reference being initialized and the +\term{source type} +is the type of the initializer expression. +If the initializer is not a single (possibly parenthesized) expression, the +source type is not defined. +\begin{itemize} +\item +If the initializer is a (non-parenthesized) \grammarterm{braced-init-list} +or is \tcode{=} \grammarterm{braced-init-list}, the object or reference +is list-initialized\iref{dcl.init.list}. +\item +If the destination type is a reference type, see~\ref{dcl.init.ref}. +\item +If the destination type is an array of characters, +an array of \tcode{char16_t}, +an array of \tcode{char32_t}, +or an array of +\tcode{wchar_t}, +and the initializer is a string literal, see~\ref{dcl.init.string}. +\item If the initializer is \tcode{()}, the object is value-initialized. +\item +Otherwise, if the destination type is an array, the program is ill-formed. +\item +If the destination type is a (possibly cv-qualified) class type: + +\begin{itemize} +\item +If the initializer expression is a prvalue +and the cv-unqualified version of the source type +is the same class as the class of the destination, +the initializer expression is used to initialize the destination object. +\begin{example} +\tcode{T x = T(T(T()));} calls the \tcode{T} default constructor to initialize \tcode{x}. +\end{example} +\item +Otherwise, if the initialization is direct-initialization, +or if it is copy-initialization where the cv-unqualified version of the source +type is the same class as, or a derived class of, the class of the destination, +constructors are considered. +The applicable constructors +are enumerated\iref{over.match.ctor}, and the best one is chosen +through overload resolution\iref{over.match}. +The constructor so selected +is called to initialize the object, with the initializer +expression or \grammarterm{expression-list} as its argument(s). +If no constructor applies, or the overload resolution is +ambiguous, the initialization is ill-formed. +\item +Otherwise (i.e., for the remaining copy-initialization cases), +user-defined conversion sequences that can convert from the +source type to the destination type or (when a conversion function +is used) to a derived class thereof are enumerated as described in~\ref{over.match.copy}, and the best one is chosen through overload +resolution\iref{over.match}. If the conversion cannot be done or +is ambiguous, the initialization is ill-formed. The function +selected is called with the initializer expression as its +argument; if the function is a constructor, the call is a prvalue +of the cv-unqualified version of the +destination type whose result object is initialized by the constructor. +The call is used +to direct-initialize, according to the rules above, the object +that is the destination of the copy-initialization. +\end{itemize} + +\item +Otherwise, if the source type +is a (possibly cv-qualified) class type, conversion functions are +considered. +The applicable conversion functions are enumerated\iref{over.match.conv}, +and the best one is chosen through overload +resolution\iref{over.match}. +The user-defined conversion so selected +is called to convert the initializer expression into the +object being initialized. +If the conversion cannot be done or is +ambiguous, the initialization is ill-formed. +\item +Otherwise, the initial value of the object being initialized is +the (possibly converted) value of the initializer expression. +Standard conversions\iref{conv} will be used, if necessary, +to convert the initializer expression to the cv-unqualified version of +the destination type; +no user-defined conversions are considered. +If the conversion cannot +be done, the initialization is ill-formed. +When initializing a bit-field with a value that it cannot represent, the +resulting value of the bit-field is +\impldefplain{value of bit-field that cannot represent!initializer}. +\indextext{initialization!\idxcode{const}}% +\begin{note} +An expression of type +``\cvqual{cv1} \tcode{T}'' +can initialize an object of type +``\cvqual{cv2} \tcode{T}'' +independently of +the cv-qualifiers +\cvqual{cv1} +and \cvqual{cv2}. + +\begin{codeblock} +int a; +const int b = a; +int c = b; +\end{codeblock} +\end{note} +\end{itemize} + +\pnum +An \grammarterm{initializer-clause} followed by an ellipsis is a +pack expansion\iref{temp.variadic}. + +\pnum +If the initializer is a parenthesized \grammarterm{expression-list}, +the expressions are evaluated in the order +specified for function calls\iref{expr.call}. + +\pnum +The same \grammarterm{identifier} +shall not appear in multiple \grammarterm{designator}{s} of a +\grammarterm{designated-initializer-list}. + +\pnum +An object whose initialization has completed +is deemed to be constructed, +even if no constructor of the object's class +is invoked for the initialization. +\begin{note} +Such an object might have been value-initialized +or initialized by aggregate initialization\iref{dcl.init.aggr} +or by an inherited constructor\iref{class.inhctor.init}. +\end{note} + +\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\iref{basic.def} of the variable, +but the initializing declaration +of a non-inline static data member\iref{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}% +\indextext{aggregate initialization}% +\indextext{initialization!array}% +\indextext{initialization!class object}% +\indextext{class object initialization|see{constructor}}% +\indextext{\idxcode{\{\}}!initializer list} + +\pnum +An \defn{aggregate} is an array or a class\iref{class} with +\begin{itemize} +\item +no user-declared or inherited constructors\iref{class.ctor}, +\item +no private or protected non-static data members\iref{class.access}, +\item +no virtual functions\iref{class.virtual}, and +\item +no virtual, private, or protected base classes\iref{class.mi}. +\end{itemize} +\begin{note} +Aggregate initialization does not allow accessing +protected and private base class' members or constructors. +\end{note} + +\pnum +The \defnx{elements}{aggregate!elements} of an aggregate are: +\begin{itemize} +\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\iref{class.mem} +that are not members of an anonymous union, in declaration order. +\end{itemize} + +\pnum +When an aggregate is initialized by an initializer list +as specified in~\ref{dcl.init.list}, +the elements of the initializer list are taken as initializers +for the elements of the aggregate. +The \defnx{explicitly initialized elements}{explicitly initialized elements!aggregate} +of the aggregate are determined as follows: +\begin{itemize} +\item +If the initializer list is a \grammarterm{designated-initializer-list}, +the aggregate shall be of class type, +the \grammarterm{identifier} in each \grammarterm{designator} +shall name a direct non-static data member of the class, and +the explicitly initialized elements of the aggregate +are the elements that are, or contain, those members. +\item +If the initializer list is an \grammarterm{initializer-list}, +the explicitly initialized elements of the aggregate +are the first $n$ elements of the aggregate, +where $n$ is the number of elements in the initializer list. +\item +Otherwise, the initializer list must be \tcode{\{\}}, +and there are no explicitly initialized elements. +\end{itemize} + +\pnum +For each explicitly initialized element: +\begin{itemize} +\item +If the element is an anonymous union object and +the initializer list is a \grammarterm{designated-initializer-list}, +the anonymous union object is initialized by the +\grammarterm{designated-initializer-list} \tcode{\{ }\placeholder{D}\tcode{ \}}, +where \placeholder{D} is the \grammarterm{designated-initializer-clause} +naming a member of the anonymous union object. +There shall be only one such \grammarterm{designated-initializer-clause}. +\item +Otherwise, the element is copy-initialized +from the corresponding \grammarterm{initializer-clause} +or is initialized with the \grammarterm{brace-or-equal-initializer} +of the corresponding \grammarterm{designated-initializer-clause}. +If that initializer is of the form +\grammarterm{assignment-expression} or +\tcode{= }\grammarterm{assignment-expression} +and +a narrowing conversion\iref{dcl.init.list} is required +to convert the expression, the program is ill-formed. +\begin{note} If an initializer is itself an initializer list, +the element is list-initialized, which will result in a recursive application +of the rules in this subclause if the element is an aggregate. \end{note} +\end{itemize} +\begin{example} +\begin{codeblock} +struct A { + int x; + struct B { + int i; + int j; + } b; +} a = { 1, { 2, 3 } }; +\end{codeblock} +initializes +\tcode{a.x} +with 1, +\tcode{a.b.i} +with 2, +\tcode{a.b.j} +with 3. + +\begin{codeblock} +struct base1 { int b1, b2 = 42; }; +struct base2 { + base2() { + b3 = 42; + } + int b3; +}; +struct derived : base1, base2 { + int d; +}; + +derived d1{{1, 2}, {}, 4}; +derived d2{{}, {}, 4}; +\end{codeblock} +initializes +\tcode{d1.b1} with 1, +\tcode{d1.b2} with 2, +\tcode{d1.b3} with 42, +\tcode{d1.d} with 4, and +\tcode{d2.b1} with 0, +\tcode{d2.b2} with 42, +\tcode{d2.b3} with 42, +\tcode{d2.d} with 4. +\end{example} + +\pnum +For a non-union aggregate, +each element that is not an explicitly initialized element +is initialized as follows: +\begin{itemize} +\item +If the element has a default member initializer\iref{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\iref{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} +struct S { int a; const char* b; int c; int d = b[a]; }; +S ss = { 1, "asdf" }; +\end{codeblock} + +initializes +\tcode{ss.a} +with 1, +\tcode{ss.b} +with \tcode{"asdf"}, +\tcode{ss.c} +with the value of an expression of the form +\tcode{int\{\}} +(that is, \tcode{0}), and \tcode{ss.d} with the value of \tcode{ss.b[ss.a]} +(that is, \tcode{'s'}), and in + +\begin{codeblock} +struct X { int i, j, k = 42; }; +X a[] = { 1, 2, 3, 4, 5, 6 }; +X b[2] = { { 1, 2, 3 }, { 4, 5, 6 } }; +\end{codeblock} + +\tcode{a} and \tcode{b} have the same value + +\begin{codeblock} +struct A { + string a; + int b = 42; + int c = -1; +}; +\end{codeblock} + +\tcode{A\{.c=21\}} has the following steps: +\begin{itemize} +\item Initialize \tcode{a} with \tcode{\{\}} +\item Initialize \tcode{b} with \tcode{= 42} +\item Initialize \tcode{c} with \tcode{= 21} +\end{itemize} +\end{example} + +\pnum +The initializations of the elements of the aggregate +are evaluated in the element order. +That is, +all value computations and side effects associated with a given element +are sequenced before +those of any element that follows it in order. + +\pnum +An aggregate that is a class can also be initialized with a single +expression not enclosed in braces, as described in~\ref{dcl.init}. + +\pnum +The destructor for each element of class type +is potentially invoked\iref{class.dtor} +from the context where the aggregate initialization occurs. +\begin{note} +This provision ensures that destructors can be called +for fully-constructed subobjects +in case an exception is thrown\iref{except.ctor}. +\end{note} + +\pnum +An array of unknown bound initialized with a +brace-enclosed +\grammarterm{initializer-list} +containing +\tcode{n} +\grammarterm{initializer-clause}{s}, +where +\tcode{n} +shall be greater than zero, is defined as having +\tcode{n} +elements\iref{dcl.array}. +\begin{example} + +\begin{codeblock} +int x[] = { 1, 3, 5 }; +\end{codeblock} + +declares and initializes +\tcode{x} +as a one-dimensional array that has three elements +since no size was specified and there are three initializers. +\end{example} +An empty initializer list +\tcode{\{\}} +shall not be used as the \grammarterm{initializer-clause} +for an array of unknown bound.\footnote{The syntax provides for empty +\grammarterm{initializer-list}{s}, +but nonetheless \Cpp{} does not have zero length arrays.} +\begin{note} +A default member initializer does not determine the bound for a member +array of unknown bound. Since the default member initializer is +ignored if a suitable \grammarterm{mem-initializer} is present\iref{class.base.init}, +the default member initializer is not +considered to initialize the array of unknown bound. +\begin{example} +\begin{codeblock} +struct S { + int y[] = { 0 }; // error: non-static data member of incomplete type +}; +\end{codeblock} +\end{example} +\end{note} + +\pnum +\begin{note} +Static data members, +non-static data members of anonymous union members, +and +unnamed bit-fields +are not considered elements of the aggregate. +\begin{example} + +\begin{codeblock} +struct A { + int i; + static int s; + int j; + int :17; + int k; +} a = { 1, 2, 3 }; +\end{codeblock} + +Here, the second initializer 2 initializes +\tcode{a.j} +and not the static data member +\tcode{A::s}, and the third initializer 3 initializes \tcode{a.k} +and not the unnamed bit-field before it. +\end{example} +\end{note} + +\pnum +An +\grammarterm{initializer-list} +is ill-formed if the number of +\grammarterm{initializer-clause}{s} +exceeds the number of elements of the aggregate. +\begin{example} + +\begin{codeblock} +char cv[4] = { 'a', 's', 'd', 'f', 0 }; // error +\end{codeblock} + +is ill-formed. +\end{example} + +\pnum +If a reference member is initialized from its default member initializer +and a potentially-evaluated subexpression thereof is an aggregate +initialization that would use that default member initializer, +the program is ill-formed. +\begin{example} +\begin{codeblock} + struct A; + extern A a; + struct A { + const A& a1 { A{a,a} }; // OK + const A& a2 { A{} }; // error + }; + A a{a,a}; // OK +\end{codeblock} +\end{example} + +\pnum +If an aggregate class \tcode{C} contains a subaggregate element +\tcode{e} with no elements, +the \grammarterm{initializer-clause} for \tcode{e} shall not be +omitted from an \grammarterm{initializer-list} for an object of type +\tcode{C} unless the \grammarterm{initializer-clause}{s} for all +elements of \tcode{C} following \tcode{e} are also omitted. +\begin{example} +\begin{codeblock} +struct S { } s; +struct A { + S s1; + int i1; + S s2; + int i2; + S s3; + int i3; +} a = { + { }, // Required initialization + 0, + s, // Required initialization + 0 +}; // Initialization not required for \tcode{A::s3} because \tcode{A::i3} is also not initialized +\end{codeblock} +\end{example} + +\pnum +When initializing a multi-dimensional array, +the +\grammarterm{initializer-clause}{s} +initialize the elements with the last (rightmost) index of the array +varying the fastest\iref{dcl.array}. +\begin{example} + +\begin{codeblock} +int x[2][2] = { 3, 1, 4, 2 }; +\end{codeblock} + +initializes +\tcode{x[0][0]} +to +\tcode{3}, +\tcode{x[0][1]} +to +\tcode{1}, +\tcode{x[1][0]} +to +\tcode{4}, +and +\tcode{x[1][1]} +to +\tcode{2}. +On the other hand, + +\begin{codeblock} +float y[4][3] = { + { 1 }, { 2 }, { 3 }, { 4 } +}; +\end{codeblock} + +initializes the first column of +\tcode{y} +(regarded as a two-dimensional array) +and leaves the rest zero. +\end{example} + +\pnum +Braces can be elided in an +\grammarterm{initializer-list} +as follows. +If the +\grammarterm{initializer-list} +begins with a left brace, +then the succeeding comma-separated list of +\grammarterm{initializer-clause}{s} +initializes the elements of a subaggregate; +it is erroneous for there to be more +\grammarterm{initializer-clause}{s} +than elements. +If, however, the +\grammarterm{initializer-list} +for a subaggregate does not begin with a left brace, +then only enough +\grammarterm{initializer-clause}{s} +from the list are taken to initialize the elements of the subaggregate; +any remaining +\grammarterm{initializer-clause}{s} +are left to initialize the next element of the aggregate +of which the current subaggregate is an element. +\begin{example} + +\begin{codeblock} +float y[4][3] = { + { 1, 3, 5 }, + { 2, 4, 6 }, + { 3, 5, 7 }, +}; +\end{codeblock} + +is a completely-braced initialization: +1, 3, and 5 initialize the first row of the array +\tcode{y[0]}, +namely +\tcode{y[0][0]}, +\tcode{y[0][1]}, +and +\tcode{y[0][2]}. +Likewise the next two lines initialize +\tcode{y[1]} +and +\tcode{y[2]}. +The initializer ends early and therefore +\tcode{y[3]}s +elements are initialized as if explicitly initialized with an +expression of the form +\tcode{float()}, +that is, are initialized with +\tcode{0.0}. +In the following example, braces in the +\grammarterm{initializer-list} +are elided; +however the +\grammarterm{initializer-list} +has the same effect as the completely-braced +\grammarterm{initializer-list} +of the above example, + +\begin{codeblock} +float y[4][3] = { + 1, 3, 5, 2, 4, 6, 3, 5, 7 +}; +\end{codeblock} + +The initializer for +\tcode{y} +begins with a left brace, but the one for +\tcode{y[0]} +does not, +therefore three elements from the list are used. +Likewise the next three are taken successively for +\tcode{y[1]} +and +\tcode{y[2]}. +\end{example} + +\pnum +All implicit type conversions\iref{conv} are considered when +initializing the element with an \grammarterm{assignment-expression}. +If the +\grammarterm{assignment-expression} +can initialize an element, the element is initialized. +Otherwise, if the element is itself a subaggregate, +brace elision is assumed and the +\grammarterm{assignment-expression} +is considered for the initialization of the first element of the subaggregate. +\begin{note} As specified above, brace elision cannot apply to +subaggregates with no elements; an +\grammarterm{initializer-clause} for the entire subobject is +required.\end{note} + +\begin{example} + +\begin{codeblock} +struct A { + int i; + operator int(); +}; +struct B { + A a1, a2; + int z; +}; +A a; +B b = { 4, a, a }; +\end{codeblock} + +Braces are elided around the +\grammarterm{initializer-clause} +for +\tcode{b.a1.i}. +\tcode{b.a1.i} +is initialized with 4, +\tcode{b.a2} +is initialized with +\tcode{a}, +\tcode{b.z} +is initialized with whatever +\tcode{a.operator int()} +returns. +\end{example} + +\pnum +\indextext{initialization!array of class objects}% +\begin{note} +An aggregate array or an aggregate class may contain elements of a +class type with a user-declared constructor\iref{class.ctor}. +Initialization of these aggregate objects is described in~\ref{class.expl.init}. +\end{note} + +\pnum +\begin{note} +Whether the initialization of aggregates with static storage duration +is static or dynamic is specified +in~\ref{basic.start.static}, \ref{basic.start.dynamic}, and~\ref{stmt.dcl}. +\end{note} + +\pnum +\indextext{initialization!\idxcode{union}}% +When a union is initialized with an initializer list, +there shall not be more than one +explicitly initialized element. +\begin{example} +\begin{codeblock} +union u { int a; const char* b; }; +u a = { 1 }; +u b = a; +u c = 1; // error +u d = { 0, "asdf" }; // error +u e = { "asdf" }; // error +u f = { .b = "asdf" }; +u g = { .a = 1, .b = "asdf" }; // error +\end{codeblock} +\end{example} + +\pnum +\begin{note} +As described above, +the braces around the +\grammarterm{initializer-clause} +for a union member can be omitted if the +union is a member of another aggregate. +\end{note} + +\rSec2[dcl.init.string]{Character arrays}% +\indextext{initialization!character array} + +\pnum +An array of narrow character type\iref{basic.fundamental}, +\tcode{char16_t} array, +\tcode{char32_t} array, +or \tcode{wchar_t} array +can be initialized by a +narrow string literal, \tcode{char16_t} string literal, \tcode{char32_t} string +literal, or wide string literal, +respectively, or by an appropriately-typed string literal enclosed in +braces\iref{lex.string}. +\indextext{initialization!character array}% +Successive +characters of the +value of the string literal +initialize the elements of the array. +\begin{example} + +\begin{codeblock} +char msg[] = "Syntax error on line %s\n"; +\end{codeblock} + +shows a character array whose members are initialized +with a +\grammarterm{string-literal}. +Note that because +\tcode{'\textbackslash n'} +is a single character and +because a trailing +\tcode{'\textbackslash 0'} +is appended, +\tcode{sizeof(msg)} +is +\tcode{25}. +\end{example} + +\pnum +There shall not be more initializers than there are array elements. +\begin{example} + +\begin{codeblock} +char cv[4] = "asdf"; // error +\end{codeblock} + +is ill-formed since there is no space for the implied trailing +\tcode{'\textbackslash 0'}. +\end{example} + +\pnum +If there are fewer initializers than there are array elements, each element not +explicitly initialized shall be zero-initialized\iref{dcl.init}. + +\rSec2[dcl.init.ref]{References}% +\indextext{initialization!reference} + +\pnum +A variable whose declared type is +``reference to type \tcode{T}''\iref{dcl.ref} +shall be initialized. +\begin{example} + +\begin{codeblock} +int g(int) noexcept; +void f() { + int i; + int& r = i; // \tcode{r} refers to \tcode{i} + r = 1; // the value of \tcode{i} becomes \tcode{1} + int* p = &r; // \tcode{p} points to \tcode{i} + int& rr = r; // \tcode{rr} refers to what \tcode{r} refers to, that is, to \tcode{i} + int (&rg)(int) = g; // \tcode{rg} refers to the function \tcode{g} + rg(i); // calls function \tcode{g} + int a[3]; + int (&ra)[3] = a; // \tcode{ra} refers to the array \tcode{a} + ra[1] = i; // modifies \tcode{a[1]} +} +\end{codeblock} +\end{example} + +\pnum +A reference cannot be changed to refer to another object after initialization. +\indextext{assignment!reference}% +\begin{note} +Assignment to a reference assigns to the object referred to by the reference\iref{expr.ass}. +\end{note} +\indextext{argument passing!reference and}% +Argument passing\iref{expr.call} +\indextext{\idxcode{return}!reference and}% +and function value return\iref{stmt.return} are initializations. + +\pnum +The initializer can be omitted for a reference only in a parameter declaration\iref{dcl.fct}, +in the declaration of a function return type, in the declaration of +a class member within its class definition\iref{class.mem}, and where the +\tcode{extern} +specifier is explicitly used. +\indextext{declaration!extern@\tcode{extern} reference}% +\begin{example} + +\begin{codeblock} +int& r1; // error: initializer missing +extern int& r2; // OK +\end{codeblock} +\end{example} + +\pnum +Given types ``\cvqual{cv1} \tcode{T1}'' and ``\cvqual{cv2} \tcode{T2}'', +``\cvqual{cv1} \tcode{T1}'' is \defn{reference-related} to +``\cvqual{cv2} \tcode{T2}'' if +\tcode{T1} is the same type as \tcode{T2}, or +\tcode{T1} is a base class of \tcode{T2}. +``\cvqual{cv1} \tcode{T1}'' is \defn{reference-compatible} +with ``\cvqual{cv2} \tcode{T2}'' if +\begin{itemize} +\item \tcode{T1} is reference-related to \tcode{T2}, or +\item \tcode{T2} is ``\tcode{noexcept} function'' and \tcode{T1} is ``function'', +where the function types are otherwise the same, +\end{itemize} +and +\cvqual{cv1} +is the same cv-qualification as, or greater cv-qualification than, +\cvqual{cv2}. +In all cases where the reference-related or reference-compatible relationship +of two types is used to establish the validity of a reference binding, and +\tcode{T1} +is a base class of +\tcode{T2}, +a program that necessitates such a binding is ill-formed if +\tcode{T1} +is an inaccessible\iref{class.access} or ambiguous\iref{class.member.lookup} +base class of +\tcode{T2}. + +\pnum +A reference to type ``\cvqual{cv1} \tcode{T1}'' is initialized by +an expression of type ``\cvqual{cv2} \tcode{T2}'' as follows:% +\indextext{binding!reference} + +\begin{itemize} +\item +If the reference is an lvalue reference and the initializer expression + +\begin{itemize} +\item +is an lvalue (but is not a +bit-field), and +``\cvqual{cv1} \tcode{T1}'' is reference-compatible with +``\cvqual{cv2} \tcode{T2}'', or +\item +has a class type (i.e., +\tcode{T2} +is a class type), where \tcode{T1} is not reference-related to \tcode{T2}, and can be converted +to an lvalue of type ``\cvqual{cv3} \tcode{T3}'', where +``\cvqual{cv1} \tcode{T1}'' is reference-compatible with +``\cvqual{cv3} \tcode{T3}''\footnote{This requires a conversion +function\iref{class.conv.fct} returning a reference type.} +(this conversion is selected by enumerating the applicable conversion +functions\iref{over.match.ref} and choosing the best one through overload +resolution\iref{over.match}), +\end{itemize} +then the reference is bound to the initializer expression lvalue in the +first case and to the lvalue result of the conversion +in the second case (or, in either case, to the appropriate base class subobject of the object). +\begin{note} +The usual lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, +and function-to-pointer\iref{conv.func} standard +conversions are not needed, and therefore are suppressed, when such +direct bindings to lvalues are done. +\end{note} + +\begin{example} + +\begin{codeblock} +double d = 2.0; +double& rd = d; // \tcode{rd} refers to \tcode{d} +const double& rcd = d; // \tcode{rcd} refers to \tcode{d} + +struct A { }; +struct B : A { operator int&(); } b; +A& ra = b; // \tcode{ra} refers to \tcode{A} subobject in \tcode{b} +const A& rca = b; // \tcode{rca} refers to \tcode{A} subobject in \tcode{b} +int& ir = B(); // \tcode{ir} refers to the result of \tcode{B::operator int\&} +\end{codeblock} +\end{example} + +\item +Otherwise, +if the reference is an lvalue reference to a +type that is not const-qualified or is volatile-qualified, +the program is ill-formed. +\begin{example} + +\begin{codeblock} +double& rd2 = 2.0; // error: not an lvalue and reference not \tcode{const} +int i = 2; +double& rd3 = i; // error: type mismatch and reference not \tcode{const} +\end{codeblock} +\end{example} + +\item Otherwise, if the initializer expression + +\begin{itemize} +\item is an rvalue (but not a bit-field) or function lvalue and +``\cvqual{cv1} \tcode{T1}'' is +reference-compatible with ``\cvqual{cv2} \tcode{T2}'', or + +\item has a class type (i.e., \tcode{T2} is a class type), where \tcode{T1} +is not reference-related to \tcode{T2}, and can be converted to +an rvalue or function lvalue of type ``\cvqual{cv3} \tcode{T3}'', +where ``\cvqual{cv1} \tcode{T1}'' is +reference-compatible with ``\cvqual{cv3} \tcode{T3}'' (see~\ref{over.match.ref}), + +\end{itemize} + +then +the value of the initializer expression in the first case and +the result of the conversion in the second case +is called the converted initializer. +If the converted initializer is a prvalue, +its type \tcode{T4} is adjusted to type ``\cvqual{cv1} \tcode{T4}''\iref{conv.qual} +and the temporary materialization conversion\iref{conv.rval} is applied. +In any case, +the reference is bound to the resulting glvalue +(or to an appropriate base class subobject). + +\begin{example} + +\begin{codeblock} +struct A { }; +struct B : A { } b; +extern B f(); +const A& rca2 = f(); // bound to the \tcode{A} subobject of the \tcode{B} rvalue. +A&& rra = f(); // same as above +struct X { + operator B(); + operator int&(); +} x; +const A& r = x; // bound to the \tcode{A} subobject of the result of the conversion +int i2 = 42; +int&& rri = static_cast(i2); // bound directly to \tcode{i2} +B&& rrb = x; // bound directly to the result of \tcode{operator B} +\end{codeblock} +\end{example} + +\item +Otherwise: +\begin{itemize} +\item +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 +``\cvqual{cv1} \tcode{T1}'' by +user-defined conversion +(\ref{dcl.init}, \ref{over.match.copy}, \ref{over.match.conv}); +the program is ill-formed if the corresponding non-reference +copy-initialization would be ill-formed. The result of the call to the +conversion function, as described for the non-reference +copy-initialization, is then used to direct-initialize the reference. +For this direct-initialization, user-defined conversions are not considered. +\item +Otherwise, +the initializer expression is implicitly converted to a prvalue +of type ``\cvqual{cv1} \tcode{T1}''. +The temporary materialization conversion is applied and the reference is +bound to the result. +\end{itemize} + +If +\tcode{T1} +is reference-related to +\tcode{T2}: +\begin{itemize} +\item +\cvqual{cv1} +shall be the same cv-qualification as, or greater cv-qualification than, +\cvqual{cv2}; and +\item +if the reference is an rvalue reference, +the initializer expression shall not be an lvalue. +\end{itemize} + +\begin{example} +\begin{codeblock} +struct Banana { }; +struct Enigma { operator const Banana(); }; +struct Alaska { operator Banana&(); }; +void enigmatic() { + typedef const Banana ConstBanana; + Banana &&banana1 = ConstBanana(); // ill-formed + Banana &&banana2 = Enigma(); // ill-formed + Banana &&banana3 = Alaska(); // ill-formed +} + +const double& rcd2 = 2; // \tcode{rcd2} refers to temporary with value \tcode{2.0} +double&& rrd = 2; // \tcode{rrd} refers to temporary with value \tcode{2.0} +const volatile int cvi = 1; +const int& r2 = cvi; // error: cv-qualifier dropped +struct A { operator volatile int&(); } a; +const int& r3 = a; // error: cv-qualifier dropped + // from result of conversion function +double d2 = 1.0; +double&& rrd2 = d2; // error: initializer is lvalue of related type +struct X { operator int&(); }; +int&& rri2 = X(); // error: result of conversion function is lvalue of related type +int i3 = 2; +double&& rrd3 = i3; // \tcode{rrd3} refers to temporary with value \tcode{2.0} +\end{codeblock} +\end{example} +\end{itemize} + +In all cases except the last +(i.e., implicitly converting the initializer expression +to the referenced type), +the reference is said to \defn{bind directly} to the +initializer expression. + +\pnum +\begin{note} +\ref{class.temporary} describes the lifetime of temporaries bound to references. +\end{note} + +\rSec2[dcl.init.list]{List-initialization}% +\indextext{initialization!list-initialization|(} + +\pnum +\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 \grammarterm{initializer-list} +or +\grammarterm{designated-initializer-clause}{s} +of the \grammarterm{designated-initializer-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 +\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} +\item as the initializer in a variable definition\iref{dcl.init} +\item as the initializer in a \grammarterm{new-expression}\iref{expr.new} +\item in a \tcode{return} statement\iref{stmt.return} +\item as a \grammarterm{for-range-initializer}\iref{stmt.iter} +\item as a function argument\iref{expr.call} +\item as a subscript\iref{expr.sub} +\item as an argument to a constructor invocation~(\ref{dcl.init}, \ref{expr.type.conv}) +\item as an initializer for a non-static data member\iref{class.mem} +\item in a \grammarterm{mem-initializer}\iref{class.base.init} +\item on the right-hand side of an assignment\iref{expr.ass} +\end{itemize} + +\begin{example} +\begin{codeblock} +int a = {1}; +std::complex z{1,2}; +new std::vector{"once", "upon", "a", "time"}; // 4 string elements +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 \tcode{double} +std::map anim = { {"bear",4}, {"cassowary",2}, {"tiger",7} }; +\end{codeblock} +\end{example} \end{note} + +\pnum +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\iref{dcl.fct.default}. +\begin{note} Initializer-list constructors are favored over other constructors in +list-initialization\iref{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 +corresponding parameter to be a non-deduced context\iref{temp.deduct.call}. \end{note} +The template +\tcode{std::initializer_list} is not predefined; if the header +\tcode{} is not included prior to a use of +\tcode{std::initializer_list} --- even an implicit use in which the type is not +named\iref{dcl.spec.auto} --- the program is ill-formed. + +\pnum +List-initialization of an object or reference of type \tcode{T} is defined as follows: +\begin{itemize} +\item +If the \grammarterm{braced-init-list} +contains a \grammarterm{designated-initializer-list}, +\tcode{T} shall be an aggregate class. +The ordered \grammarterm{identifier}{s} +in the \grammarterm{designator}{s} +of the \grammarterm{designated-initializer-list} +shall form a subsequence +of the ordered \grammarterm{identifier}{s} +in the direct non-static data members of \tcode{T}. +Aggregate initialization is performed\iref{dcl.init.aggr}. +\begin{example} +\begin{codeblock} +struct A { int x; int y; int z; }; +A a{.y = 2, .x = 1}; // error: designator order does not match declaration order +A b{.x = 1, .z = 2}; // OK, \tcode{b.y} initialized to \tcode{0} +\end{codeblock} +\end{example} + +\item If \tcode{T} is an aggregate class and the initializer list has a single element +of type \cvqual{cv} \tcode{U}, +where \tcode{U} is \tcode{T} or a class derived from \tcode{T}, +the object is initialized from that element (by copy-initialization for +copy-list-initialization, or by direct-initialization for +direct-list-initialization). + +\item Otherwise, if \tcode{T} is a character array and the initializer list has a +single element that is an appropriately-typed string literal\iref{dcl.init.string}, +initialization is performed as described in that subclause. + +\item Otherwise, if \tcode{T} is an aggregate, aggregate initialization is +performed\iref{dcl.init.aggr}. + +\begin{example} +\begin{codeblock} +double ad[] = { 1, 2.0 }; // OK +int ai[] = { 1, 2.0 }; // error: narrowing + +struct S2 { + int m1; + double m2, m3; +}; +S2 s21 = { 1, 2, 3.0 }; // OK +S2 s22 { 1.0, 2, 3 }; // error: narrowing +S2 s23 { }; // OK: default to 0,0,0 +\end{codeblock} +\end{example} + +\item Otherwise, if the initializer list has no elements and \tcode{T} is a class type with a +default constructor, the object is value-initialized. + +\item Otherwise, if \tcode{T} is a specialization of \tcode{std::initializer_list}, +the object is constructed as described below. + +\item Otherwise, if \tcode{T} is a class type, constructors are considered. +The applicable constructors are enumerated and +the best one is chosen through overload resolution~(\ref{over.match}, \ref{over.match.list}). If a narrowing +conversion (see below) is required to convert any of the arguments, the program is +ill-formed. + +\begin{example} +\begin{codeblock} +struct S { + S(std::initializer_list); // \#1 + S(std::initializer_list); // \#2 + S(); // \#3 + // ... +}; +S s1 = { 1.0, 2.0, 3.0 }; // invoke \#1 +S s2 = { 1, 2, 3 }; // invoke \#2 +S s3 = { }; // invoke \#3 +\end{codeblock} +\end{example} + +\begin{example} +\begin{codeblock} +struct Map { + Map(std::initializer_list>); +}; +Map ship = {{"Sophie",14}, {"Surprise",28}}; +\end{codeblock} +\end{example} + +\begin{example} +\begin{codeblock} +struct S { + // no initializer-list constructors + S(int, double, double); // \#1 + S(); // \#2 + // ... +}; +S s1 = { 1, 2, 3.0 }; // OK: invoke \#1 +S s2 { 1.0, 2, 3 }; // error: narrowing +S s3 { }; // OK: invoke \#2 +\end{codeblock} +\end{example} + +\item Otherwise, if \tcode{T} is an enumeration +with a fixed underlying type\iref{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)}\iref{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 +reference-related to \tcode{E}, the object or reference is initialized +from that element (by copy-initialization for copy-list-initialization, +or by direct-initialization for direct-list-initialization); +if a narrowing conversion (see below) is required +to convert the element to \tcode{T}, the program is ill-formed. + +\begin{example} +\begin{codeblock} +int x1 {2}; // OK +int x2 {2.0}; // error: narrowing +\end{codeblock} +\end{example} + +\item Otherwise, if \tcode{T} is a reference type, a prvalue of the type +referenced by \tcode{T} is generated. +The prvalue initializes its result object by +copy-list-initialization or direct-list-initialization, +depending on the kind of initialization for the reference. +The prvalue is then used to direct-initialize the reference. +\begin{note} As usual, the binding will fail and the program is ill-formed if +the reference type is an lvalue reference to a non-const type. \end{note} + +\begin{example} +\begin{codeblock} +struct S { + S(std::initializer_list); // \#1 + S(const std::string&); // \#2 + // ... +}; +const S& r1 = { 1, 2, 3.0 }; // OK: invoke \#1 +const S& r2 { "Spinach" }; // OK: invoke \#2 +S& r3 = { 1, 2, 3 }; // error: initializer is not an lvalue +const int& i1 = { 1 }; // OK +const int& i2 = { 1.1 }; // error: narrowing +const int (&iar)[2] = { 1, 2 }; // OK: \tcode{iar} is bound to temporary array +\end{codeblock} +\end{example} + +\item Otherwise, if the initializer list has no elements, the object is +value-initialized. + +\begin{example} +\begin{codeblock} +int** pp {}; // initialized to null pointer +\end{codeblock} +\end{example} + +\item Otherwise, the program is ill-formed. + +\begin{example} +\begin{codeblock} +struct A { int i; int j; }; +A a1 { 1, 2 }; // aggregate initialization +A a2 { 1.2 }; // error: narrowing +struct B { + B(std::initializer_list); +}; +B b1 { 1, 2 }; // creates \tcode{initializer_list} and calls constructor +B b2 { 1, 2.0 }; // error: narrowing +struct C { + C(int i, double j); +}; +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 +int k { }; // initialize to 0 +\end{codeblock} +\end{example} + +\end{itemize} + +\pnum +Within the \grammarterm{initializer-list} of a \grammarterm{braced-init-list}, +the \grammarterm{initializer-clause}{s}, including any that result from pack +expansions\iref{temp.variadic}, are evaluated in the order in which they +appear. That is, every value computation and side effect associated with a +given \grammarterm{initializer-clause} is sequenced before every value +computation and side effect associated with any \grammarterm{initializer-clause} +that follows it in the comma-separated list of the \grammarterm{initializer-list}. +\begin{note} This evaluation ordering holds regardless of the semantics of the +initialization; for example, it applies when the elements of the +\grammarterm{initializer-list} are interpreted as arguments of a constructor +call, even though ordinarily there are no sequencing constraints on the +arguments of a call. \end{note} + +\pnum +An object of type \tcode{std::initializer_list} is constructed from +an initializer list as if +the implementation generated and materialized\iref{conv.rval} +a prvalue of type ``array of $N$ \tcode{const E}'', +where $N$ is the number of elements in the +initializer list. Each element of that array is copy-initialized with the +corresponding element of the initializer list, and the +\tcode{std::initializer_list} object is constructed to refer to that array. +\begin{note} A constructor or conversion function selected for the copy shall be +accessible\iref{class.access} in the context of the initializer list. +\end{note} +If a narrowing conversion is required to initialize any of the elements, the program is ill-formed. \begin{example} +\begin{codeblock} +struct X { + X(std::initializer_list v); +}; +X x{ 1,2,3 }; +\end{codeblock} + +The initialization will be implemented in a way roughly equivalent to this: + +\begin{codeblock} +const double __a[3] = {double{1}, double{2}, double{3}}; +X x(std::initializer_list(__a, __a+3)); +\end{codeblock} + +assuming that the implementation can construct an \tcode{initializer_list} object with a pair of pointers. \end{example} + +\pnum +The array has the same lifetime as any other temporary +object\iref{class.temporary}, except that initializing an +\tcode{initiali\-zer_list} object from the array extends the lifetime of +the array exactly like binding a reference to a temporary. +\begin{example} + +\begin{codeblock} +typedef std::complex cmplx; +std::vector v1 = { 1, 2, 3 }; + +void f() { + std::vector v2{ 1, 2, 3 }; + std::initializer_list i3 = { 1, 2, 3 }; +} + +struct A { + std::initializer_list i4; + A() : i4{ 1, 2, 3 } {} // ill-formed, would create a dangling reference +}; +\end{codeblock} + +For \tcode{v1} and \tcode{v2}, the \tcode{initializer_list} object +is a parameter in a function call, so the array created for +\tcode{\{ 1, 2, 3 \}} has full-expression lifetime. +For \tcode{i3}, the \tcode{initializer_list} object is a variable, +so the array persists for the lifetime of the variable. +For \tcode{i4}, the \tcode{initializer_list} object is initialized in +the constructor's \grammarterm{ctor-initializer} as if by binding +a temporary array to a reference member, so the program is +ill-formed\iref{class.base.init}. +\end{example} +\begin{note} +The implementation is free to allocate the array in read-only memory if an explicit array with the same initializer could be so allocated. \end{note} + +\pnum +A +\indextext{narrowing conversion}% +\indextext{conversion!narrowing}% +\term{narrowing conversion} is an implicit conversion + +\begin{itemize} +\item from a floating-point type to an integer type, or + +\item from \tcode{long double} to \tcode{double} or \tcode{float}, or from +\tcode{double} to \tcode{float}, except where the source is a constant expression and +the actual value after conversion +is within the range of values that can be represented (even if it cannot be represented exactly), +or + +\item from an integer type or unscoped enumeration type to a floating-point type, except +where the source is a constant expression and the actual value after conversion will fit +into the target type and will produce the original value when converted back to the +original type, or + +\item from an integer type or unscoped enumeration type to an integer type that cannot +represent all the values of the original type, except where the source is a constant +expression whose value after integral promotions will fit into the target type. +\end{itemize} + +\begin{note} As indicated above, such conversions are not allowed at the top level in +list-initializations.\end{note} \begin{example} + +\begin{codeblock} +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) +char c2{x}; // error: might narrow +char c3{y}; // error: narrows (assuming \tcode{char} is 8 bits) +char c4{z}; // OK: no narrowing needed +unsigned char uc1 = {5}; // OK: no narrowing needed +unsigned char uc2 = {-1}; // error: narrows +unsigned int ui1 = {-1}; // error: narrows +signed int si1 = + { (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 \tcode{float} +int f(int); +int a[] = { 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|)}% +\indextext{initialization|)}% +\indextext{declarator|)} + +\rSec1[dcl.fct.def]{Function definitions}% +\indextext{definition!function|(} + +\rSec2[dcl.fct.def.general]{In general} + +\pnum +\indextext{body!function}% +Function definitions have the form + +\indextext{\idxgram{function-definition}}% +% +\begin{bnf} +\nontermdef{function-definition}\br + \opt{attribute-specifier-seq} \opt{decl-specifier-seq} declarator \opt{virt-specifier-seq} function-body\br + \opt{attribute-specifier-seq} \opt{decl-specifier-seq} declarator requires-clause function-body +\end{bnf} + +\begin{bnf} +\nontermdef{function-body}\br + \opt{ctor-initializer} compound-statement\br + function-try-block\br + \terminal{= default ;}\br + \terminal{= delete ;} +\end{bnf} + +Any informal reference to the body of a function should be interpreted as a reference to +the non-terminal \grammarterm{function-body}. +The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{function-definition} +appertains to the function. +A \grammarterm{virt-specifier-seq} can be part of a \grammarterm{function-definition} +only if it is a \grammarterm{member-declaration}\iref{class.mem}. + +\pnum +In a \grammarterm{function-definition}, +either \tcode{void} \grammarterm{declarator} \tcode{;} +or \grammarterm{declarator} \tcode{;} +shall be a well-formed function declaration +as described in~\ref{dcl.fct}. +A function shall be defined only in namespace or class scope. +The type of a parameter or the return type for a function +definition shall not be +an incomplete or abstract (possibly cv-qualified) class type +in the context of the function definition +unless the function is deleted\iref{dcl.fct.def.delete}. + +\pnum +\begin{example} +A simple example of a complete function definition is + +\begin{codeblock} +int max(int a, int b, int c) { + int m = (a > b) ? a : b; + return (m > c) ? m : c; +} +\end{codeblock} + +Here +\tcode{int} +is the +\grammarterm{decl-specifier-seq}; +\tcode{max(int} +\tcode{a,} +\tcode{int} +\tcode{b,} +\tcode{int} +\tcode{c)} +is the +\grammarterm{declarator}; +\tcode{\{ \commentellip{} \}} +is the +\grammarterm{function-body}. +\end{example} + +\pnum +\indextext{initializer!base class}% +\indextext{initializer!member}% +\indextext{definition!constructor}% +A +\grammarterm{ctor-initializer} +is used only in a constructor; see~\ref{class.ctor} and~\ref{class.init}. + +\pnum +\begin{note} +A \grammarterm{cv-qualifier-seq} affects the type of \tcode{this} +in the body of a member function; see~\ref{dcl.ref}. +\end{note} + +\pnum +\begin{note} +Unused parameters need not be named. +For example, + +\begin{codeblock} +void print(int a, int) { + std::printf("a = %d\n",a); +} +\end{codeblock} +\end{note} + +\pnum +In the \grammarterm{function-body}, a +\defnx{function-local predefined variable}{variable!function-local predefined} denotes a block-scope object of static +storage duration that is implicitly defined (see~\ref{basic.scope.block}). + +\pnum +The function-local predefined variable \tcode{__func__} is +defined as if a definition of the form +\begin{codeblock} +static const char __func__[] = "@\placeholder{function-name}@"; +\end{codeblock} +had been provided, where \tcode{\placeholder{function-name}} is an \impldef{string resulting +from \mname{func}} string. +It is unspecified whether such a variable has an address +distinct from that of any other object in the program.\footnote{Implementations are +permitted to provide additional predefined variables with names that are reserved to the +implementation\iref{lex.name}. If a predefined variable is not +odr-used\iref{basic.def.odr}, its string value need not be present in the program image.} +\begin{example} +\begin{codeblock} +struct S { + S() : s(__func__) { } // OK + const char* s; +}; +void f(const char* s = __func__); // error: \tcode{__func__} is undeclared +\end{codeblock} +\end{example} + +\rSec2[dcl.fct.def.default]{Explicitly-defaulted functions}% + +\pnum +A function definition whose +\grammarterm{function-body} +is of the form +\tcode{= default ;} +is called an \defnx{explicitly-defaulted}{definition!function!explicitly-defaulted} definition. +A function that is explicitly defaulted shall + +\begin{itemize} +\item be a special member function or a comparison operator +(\ref{expr.spaceship}, \ref{expr.rel}, \ref{expr.eq}), and + +\item not have default arguments. +\end{itemize} + +% FIXME: there's no such thing as an implicit declaration of a comparison operator +\pnum +The type \tcode{T}$_1$ of an explicitly defaulted function \tcode{F} +is allowed to differ from the type \tcode{T}$_2$ it would have had +if it were implicitly declared, as follows: +\begin{itemize} +\item + \tcode{T}$_1$ and \tcode{T}$_2$ may have differing \grammarterm{ref-qualifier}{s}; and +\item + if \tcode{T}$_2$ has a parameter of type \tcode{const C\&}, + the corresponding parameter of \tcode{T}$_1$ may be of type \tcode{C\&}. +\end{itemize} +If \tcode{T}$_1$ differs from \tcode{T}$_2$ in any other way, then: +\begin{itemize} +\item + if \tcode{F} is an assignment operator, and + the return type of \tcode{T}$_1$ differs from + the return type of \tcode{T}$_2$ or + \tcode{T}$_1${'s} parameter type is not a reference, + the program is ill-formed; +\item + otherwise, if \tcode{F} is explicitly defaulted on its first declaration, + it is defined as deleted; +\item + otherwise, the program is ill-formed. +\end{itemize} + +\pnum +An explicitly-defaulted function that is not defined as deleted may be declared +\tcode{constexpr} only if it would have been implicitly declared as +\tcode{constexpr}. If +a function is explicitly defaulted on its first declaration, +it is implicitly considered to be \tcode{constexpr} if the implicit +declaration would be. + +\pnum +\begin{example} +\begin{codeblock} +struct S { + constexpr S() = default; // ill-formed: implicit \tcode{S()} is not \tcode{constexpr} + S(int a = 0) = default; // ill-formed: default argument + void operator=(const S&) = default; // ill-formed: non-matching return type + ~S() noexcept(false) = default; // deleted: exception specification does not match +private: + int i; + S(S&); // OK: private copy constructor +}; +S::S(S&) = default; // OK: defines copy constructor +\end{codeblock} +\end{example} + +\pnum +Explicitly-defaulted functions and implicitly-declared functions are collectively +called \defn{defaulted} functions, and the implementation +shall provide implicit definitions +for them~(\ref{class.ctor} +\ref{class.dtor}, \ref{class.copy.ctor}, \ref{class.copy.assign}), +which might mean defining them as deleted. +A function is +\defn{user-provided} if it is user-declared and not explicitly +defaulted or deleted on its first declaration. A user-provided explicitly-defaulted function +(i.e., explicitly defaulted after its first declaration) +is defined at the point where it is explicitly defaulted; if such a function is implicitly +defined as deleted, the program is ill-formed. +\begin{note} +Declaring a function as defaulted after its first declaration can provide +efficient execution and concise +definition while enabling a stable binary interface to an evolving code +base.\end{note} + +\pnum +\begin{example} + +\begin{codeblock} +struct trivial { + trivial() = default; + trivial(const trivial&) = default; + trivial(trivial&&) = default; + trivial& operator=(const trivial&) = default; + trivial& operator=(trivial&&) = default; + ~trivial() = default; +}; + +struct nontrivial1 { + nontrivial1(); +}; +nontrivial1::nontrivial1() = default; // not first declaration +\end{codeblock} +\end{example} + +\rSec2[dcl.fct.def.delete]{Deleted definitions}% +\indextext{definition!function!deleted}% + +\pnum +A function definition whose +\grammarterm{function-body} +is of the form +\tcode{= delete ;} +is called a \term{deleted definition}. A function with a +deleted definition is also called a \term{deleted function}. + +\pnum +A program that refers to a deleted function implicitly or explicitly, other +than to declare it, is ill-formed. \begin{note} This includes calling the function +implicitly or explicitly and forming a pointer or pointer-to-member to the +function. It applies even for references in expressions that are not +potentially-evaluated. If a function is overloaded, it is referenced only if the +function is selected by overload resolution. The implicit +odr-use\iref{basic.def.odr} of a virtual function does not, by itself, +constitute a reference. \end{note} + +\pnum +\begin{example} One can prevent default initialization and +initialization by non-\tcode{double}s with +\begin{codeblock} +struct onlydouble { + onlydouble() = delete; // OK, but redundant + template + onlydouble(T) = delete; + onlydouble(double); +}; +\end{codeblock} +\end{example} + +\begin{example} +One can prevent use of a +class in certain \grammarterm{new-expression}{s} by using deleted definitions +of a user-declared \tcode{operator new} for that class. +\begin{codeblock} +struct sometype { + void* operator new(std::size_t) = delete; + void* operator new[](std::size_t) = delete; +}; +sometype* p = new sometype; // error, deleted class \tcode{operator new} +sometype* q = new sometype[3]; // error, deleted class \tcode{operator new[]} +\end{codeblock} +\end{example} + +\begin{example} +One can make a class uncopyable, i.e., move-only, by using deleted +definitions of the copy constructor and copy assignment operator, and then +providing defaulted definitions of the move constructor and move assignment operator. +\begin{codeblock} +struct moveonly { + moveonly() = default; + moveonly(const moveonly&) = delete; + moveonly(moveonly&&) = default; + moveonly& operator=(const moveonly&) = delete; + moveonly& operator=(moveonly&&) = default; + ~moveonly() = default; +}; +moveonly* p; +moveonly q(*p); // error, deleted copy constructor +\end{codeblock} +\end{example} + +\pnum +A deleted function is implicitly an inline function\iref{dcl.inline}. \begin{note} The +one-definition rule\iref{basic.def.odr} applies to deleted definitions. \end{note} +A deleted definition of a function shall be the first declaration of the function or, +for an explicit specialization of a function template, the first declaration of that +specialization. +An implicitly declared allocation or deallocation function\iref{basic.stc.dynamic} +shall not be defined as deleted. +\begin{example} +\begin{codeblock} +struct sometype { + sometype(); +}; +sometype::sometype() = delete; // ill-formed; not first declaration +\end{codeblock} +\end{example}% +\indextext{definition!function|)} + +\rSec1[dcl.struct.bind]{Structured binding declarations}% +\indextext{structured binding declaration}% +\indextext{declaration!structured binding|see{structured binding declaration}}% + +\pnum +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\iref{basic.scope.declarative} +of \defn{structured binding}{s}. +Let \cv{} denote the +\grammarterm{cv-qualifier}{s} in the \grammarterm{decl-specifier-seq}. First, a +variable with a unique name \tcode{e} is introduced. If the +\grammarterm{assignment-expression} in the \grammarterm{initializer} +has array type \tcode{A} and no \grammarterm{ref-qualifier} is present, \tcode{e} +has type \cv{}~\tcode{A} and each element is copy-initialized or direct-initialized +from the corresponding element of the \grammarterm{assignment-expression} as specified +by the form of the \grammarterm{initializer}. +Otherwise, \tcode{e} +is defined as-if by + +\begin{ncbnf} +\opt{attribute-specifier-seq} decl-specifier-seq \opt{ref-qualifier} \terminal{e} initializer \terminal{;} +\end{ncbnf} + +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 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\iref{expr.prop}. +\end{note} + +\pnum +If the \grammarterm{initializer} refers to +one of the names introduced by the structured binding declaration, +the program is ill-formed. + +\pnum +If \tcode{E} is an array type with element type \tcode{T}, the number +of elements in the \grammarterm{identifier-list} shall be equal to the +number of elements of \tcode{E}. Each \tcode{v}$_i$ is the name of an +lvalue that refers to the element $i$ of the array and whose type +is \tcode{T}; the referenced type is \tcode{T}. +\begin{note} +The top-level cv-qualifiers of \tcode{T} are \cv. +\end{note} +\begin{example} +\begin{codeblock} + auto f() -> int(&)[2]; + auto [ x, y ] = f(); // \tcode{x} and \tcode{y} refer to elements in a copy of the array return value + auto& [ xr, yr ] = f(); // \tcode{xr} and \tcode{yr} refer to elements in the array referred to by \tcode{f}'s return value +\end{codeblock} +\end{example} + +\pnum +Otherwise, if +the \grammarterm{qualified-id} \tcode{std::tuple_size} +names a complete type, +the expression \tcode{std::tuple_size::value} +shall be a well-formed integral constant expression +and +the number of elements in +the \grammarterm{identifier-list} shall be equal to the value of that +expression. +Let \tcode{i} be an index prvalue of type \tcode{std::size_t} +corresponding to $\tcode{v}_\tcode{i}$. +The \grammarterm{unqualified-id} \tcode{get} is looked up +in the scope of \tcode{E} by class member access lookup\iref{basic.lookup.classref}, +and if that finds at least one declaration +that is a function template whose first template parameter +is a non-type parameter, +the initializer is +\tcode{e.get()}. Otherwise, the initializer is \tcode{get(e)}, +where \tcode{get} is looked up in the associated namespaces\iref{basic.lookup.argdep}. +In either case, \tcode{get} is interpreted as a \grammarterm{template-id}. +\begin{note} +Ordinary unqualified lookup\iref{basic.lookup.unqual} is not performed. +\end{note} +In either case, \tcode{e} is an lvalue if the type of the entity \tcode{e} +is an lvalue reference and an xvalue otherwise. Given the type $\tcode{T}_i$ +designated by \tcode{std::tuple_element::type}, +variables are introduced with unique names $\tcode{r}_i$ +of type ``reference to $\tcode{T}_i$'' +initialized with the initializer~(\ref{dcl.init.ref}), +where the reference is an lvalue reference if the initializer is +an lvalue and an rvalue reference otherwise. +Each $\tcode{v}_i$ is the name of an lvalue of type $\tcode{T}_i$ +that refers to the object bound to $\tcode{r}_i$; +the referenced type is $\tcode{T}_i$. + +\pnum +Otherwise, +all of \tcode{E}'s non-static data members +shall be direct members of \tcode{E} or +of the same base class of \tcode{E}, +well-formed when named as \tcode{e.\placeholder{name}} +in the context of the structured binding, +\tcode{E} shall not have an anonymous union member, and +the number of elements in the \grammarterm{identifier-list} shall be +equal to the number of non-static data members of \tcode{E}. +Designating the non-static data members of \tcode{E} as +\tcode{m}$_0$, \tcode{m}$_1$, \tcode{m}$_2$, ... +(in declaration order), +each \tcode{v}$_i$ is the +name of an lvalue that refers to the member \tcode{m}$_i$ of \tcode{e} and +whose type is \cv{}~$\tcode{T}_i$, where $\tcode{T}_i$ is the declared type of +that member; the referenced type is \cv{}~$\tcode{T}_i$. The lvalue is a +bit-field if that member is a bit-field. +\begin{example} +\begin{codeblock} +struct S { int x1 : 2; volatile double y1; }; +S f(); +const auto [ x, y ] = f(); +\end{codeblock} +The type of the \grammarterm{id-expression} \tcode{x} is ``\tcode{const int}'', +the type of the \grammarterm{id-expression} \tcode{y} is ``\tcode{const volatile double}''. +\end{example} + +\rSec1[dcl.enum]{Enumeration declarations}% +\indextext{enumeration}% +\indextext{\idxcode{\{\}}!enum declaration@\tcode{enum} declaration}% +\indextext{\idxcode{enum}!type of} + +\pnum +An enumeration is a distinct type\iref{basic.compound} with named +constants. Its name becomes an \grammarterm{enum-name} within its scope. + +\begin{bnf} +\nontermdef{enum-name}\br + identifier +\end{bnf} + +\begin{bnf} +\nontermdef{enum-specifier}\br + enum-head \terminal{\{} \opt{enumerator-list} \terminal{\}}\br + enum-head \terminal{\{} enumerator-list \terminal{, \}} +\end{bnf} + +\begin{bnf} +\nontermdef{enum-head}\br + enum-key \opt{attribute-specifier-seq} \opt{enum-head-name} \opt{enum-base} +\end{bnf} + +\begin{bnf} +\nontermdef{enum-head-name}\br + \opt{nested-name-specifier} identifier +\end{bnf} + +\begin{bnf} +\nontermdef{opaque-enum-declaration}\br + enum-key \opt{attribute-specifier-seq} \opt{nested-name-specifier} identifier \opt{enum-base} \terminal{;} +\end{bnf} + +\begin{bnf} +\nontermdef{enum-key}\br + \terminal{enum}\br + \terminal{enum class}\br + \terminal{enum struct} +\end{bnf} + +\begin{bnf} +\nontermdef{enum-base}\br + \terminal{:} type-specifier-seq +\end{bnf} + +\begin{bnf} +\nontermdef{enumerator-list}\br + enumerator-definition\br + enumerator-list \terminal{,} enumerator-definition +\end{bnf} + +\begin{bnf} +\nontermdef{enumerator-definition}\br + enumerator\br + enumerator \terminal{=} constant-expression +\end{bnf} + +\begin{bnf} +\nontermdef{enumerator}\br + identifier \opt{attribute-specifier-seq} +\end{bnf} + +The optional \grammarterm{attribute-specifier-seq} in the \grammarterm{enum-head} and +the \grammarterm{opaque-enum-declaration} appertains to the enumeration; the attributes +in that \grammarterm{attribute-specifier-seq} are thereafter considered attributes of the +enumeration whenever it is named. +A \tcode{:} following +``\tcode{enum} \opt{\grammarterm{nested-name-specifier}} \grammarterm{identifier}'' +within the \grammarterm{decl-specifier-seq} of a \grammarterm{member-declaration} +is parsed as part of an \grammarterm{enum-base}. +\begin{note} This resolves a potential ambiguity between the declaration of an enumeration +with an \grammarterm{enum-base} and the declaration of an unnamed bit-field of enumeration +type. \begin{example} + +\begin{codeblock} + struct S { + enum E : int {}; + enum E : int {}; // error: redeclaration of enumeration + }; +\end{codeblock} + +\end{example} +\end{note} +If an \grammarterm{opaque-enum-declaration} contains +a \grammarterm{nested-name-specifier}, +the declaration shall be an explicit specialization\iref{temp.expl.spec}. + +\pnum +\indextext{constant!enumeration}% +\indextext{enumeration}% +The enumeration type declared with an \grammarterm{enum-key} +of only \tcode{enum} is an \defnx{unscoped enumeration}{enumeration!unscoped}, +and its \grammarterm{enumerator}{s} are \defnx{unscoped enumerators}{enumerator!unscoped}. +The \grammarterm{enum-key}{s} \tcode{enum class} and +\tcode{enum struct} are semantically equivalent; an enumeration +type declared with one of these is a \defnx{scoped enumeration}{enumeration!scoped}, +and its \grammarterm{enumerator}{s} are \defnx{scoped enumerators}{enumerator!scoped}. +The optional \grammarterm{identifier} shall not be omitted in the declaration of a scoped enumeration. +The \grammarterm{type-specifier-seq} of an \grammarterm{enum-base} +shall name an integral type; any cv-qualification is ignored. +An \grammarterm{opaque-enum-declaration} declaring an unscoped enumeration shall +not omit the \grammarterm{enum-base}. +The identifiers in an \grammarterm{enumerator-list} are declared as +constants, and can appear wherever constants are required. +\indextext{enumerator!value of}% +An \grammarterm{enumerator-definition} with \tcode{=} gives the associated +\grammarterm{enumerator} the value indicated by the +\grammarterm{constant-expression}. +If the first \grammarterm{enumerator} +has no \grammarterm{initializer}, the value of the corresponding constant +is zero. An \grammarterm{enumerator-definition} without an +\grammarterm{initializer} gives the \grammarterm{enumerator} the value +obtained by increasing the value of the previous \grammarterm{enumerator} +by one. +\begin{example} + +\begin{codeblock} +enum { a, b, c=0 }; +enum { d, e, f=e+2 }; +\end{codeblock} + +defines \tcode{a}, \tcode{c}, and \tcode{d} to be zero, \tcode{b} and +\tcode{e} to be \tcode{1}, and \tcode{f} to be \tcode{3}. +\end{example} +The optional \grammarterm{attribute-specifier-seq} in an +\grammarterm{enumerator} appertains to that enumerator. + +\pnum +An \grammarterm{opaque-enum-declaration} is either a redeclaration +of an enumeration in the current scope or a declaration of a new enumeration. +\begin{note} An enumeration declared by an +\grammarterm{opaque-enum-declaration} has a fixed underlying type and is a +complete type. The list of enumerators can be provided in a later redeclaration +with an \grammarterm{enum-specifier}. \end{note} A scoped enumeration +shall not be later redeclared as unscoped or with a different underlying type. +An unscoped enumeration shall not be later redeclared as scoped and each +redeclaration shall include an \grammarterm{enum-base} specifying the same +underlying type as in the original declaration. + +\pnum +If the \grammarterm{enum-key} is followed by a +\grammarterm{nested-name-specifier}, the \grammarterm{enum-specifier} shall +refer to an enumeration that was previously declared directly in the class or +namespace to which the \grammarterm{nested-name-specifier} refers (i.e., neither +inherited nor introduced by a \grammarterm{using-declaration}), and the +\grammarterm{enum-specifier} shall appear in a namespace enclosing the previous +declaration. + +\pnum +\indextext{\idxcode{enum}!type of}% +\indextext{\idxcode{enum}!underlying type|see{type, underlying}}% +Each enumeration defines a type that is different from all other types. +Each enumeration also has an \defnx{underlying type}{type!underlying!enumeration}. +The underlying type can be explicitly specified using an \grammarterm{enum-base}. +For a scoped enumeration type, the underlying type is \tcode{int} if it is not +explicitly specified. In both of these cases, the underlying type is said to be +\defnx{fixed}{type!underlying!fixed}. +Following the closing brace of an \grammarterm{enum-specifier}, each +enumerator has the type of its enumeration. +If the underlying type is fixed, the type of each enumerator +prior to the closing brace is the underlying +type +and the \grammarterm{constant-expression} in the \grammarterm{enumerator-definition} +shall be a converted constant expression of the underlying +type\iref{expr.const}. +If the underlying +type is not fixed, +the type of each enumerator prior to the closing brace is determined as +follows: + +\begin{itemize} +\item If an +initializer is specified for an enumerator, the +\grammarterm{constant-expression} shall be an integral constant +expression\iref{expr.const}. If the expression has +unscoped enumeration type, the enumerator has the underlying type of that +enumeration type, otherwise it has the same type as the expression. + +\item If no initializer is specified for the +first enumerator, its type is an unspecified signed integral type. + +\item Otherwise +the type of the enumerator is the same as that of the +preceding enumerator unless the incremented value is not representable +in that type, in which case the type is an unspecified integral type +sufficient to contain the incremented value. If no such type exists, the program +is ill-formed. +\end{itemize} + +\pnum +An enumeration whose underlying type is fixed is an incomplete type from its +point of declaration\iref{basic.scope.pdecl} to immediately after its +\grammarterm{enum-base} (if any), at which point it becomes a complete type. +An enumeration whose underlying type is not fixed is an incomplete type from +its point of declaration to immediately after the closing \tcode{\}} of its +\grammarterm{enum-specifier}, at which point it becomes a complete type. + +\pnum +For an enumeration whose underlying type is not fixed, +the underlying type +is an +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 +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 +underlying type is as if the enumeration had a single enumerator with value 0. \pnum @@ -2614,24 +6848,235 @@ \grammarterm{namespace-alias-definition}, only namespace names are considered, see~\ref{basic.lookup.udir}. \end{note} - -\pnum -In a declarative region, a \grammarterm{namespace-alias-definition} can be -used to redefine a \grammarterm{namespace-alias} declared in that -declarative region to refer only to the namespace to which it already -refers. + +\pnum +In a declarative region, a \grammarterm{namespace-alias-definition} can be +used to redefine a \grammarterm{namespace-alias} declared in that +declarative region to refer only to the namespace to which it already +refers. +\begin{example} +The following declarations are well-formed: + +\begin{codeblock} +namespace Company_with_very_long_name { @\commentellip@ } +namespace CWVLN = Company_with_very_long_name; +namespace CWVLN = Company_with_very_long_name; // OK: duplicate +namespace CWVLN = CWVLN; +\end{codeblock} +\end{example} + +\rSec2[namespace.udir]{Using directive}% +\indextext{using-directive|(} + +\begin{bnf} +\nontermdef{using-directive}\br + \opt{attribute-specifier-seq} \terminal{using namespace} \opt{nested-name-specifier} namespace-name \terminal{;} +\end{bnf} + +\pnum +A \grammarterm{using-directive} shall not appear in class scope, but may +appear in namespace scope or in block scope. +\begin{note} +When looking up a \grammarterm{namespace-name} in a +\grammarterm{using-directive}, only namespace names are considered, +see~\ref{basic.lookup.udir}. +\end{note} +The optional \grammarterm{attribute-specifier-seq} appertains to the \grammarterm{using-directive}. + +\pnum +A \grammarterm{using-directive} specifies that the names in the nominated +namespace can be used in the scope in which the +\grammarterm{using-directive} appears after the \grammarterm{using-directive}. +During unqualified name lookup\iref{basic.lookup.unqual}, the names +appear as if they were declared in the nearest enclosing namespace which +contains both the \grammarterm{using-directive} and the nominated +namespace. +\begin{note} +In this context, ``contains'' means ``contains directly or indirectly''. +\end{note} + +\pnum +A \grammarterm{using-directive} does not add any members to the declarative +region in which it appears. +\begin{example} + +\begin{codeblock} +namespace A { + int i; + namespace B { + namespace C { + int i; + } + using namespace A::B::C; + void f1() { + i = 5; // OK, \tcode{C::i} visible in \tcode{B} and hides \tcode{A::i} + } + } + namespace D { + using namespace B; + using namespace C; + void f2() { + i = 5; // ambiguous, \tcode{B::C::i} or \tcode{A::i}? + } + } + void f3() { + i = 5; // uses \tcode{A::i} + } +} +void f4() { + i = 5; // ill-formed; neither \tcode{i} is visible +} +\end{codeblock} +\end{example} + +\pnum +For unqualified lookup\iref{basic.lookup.unqual}, the +\grammarterm{using-directive} is transitive: if a scope contains a +\grammarterm{using-directive} that nominates a second namespace that itself +contains \grammarterm{using-directive}{s}, the effect is as if the +\grammarterm{using-directive}{s} from the second namespace also appeared in +the first. +\begin{note} For qualified lookup, see~\ref{namespace.qual}. \end{note} +\begin{example} + +\begin{codeblock} +namespace M { + int i; +} + +namespace N { + int i; + using namespace M; +} + +void f() { + using namespace N; + i = 7; // error: both \tcode{M::i} and \tcode{N::i} are visible +} +\end{codeblock} + +For another example, + +\begin{codeblock} +namespace A { + int i; +} +namespace B { + int i; + int j; + namespace C { + namespace D { + using namespace A; + int j; + int k; + int a = i; // \tcode{B::i} hides \tcode{A::i} + } + using namespace D; + int k = 89; // no problem yet + int l = k; // ambiguous: \tcode{C::k} or \tcode{D::k} + int m = i; // \tcode{B::i} hides \tcode{A::i} + int n = j; // \tcode{D::j} hides \tcode{B::j} + } +} +\end{codeblock} +\end{example} + + +\pnum +If a namespace is extended\iref{namespace.def} after a +\grammarterm{using-directive} for that namespace is given, the additional +members of the extended namespace and the members of namespaces +nominated by \grammarterm{using-directive}{s} in the +extending \grammarterm{namespace-definition} can be used after the +extending \grammarterm{namespace-definition}. + +\pnum +\begin{note} +If name lookup finds a declaration for a name in two different +namespaces, and the declarations do not declare the same entity and do +not declare functions or function templates, the use of the name is ill-formed\iref{basic.lookup}. +In particular, the name of a variable, function or enumerator does not +hide the name of a class or enumeration declared in a different +namespace. For example, + +\begin{codeblock} +namespace A { + class X { }; + extern "C" int g(); + extern "C++" int h(); +} +namespace B { + void X(int); + extern "C" int g(); + extern "C++" int h(int); +} +using namespace A; +using namespace B; + +void f() { + X(1); // error: name \tcode{X} found in two namespaces + g(); // OK: name \tcode{g} refers to the same entity + h(); // OK: overload resolution selects \tcode{A::h} +} +\end{codeblock} +\end{note} + +\pnum +\indextext{overloading!using directive and}% +During overload resolution, all functions from the transitive search are +considered for argument matching. The set of declarations found by the +transitive search is unordered. +\begin{note} +In particular, the order in which namespaces were considered and the +relationships among the namespaces implied by the +\grammarterm{using-directive}{s} do not cause preference to be given to any +of the declarations found by the search. +\end{note} +An ambiguity exists if the best match finds two functions with the same +signature, even if one is in a namespace reachable through +\grammarterm{using-directive}{s} in the namespace of the other.\footnote{During +name lookup in a class hierarchy, some ambiguities may be +resolved by considering whether one member hides the other along some +paths\iref{class.member.lookup}. There is no such disambiguation when +considering the set of names found as a result of following +\grammarterm{using-directive}{s}.} \begin{example} -The following declarations are well-formed: \begin{codeblock} -namespace Company_with_very_long_name { @\commentellip@ } -namespace CWVLN = Company_with_very_long_name; -namespace CWVLN = Company_with_very_long_name; // OK: duplicate -namespace CWVLN = CWVLN; +namespace D { + int d1; + void f(char); +} +using namespace D; + +int d1; // OK: no conflict with \tcode{D::d1} + +namespace E { + int e; + void f(int); +} + +namespace D { // namespace extension + int d2; + using namespace E; + void f(int); +} + +void f() { + d1++; // error: ambiguous \tcode{::d1} or \tcode{D::d1}? + ::d1++; // OK + D::d1++; // OK + d2++; // OK: \tcode{D::d2} + e++; // OK: \tcode{E::e} + f(1); // error: ambiguous: \tcode{D::f(int)} or \tcode{E::f(int)}? + f('a'); // OK: \tcode{D::f(char)} +} \end{codeblock} -\end{example} +\end{example}% +\indextext{using-directive|)}% +\indextext{namespaces|)} -\rSec2[namespace.udecl]{The \tcode{using} declaration}% +\rSec1[namespace.udecl]{The \tcode{using} declaration}% \indextext{using-declaration|(} \begin{bnf} @@ -2741,7 +7186,7 @@ \end{note} If a constructor or assignment operator brought from a base class into a derived class has the signature of a copy/move constructor or assignment operator -for the derived class\iref{class.copy}, +for the derived class~(\ref{class.copy.ctor}, \ref{class.copy.assign}), the \grammarterm{using-declaration} does not by itself suppress the implicit declaration of the derived class member; the member from the base class is hidden or overridden @@ -3020,24 +7465,28 @@ \pnum \indextext{overloading!using-declaration and}% +\begin{note} For the purpose of forming a set of candidates during overload resolution, the functions that are introduced by a \grammarterm{using-declaration} into a derived class -are treated as though they were members of the derived class. In -particular, the implicit \tcode{this} parameter shall be treated as if -it were a pointer to the derived class rather than to the base class. +are treated as though they were members of the derived class\iref{class.member.lookup}. In +particular, the implicit object parameter is treated as if +it were a reference to the derived class rather than to the base class\iref{over.match.funcs}. This has no effect on the type of the function, and in all other respects the function remains a member of the base class. -Likewise, constructors that are introduced by a \grammarterm{using-declaration} +\end{note} + +\pnum +Constructors that are introduced by a \grammarterm{using-declaration} are treated as though they were constructors of the derived class when looking up the constructors of the derived class\iref{class.qual} or forming a set of overload candidates~(\ref{over.match.ctor}, \ref{over.match.copy}, \ref{over.match.list}). +\begin{note} If such a constructor is selected to perform the initialization of an object of class type, all subobjects other than the base class from which the constructor originated are implicitly initialized\iref{class.inhctor.init}. -\begin{note} -A member of a derived class is sometimes preferred to a member of a base class +A constructor of a derived class is sometimes preferred to a constructor of a base class if they would otherwise be ambiguous\iref{over.match.best}. \end{note} @@ -3052,280 +7501,69 @@ member name shall be accessible. If the name is that of an overloaded member function, then all functions named shall be accessible. The base class members mentioned by a \grammarterm{using-declarator} shall be -visible in the scope of at least one of the direct base classes of the -class where the \grammarterm{using-declarator} is specified. - -\pnum -\begin{note} -Because a \grammarterm{using-declarator} designates a base class member -(and not a member subobject or a member function of a base class -subobject), a \grammarterm{using-declarator} cannot be used to resolve -inherited member ambiguities. -\begin{example} -\begin{codeblock} -struct A { int x(); }; -struct B : A { }; -struct C : A { - using A::x; - int x(int); -}; - -struct D : B, C { - using C::x; - int x(double); -}; -int f(D* d) { - return d->x(); // error: overload resolution selects \tcode{A::x}, but \tcode{A} is an ambiguous base class -} -\end{codeblock} -\end{example} -\end{note} - -\pnum -A synonym created by a \grammarterm{using-declaration} has the usual -accessibility for a \grammarterm{member-declaration}. -A \grammarterm{using-declarator} that names a constructor does not -create a synonym; instead, the additional constructors -are accessible if they would be accessible -when used to construct an object of the corresponding base class, -and the accessibility of the \grammarterm{using-declaration} is ignored. -\begin{example} - -\begin{codeblock} -class A { -private: - void f(char); -public: - void f(int); -protected: - void g(); -}; - -class B : public A { - using A::f; // error: \tcode{A::f(char)} is inaccessible -public: - using A::g; // \tcode{B::g} is a public synonym for \tcode{A::g} -}; -\end{codeblock} -\end{example} - -\pnum -If a \grammarterm{using-declarator} uses the keyword \tcode{typename} and -specifies a dependent name\iref{temp.dep}, the name introduced by the -\grammarterm{using-declaration} is treated as a -\grammarterm{typedef-name}\iref{dcl.typedef}.% -\indextext{using-declaration|)} - -\rSec2[namespace.udir]{Using directive}% -\indextext{using-directive|(} - -\begin{bnf} -\nontermdef{using-directive}\br - \opt{attribute-specifier-seq} \terminal{using namespace} \opt{nested-name-specifier} namespace-name \terminal{;} -\end{bnf} - -\pnum -A \grammarterm{using-directive} shall not appear in class scope, but may -appear in namespace scope or in block scope. -\begin{note} -When looking up a \grammarterm{namespace-name} in a -\grammarterm{using-directive}, only namespace names are considered, -see~\ref{basic.lookup.udir}. -\end{note} -The optional \grammarterm{attribute-specifier-seq} appertains to the \grammarterm{using-directive}. - -\pnum -A \grammarterm{using-directive} specifies that the names in the nominated -namespace can be used in the scope in which the -\grammarterm{using-directive} appears after the \grammarterm{using-directive}. -During unqualified name lookup\iref{basic.lookup.unqual}, the names -appear as if they were declared in the nearest enclosing namespace which -contains both the \grammarterm{using-directive} and the nominated -namespace. -\begin{note} -In this context, ``contains'' means ``contains directly or indirectly''. -\end{note} - -\pnum -A \grammarterm{using-directive} does not add any members to the declarative -region in which it appears. -\begin{example} - -\begin{codeblock} -namespace A { - int i; - namespace B { - namespace C { - int i; - } - using namespace A::B::C; - void f1() { - i = 5; // OK, \tcode{C::i} visible in \tcode{B} and hides \tcode{A::i} - } - } - namespace D { - using namespace B; - using namespace C; - void f2() { - i = 5; // ambiguous, \tcode{B::C::i} or \tcode{A::i}? - } - } - void f3() { - i = 5; // uses \tcode{A::i} - } -} -void f4() { - i = 5; // ill-formed; neither \tcode{i} is visible -} -\end{codeblock} -\end{example} - -\pnum -For unqualified lookup\iref{basic.lookup.unqual}, the -\grammarterm{using-directive} is transitive: if a scope contains a -\grammarterm{using-directive} that nominates a second namespace that itself -contains \grammarterm{using-directive}{s}, the effect is as if the -\grammarterm{using-directive}{s} from the second namespace also appeared in -the first. -\begin{note} For qualified lookup, see~\ref{namespace.qual}. \end{note} -\begin{example} - -\begin{codeblock} -namespace M { - int i; -} - -namespace N { - int i; - using namespace M; -} - -void f() { - using namespace N; - i = 7; // error: both \tcode{M::i} and \tcode{N::i} are visible -} -\end{codeblock} - -For another example, - -\begin{codeblock} -namespace A { - int i; -} -namespace B { - int i; - int j; - namespace C { - namespace D { - using namespace A; - int j; - int k; - int a = i; // \tcode{B::i} hides \tcode{A::i} - } - using namespace D; - int k = 89; // no problem yet - int l = k; // ambiguous: \tcode{C::k} or \tcode{D::k} - int m = i; // \tcode{B::i} hides \tcode{A::i} - int n = j; // \tcode{D::j} hides \tcode{B::j} - } -} -\end{codeblock} -\end{example} - - -\pnum -If a namespace is extended\iref{namespace.def} after a -\grammarterm{using-directive} for that namespace is given, the additional -members of the extended namespace and the members of namespaces -nominated by \grammarterm{using-directive}{s} in the -extending \grammarterm{namespace-definition} can be used after the -extending \grammarterm{namespace-definition}. - -\pnum -\begin{note} -If name lookup finds a declaration for a name in two different -namespaces, and the declarations do not declare the same entity and do -not declare functions or function templates, the use of the name is ill-formed\iref{basic.lookup}. -In particular, the name of a variable, function or enumerator does not -hide the name of a class or enumeration declared in a different -namespace. For example, +visible in the scope of at least one of the direct base classes of the +class where the \grammarterm{using-declarator} is specified. +\pnum +\begin{note} +Because a \grammarterm{using-declarator} designates a base class member +(and not a member subobject or a member function of a base class +subobject), a \grammarterm{using-declarator} cannot be used to resolve +inherited member ambiguities. +\begin{example} \begin{codeblock} -namespace A { - class X { }; - extern "C" int g(); - extern "C++" int h(); -} -namespace B { - void X(int); - extern "C" int g(); - extern "C++" int h(int); -} -using namespace A; -using namespace B; +struct A { int x(); }; +struct B : A { }; +struct C : A { + using A::x; + int x(int); +}; -void f() { - X(1); // error: name \tcode{X} found in two namespaces - g(); // OK: name \tcode{g} refers to the same entity - h(); // OK: overload resolution selects \tcode{A::h} +struct D : B, C { + using C::x; + int x(double); +}; +int f(D* d) { + return d->x(); // error: overload resolution selects \tcode{A::x}, but \tcode{A} is an ambiguous base class } \end{codeblock} +\end{example} \end{note} \pnum -\indextext{overloading!using directive and}% -During overload resolution, all functions from the transitive search are -considered for argument matching. The set of declarations found by the -transitive search is unordered. -\begin{note} -In particular, the order in which namespaces were considered and the -relationships among the namespaces implied by the -\grammarterm{using-directive}{s} do not cause preference to be given to any -of the declarations found by the search. -\end{note} -An ambiguity exists if the best match finds two functions with the same -signature, even if one is in a namespace reachable through -\grammarterm{using-directive}{s} in the namespace of the other.\footnote{During -name lookup in a class hierarchy, some ambiguities may be -resolved by considering whether one member hides the other along some -paths\iref{class.member.lookup}. There is no such disambiguation when -considering the set of names found as a result of following -\grammarterm{using-directive}{s}.} +A synonym created by a \grammarterm{using-declaration} has the usual +accessibility for a \grammarterm{member-declaration}. +A \grammarterm{using-declarator} that names a constructor does not +create a synonym; instead, the additional constructors +are accessible if they would be accessible +when used to construct an object of the corresponding base class, +and the accessibility of the \grammarterm{using-declaration} is ignored. \begin{example} \begin{codeblock} -namespace D { - int d1; - void f(char); -} -using namespace D; - -int d1; // OK: no conflict with \tcode{D::d1} - -namespace E { - int e; - void f(int); -} - -namespace D { // namespace extension - int d2; - using namespace E; - void f(int); -} +class A { +private: + void f(char); +public: + void f(int); +protected: + void g(); +}; -void f() { - d1++; // error: ambiguous \tcode{::d1} or \tcode{D::d1}? - ::d1++; // OK - D::d1++; // OK - d2++; // OK: \tcode{D::d2} - e++; // OK: \tcode{E::e} - f(1); // error: ambiguous: \tcode{D::f(int)} or \tcode{E::f(int)}? - f('a'); // OK: \tcode{D::f(char)} -} +class B : public A { + using A::f; // error: \tcode{A::f(char)} is inaccessible +public: + using A::g; // \tcode{B::g} is a public synonym for \tcode{A::g} +}; \end{codeblock} -\end{example}% -\indextext{using-directive|)}% -\indextext{namespaces|)} +\end{example} + +\pnum +If a \grammarterm{using-declarator} uses the keyword \tcode{typename} and +specifies a dependent name\iref{temp.dep}, the name introduced by the +\grammarterm{using-declaration} is treated as a +\grammarterm{typedef-name}\iref{dcl.typedef}.% +\indextext{using-declaration|)} \rSec1[dcl.asm]{The \tcode{asm} declaration}% \indextext{declaration!\idxcode{asm}}% @@ -3602,6 +7840,7 @@ \begin{bnf} \nontermdef{attribute-specifier}\br \terminal{[} \terminal{[} \opt{attribute-using-prefix} attribute-list \terminal{]} \terminal{]}\br + contract-attribute-specifier\br alignment-specifier \end{bnf} @@ -3935,6 +8174,431 @@ \indextext{attribute|)}% \indextext{declaration|)} +\rSec2[dcl.attr.contract]{Contract attributes}% +\indextext{attribute!contracts|(} + +\rSec3[dcl.attr.contract.syn]{Syntax} + +\pnum +Contract attributes are used to specify +preconditions, postconditions, and assertions for functions. + +\begin{bnf} +\nontermdef{contract-attribute-specifier}\br + \terminal{[} \terminal{[} \terminal{expects} \opt{contract-level} \terminal{:} conditional-expression \terminal{]} \terminal{]}\br + \terminal{[} \terminal{[} \terminal{ensures} \opt{contract-level} \opt{identifier} \terminal{:} conditional-expression \terminal{]} \terminal{]}\br + \terminal{[} \terminal{[} \terminal{assert} \opt{contract-level} \terminal{:} conditional-expression \terminal{]} \terminal{]} +\end{bnf} + +\begin{bnf} +\nontermdef{contract-level}\br + \terminal{default}\br + \terminal{audit}\br + \terminal{axiom} +\end{bnf} + + +An ambiguity between +a \grammarterm{contract-level} and an \grammarterm{identifier} +is resolved in favor of \grammarterm{contract-level}. + +\pnum +A \grammarterm{contract-attribute-specifier} using \tcode{expects} +is a \defn{precondition}. +It expresses a function's expectation on its arguments and/or +the state of other objects using a predicate +that is intended to hold upon entry into the function. +The attribute may be applied to the function type of a function declaration. + +\pnum +A \grammarterm{contract-attribute-specifier} using \tcode{ensures} +is a \defn{postcondition}. +It expresses a condition that a function should ensure +for the return value and/or the state of objects +using a predicate that is intended to hold upon exit from the function. +The attribute may be applied to the function type of a function declaration. +A postcondition may introduce an identifier to represent +the glvalue result or the prvalue result object of the function. +\begin{example} +\begin{codeblock} +int f(char * c) + [[ensures res: res > 0 && c != nullptr]]; + +int g(double * p) + [[ensures audit res: res != 0 && p != nullptr && *p <= 0.0]]; +\end{codeblock} +\end{example} + +\pnum +A \grammarterm{contract-attribute-specifier} using \tcode{assert} +is an \defn{assertion}. +It expresses a condition that is intended to be satisfied +where it appears in a function body. +The attribute may be applied to a null statement\iref{stmt.expr}. +An assertion is checked by evaluating its predicate +as part of the evaluation of the null statement +it applies to. + +\pnum +Preconditions, postconditions, and assertions +are collectively called \defnx{contracts}{contract}. +The \grammarterm{conditional-expression} in a contract +is contextually converted to \tcode{bool}\iref{conv}; +the converted expression is called +the \defnx{predicate}{contract!predicate} of the contract. +\begin{note} +The predicate of a contract is potentially evaluated\iref{basic.def.odr}. +\end{note} + +\pnum +The only side effects of a predicate +that are allowed in a \grammarterm{contract-attribute-specifier} +are modifications of non-volatile objects +whose lifetime began and ended within the evaluation of the predicate. +An evaluation of a predicate that exits via an exception +invokes the function \tcode{std::terminate}\iref{except.terminate}. +The behavior of any other side effect is undefined. +\begin{example} +\begin{codeblock} +void push(int x, queue & q) + [[expects: !q.full()]] + [[ensures: !q.empty()]] +{ + @\commentellip@ + [[assert: q.is_valid()]]; + @\commentellip@ +} + +int min = -42; +constexpr int max = 42; + +constexpr int g(int x) + [[expects: min <= x]] // error + [[expects: x < max]] // OK +{ + @\commentellip@ + [[assert: 2*x < max]]; + [[assert: ++min > 0]]; // undefined behavior + @\commentellip@ +} +\end{codeblock} +\end{example} + +\rSec3[dcl.attr.contract.cond]{Contract conditions} + +\pnum +A \defn{contract condition} is a precondition or a postcondition. +The first declaration of a function shall specify +all contract conditions (if any) of the function. +Subsequent declarations shall either specify no contract conditions +or the same list of contract conditions; +no diagnostic is required +if corresponding conditions will always evaluate to the same value. +The list of contract conditions of a function shall be the same +if the declarations of that function appear in different translation units; +no diagnostic required. +If a friend declaration +is the first declaration of the function in a translation unit +and has a contract condition, +the declaration shall be a definition and +shall be the only declaration of the function in the translation unit. + +\pnum +Two lists of contract conditions are the same +if they consist of the same contract conditions in the same order. +Two contract conditions are the same +if their contract levels are the same and their predicates are the same. +Two predicates contained in \grammarterm{contract-attribute-specifier}{s} +are the same +if they would satisfy the one-definition rule\iref{basic.def.odr} +were they to appear in function definitions, +except for renaming of parameters, +return value identifiers (if any), +and template parameters. + +\pnum +\begin{note} +A function pointer cannot include contract conditions. +\begin{example} +\begin{codeblock} +typedef int (*fpt)() [[ensures r: r != 0]]; // error: contract condition not on a function declaration + +int g(int x) + [[expects: x >= 0]] + [[ensures r: r > x]] +{ + return x+1; +} + +int (*pf)(int) = g; // OK +int x = pf(5); // contract conditions of \tcode{g} are checked +\end{codeblock} +\end{example} +\end{note} + +\pnum +The predicate of a contract condition has the same semantic restrictions +as if it appeared as the first \grammarterm{expression-statement} +in the body of the function it applies to. +Additional access restrictions apply to names appearing in +a contract condition of a member function of class \tcode{C}: +\begin{itemize} +\item Friendship is not considered\iref{class.friend}. +\item For a contract condition of a public member function, +no member of \tcode{C} or of an enclosing class of \tcode{C} is accessible +unless it is a public member of \tcode{C}, +or a member of a base class +accessible as a public member of \tcode{C}\iref{class.access.base}. +\item For a contract condition of a protected member function, +no member of \tcode{C} or of an enclosing class of \tcode{C} is accessible +unless it is a public or protected member of \tcode{C}, +or a member of a base class +accessible as a public or protected member of \tcode{C}. +\end{itemize} +For names appearing in a contract condition of a non-member function, +friendship is not considered. +\begin{example} +\begin{codeblock} +class X { +public: + int v() const; + void f() [[expects: x > 0]]; // error: \tcode{x} is private + void g() [[expects: v() > 0]]; // OK + friend void r(int z) [[expects: z > 0]]; // OK + friend void s(int z) [[expects: z > x]]; // error: \tcode{x} is private +protected: + int w(); + void h() [[expects: x > 0]]; // error: \tcode{x} is private + void i() [[ensures: y > 0]]; // OK + void j() [[ensures: w() > 0]]; // OK + int y; +private: + void k() [[expects: x > 0]]; // OK + int x; +}; + +class Y : public X { +public: + void a() [[expects: v() > 0]]; // OK + void b() [[ensures: w() > 0]]; // error: \tcode{w} is protected +protected: + void c() [[expects: w() > 0]]; // OK +}; +\end{codeblock} +\end{example} + +\pnum +A precondition is checked by evaluating its predicate +immediately before starting evaluation of the function body. +\begin{note} +The function body includes +the \grammarterm{function-try-block}\iref{except} and +the \grammarterm{ctor-initializer}\iref{class.base.init}. +\end{note} +A postcondition is checked by evaluating its predicate +immediately before returning control to the caller of the function. +\begin{note} +The lifetime of local variables and temporaries has ended. +Exiting via an exception or via \tcode{longjmp}\iref{csetjmp.syn} +is not considered returning control to the caller of the function. +\end{note} + +\pnum +If a function has multiple preconditions, +their evaluation (if any) will be performed +in the order they appear lexically. +If a function has multiple postconditions, +their evaluation (if any) will be performed +in the order they appear lexically. +\begin{example} +\begin{codeblock} +void f(int * p) + [[expects: p != nullptr]] // \#1 + [[ensures: *p == 1]] // \#3 + [[expects: *p == 0]] // \#2 +{ + *p = 1; +} +\end{codeblock} +\end{example} + +\pnum +If a postcondition odr-uses\iref{basic.def.odr} +a parameter in its predicate +and the function body makes direct or indirect modifications of +the value of that parameter, +the behavior is undefined. +\begin{example} +\begin{codeblock} +int f(int x) + [[ensures r: r == x]] +{ + return ++x; // undefined behavior +} + +int g(int * p) + [[ensures r: p != nullptr]] +{ + *p = 42; // OK, \tcode{p} is not modified +} + +int h(int x) + [[ensures r: r == x]] +{ + potentially_modify(x); // undefined behavior if \tcode{x} is modified + return x; +} +\end{codeblock} +\end{example} + +\rSec3[dcl.attr.contract.check]{Checking contracts} + +\pnum +If the \grammarterm{contract-level} +of a \grammarterm{contract-attribute-specifier} is absent, +it is assumed to be \tcode{default}. +\begin{note} +A \tcode{default} \grammarterm{contract-level} is expected to be used +for those contracts where +the cost of run-time checking is assumed to be +small (or at least not expensive) compared to +the cost of executing the function. +An \tcode{audit} \grammarterm{contract-level} is expected to be used +for those contracts where +the cost of run-time checking is assumed to be +large (or at least significant) compared to +the cost of executing the function. +An \tcode{axiom} \grammarterm{contract-level} is expected to be used +for those contracts that are formal comments +and are not evaluated at run-time. +\end{note} + +\pnum +\begin{note} +Multiple contract conditions may be applied to a function type +with the same or different \grammarterm{contract-level}{s}. +\begin{example} +\begin{codeblock} +int z; + +bool is_prime(int k); + +void f(int x) + [[expects: x > 0]] + [[expects audit: is_prime(x)]] + [[ensures: z > 10]] +{ + @\commentellip@ +} +\end{codeblock} +\end{example} +\end{note} + +\pnum +A translation may be performed +with one of the following \defnx{build levels}{build level}: +\term{off}, \term{default}, or \term{audit}. +A translation with build level set to \term{off} +performs no checking for any contract. +A translation with build level set to \term{default} +performs checking for \tcode{default} contracts. +A translation with build level set to \term{audit} +performs checking for \tcode{default} and \tcode{audit} contracts. +If no build level is explicitly selected, the build level is \term{default}. +The mechanism for selecting the build level is +\impldef{mechanism for selecting the build level}. +The translation of a program consisting of translation units +where the build level is not the same in all translation units +is conditionally-supported. +There should be no programmatic way of setting, modifying, or querying +the build level of a translation unit. + +\pnum +During constant expression evaluation\iref{expr.const}, +only predicates of checked contracts are evaluated. +In other contexts, +it is unspecified whether the predicate for a contract +that is not checked under the current build level is evaluated; +if the predicate of such a contract +would evaluate to \tcode{false}, the behavior is undefined. + +\pnum +The \defn{violation handler} of a program is a function of type +``\opt{\tcode{noexcept}} function of +(lvalue reference to \tcode{const std::contract_violation}) +returning \tcode{void}'', and is specified in an +\impldef{specification of violation handler} manner. +The violation handler is invoked +when the predicate of a checked contract evaluates to \tcode{false} +(called a \defn{contract violation}). +There should be no programmatic way of +setting or modifying the violation handler. +It is \impldef{argument for violation handler} +how the violation handler is established for a program and +how +the \tcode{std::contract_violation}\iref{support.contract.cviol} argument value +is set, +except as specified below. +If a precondition is violated, the source location of the violation is +\impldef{source location of precondition violation}. +\begin{note} +Implementations are encouraged but not required to report the caller site. +\end{note} +If a postcondition is violated, the source location of the violation is +the source location of the function definition. +If an assertion is violated, the source location of the violation is +the source location of the statement to which the assertion is applied. + +\pnum +If a user-provided violation handler exits by throwing an exception +and a contract is violated on a call to a function +with a non-throwing exception specification, +then the behavior is as if the exception escaped the function body. +\begin{note} +The function \tcode{std::terminate} is invoked\iref{except.terminate}. +\end{note} +\begin{example} +\begin{codeblock} +void f(int x) noexcept [[expects: x > 0]]; + +void g() { + f(0); // \tcode{std::terminate()} if violation handler throws + @\commentellip@ +} +\end{codeblock} +\end{example} + +\pnum +A translation may be performed with one of the following +\defnx{violation continuation modes}{violation continuation mode}: +\term{off} or \term{on}. +A translation with violation continuation mode set to \term{off} +terminates execution +by invoking the function \tcode{std::terminate}\iref{except.terminate} +after completing the execution of the violation handler. +A translation with a violation continuation mode set to \term{on} +continues execution after completing the execution of the violation handler. +If no continuation mode is explicitly selected, +the default continuation mode is \term{off}. +\begin{note} +A continuation mode set to \term{on} provides the opportunity +to install a logging handler to instrument a pre-existing code base +and fix errors before enforcing checks. +\end{note} +\begin{example} +\begin{codeblock} +void f(int x) [[expects: x > 0]]; + +void g() { + f(0); // \tcode{std::terminate()} after handler if continuation mode is off; + // proceeds after handler if continuation mode is on + @\commentellip@ +} +\end{codeblock} +\end{example} + +\indextext{attribute!contracts|)} + \rSec2[dcl.attr.deprecated]{Deprecated attribute}% \indextext{attribute!deprecated} @@ -4079,7 +8743,7 @@ g(1); [[fallthrough]]; - [[likely]] case 2: // \tcode{n == 3} is considered to be arbitrarily more + [[likely]] case 2: // \tcode{n == 2} is considered to be arbitrarily more g(2); // likely than any other value of \tcode{n} break; } diff --git a/source/declarators.tex b/source/declarators.tex deleted file mode 100644 index 4bd8d4cb4d..0000000000 --- a/source/declarators.tex +++ /dev/null @@ -1,4196 +0,0 @@ -%!TEX root = std.tex -\rSec0[dcl.decl]{Declarators}% -\indextext{declarator|(} - -\gramSec[gram.decl]{Declarators} - -\indextext{initialization!class object|seealso{constructor}}% -\indextext{\idxcode{*}|see{declarator, pointer}} -\indextext{\idxcode{\&}|see{declarator, reference}}% -\indextext{\idxcode{::*}|see{declarator, pointer-to-member}}% -\indextext{\idxcode{[]}|see{declarator, array}}% -\indextext{\idxcode{()}|see{declarator, function}}% - -\pnum -A declarator declares a single variable, function, or type, within a declaration. -The -\grammarterm{init-declarator-list} -appearing in a declaration -is a comma-separated sequence of declarators, -each of which can have an initializer. - -\begin{bnf} -\nontermdef{init-declarator-list}\br - init-declarator\br - init-declarator-list \terminal{,} init-declarator -\end{bnf} - -\begin{bnf} -\nontermdef{init-declarator}\br - declarator \opt{initializer}\br - declarator requires-clause -\end{bnf} - -\pnum -The three components of a -\grammarterm{simple-declaration} -are the -attributes\iref{dcl.attr}, the -specifiers -(\grammarterm{decl-specifier-seq}; -\ref{dcl.spec}) and the declarators -(\grammarterm{init-declarator-list}). -The specifiers indicate the type, storage class or other properties of -the entities being declared. -The declarators specify the names of these entities -and (optionally) modify the type of the specifiers with operators such as -\tcode{*} -(pointer -to) -and -\tcode{()} -(function returning). -Initial values can also be specified in a declarator; -initializers are discussed in~\ref{dcl.init} and~\ref{class.init}. - -\pnum -Each -\grammarterm{init-declarator} -in a declaration is analyzed separately as if it was in a declaration by itself. -\begin{note} -A declaration with several declarators is usually equivalent to the corresponding -sequence of declarations each with a single declarator. That is -\begin{codeblock} -T D1, D2, ... Dn; -\end{codeblock} -is usually equivalent to -\begin{codeblock} -T D1; T D2; ... T Dn; -\end{codeblock} -where \tcode{T} is a \grammarterm{decl-specifier-seq} -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-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 { @\commentellip@ }; -S S, T; // declare two instances of \tcode{struct S} -\end{codeblock} -which is not equivalent to -\begin{codeblock} -struct S { @\commentellip@ }; -S S; -S T; // error -\end{codeblock} -Another exception is when \tcode{T} is \tcode{auto}\iref{dcl.spec.auto}, -for example: -\begin{codeblock} -auto i = 1, j = 2.0; // error: deduced types for \tcode{i} and \tcode{j} do not match -\end{codeblock} -as opposed to -\begin{codeblock} -auto i = 1; // OK: \tcode{i} deduced to have type \tcode{int} -auto j = 2.0; // OK: \tcode{j} deduced to have type \tcode{double} -\end{codeblock} -\end{note} - -\pnum -The optional \grammarterm{requires-clause}\iref{temp} in an -\grammarterm{init-declarator} or \grammarterm{member-declarator} -shall not be present when the declarator does not declare a -function\iref{dcl.fct}. -% -\indextext{trailing requires-clause@trailing \textit{requires-clause}|see{\textit{requires-clause}, trailing}}% -When present after a declarator, the \grammarterm{requires-clause} -is called the \defnx{trailing \grammarterm{requires-clause}}{% -\idxgram{requires-clause}!trailing}. -The trailing \grammarterm{requires-clause} introduces the -\grammarterm{constraint-expression} that results from interpreting -its \grammarterm{constraint-logical-or-expression} as a -\grammarterm{constraint-expression}. -% -\begin{example} -\begin{codeblock} -void f1(int a) requires true; // OK -auto f2(int a) -> bool requires true; // OK -auto f3(int a) requires true -> bool; // error: \grammarterm{requires-clause} precedes \grammarterm{trailing-return-type} -void (*pf)() requires true; // error: constraint on a variable -void g(int (*)() requires true); // error: constraint on a \grammarterm{parameter-declaration} - -auto* p = new void(*)(char) requires true; // error: not a function declaration -\end{codeblock} -\end{example} - -\pnum -Declarators have the syntax - -\begin{bnf} -\nontermdef{declarator}\br - ptr-declarator\br - noptr-declarator parameters-and-qualifiers trailing-return-type -\end{bnf} - -\begin{bnf} -\nontermdef{ptr-declarator}\br - noptr-declarator\br - ptr-operator ptr-declarator -\end{bnf} - -\begin{bnf} -\nontermdef{noptr-declarator}\br - declarator-id \opt{attribute-specifier-seq}\br - noptr-declarator parameters-and-qualifiers\br - noptr-declarator \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq}\br - \terminal{(} ptr-declarator \terminal{)} -\end{bnf} - -\begin{bnf} -\nontermdef{parameters-and-qualifiers}\br - \terminal{(} parameter-declaration-clause \terminal{)} \opt{cv-qualifier-seq}\br - \bnfindent\opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq} -\end{bnf} - -\begin{bnf} -\nontermdef{trailing-return-type}\br - \terminal{->} type-id -\end{bnf} - -\begin{bnf} -\nontermdef{ptr-operator}\br - \terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq}\br - \terminal{\&} \opt{attribute-specifier-seq}\br - \terminal{\&\&} \opt{attribute-specifier-seq}\br - nested-name-specifier \terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq} -\end{bnf} - -\begin{bnf} -\nontermdef{cv-qualifier-seq}\br - cv-qualifier \opt{cv-qualifier-seq} -\end{bnf} - -\begin{bnf} -\nontermdef{cv-qualifier}\br - \terminal{const}\br - \terminal{volatile} -\end{bnf} - -\begin{bnf} -\nontermdef{ref-qualifier}\br - \terminal{\&}\br - \terminal{\&\&} -\end{bnf} - -\begin{bnf} -\nontermdef{declarator-id}\br - \opt{\terminal{...}} id-expression -\end{bnf} - -\rSec1[dcl.name]{Type names} - -\pnum -\indextext{type name}% -To specify type conversions explicitly, -\indextext{operator!cast}% -and as an argument of -\tcode{sizeof}, -\tcode{alignof}, -\tcode{new}, -or -\tcode{typeid}, -the name of a type shall be specified. -This can be done with a -\grammarterm{type-id}, -which is syntactically a declaration for a variable or function -of that type that omits the name of the entity. - -\begin{bnf} -\nontermdef{type-id}\br - type-specifier-seq \opt{abstract-declarator} -\end{bnf} - -\begin{bnf} -\nontermdef{defining-type-id}\br - defining-type-specifier-seq \opt{abstract-declarator} -\end{bnf} - -\begin{bnf} -\nontermdef{abstract-declarator}\br - ptr-abstract-declarator\br - \opt{noptr-abstract-declarator} parameters-and-qualifiers trailing-return-type\br - abstract-pack-declarator -\end{bnf} - -\begin{bnf} -\nontermdef{ptr-abstract-declarator}\br - noptr-abstract-declarator\br - ptr-operator \opt{ptr-abstract-declarator} -\end{bnf} - -\begin{bnf} -\nontermdef{noptr-abstract-declarator}\br - \opt{noptr-abstract-declarator} parameters-and-qualifiers\br - \opt{noptr-abstract-declarator} \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq}\br - \terminal{(} ptr-abstract-declarator \terminal{)} -\end{bnf} - -\begin{bnf} -\nontermdef{abstract-pack-declarator}\br - noptr-abstract-pack-declarator\br - ptr-operator abstract-pack-declarator -\end{bnf} - -\begin{bnf} -\nontermdef{noptr-abstract-pack-declarator}\br - noptr-abstract-pack-declarator parameters-and-qualifiers\br - noptr-abstract-pack-declarator \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq}\br - \terminal{...} -\end{bnf} - -It is possible to identify uniquely the location in the -\grammarterm{abstract-declarator} -where the identifier would appear if the construction were a declarator -in a declaration. -The named type is then the same as the type of the -hypothetical identifier. -\begin{example} -\begin{codeblock} -int // \tcode{int i} -int * // \tcode{int *pi} -int *[3] // \tcode{int *p[3]} -int (*)[3] // \tcode{int (*p3i)[3]} -int *() // \tcode{int *f()} -int (*)(double) // \tcode{int (*pf)(double)} -\end{codeblock} -name respectively the types -``\tcode{int}'', -``pointer to -\tcode{int}'', -``array of 3 pointers to -\tcode{int}'', -``pointer to array of 3 -\tcode{int}'', -``function of (no parameters) returning pointer to -\tcode{int}'', -and ``pointer to a function of -(\tcode{double}) -returning -\tcode{int}''. -\end{example} - -\pnum -A type can also be named (often more easily) by using a -\tcode{typedef}\iref{dcl.typedef}. - -\rSec1[dcl.ambig.res]{Ambiguity resolution}% -\indextext{ambiguity!declaration versus cast}% -\indextext{declaration!parentheses in} - -\pnum -The ambiguity arising from the similarity between a function-style cast and -a declaration mentioned in~\ref{stmt.ambig} can also occur in the context of a declaration. -In that context, the choice is between a function declaration with -a redundant set of parentheses around a parameter name and an object declaration -with a function-style cast as the initializer. -Just as for the ambiguities mentioned in~\ref{stmt.ambig}, -the resolution is to consider any construct that could possibly -be a declaration a declaration. -\begin{note} -A declaration can be explicitly disambiguated by adding parentheses -around the argument. -The ambiguity can be avoided by use of copy-initialization or -list-initialization syntax, or by use of a non-function-style cast. -\end{note} -\begin{example} -\begin{codeblock} -struct S { - S(int); -}; - -void foo(double a) { - S w(int(a)); // function declaration - S x(int()); // function declaration - S y((int(a))); // object declaration - S y((int)a); // object declaration - S z = int(a); // object declaration -} -\end{codeblock} -\end{example} - -\pnum -An ambiguity can arise from the similarity between a function-style -cast and a -\grammarterm{type-id}. -The resolution is that any construct that could possibly be a -\grammarterm{type-id} -in its syntactic context shall be considered a -\grammarterm{type-id}. -\begin{example} - -\begin{codeblock} -template struct X {}; -template struct Y {}; -X a; // type-id -X b; // expression (ill-formed) -Y c; // type-id (ill-formed) -Y d; // expression - -void foo(signed char a) { - sizeof(int()); // type-id (ill-formed) - sizeof(int(a)); // expression - sizeof(int(unsigned(a))); // type-id (ill-formed) - - (int())+1; // type-id (ill-formed) - (int(a))+1; // expression - (int(unsigned(a)))+1; // type-id (ill-formed) -} -\end{codeblock} -\end{example} - -\pnum -Another ambiguity arises in 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 -pointer to function and the declaration of a parameter with redundant -parentheses around the -\grammarterm{declarator-id}. -The resolution is to consider the -\grammarterm{type-name} -as a -\grammarterm{simple-type-specifier} -rather than a -\grammarterm{declarator-id}. -\begin{example} - -\begin{codeblock} -class C { }; -void f(int(C)) { } // \tcode{void f(int(*fp)(C c)) \{ \}} - // not: \tcode{void f(int C) \{ \}} - -int g(C); - -void foo() { - f(1); // error: cannot convert \tcode{1} to function pointer - f(g); // OK -} -\end{codeblock} - -For another example, - -\begin{codeblock} -class C { }; -void h(int *(C[10])); // \tcode{void h(int *(*_fp)(C _parm[10]));} - // not: \tcode{void h(int *C[10]);} -\end{codeblock} -\end{example} - -\rSec1[dcl.meaning]{Meaning of declarators}% -\indextext{declarator!meaning of|(} - -\pnum -\indextext{declaration!type}% -A declarator contains exactly one -\grammarterm{declarator-id}; -it names the identifier that is declared. -An -\grammarterm{unqualified-id} -occurring in -a -\grammarterm{declarator-id} -shall be a simple -\grammarterm{identifier} -except for the declaration of some special functions~(\ref{class.ctor}, -\ref{class.conv}, \ref{class.dtor}, \ref{over.oper}) and -for the declaration of template specializations -or partial specializations\iref{temp.spec}. -When the -\grammarterm{declarator-id} -is qualified, the declaration shall refer to a previously declared member -of the class or namespace to which the qualifier refers (or, -in the case of a namespace, -of an element of the inline namespace -set of that namespace\iref{namespace.def}) or to a specialization thereof; the member -shall not merely have been introduced by a -\grammarterm{using-declaration} -in the scope of the class or namespace nominated by the -\grammarterm{nested-name-specifier} -of the -\grammarterm{declarator-id}. -The \grammarterm{nested-name-specifier} of a qualified \grammarterm{declarator-id} shall not -begin with a \grammarterm{decltype-specifier}. -\begin{note} -If the qualifier is the global -\tcode{::} -scope resolution operator, the -\grammarterm{declarator-id} -refers to a name declared in the global namespace scope. -\end{note} -The optional \grammarterm{attribute-specifier-seq} following a \grammarterm{declarator-id} appertains to the entity that is declared. - -\pnum -A -\tcode{static}, -\tcode{thread_local}, -\tcode{extern}, -\tcode{mutable}, -\tcode{friend}, -\tcode{inline}, -\tcode{virtual}, -\tcode{constexpr}, -\tcode{explicit}, -or -\tcode{typedef} -specifier applies directly to each \grammarterm{declarator-id} -in an \grammarterm{init-declarator-list} or \grammarterm{member-declarator-list}; -the type specified for each \grammarterm{declarator-id} depends on -both the \grammarterm{decl-specifier-seq} and its \grammarterm{declarator}. - -\pnum -Thus, a declaration of a particular identifier has the form - -\begin{codeblock} -T D -\end{codeblock} - -where -\tcode{T} -is of the form \opt{\grammarterm{attribute-specifier-seq}} -\grammarterm{decl-specifier-seq} -and -\tcode{D} -is a declarator. -Following is a recursive procedure for determining -the type specified for the contained -\grammarterm{declarator-id} -by such a declaration. - -\pnum -First, the -\grammarterm{decl-specifier-seq} -determines a type. -In a declaration - -\begin{codeblock} -T D -\end{codeblock} - -the -\grammarterm{decl-specifier-seq} -\tcode{T} -determines the type -\tcode{T}. -\begin{example} -In the declaration - -\begin{codeblock} -int unsigned i; -\end{codeblock} - -the type specifiers -\tcode{int} -\tcode{unsigned} -determine the type -``\tcode{unsigned int}''\iref{dcl.type.simple}. -\end{example} - -\pnum -In a declaration -\opt{\grammarterm{attribute-specifier-seq}} -\tcode{T} -\tcode{D} -where -\tcode{D} -is an unadorned identifier the type of this identifier is -``\tcode{T}''. - -\pnum -In a declaration -\tcode{T} -\tcode{D} -where -\tcode{D} -has the form - -\begin{ncsimplebnf} -\terminal{(} \terminal{D1} \terminal{)} -\end{ncsimplebnf} - -the type of the contained -\grammarterm{declarator-id} -is the same as that of the contained -\grammarterm{declarator-id} -in the declaration -\begin{codeblock} -T D1 -\end{codeblock} -\indextext{declaration!parentheses in}% -Parentheses do not alter the type of the embedded -\grammarterm{declarator-id}, -but they can alter the binding of complex declarators. - -\rSec2[dcl.ptr]{Pointers}% -\indextext{declarator!pointer}% - -\pnum -In a declaration -\tcode{T} -\tcode{D} -where -\tcode{D} -has the form - -\begin{ncsimplebnf} -\terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq} \terminal{D1} -\end{ncsimplebnf} - -and the type of the identifier in the declaration -\tcode{T} -\tcode{D1} -is ``\placeholder{derived-declarator-type-list} -\tcode{T}'', -then the type of the identifier of -\tcode{D} -is ``\placeholder{derived-declarator-type-list} \grammarterm{cv-qualifier-seq} pointer to -\tcode{T}''. -\indextext{declaration!pointer}% -\indextext{declaration!constant pointer}% -The -\grammarterm{cv-qualifier}{s} -apply to the pointer and not to the object pointed to. -Similarly, the optional \grammarterm{attribute-specifier-seq}\iref{dcl.attr.grammar} appertains to the pointer and not to the object pointed to. - -\pnum -\begin{example} -The declarations -\begin{codeblock} -const int ci = 10, *pc = &ci, *const cpc = pc, **ppc; -int i, *p, *const cp = &i; -\end{codeblock} - -declare -\tcode{ci}, -a constant integer; -\tcode{pc}, -a pointer to a constant integer; -\tcode{cpc}, -a constant pointer to a constant integer; -\tcode{ppc}, -a pointer to a pointer to a constant integer; -\tcode{i}, -an integer; -\tcode{p}, -a pointer to integer; and -\tcode{cp}, -a constant pointer to integer. -The value of -\tcode{ci}, -\tcode{cpc}, -and -\tcode{cp} -cannot be changed after initialization. -The value of -\tcode{pc} -can be changed, and so can the object pointed to by -\tcode{cp}. -Examples of -some correct operations are - -\begin{codeblock} -i = ci; -*cp = ci; -pc++; -pc = cpc; -pc = p; -ppc = &pc; -\end{codeblock} - -Examples of ill-formed operations are - -\begin{codeblock} -ci = 1; // error -ci++; // error -*pc = 2; // error -cp = &ci; // error -cpc++; // error -p = pc; // error -ppc = &p; // error -\end{codeblock} - -Each is unacceptable because it would either change the value of an object declared -\tcode{const} -or allow it to be changed through a cv-unqualified pointer later, for example: - -\begin{codeblock} -*ppc = &ci; // OK, but would make \tcode{p} point to \tcode{ci} because of previous error -*p = 5; // clobber \tcode{ci} -\end{codeblock} -\end{example} - -\pnum -See also~\ref{expr.ass} and~\ref{dcl.init}. - -\pnum -\begin{note} -Forming a pointer to reference type is ill-formed; see~\ref{dcl.ref}. -Forming a function pointer type is ill-formed if the function type has -\grammarterm{cv-qualifier}{s} or a \grammarterm{ref-qualifier}; -see~\ref{dcl.fct}. -Since the address of a bit-field\iref{class.bit} cannot be taken, -a pointer can never point to a bit-field. -\end{note} - -\rSec2[dcl.ref]{References}% -\indextext{declarator!reference} - -\pnum -In a declaration -\tcode{T} -\tcode{D} -where -\tcode{D} -has either of the forms - -\begin{ncsimplebnf} -\terminal{\&} \opt{attribute-specifier-seq} \terminal{D1}\br -\terminal{\&\&} \opt{attribute-specifier-seq} \terminal{D1} -\end{ncsimplebnf} - -and the type of the identifier in the declaration -\tcode{T} -\tcode{D1} -is ``\placeholder{derived-declarator-type-list} -\tcode{T}'', -then the type of the identifier of -\tcode{D} -is ``\placeholder{derived-declarator-type-list} reference to -\tcode{T}''. -The optional \grammarterm{attribute-specifier-seq} appertains to the reference type. -Cv-qualified references are ill-formed except when the cv-qualifiers -are introduced through the use of a -\grammarterm{typedef-name}~(\ref{dcl.typedef}, \ref{temp.param}) or -\grammarterm{decltype-specifier}\iref{dcl.type.simple}, -in which case the cv-qualifiers are ignored. -\begin{example} - -\begin{codeblock} -typedef int& A; -const A aref = 3; // ill-formed; lvalue reference to non-\tcode{const} initialized with rvalue -\end{codeblock} - -The type of -\tcode{aref} -is ``lvalue reference to \tcode{int}'', -not ``lvalue reference to \tcode{const int}''. -\end{example} -\begin{note} -A reference can be thought of as a name of an object. -\end{note} -\indextext{\idxcode{void\&}}% -A declarator that specifies the type -``reference to \cv{}~\tcode{void}'' -is ill-formed. - - -\pnum -A reference type that is declared using \tcode{\&} is called an -\defn{lvalue reference}, and a reference type that -is declared using \tcode{\&\&} is called an -\defn{rvalue reference}. Lvalue references and -rvalue references are distinct types. Except where explicitly noted, they are -semantically equivalent and commonly referred to as references. - -\pnum -\indextext{declaration!reference}% -\indextext{parameter!reference}% -\begin{example} - -\begin{codeblock} -void f(double& a) { a += 3.14; } -// ... -double d = 0; -f(d); -\end{codeblock} - -declares -\tcode{a} -to be a reference parameter of -\tcode{f} -so the call -\tcode{f(d)} -will add -\tcode{3.14} -to -\tcode{d}. - -\begin{codeblock} -int v[20]; -// ... -int& g(int i) { return v[i]; } -// ... -g(3) = 7; -\end{codeblock} - -declares the function -\tcode{g()} -to return a reference to an integer so -\tcode{g(3)=7} -will assign -\tcode{7} -to the fourth element of the array -\tcode{v}. -For another example, - -\begin{codeblock} -struct link { - link* next; -}; - -link* first; - -void h(link*& p) { // \tcode{p} is a reference to pointer - p->next = first; - first = p; - p = 0; -} - -void k() { - link* q = new link; - h(q); -} -\end{codeblock} - -declares -\tcode{p} -to be a reference to a pointer to -\tcode{link} -so -\tcode{h(q)} -will leave -\tcode{q} -with the value zero. -See also~\ref{dcl.init.ref}. -\end{example} - -\pnum -It is unspecified whether or not -a reference requires storage\iref{basic.stc}. - -\pnum -\indextext{restriction!reference}% -There shall be no references to references, -no arrays of references, and no pointers to references. -\indextext{initialization!reference}% -The declaration of a reference shall contain an -\grammarterm{initializer}\iref{dcl.init.ref} -except when the declaration contains an explicit -\tcode{extern} -specifier\iref{dcl.stc}, -is a class member\iref{class.mem} declaration within a class definition, -or is the declaration of a parameter or a return type\iref{dcl.fct}; see~\ref{basic.def}. -A reference shall be initialized to refer to a valid object or function. -\begin{note} -\indextext{reference!null}% -In particular, a null reference cannot exist in a well-defined program, -because the only way to create such a reference would be to bind it to -the ``object'' obtained by indirection through a null pointer, -which causes undefined behavior. -As described in~\ref{class.bit}, a reference cannot be bound directly -to a bit-field. -\end{note} - -\pnum -\indextext{reference collapsing}% -If a \grammarterm{typedef-name}~(\ref{dcl.typedef}, \ref{temp.param}) -or a \grammarterm{decltype-specifier}\iref{dcl.type.simple} denotes a type \tcode{TR} that -is a reference to a type \tcode{T}, an attempt to create the type ``lvalue reference to \cv{}~\tcode{TR}'' -creates the type ``lvalue reference to \tcode{T}'', while an attempt to create -the type ``rvalue reference to \cv{}~\tcode{TR}'' creates the type \tcode{TR}. -\begin{note} This rule is known as reference collapsing. \end{note} -\begin{example} - -\begin{codeblock} -int i; -typedef int& LRI; -typedef int&& RRI; - -LRI& r1 = i; // \tcode{r1} has the type \tcode{int\&} -const LRI& r2 = i; // \tcode{r2} has the type \tcode{int\&} -const LRI&& r3 = i; // \tcode{r3} has the type \tcode{int\&} - -RRI& r4 = i; // \tcode{r4} has the type \tcode{int\&} -RRI&& r5 = 5; // \tcode{r5} has the type \tcode{int\&\&} - -decltype(r2)& r6 = i; // \tcode{r6} has the type \tcode{int\&} -decltype(r2)&& r7 = i; // \tcode{r7} has the type \tcode{int\&} -\end{codeblock} -\end{example} - -\pnum -\begin{note} Forming a reference to function type is ill-formed if the function -type has \grammarterm{cv-qualifier}{s} or a \grammarterm{ref-qualifier}; -see~\ref{dcl.fct}. -\end{note} - -\rSec2[dcl.mptr]{Pointers to members}% -\indextext{declarator!pointer-to-member} - -\pnum -In a declaration -\tcode{T} -\tcode{D} -where -\tcode{D} -has the form - -\begin{ncsimplebnf} -nested-name-specifier \terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq} \terminal{D1} -\end{ncsimplebnf} - -and the -\grammarterm{nested-name-specifier} -denotes a class, -and the type of the identifier in the declaration -\tcode{T} -\tcode{D1} -is ``\placeholder{derived-declarator-type-list} -\tcode{T}'', -then the type of the identifier of -\tcode{D} -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}\iref{dcl.attr.grammar} appertains to the -pointer-to-member. - -\pnum -\begin{example} -\begin{codeblock} -struct X { - void f(int); - int a; -}; -struct Y; - -int X::* pmi = &X::a; -void (X::* pmf)(int) = &X::f; -double X::* pmd; -char Y::* pmc; -\end{codeblock} - -declares -\tcode{pmi}, -\tcode{pmf}, -\tcode{pmd} -and -\tcode{pmc} -to be a pointer to a member of -\tcode{X} -of type -\tcode{int}, -a pointer to a member of -\tcode{X} -of type -\tcode{void(int)}, -a pointer to a member of -\tcode{X} -of type -\tcode{double} -and a pointer to a member of -\tcode{Y} -of type -\tcode{char} -respectively. -The declaration of -\tcode{pmd} -is well-formed even though -\tcode{X} -has no members of type -\tcode{double}. -Similarly, the declaration of -\tcode{pmc} -is well-formed even though -\tcode{Y} -is an incomplete type. -\tcode{pmi} -and -\tcode{pmf} -can be used like this: -\begin{codeblock} -X obj; -// ... -obj.*pmi = 7; // assign \tcode{7} to an integer member of \tcode{obj} -(obj.*pmf)(7); // call a function member of \tcode{obj} with the argument \tcode{7} -\end{codeblock} -\end{example} - -\pnum -A pointer to member shall not point to a static member -of a class\iref{class.static}, -a member with reference type, -or -``\cv{}~\tcode{void}''. - -\begin{note} -See also~\ref{expr.unary} and~\ref{expr.mptr.oper}. -The type ``pointer to member'' is distinct from the type ``pointer'', -that is, a pointer to member is declared only by the pointer-to-member -declarator syntax, and never by the pointer declarator syntax. -There is no ``reference-to-member'' type in \Cpp{}. -\end{note} - -\rSec2[dcl.array]{Arrays}% -\indextext{declarator!array} - -\pnum -In a declaration -\tcode{T} -\tcode{D} -where -\tcode{D} -has the form - -\begin{ncsimplebnf} -\terminal{D1 [} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq} -\end{ncsimplebnf} - -and the type of the identifier in the declaration -\tcode{T} -\tcode{D1} -is -``\placeholder{derived-declarator-type-list} -\tcode{T}'', -then the type of the identifier of -\tcode{D} -is an array type; if the type of the identifier of \tcode{D} -contains the \tcode{auto} \grammarterm{type-specifier}, -the program is ill-formed. -\tcode{T} -is called the array -\term{element type}; -this type shall not be a reference type, \cv{}~\tcode{void}, -a function type or an abstract class type. -\indextext{declaration!array}% -If the -\grammarterm{constant-expression}\iref{expr.const} -is present, it shall be a converted constant -expression of type \tcode{std::size_t} and -its value shall be greater than zero. -The constant expression specifies the -\indextext{array!bound}% -\indextext{bound, of array}% -\term{bound} -of (number of elements in) the array. -If the value of the constant expression is -\tcode{N}, -the array has -\tcode{N} -elements numbered -\tcode{0} -to -\tcode{N-1}, -and the type of the identifier of -\tcode{D} -is ``\placeholder{derived-declarator-type-list} array of -\tcode{N} -\tcode{T}''. -An object of array type contains a contiguously allocated non-empty set of -\tcode{N} -subobjects of type -\tcode{T}. -Except as noted below, if -the constant expression is omitted, the type of the identifier of -\tcode{D} -is ``\placeholder{derived-declarator-type-list} array of unknown bound of -\tcode{T}'', -an incomplete object type. -The type ``\placeholder{derived-declarator-type-list} array of -\tcode{N} -\tcode{T}'' -is a different type from the type -``\placeholder{derived-declarator-type-list} array of unknown bound of -\tcode{T}'', -see~\ref{basic.types}. -Any type of the form -``\grammarterm{cv-qualifier-seq} array of -\tcode{N} -\tcode{T}'' -is adjusted to -``array of -\tcode{N} -\grammarterm{cv-qualifier-seq} -\tcode{T}'', -and similarly for -``array of unknown bound of -\tcode{T}''. -The optional \grammarterm{attribute-specifier-seq} appertains to the array. -\begin{example} - -\begin{codeblock} -typedef int A[5], AA[2][3]; -typedef const A CA; // type is ``array of 5 \tcode{const int}'' -typedef const AA CAA; // type is ``array of 2 array of 3 \tcode{const int}'' -\end{codeblock} -\end{example} -\begin{note} -An -``array of -\tcode{N} -\grammarterm{cv-qualifier-seq} -\tcode{T}'' -has cv-qualified type; see~\ref{basic.type.qualifier}. -\end{note} - -\pnum -An array can be constructed from one of the fundamental types -(except -\tcode{void}), -from a pointer, -from a pointer to member, from a class, -from an enumeration type, -or from another array. - -\pnum -\indextext{declarator!multidimensional array}% -When several ``array of'' specifications are adjacent, a -multidimensional array -type is created; -only the first of -the constant expressions that specify the bounds -of the arrays may be omitted. -In addition to declarations in which an incomplete object type is allowed, -an array bound may be omitted in some cases in the declaration of a function -parameter\iref{dcl.fct}. -An array bound may also be omitted -when the declarator is followed by an -\grammarterm{initializer}\iref{dcl.init}, -when a declarator for a static data member is followed by a -\grammarterm{brace-or-equal-initializer}\iref{class.mem}, -or in an explicit type conversion\iref{expr.type.conv}. -In these cases, the bound is calculated from the number -\indextext{array size!default}% -of initial elements (say, -\tcode{N}) -supplied\iref{dcl.init.aggr}, -and the type of the identifier of -\tcode{D} -is ``array of -\tcode{N} -\tcode{T}''. -Furthermore, if there is a preceding declaration of the entity in the same -scope in which the bound was specified, an omitted array bound is taken to -be the same as in that earlier declaration, and similarly for the definition -of a static data member of a class. - -\pnum -\begin{example} -\begin{codeblock} -float fa[17], *afp[17]; -\end{codeblock} -declares an array of -\tcode{float} -numbers and an array of -pointers to -\tcode{float} -numbers. -\end{example} - -\pnum -\begin{example} -\begin{codeblock} -int x3d[3][5][7]; -\end{codeblock} -declares an array of three elements, -each of which is an array of five elements, -each of which is an array of seven integers. -The overall array can be viewed as a -three-dimensional array of integers, -with rank $3 \times 5 \times 7$. -Any of the expressions -\tcode{x3d}, -\tcode{x3d[i]}, -\tcode{x3d[i][j]}, -\tcode{x3d[i][j][k]} -can reasonably appear in an expression. -The expression -\tcode{x3d[i]} -is equivalent to -\tcode{*(x3d + i)}; -in that expression, -\tcode{x3d} -is subject to the array-to-pointer conversion\iref{conv.array} -and is first converted to -a pointer to a 2-dimensional -array with rank -$5 \times 7$ -that points to the first element of \tcode{x3d}. -Then \tcode{i} is added, -which on typical implementations involves multiplying -\tcode{i} by the -length of the object to which the pointer points, -which is \tcode{sizeof(int)}$ \times 5 \times 7$. -The result of the addition and indirection is -an lvalue denoting -the \tcode{i}\textsuperscript{th} array element of -\tcode{x3d} -(an array of five arrays of seven integers). -If there is another subscript, -the same argument applies again, so -\tcode{x3d[i][j]} is -an lvalue denoting -the \tcode{j}\textsuperscript{th} array element of -the \tcode{i}\textsuperscript{th} array element of -\tcode{x3d} -(an array of seven integers), and -\tcode{x3d[i][j][k]} is -an lvalue denoting -the \tcode{k}\textsuperscript{th} array element of -the \tcode{j}\textsuperscript{th} array element of -the \tcode{i}\textsuperscript{th} array element of -\tcode{x3d} -(an integer). -\end{example} -\begin{note} -The first subscript in the declaration helps determine -the amount of storage consumed by an array -but plays no other part in subscript calculations. -\end{note} - -\pnum -\begin{example} -\begin{codeblock} -extern int x[10]; -struct S { - static int y[10]; -}; - -int x[]; // OK: bound is 10 -int S::y[]; // OK: bound is 10 - -void f() { - extern int x[]; - int i = sizeof(x); // error: incomplete object type -} -\end{codeblock} -\end{example} - -\pnum -\begin{note} -Conversions affecting expressions of array type are described in~\ref{conv.array}. -\end{note} - -\pnum -\begin{note} -The subscript operator can be overloaded for a class\iref{over.sub}. -For the operator's built-in meaning, see \ref{expr.sub}. -\end{note} - -\rSec2[dcl.fct]{Functions}% -\indextext{declarator!function|(} - -\pnum -\indextext{type!function}% -In a declaration -\tcode{T} -\tcode{D} -where -\tcode{D} -has the form -\begin{ncsimplebnf} -\terminal{D1 (} parameter-declaration-clause \terminal{)} \opt{cv-qualifier-seq}\br -\bnfindent\opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq} -\end{ncsimplebnf} -and the type of the contained -\grammarterm{declarator-id} -in the declaration -\tcode{T} -\tcode{D1} -is -``\placeholder{derived-declarator-type-list} -\tcode{T}'', -the type of the -\grammarterm{declarator-id} -in -\tcode{D} -is -``\placeholder{derived-declarator-type-list} -\opt{\tcode{noexcept}} -function of -(\grammarterm{parameter-declaration-clause}) -\opt{\grammarterm{cv-qualifier-seq}} \opt{\grammarterm{ref-qualifier}} -returning \tcode{T}'', -where the optional \tcode{noexcept} is present -if and only if -the exception specification\iref{except.spec} is non-throwing. -The optional \grammarterm{attribute-specifier-seq} -appertains to the function type. - -\pnum -In a declaration -\tcode{T} -\tcode{D} -where -\tcode{D} -has the form - -\begin{ncsimplebnf} -\terminal{D1 (} parameter-declaration-clause \terminal{)} \opt{cv-qualifier-seq}\br -\bnfindent\opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq} trailing-return-type -\end{ncsimplebnf} - -and the type of the contained -\grammarterm{declarator-id} -in the declaration -\tcode{T} -\tcode{D1} -is -``\placeholder{derived-declarator-type-list} \tcode{T}'', -\tcode{T} shall be the single \grammarterm{type-specifier} \tcode{auto}. -The type of the -\grammarterm{declarator-id} -in -\tcode{D} -is -``\placeholder{derived-declarator-type-list} -\opt{\tcode{noexcept}} -function of -(\grammarterm{parameter-declaration-clause}) -\opt{\grammarterm{cv-qualifier-seq}} \opt{\grammarterm{ref-qualifier}} -returning \tcode{U}'', -where \tcode{U} is the type specified by -the \grammarterm{trailing-return-type}, and -where the optional \tcode{noexcept} is present if and only if -the exception specification is non-throwing. -The optional \grammarterm{attribute-specifier-seq} -appertains to the function type. - -\pnum -\indextext{type!function}% -A type of either form is a \term{function type}.\footnote{As indicated by syntax, cv-qualifiers are a significant component in function return types.} - -\indextext{declaration!function}% -\begin{bnf} -\nontermdef{parameter-declaration-clause}\br - \opt{parameter-declaration-list} \opt{\terminal{...}}\br - parameter-declaration-list \terminal{, ...} -\end{bnf} - -\begin{bnf} -\nontermdef{parameter-declaration-list}\br - parameter-declaration\br - parameter-declaration-list \terminal{,} parameter-declaration -\end{bnf} - -\begin{bnf} -\nontermdef{parameter-declaration}\br - \opt{attribute-specifier-seq} decl-specifier-seq declarator\br - \opt{attribute-specifier-seq} decl-specifier-seq declarator \terminal{=} initializer-clause\br - \opt{attribute-specifier-seq} decl-specifier-seq \opt{abstract-declarator}\br - \opt{attribute-specifier-seq} decl-specifier-seq \opt{abstract-declarator} \terminal{=} initializer-clause -\end{bnf} - -The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{parameter-declaration} -appertains to the parameter. - -\pnum -\indextext{declaration!parameter}% -The -\grammarterm{parameter-declaration-clause} -determines the arguments that can be specified, and their processing, when the function is called. -\begin{note} -\indextext{conversion!argument}% -The -\grammarterm{parameter-declaration-clause} -is used to convert the arguments specified on the function call; -see~\ref{expr.call}. -\end{note} -\indextext{argument list!empty}% -If the -\grammarterm{parameter-declaration-clause} -is empty, the function takes no arguments. -A parameter list consisting of a single unnamed parameter of -non-dependent type \tcode{void} is equivalent to an empty parameter -list. -\indextext{parameter!\idxcode{void}}% -Except for this special case, a parameter shall not have type \term{cv} -\tcode{void}. -If the -\grammarterm{parameter-declaration-clause} -\indextext{argument type!unknown}% -\indextext{\idxcode{...}|see{ellipsis}}% -\indextext{declaration!ellipsis in function}% -\indextext{argument list!variable}% -\indextext{parameter list!variable}% -terminates with an ellipsis or a function parameter -pack\iref{temp.variadic}, the number of arguments shall be equal -to or greater than the number of parameters that do not have a default -argument and are not function parameter packs. -Where syntactically correct and where ``\tcode{...}'' is not -part of an \grammarterm{abstract-declarator}, -``\tcode{, ...}'' -is synonymous with -``\tcode{...}''. -\begin{example} -The declaration - -\begin{codeblock} -int printf(const char*, ...); -\end{codeblock} - -declares a function that can be called with varying numbers and types of arguments. - -\begin{codeblock} -printf("hello world"); -printf("a=%d b=%d", a, b); -\end{codeblock} - -However, the first argument must be of a type -that can be converted to a -\tcode{const} -\tcode{char*} -\end{example} -\begin{note} -The standard header -\tcode{} -\indexhdr{cstdarg}% -contains a mechanism for accessing arguments passed using the ellipsis -(see~\ref{expr.call} and~\ref{support.runtime}). -\end{note} - -\pnum -\indextext{type!function}% -The type of a function is determined using the following rules. -The type of each parameter (including function parameter packs) is -determined from its own -\grammarterm{decl-specifier-seq} -and -\grammarterm{declarator}. -After determining the type of each parameter, any parameter -\indextext{array!parameter of type}% -of type ``array of \tcode{T}'' or -\indextext{function!parameter of type}% -of function type \tcode{T} -is adjusted to be ``pointer to \tcode{T}''. -After producing the list of parameter types, -any top-level -\grammarterm{cv-qualifier}{s} -modifying a parameter type are deleted -when forming the function type. -The resulting list of transformed parameter types -and the presence or absence of the ellipsis or a function parameter pack -is the function's -\defn{parameter-type-list}. -\begin{note} This transformation does not affect the types of the parameters. -For example, \tcode{int(*)(const int p, decltype(p)*)} and -\tcode{int(*)(int, const int*)} are identical types. \end{note} - -\pnum -A function type with a \grammarterm{cv-qualifier-seq} or a -\grammarterm{ref-qualifier} (including a type named by -\grammarterm{typedef-name}~(\ref{dcl.typedef}, \ref{temp.param})) -shall appear only as: -\begin{itemize} -\item the function type for a non-static member function, - -\item the function type to which a pointer to member refers, - -\item the top-level function type of a function typedef declaration -or \grammarterm{alias-declaration}, - -\item the \grammarterm{type-id} in the default argument of a -\grammarterm{type-parameter}\iref{temp.param}, or - -\item the \grammarterm{type-id} of a \grammarterm{template-argument} for a -\grammarterm{type-parameter}\iref{temp.arg.type}. -\end{itemize} -\begin{example} - -\begin{codeblock} -typedef int FIC(int) const; -FIC f; // ill-formed: does not declare a member function -struct S { - FIC f; // OK -}; -FIC S::*pm = &S::f; // OK -\end{codeblock} -\end{example} - -\pnum -The effect of a -\grammarterm{cv-qualifier-seq} -in a function declarator is not the same as -adding cv-qualification on top of the function type. -In the latter case, the cv-qualifiers are ignored. -\begin{note} A function type that has a \grammarterm{cv-qualifier-seq} is not a -cv-qualified type; there are no cv-qualified function types. \end{note} -\begin{example} - -\begin{codeblock} -typedef void F(); -struct S { - const F f; // OK: equivalent to: \tcode{void f();} -}; -\end{codeblock} -\end{example} - -\pnum -The return type, the parameter-type-list, the \grammarterm{ref-qualifier}, -the \grammarterm{cv-qualifier-seq}, and -the exception specification, -but not the default arguments\iref{dcl.fct.default} -or the trailing \grammarterm{requires-clause}\iref{dcl.decl}, -are part of the function type. -\begin{note} -Function types are checked during the assignments and initializations of -pointers to functions, references to functions, and pointers to member functions. -\end{note} - -\pnum -\begin{example} -The declaration - -\begin{codeblock} -int fseek(FILE*, long, int); -\end{codeblock} - -declares a function taking three arguments of the specified types, -and returning -\tcode{int}\iref{dcl.type}. -\end{example} - -\pnum -\indextext{overloading}% -A single name can be used for several different functions in a single scope; -this is function overloading\iref{over}. -All declarations for a function shall have equivalent return types, -parameter-type-lists, and \grammarterm{requires-clause}{s}\iref{temp.over.link}. - -\pnum -\indextext{function return type|see{return type}}% -\indextext{return type}% -Functions shall not have a return type of type array or function, -although they may have a return type of type pointer or reference to such things. -There shall be no arrays of functions, although there can be arrays of pointers -to functions. - -\pnum -Types shall not be defined in return or parameter types. -The type of a parameter or the return type for a function -definition shall not be an incomplete -(possibly cv-qualified) class type -in the context of the function definition -unless the function is -deleted\iref{dcl.fct.def.delete}. - -\pnum -\indextext{typedef!function}% -A typedef of function type may be used to declare a function but shall not be -used to define a function\iref{dcl.fct.def}. -\begin{example} - -\begin{codeblock} -typedef void F(); -F fv; // OK: equivalent to \tcode{void fv();} -F fv { } // ill-formed -void fv() { } // OK: definition of \tcode{fv} -\end{codeblock} -\end{example} - -\pnum -An identifier can optionally be provided as a parameter name; -if present in a function definition\iref{dcl.fct.def}, it names a parameter. -\begin{note} -In particular, parameter names are also optional in function definitions -and names used for a parameter in different declarations and the definition -of a function need not be the same. -If a parameter name is present in a function declaration that is not a definition, -it cannot be used outside of -its function declarator because that is the extent of its potential scope\iref{basic.scope.param}. -\end{note} - -\pnum -\begin{example} -The declaration - -\begin{codeblock} -int i, - *pi, - f(), - *fpi(int), - (*pif)(const char*, const char*), - (*fpif(int))(int); -\end{codeblock} - -declares an integer -\tcode{i}, -a pointer -\tcode{pi} -to an integer, -a function -\tcode{f} -taking no arguments and returning an integer, -a function -\tcode{fpi} -taking an integer argument and returning a pointer to an integer, -a pointer -\tcode{pif} -to a function which -takes two pointers to constant characters and returns an integer, -a function -\tcode{fpif} -taking an integer argument and returning a pointer to a function that takes an integer argument and returns an integer. -It is especially useful to compare -\tcode{fpi} -and -\tcode{pif}. -The binding of -\tcode{*fpi(int)} -is -\tcode{*(fpi(int))}, -so the declaration suggests, -and the same construction in an expression -requires, the calling of a function -\tcode{fpi}, -and then using indirection through the (pointer) result -to yield an integer. -In the declarator -\tcode{(*pif)(const char*, const char*)}, -the extra parentheses are necessary to indicate that indirection through -a pointer to a function yields a function, which is then called. -\end{example} -\begin{note} -Typedefs and \grammarterm{trailing-return-type}{s} are sometimes convenient when the return type of a function is complex. -For example, -the function -\tcode{fpif} -above could have been declared - -\begin{codeblock} -typedef int IFUNC(int); -IFUNC* fpif(int); -\end{codeblock} - -or - -\begin{codeblock} -auto fpif(int)->int(*)(int); -\end{codeblock} - -A \grammarterm{trailing-return-type} is most useful for a type that would be more complicated to specify before the \grammarterm{declarator-id}: - -\begin{codeblock} -template auto add(T t, U u) -> decltype(t + u); -\end{codeblock} - -rather than - -\begin{codeblock} -template decltype((*(T*)0) + (*(U*)0)) add(T t, U u); -\end{codeblock} -\end{note} - -\pnum -A \term{non-template function} is a function that is not a function template -specialization. \begin{note} A function template is not a function. \end{note} - -\pnum -A \grammarterm{declarator-id} or \grammarterm{abstract-declarator} -containing an ellipsis shall only -be used in a \grammarterm{parameter-declaration}. -When it is part of a -\grammarterm{parameter-declaration-clause}, -the \grammarterm{parameter-declaration} declares a -function parameter pack\iref{temp.variadic}. -Otherwise, the \grammarterm{parameter-declaration} is part of a -\grammarterm{template-parameter-list} and declares a -template parameter pack; see~\ref{temp.param}. -A function parameter pack is a pack expansion\iref{temp.variadic}. -\begin{example} - -\begin{codeblock} -template void f(T (* ...t)(int, int)); - -int add(int, int); -float subtract(int, int); - -void g() { - f(add, subtract); -} -\end{codeblock} -\end{example} - -\pnum -There is a syntactic ambiguity when an ellipsis occurs at the end -of a \grammarterm{parameter-declaration-clause} without a preceding -comma. In this case, the ellipsis is parsed as part of the -\grammarterm{abstract-declarator} if the type of the parameter either names -a template parameter pack that has not been expanded or contains \tcode{auto}; -otherwise, it is -parsed as part of the \grammarterm{parameter-declaration-clause}.\footnote{One can explicitly disambiguate the parse either by -introducing a comma (so the ellipsis will be parsed as part of the -\grammarterm{parameter-declaration-clause}) or by introducing a name for the -parameter (so the ellipsis will be parsed as part of the -\grammarterm{declarator-id}).}% -\indextext{declarator!function|)} - -\rSec2[dcl.fct.default]{Default arguments}% -\indextext{declaration!default argument|(} - -\pnum -If an \grammarterm{initializer-clause}{} is specified in a -\grammarterm{parameter-declaration}{} this -\grammarterm{initializer-clause}{} -is used as a default argument. -Default arguments will be used in calls where trailing arguments are missing. - -\pnum -\indextext{argument!example of default}% -\begin{example} -The declaration - -\begin{codeblock} -void point(int = 3, int = 4); -\end{codeblock} - -declares a function that can be called with zero, one, or two arguments of type -\tcode{int}. -It can be called in any of these ways: - -\begin{codeblock} -point(1,2); point(1); point(); -\end{codeblock} - -The last two calls are equivalent to -\tcode{point(1,4)} -and -\tcode{point(3,4)}, -respectively. -\end{example} - -\pnum -A default argument shall be specified only in the -\grammarterm{parameter-declaration-clause} -of a function declaration -or \grammarterm{lambda-declarator} -or in a -\grammarterm{template-parameter}\iref{temp.param}; -in the latter case, the \grammarterm{initializer-clause} shall be an -\grammarterm{assignment-expression}. -A default argument shall not be specified for -a template parameter pack or -a function parameter pack. -If it is specified in a -\grammarterm{parameter-declaration-clause}, -it shall not occur within a -\grammarterm{declarator} -or -\grammarterm{abstract-declarator} -of a -\grammarterm{parameter-declaration}.\footnote{This means that default -arguments cannot appear, -for example, in declarations of pointers to functions, -references to functions, or -\tcode{typedef} -declarations. -} - -\pnum -For non-template functions, default arguments can be added in later -declarations of a -function in the same scope. -Declarations in different -scopes have completely distinct sets of default arguments. -That -is, declarations in inner scopes do not acquire default -arguments from declarations in outer scopes, and vice versa. -In -a given function declaration, each parameter subsequent to a -parameter with a default argument shall have a default argument -supplied in this or a previous declaration -or shall be a function parameter pack. -A default argument -shall not be redefined by a later declaration (not even to the -same value). -\begin{example} - -\begin{codeblock} -void g(int = 0, ...); // OK, ellipsis is not a parameter so it can follow - // a parameter with a default argument -void f(int, int); -void f(int, int = 7); -void h() { - f(3); // OK, calls \tcode{f(3, 7)} - void f(int = 1, int); // error: does not use default from surrounding scope -} -void m() { - void f(int, int); // has no defaults - f(4); // error: wrong number of arguments - void f(int, int = 5); // OK - f(4); // OK, calls \tcode{f(4, 5);} - void f(int, int = 5); // error: cannot redefine, even to same value -} -void n() { - f(6); // OK, calls \tcode{f(6, 7)} -} -\end{codeblock} -\end{example} -For a given inline function defined in different translation units, -the accumulated sets of default arguments at the end of the -translation units shall be the same; -see~\ref{basic.def.odr}. -If a friend declaration specifies a default argument expression, -that declaration shall be a definition and shall be the only -declaration of the function or function template in the translation unit. - -\pnum -\indextext{argument!type checking of default}% -\indextext{argument!binding of default}% -\indextext{argument!evaluation of default}% -The default argument has the -same semantic constraints as the initializer in a -declaration of a variable of the parameter type, using the -copy-initialization semantics\iref{dcl.init}. -The names in the -default argument are bound, and the semantic constraints are checked, -at the point where the default argument appears. -Name lookup and checking of semantic constraints for default -arguments in function templates and in member functions of -class templates are performed as described in~\ref{temp.inst}. -\begin{example} -In the following code, -\indextext{argument!example of default}% -\tcode{g} -will be called with the value -\tcode{f(2)}: - -\begin{codeblock} -int a = 1; -int f(int); -int g(int x = f(a)); // default argument: \tcode{f(::a)} - -void h() { - a = 2; - { - int a = 3; - g(); // \tcode{g(f(::a))} - } -} -\end{codeblock} -\end{example} -\begin{note} -In member function declarations, -names in default arguments are looked up -as described in~\ref{basic.lookup.unqual}. -Access checking applies to names in default arguments as -described in \ref{class.access}. -\end{note} - -\pnum -Except for member functions of class templates, the -default arguments in a member function definition that appears -outside of the class definition -are added to the set of default arguments provided by the -member function declaration in the class definition; -the program is ill-formed if a default constructor\iref{class.ctor}, -copy or move constructor, or copy or move assignment operator\iref{class.copy} -is so declared. -Default arguments for a member function of a class template -shall be specified on the initial declaration of the member -function within the class template. -\begin{example} -\begin{codeblock} -class C { - void f(int i = 3); - void g(int i, int j = 99); -}; - -void C::f(int i = 3) {} // error: default argument already specified in class scope -void C::g(int i = 88, int j) {} // in this translation unit, \tcode{C::g} can be called with no argument -\end{codeblock} -\end{example} - -\pnum -\begin{note} -A local variable cannot be odr-used\iref{basic.def.odr} -in a default argument. -\end{note} -\begin{example} -\begin{codeblock} -void f() { - int i; - extern void g(int x = i); // error - extern void h(int x = sizeof(i)); // OK - // ... -} -\end{codeblock} -\end{example} - -\pnum -\begin{note} -The keyword -\tcode{this} -may not appear in a default argument of a member function; -see~\ref{expr.prim.this}. -\begin{example} - -\begin{codeblock} -class A { - void f(A* p = this) { } // error -}; -\end{codeblock} -\end{example} -\end{note} - -\pnum -\indextext{argument!evaluation of default}% -A default argument is evaluated each time the function is called -with no argument for the corresponding parameter. -\indextext{argument!scope of default}% -A parameter shall not appear as a potentially-evaluated expression -in a default argument. -\indextext{argument and name hiding!default}% -Parameters of a function declared before a default argument -are in scope and can hide namespace and class member names. -\begin{example} -\begin{codeblock} -int a; -int f(int a, int b = a); // error: parameter \tcode{a} used as default argument -typedef int I; -int g(float I, int b = I(2)); // error: parameter \tcode{I} found -int h(int a, int b = sizeof(a)); // OK, unevaluated operand -\end{codeblock} -\end{example} -A non-static member shall not appear in a default argument unless it appears as -the \grammarterm{id-expression} of a class member access expression\iref{expr.ref} or -unless it is used to form a pointer to member\iref{expr.unary.op}. -\begin{example} -The declaration of -\tcode{X::mem1()} -in the following example is ill-formed because no object is supplied for the -non-static member -\tcode{X::a} -used as an initializer. -\begin{codeblock} -int b; -class X { - int a; - int mem1(int i = a); // error: non-static member \tcode{a} used as default argument - int mem2(int i = b); // OK; use \tcode{X::b} - static int b; -}; -\end{codeblock} -The declaration of -\tcode{X::mem2()} -is meaningful, however, since no object is needed to access the static member -\tcode{X::b}. -Classes, objects, and members are described in \ref{class}. -\end{example} -A default argument is not part of the -type of a function. -\begin{example} -\begin{codeblock} -int f(int = 0); - -void h() { - int j = f(1); - int k = f(); // OK, means \tcode{f(0)} -} - -int (*p1)(int) = &f; -int (*p2)() = &f; // error: type mismatch -\end{codeblock} -\end{example} -When a declaration of a function is introduced by way of a -\grammarterm{using-declaration}\iref{namespace.udecl}, -any default argument information associated -with the declaration is made known as well. -If the function is redeclared -thereafter in the namespace with additional default arguments, -the additional arguments are also known at any point following -the redeclaration where the -\grammarterm{using-declaration} -is in scope. - -\pnum -\indextext{argument and virtual function!default}% -A virtual function call\iref{class.virtual} uses the default -arguments in the declaration of the virtual function determined -by the static type of the pointer or reference denoting the -object. -An overriding function in a derived class does not -acquire default arguments from the function it overrides. -\begin{example} - -\begin{codeblock} -struct A { - virtual void f(int a = 7); -}; -struct B : public A { - void f(int a); -}; -void m() { - B* pb = new B; - A* pa = pb; - pa->f(); // OK, calls \tcode{pa->B::f(7)} - pb->f(); // error: wrong number of arguments for \tcode{B::f()} -} -\end{codeblock} -\end{example}% -\indextext{declaration!default argument|)}% -\indextext{declarator!meaning of|)} - -\rSec1[dcl.fct.def]{Function definitions}% -\indextext{definition!function|(} - -\rSec2[dcl.fct.def.general]{In general} - -\pnum -\indextext{body!function}% -Function definitions have the form - -\indextext{\idxgram{function-definition}}% -% -\begin{bnf} -\nontermdef{function-definition}\br - \opt{attribute-specifier-seq} \opt{decl-specifier-seq} declarator \opt{virt-specifier-seq} function-body\br - \opt{attribute-specifier-seq} \opt{decl-specifier-seq} declarator requires-clause function-body -\end{bnf} - -\begin{bnf} -\nontermdef{function-body}\br - \opt{ctor-initializer} compound-statement\br - function-try-block\br - \terminal{= default ;}\br - \terminal{= delete ;} -\end{bnf} - -Any informal reference to the body of a function should be interpreted as a reference to -the non-terminal \grammarterm{function-body}. -The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{function-definition} -appertains to the function. -A \grammarterm{virt-specifier-seq} can be part of a \grammarterm{function-definition} -only if it is a \grammarterm{member-declaration}\iref{class.mem}. - -\pnum -In a \grammarterm{function-definition}, -either \tcode{void} \grammarterm{declarator} \tcode{;} -or \grammarterm{declarator} \tcode{;} -shall be a well-formed function declaration -as described in~\ref{dcl.fct}. -A function shall be defined only in namespace or class scope. - -\pnum -\begin{example} -A simple example of a complete function definition is - -\begin{codeblock} -int max(int a, int b, int c) { - int m = (a > b) ? a : b; - return (m > c) ? m : c; -} -\end{codeblock} - -Here -\tcode{int} -is the -\grammarterm{decl-specifier-seq}; -\tcode{max(int} -\tcode{a,} -\tcode{int} -\tcode{b,} -\tcode{int} -\tcode{c)} -is the -\grammarterm{declarator}; -\tcode{\{ \commentellip{} \}} -is the -\grammarterm{function-body}. -\end{example} - -\pnum -\indextext{initializer!base class}% -\indextext{initializer!member}% -\indextext{definition!constructor}% -A -\grammarterm{ctor-initializer} -is used only in a constructor; see~\ref{class.ctor} and~\ref{class.init}. - -\pnum -\begin{note} -A \grammarterm{cv-qualifier-seq} affects the type of \tcode{this} -in the body of a member function; see~\ref{dcl.ref}. -\end{note} - -\pnum -\begin{note} -Unused parameters need not be named. -For example, - -\begin{codeblock} -void print(int a, int) { - std::printf("a = %d\n",a); -} -\end{codeblock} -\end{note} - -\pnum -In the \grammarterm{function-body}, a -\defnx{function-local predefined variable}{variable!function-local predefined} denotes a block-scope object of static -storage duration that is implicitly defined (see~\ref{basic.scope.block}). - -\pnum -The function-local predefined variable \tcode{__func__} is -defined as if a definition of the form -\begin{codeblock} -static const char __func__[] = "@\placeholder{function-name}@"; -\end{codeblock} -had been provided, where \tcode{\placeholder{function-name}} is an \impldef{string resulting -from \mname{func}} string. -It is unspecified whether such a variable has an address -distinct from that of any other object in the program.\footnote{Implementations are -permitted to provide additional predefined variables with names that are reserved to the -implementation\iref{lex.name}. If a predefined variable is not -odr-used\iref{basic.def.odr}, its string value need not be present in the program image.} -\begin{example} -\begin{codeblock} -struct S { - S() : s(__func__) { } // OK - const char* s; -}; -void f(const char* s = __func__); // error: \tcode{__func__} is undeclared -\end{codeblock} -\end{example} - -\rSec2[dcl.fct.def.default]{Explicitly-defaulted functions}% - -\pnum -A function definition whose -\grammarterm{function-body} -is of the form -\tcode{= default ;} -is called an \defnx{explicitly-defaulted}{definition!function!explicitly-defaulted} definition. -A function that is explicitly defaulted shall - -\begin{itemize} -\item be a special member function or a comparison operator -(\ref{expr.spaceship}, \ref{expr.rel}, \ref{expr.eq}), and - -\item not have default arguments. -\end{itemize} - -% FIXME: there's no such thing as an implicit declaration of a comparison operator -\pnum -The type \tcode{T}$_1$ of an explicitly defaulted function \tcode{F} -is allowed to differ from the type \tcode{T}$_2$ it would have had -if it were implicitly declared, as follows: -\begin{itemize} -\item - \tcode{T}$_1$ and \tcode{T}$_2$ may have differing \grammarterm{ref-qualifier}{s}; and -\item - if \tcode{T}$_2$ has a parameter of type \tcode{const C\&}, - the corresponding parameter of \tcode{T}$_1$ may be of type \tcode{C\&}. -\end{itemize} -If \tcode{T}$_1$ differs from \tcode{T}$_2$ in any other way, then: -\begin{itemize} -\item - if \tcode{F} is an assignment operator, and - the return type of \tcode{T}$_1$ differs from - the return type of \tcode{T}$_2$ or - \tcode{T}$_1${'s} parameter type is not a reference, - the program is ill-formed; -\item - otherwise, if \tcode{F} is explicitly defaulted on its first declaration, - it is defined as deleted; -\item - otherwise, the program is ill-formed. -\end{itemize} - -\pnum -An explicitly-defaulted function that is not defined as deleted may be declared -\tcode{constexpr} only if it would have been implicitly declared as -\tcode{constexpr}. If -a function is explicitly defaulted on its first declaration, -it is implicitly considered to be \tcode{constexpr} if the implicit -declaration would be. - -\pnum -\begin{example} -\begin{codeblock} -struct S { - constexpr S() = default; // ill-formed: implicit \tcode{S()} is not \tcode{constexpr} - S(int a = 0) = default; // ill-formed: default argument - void operator=(const S&) = default; // ill-formed: non-matching return type - ~S() noexcept(false) = default; // deleted: exception specification does not match -private: - int i; - S(S&); // OK: private copy constructor -}; -S::S(S&) = default; // OK: defines copy constructor -\end{codeblock} -\end{example} - -\pnum -Explicitly-defaulted functions and implicitly-declared functions are collectively -called \defn{defaulted} functions, and the implementation -shall provide implicit definitions -for them~(\ref{class.ctor} -\ref{class.dtor}, \ref{class.copy}), which might mean defining them as deleted. -A function is -\defn{user-provided} if it is user-declared and not explicitly -defaulted or deleted on its first declaration. A user-provided explicitly-defaulted function -(i.e., explicitly defaulted after its first declaration) -is defined at the point where it is explicitly defaulted; if such a function is implicitly -defined as deleted, the program is ill-formed. -\begin{note} -Declaring a function as defaulted after its first declaration can provide -efficient execution and concise -definition while enabling a stable binary interface to an evolving code -base.\end{note} - -\pnum -\begin{example} - -\begin{codeblock} -struct trivial { - trivial() = default; - trivial(const trivial&) = default; - trivial(trivial&&) = default; - trivial& operator=(const trivial&) = default; - trivial& operator=(trivial&&) = default; - ~trivial() = default; -}; - -struct nontrivial1 { - nontrivial1(); -}; -nontrivial1::nontrivial1() = default; // not first declaration -\end{codeblock} -\end{example} - -\rSec2[dcl.fct.def.delete]{Deleted definitions}% -\indextext{definition!function!deleted}% - -\pnum -A function definition whose -\grammarterm{function-body} -is of the form -\tcode{= delete ;} -is called a \term{deleted definition}. A function with a -deleted definition is also called a \term{deleted function}. - -\pnum -A program that refers to a deleted function implicitly or explicitly, other -than to declare it, is ill-formed. \begin{note} This includes calling the function -implicitly or explicitly and forming a pointer or pointer-to-member to the -function. It applies even for references in expressions that are not -potentially-evaluated. If a function is overloaded, it is referenced only if the -function is selected by overload resolution. The implicit -odr-use\iref{basic.def.odr} of a virtual function does not, by itself, -constitute a reference. \end{note} - -\pnum -\begin{example} One can prevent default initialization and -initialization by non-\tcode{double}s with -\begin{codeblock} -struct onlydouble { - onlydouble() = delete; // OK, but redundant - template - onlydouble(T) = delete; - onlydouble(double); -}; -\end{codeblock} -\end{example} - -\begin{example} -One can prevent use of a -class in certain \grammarterm{new-expression}{s} by using deleted definitions -of a user-declared \tcode{operator new} for that class. -\begin{codeblock} -struct sometype { - void* operator new(std::size_t) = delete; - void* operator new[](std::size_t) = delete; -}; -sometype* p = new sometype; // error, deleted class \tcode{operator new} -sometype* q = new sometype[3]; // error, deleted class \tcode{operator new[]} -\end{codeblock} -\end{example} - -\begin{example} -One can make a class uncopyable, i.e., move-only, by using deleted -definitions of the copy constructor and copy assignment operator, and then -providing defaulted definitions of the move constructor and move assignment operator. -\begin{codeblock} -struct moveonly { - moveonly() = default; - moveonly(const moveonly&) = delete; - moveonly(moveonly&&) = default; - moveonly& operator=(const moveonly&) = delete; - moveonly& operator=(moveonly&&) = default; - ~moveonly() = default; -}; -moveonly* p; -moveonly q(*p); // error, deleted copy constructor -\end{codeblock} -\end{example} - -\pnum -A deleted function is implicitly an inline function\iref{dcl.inline}. \begin{note} The -one-definition rule\iref{basic.def.odr} applies to deleted definitions. \end{note} -A deleted definition of a function shall be the first declaration of the function or, -for an explicit specialization of a function template, the first declaration of that -specialization. -An implicitly declared allocation or deallocation function\iref{basic.stc.dynamic} -shall not be defined as deleted. -\begin{example} -\begin{codeblock} -struct sometype { - sometype(); -}; -sometype::sometype() = delete; // ill-formed; not first declaration -\end{codeblock} -\end{example}% -\indextext{definition!function|)} - -\rSec1[dcl.struct.bind]{Structured binding declarations}% -\indextext{structured binding declaration}% -\indextext{declaration!structured binding|see{structured binding declaration}}% - -\pnum -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\iref{basic.scope.declarative} -of \defn{structured binding}{s}. -Let \cv{} denote the -\grammarterm{cv-qualifier}{s} in the \grammarterm{decl-specifier-seq}. First, a -variable with a unique name \tcode{e} is introduced. If the -\grammarterm{assignment-expression} in the \grammarterm{initializer} -has array type \tcode{A} and no \grammarterm{ref-qualifier} is present, \tcode{e} -has type \cv{}~\tcode{A} and each element is copy-initialized or direct-initialized -from the corresponding element of the \grammarterm{assignment-expression} as specified -by the form of the \grammarterm{initializer}. -Otherwise, \tcode{e} -is defined as-if by - -\begin{ncbnf} -\opt{attribute-specifier-seq} decl-specifier-seq \opt{ref-qualifier} \terminal{e} initializer \terminal{;} -\end{ncbnf} - -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 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\iref{expr.prop}. -\end{note} - -\pnum -If \tcode{E} is an array type with element type \tcode{T}, the number -of elements in the \grammarterm{identifier-list} shall be equal to the -number of elements of \tcode{E}. Each \tcode{v}$_i$ is the name of an -lvalue that refers to the element $i$ of the array and whose type -is \tcode{T}; the referenced type is \tcode{T}. -\begin{note} -The top-level cv-qualifiers of \tcode{T} are \cv. -\end{note} -\begin{example} -\begin{codeblock} - auto f() -> int(&)[2]; - auto [ x, y ] = f(); // \tcode{x} and \tcode{y} refer to elements in a copy of the array return value - auto& [ xr, yr ] = f(); // \tcode{xr} and \tcode{yr} refer to elements in the array referred to by \tcode{f}'s return value -\end{codeblock} -\end{example} - -\pnum -Otherwise, if -the \grammarterm{qualified-id} \tcode{std::tuple_size} -names a complete type, -the expression \tcode{std::tuple_size::value} -shall be a well-formed integral constant expression -and -the number of elements in -the \grammarterm{identifier-list} shall be equal to the value of that -expression. The \grammarterm{unqualified-id} \tcode{get} is looked up -in the scope of \tcode{E} by class member access lookup\iref{basic.lookup.classref}, -and if that finds at least one declaration -that is a function template whose first template parameter -is a non-type parameter, -the initializer is -\tcode{e.get()}. Otherwise, the initializer is \tcode{get(e)}, -where \tcode{get} is looked up in the associated namespaces\iref{basic.lookup.argdep}. -In either case, \tcode{get} is interpreted as a \grammarterm{template-id}. -\begin{note} -Ordinary unqualified lookup\iref{basic.lookup.unqual} is not performed. -\end{note} -In either case, \tcode{e} is an lvalue if the type of the entity \tcode{e} -is an lvalue reference and an xvalue otherwise. Given the type $\tcode{T}_i$ -designated by \tcode{std::tuple_element::type}, -variables are introduced with unique names $\tcode{r}_i$ -of type ``reference to $\tcode{T}_i$'' -initialized with the initializer~(\ref{dcl.init.ref}), -where the reference is an lvalue reference if the initializer is -an lvalue and an rvalue reference otherwise. -Each $\tcode{v}_i$ is the name of an lvalue of type $\tcode{T}_i$ -that refers to the object bound to $\tcode{r}_i$; -the referenced type is $\tcode{T}_i$. - -\pnum -Otherwise, -all of \tcode{E}'s non-static data members -shall be direct members of \tcode{E} or -of the same base class of \tcode{E}, -well-formed when named as \tcode{e.\placeholder{name}} -in the context of the structured binding, -\tcode{E} shall not have an anonymous union member, and -the number of elements in the \grammarterm{identifier-list} shall be -equal to the number of non-static data members of \tcode{E}. -Designating the non-static data members of \tcode{E} as -\tcode{m}$_0$, \tcode{m}$_1$, \tcode{m}$_2$, ... -(in declaration order), -each \tcode{v}$_i$ is the -name of an lvalue that refers to the member \tcode{m}$_i$ of \tcode{e} and -whose type is \cv{}~$\tcode{T}_i$, where $\tcode{T}_i$ is the declared type of -that member; the referenced type is \cv{}~$\tcode{T}_i$. The lvalue is a -bit-field if that member is a bit-field. -\begin{example} -\begin{codeblock} -struct S { int x1 : 2; volatile double y1; }; -S f(); -const auto [ x, y ] = f(); -\end{codeblock} -The type of the \grammarterm{id-expression} \tcode{x} is ``\tcode{const int}'', -the type of the \grammarterm{id-expression} \tcode{y} is ``\tcode{const volatile double}''. -\end{example} - -\rSec1[dcl.init]{Initializers}% -\indextext{initialization|(} - -\pnum -The process of initialization described in this subclause applies to -all initializations regardless of syntactic context, including the -initialization of a function parameter\iref{expr.call}, the -initialization of a return value\iref{stmt.return}, or when an -initializer follows a declarator. - -\begin{bnf} -\nontermdef{initializer}\br - brace-or-equal-initializer\br - \terminal{(} expression-list \terminal{)} -\end{bnf} - -\begin{bnf} -\nontermdef{brace-or-equal-initializer}\br - \terminal{=} initializer-clause\br - braced-init-list -\end{bnf} - -\begin{bnf} -\nontermdef{initializer-clause}\br - assignment-expression\br - braced-init-list -\end{bnf} - -\begin{bnf} -\nontermdef{braced-init-list}\br - \terminal{\{} initializer-list \opt{\terminal{,}} \terminal{\}}\br - \terminal{\{} designated-initializer-list \opt{\terminal{,}} \terminal{\}}\br - \terminal{\{} \terminal{\}} -\end{bnf} - -\begin{bnf} -\nontermdef{initializer-list}\br - initializer-clause \opt{\terminal{...}}\br - initializer-list \terminal{,} initializer-clause \opt{\terminal{...}} -\end{bnf} - -\begin{bnf} -\nontermdef{designated-initializer-list}\br - designated-initializer-clause\br - designated-initializer-list \terminal{,} designated-initializer-clause -\end{bnf} - -\begin{bnf} -\nontermdef{designated-initializer-clause}\br - designator brace-or-equal-initializer -\end{bnf} - -\begin{bnf} -\nontermdef{designator}\br - \terminal{.} identifier -\end{bnf} - -\begin{bnf} -\nontermdef{expr-or-braced-init-list}\br - expression\br - braced-init-list -\end{bnf} - -\begin{note} -The rules in this subclause apply even if the grammar permits only -the \grammarterm{brace-or-equal-initializer} form -of \grammarterm{initializer} in a given context. -\end{note} - -\pnum -Except for objects declared with the \tcode{constexpr} specifier, for which see~\ref{dcl.constexpr}, -an \grammarterm{initializer} in the definition of a variable can consist of -arbitrary -\indextext{initialization!automatic object}% -\indextext{initialization!static object@\tcode{static} object}% -expressions involving literals and previously declared -variables and functions, -regardless of the variable's storage duration. -\begin{example} - -\begin{codeblock} -int f(int); -int a = 2; -int b = f(a); -int c(b); -\end{codeblock} -\end{example} - -\pnum -\begin{note} -Default arguments are more restricted; see~\ref{dcl.fct.default}. -\end{note} - -\pnum -\begin{note} -The order of initialization of variables with static storage duration is described in~\ref{basic.start} -and~\ref{stmt.dcl}. -\end{note} - -\pnum -A declaration of a block-scope variable with external or internal -linkage that has an \grammarterm{initializer} is ill-formed. - -\pnum -\indextext{initialization!static object@\tcode{static} object}% -\indextext{initialization!default}% -\indextext{variable!indeterminate uninitialized}% -\indextext{initialization!zero-initialization}% -To -\defnx{zero-initialize}{zero-initialization} -an object or reference of type -\tcode{T} -means: - -\begin{itemize} -\item -if -\tcode{T} -is a scalar type\iref{basic.types}, the -object -is initialized to the value obtained by converting the integer literal \tcode{0} -(zero) to -\tcode{T};\footnote{As specified in~\ref{conv.ptr}, converting an integer -literal whose value is -\tcode{0} -to a pointer type results in a null pointer value. -} - -\item -if -\tcode{T} -is a (possibly cv-qualified) non-union class type, -its padding bits\iref{basic.types} are initialized to zero bits and -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; - -\item -if -\tcode{T} -is a (possibly cv-qualified) union type, -its padding bits\iref{basic.types} are initialized to zero bits and -the -object's first non-static named -data member -is zero-initialized; - -\item -if -\tcode{T} -is an array type, -each element is zero-initialized; -\item -if -\tcode{T} -is a reference type, no initialization is performed. -\end{itemize} - -\pnum -To -\defnx{default-initialize}{default-initialization} -an object of type -\tcode{T} -means: - -\begin{itemize} -\item -If -\tcode{T} -is a (possibly cv-qualified) class type\iref{class}, -constructors are considered. The applicable constructors are -enumerated\iref{over.match.ctor}, and the best one for the -\grammarterm{initializer} \tcode{()} is chosen through -overload resolution\iref{over.match}. The constructor thus selected -is called, with an empty argument list, to initialize the object. - -\item -If -\tcode{T} -is an array type, each element is default-initialized. - -\item -Otherwise, -no initialization is performed. -\end{itemize} - -A class type \tcode{T} is \defn{const-default-constructible} if -default-initialization of \tcode{T} would invoke -a user-provided constructor of \tcode{T} (not inherited from a base class) -or if - -\begin{itemize} -\item -each direct non-variant non-static data member \tcode{M} of \tcode{T} -has a default member initializer -or, if \tcode{M} is of class type \tcode{X} (or array thereof), -\tcode{X} is const-default-constructible, -\item -if \tcode{T} is a union with at least one non-static data member, -exactly one variant member has a default member initializer, -\item -if \tcode{T} is not a union, -for each anonymous union member with at least one non-static data member (if any), -exactly one non-static data member has a default member initializer, and -\item -each potentially constructed base class of \tcode{T} is const-default-constructible. -\end{itemize} - -If a program calls for the default-initialization of an object of a -const-qualified type \tcode{T}, -\tcode{T} shall be a const-default-constructible class type or array thereof. - -\pnum -To -\defnx{value-initialize}{value-initialization} -an object of type -\tcode{T} -means: - -\begin{itemize} -\item -if -\tcode{T} -is a (possibly cv-qualified) class type\iref{class} with -either no default constructor\iref{class.ctor} or a default -constructor that is user-provided or deleted, then the object is default-initialized; - -\item -if -\tcode{T} -is a (possibly cv-qualified) class type without a -user-provided or deleted default constructor, -then the object is zero-initialized and the semantic constraints for -default-initialization are checked, and if \tcode{T} has a -non-trivial default constructor, the object is default-initialized; - -\item -if -\tcode{T} -is an array type, then each element is value-initialized; - -\item -otherwise, the object is zero-initialized. -\end{itemize} - -\pnum -A program that calls for default-initialization -or value-initialization -of an entity -of reference type is ill-formed. - -\pnum -\begin{note} Every -object of static storage duration is -zero-initialized at program startup before any other initialization -takes place. -In some cases, additional initialization is done later. -\end{note} - -\pnum -An object whose initializer is an empty set of parentheses, i.e., -\tcode{()}, -shall be -value-initialized. - -\indextext{ambiguity!function declaration}% -\begin{note} -Since -\tcode{()} -is not permitted by the syntax for -\grammarterm{initializer}, - -\begin{codeblock} -X a(); -\end{codeblock} - -is not the declaration of an object of class -\tcode{X}, -but the declaration of a function taking no argument and returning an -\tcode{X}. -The form -\tcode{()} -is permitted in certain other initialization contexts~(\ref{expr.new}, -\ref{expr.type.conv}, \ref{class.base.init}). -\end{note} - -\pnum -\indextext{value!indeterminate}% -\indextext{indeterminate value}% -If no initializer is specified for an object, the object is default-initialized. -When storage for an object with automatic or dynamic storage duration -is obtained, the object has an \term{indeterminate value}, and if -no initialization is performed for the object, that object retains an -indeterminate value until that value is replaced\iref{expr.ass}. -\begin{note} Objects with static or thread storage duration are zero-initialized, -see~\ref{basic.start.static}. \end{note} -If an indeterminate value is produced by an evaluation, the behavior is -undefined except in the following cases: - -\begin{itemize} -\item -If an indeterminate value of -unsigned narrow character type\iref{basic.fundamental} -or \tcode{std::byte} type\iref{cstddef.syn} -is produced by the evaluation of: -\begin{itemize} -\item the second or third operand of a conditional expression\iref{expr.cond}, -\item the right operand of a comma expression\iref{expr.comma}, -\item the operand of a cast or conversion~(\ref{conv.integral}, -\ref{expr.type.conv}, \ref{expr.static.cast}, \ref{expr.cast}) to an -unsigned narrow character type -or \tcode{std::byte} type\iref{cstddef.syn}, or -\item a discarded-value expression\iref{expr.prop}, -\end{itemize} -then the result of the operation is 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 right -operand of a simple assignment operator\iref{expr.ass} whose first operand -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 -If an indeterminate value of unsigned narrow character type is produced by the -evaluation of the initialization expression when initializing an object of -unsigned narrow character type, that object is initialized to an indeterminate -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} - int f(bool b) { - unsigned char c; - unsigned char d = c; // OK, \tcode{d} has an indeterminate value - int e = d; // undefined behavior - return b ? d : 0; // undefined behavior if \tcode{b} is \tcode{true} - } -\end{codeblock} -\end{example} - -\pnum -\indextext{initialization!class member}% -An initializer for a static member is in the scope of the member's class. -\begin{example} -\begin{codeblock} -int a; - -struct X { - static int a; - static int b; -}; - -int X::a = 1; -int X::b = a; // \tcode{X::b = X::a} -\end{codeblock} -\end{example} - -\pnum -If the entity being initialized does not have class type, the -\grammarterm{expression-list} in a -parenthesized initializer shall be a single expression. - -\pnum -\indextext{initialization!copy}% -\indextext{initialization!direct}% -The initialization that occurs in the \tcode{=} form of a -\grammarterm{brace-or-equal-initializer} or -\grammarterm{condition}\iref{stmt.select}, -as well as in argument passing, function return, -throwing an exception\iref{except.throw}, -handling an exception\iref{except.handle}, -and aggregate member initialization\iref{dcl.init.aggr}, -is called -\defn{copy-initialization}. -\begin{note} Copy-initialization may invoke a move\iref{class.copy}. \end{note} - -\pnum -The initialization that occurs in the forms -\begin{codeblock} -T x(a); -T x{a}; -\end{codeblock} -as well as in -\tcode{new} -expressions\iref{expr.new}, -\tcode{static_cast} -expressions\iref{expr.static.cast}, -functional notation type conversions\iref{expr.type.conv}, -\grammarterm{mem-initializer}{s}\iref{class.base.init}, and -the \grammarterm{braced-init-list} form of a \grammarterm{condition} -is called -\defn{direct-initialization}. - -\pnum -The semantics of initializers are as follows. -The -\indextext{type!destination}% -\term{destination type} -is the type of the object or reference being initialized and the -\term{source type} -is the type of the initializer expression. -If the initializer is not a single (possibly parenthesized) expression, the -source type is not defined. -\begin{itemize} -\item -If the initializer is a (non-parenthesized) \grammarterm{braced-init-list} -or is \tcode{=} \grammarterm{braced-init-list}, the object or reference -is list-initialized\iref{dcl.init.list}. -\item -If the destination type is a reference type, see~\ref{dcl.init.ref}. -\item -If the destination type is an array of characters, -an array of \tcode{char16_t}, -an array of \tcode{char32_t}, -or an array of -\tcode{wchar_t}, -and the initializer is a string literal, see~\ref{dcl.init.string}. -\item If the initializer is \tcode{()}, the object is value-initialized. -\item -Otherwise, if the destination type is an array, the program is ill-formed. -\item -If the destination type is a (possibly cv-qualified) class type: - -\begin{itemize} -\item -If the initializer expression is a prvalue -and the cv-unqualified version of the source type -is the same class as the class of the destination, -the initializer expression is used to initialize the destination object. -\begin{example} -\tcode{T x = T(T(T()));} calls the \tcode{T} default constructor to initialize \tcode{x}. -\end{example} -\item -Otherwise, if the initialization is direct-initialization, -or if it is copy-initialization where the cv-unqualified version of the source -type is the same class as, or a derived class of, the class of the destination, -constructors are considered. -The applicable constructors -are enumerated\iref{over.match.ctor}, and the best one is chosen -through overload resolution\iref{over.match}. -The constructor so selected -is called to initialize the object, with the initializer -expression or \grammarterm{expression-list} as its argument(s). -If no constructor applies, or the overload resolution is -ambiguous, the initialization is ill-formed. -\item -Otherwise (i.e., for the remaining copy-initialization cases), -user-defined conversion sequences that can convert from the -source type to the destination type or (when a conversion function -is used) to a derived class thereof are enumerated as described in~\ref{over.match.copy}, and the best one is chosen through overload -resolution\iref{over.match}. If the conversion cannot be done or -is ambiguous, the initialization is ill-formed. The function -selected is called with the initializer expression as its -argument; if the function is a constructor, the call is a prvalue -of the cv-unqualified version of the -destination type whose result object is initialized by the constructor. -The call is used -to direct-initialize, according to the rules above, the object -that is the destination of the copy-initialization. -\end{itemize} - -\item -Otherwise, if the source type -is a (possibly cv-qualified) class type, conversion functions are -considered. -The applicable conversion functions are enumerated\iref{over.match.conv}, -and the best one is chosen through overload -resolution\iref{over.match}. -The user-defined conversion so selected -is called to convert the initializer expression into the -object being initialized. -If the conversion cannot be done or is -ambiguous, the initialization is ill-formed. -\item -Otherwise, the initial value of the object being initialized is -the (possibly converted) value of the initializer expression. -Standard conversions\iref{conv} will be used, if necessary, -to convert the initializer expression to the cv-unqualified version of -the destination type; -no user-defined conversions are considered. -If the conversion cannot -be done, the initialization is ill-formed. -When initializing a bit-field with a value that it cannot represent, the -resulting value of the bit-field is -\impldefplain{value of bit-field that cannot represent!initializer}. -\indextext{initialization!\idxcode{const}}% -\begin{note} -An expression of type -``\cvqual{cv1} \tcode{T}'' -can initialize an object of type -``\cvqual{cv2} \tcode{T}'' -independently of -the cv-qualifiers -\cvqual{cv1} -and \cvqual{cv2}. - -\begin{codeblock} -int a; -const int b = a; -int c = b; -\end{codeblock} -\end{note} -\end{itemize} - -\pnum -An \grammarterm{initializer-clause} followed by an ellipsis is a -pack expansion\iref{temp.variadic}. - -\pnum -If the initializer is a parenthesized \grammarterm{expression-list}, -the expressions are evaluated in the order -specified for function calls\iref{expr.call}. - -\pnum -The same \grammarterm{identifier} -shall not appear in multiple \grammarterm{designator}{s} of a -\grammarterm{designated-initializer-list}. - -\pnum -An object whose initialization has completed -is deemed to be constructed, -even if no constructor of the object's class -is invoked for the initialization. -\begin{note} -Such an object might have been value-initialized -or initialized by aggregate initialization\iref{dcl.init.aggr} -or by an inherited constructor\iref{class.inhctor.init}. -\end{note} - -\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\iref{basic.def} of the variable, -but the initializing declaration -of a non-inline static data member\iref{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}% -\indextext{aggregate initialization}% -\indextext{initialization!array}% -\indextext{initialization!class object}% -\indextext{class object initialization|see{constructor}}% -\indextext{\idxcode{\{\}}!initializer list} - -\pnum -An \defn{aggregate} is an array or a class\iref{class} with -\begin{itemize} -\item -no user-provided, \tcode{explicit}, or inherited constructors\iref{class.ctor}, -\item -no private or protected non-static data members\iref{class.access}, -\item -no virtual functions\iref{class.virtual}, and -\item -no virtual, private, or protected base classes\iref{class.mi}. -\end{itemize} -\begin{note} -Aggregate initialization does not allow accessing -protected and private base class' members or constructors. -\end{note} - -\pnum -The \defnx{elements}{aggregate!elements} of an aggregate are: -\begin{itemize} -\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\iref{class.mem} -that are not members of an anonymous union, in declaration order. -\end{itemize} - -\pnum -When an aggregate is initialized by an initializer list -as specified in~\ref{dcl.init.list}, -the elements of the initializer list are taken as initializers -for the elements of the aggregate. -The \defnx{explicitly initialized elements}{explicitly initialized elements!aggregate} -of the aggregate are determined as follows: -\begin{itemize} -\item -If the initializer list is a \grammarterm{designated-initializer-list}, -the aggregate shall be of class type, -the \grammarterm{identifier} in each \grammarterm{designator} -shall name a direct non-static data member of the class, and -the explicitly initialized elements of the aggregate -are the elements that are, or contain, those members. -\item -If the initializer list is an \grammarterm{initializer-list}, -the explicitly initialized elements of the aggregate -are the first $n$ elements of the aggregate, -where $n$ is the number of elements in the initializer list. -\item -Otherwise, the initializer list must be \tcode{\{\}}, -and there are no explicitly initialized elements. -\end{itemize} - -\pnum -For each explicitly initialized element: -\begin{itemize} -\item -If the element is an anonymous union object and -the initializer list is a \grammarterm{designated-initializer-list}, -the anonymous union object is initialized by the -\grammarterm{designated-initializer-list} \tcode{\{ }\placeholder{D}\tcode{ \}}, -where \placeholder{D} is the \grammarterm{designated-initializer-clause} -naming a member of the anonymous union object. -There shall be only one such \grammarterm{designated-initializer-clause}. -\item -Otherwise, the element is copy-initialized -from the corresponding \grammarterm{initializer-clause} -or the \grammarterm{brace-or-equal-initializer} -of the corresponding \grammarterm{designated-initializer-clause}. -If that initializer is of the form -\grammarterm{assignment-expression} or -\tcode{= }\grammarterm{assignment-expression} -and -a narrowing conversion\iref{dcl.init.list} is required -to convert the expression, the program is ill-formed. -\begin{note} If an initializer is itself an initializer list, -the element is list-initialized, which will result in a recursive application -of the rules in this subclause if the element is an aggregate. \end{note} -\end{itemize} -\begin{example} -\begin{codeblock} -struct A { - int x; - struct B { - int i; - int j; - } b; -} a = { 1, { 2, 3 } }; -\end{codeblock} -initializes -\tcode{a.x} -with 1, -\tcode{a.b.i} -with 2, -\tcode{a.b.j} -with 3. - -\begin{codeblock} -struct base1 { int b1, b2 = 42; }; -struct base2 { - base2() { - b3 = 42; - } - int b3; -}; -struct derived : base1, base2 { - int d; -}; - -derived d1{{1, 2}, {}, 4}; -derived d2{{}, {}, 4}; -\end{codeblock} -initializes -\tcode{d1.b1} with 1, -\tcode{d1.b2} with 2, -\tcode{d1.b3} with 42, -\tcode{d1.d} with 4, and -\tcode{d2.b1} with 0, -\tcode{d2.b2} with 42, -\tcode{d2.b3} with 42, -\tcode{d2.d} with 4. -\end{example} - -\pnum -For a non-union aggregate, -each element that is not an explicitly initialized element -is initialized as follows: -\begin{itemize} -\item -If the element has a default member initializer\iref{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\iref{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} -struct S { int a; const char* b; int c; int d = b[a]; }; -S ss = { 1, "asdf" }; -\end{codeblock} - -initializes -\tcode{ss.a} -with 1, -\tcode{ss.b} -with \tcode{"asdf"}, -\tcode{ss.c} -with the value of an expression of the form -\tcode{int\{\}} -(that is, \tcode{0}), and \tcode{ss.d} with the value of \tcode{ss.b[ss.a]} -(that is, \tcode{'s'}), and in - -\begin{codeblock} -struct X { int i, j, k = 42; }; -X a[] = { 1, 2, 3, 4, 5, 6 }; -X b[2] = { { 1, 2, 3 }, { 4, 5, 6 } }; -\end{codeblock} - -\tcode{a} and \tcode{b} have the same value - -\begin{codeblock} -struct A { - string a; - int b = 42; - int c = -1; -}; -\end{codeblock} - -\tcode{A\{.c=21\}} has the following steps: -\begin{itemize} -\item Initialize \tcode{a} with \tcode{\{\}} -\item Initialize \tcode{b} with \tcode{= 42} -\item Initialize \tcode{c} with \tcode{= 21} -\end{itemize} -\end{example} - -\pnum -The initializations of the elements of the aggregate -are evaluated in the element order. -That is, -all value computations and side effects associated with a given element -are sequenced before -those of any element that follows it in order. - -\pnum -An aggregate that is a class can also be initialized with a single -expression not enclosed in braces, as described in~\ref{dcl.init}. - -\pnum -The destructor for each element of class type -is potentially invoked\iref{class.dtor} -from the context where the aggregate initialization occurs. -\begin{note} -This provision ensures that destructors can be called -for fully-constructed subobjects -in case an exception is thrown\iref{except.ctor}. -\end{note} - -\pnum -An array of unknown bound initialized with a -brace-enclosed -\grammarterm{initializer-list} -containing -\tcode{n} -\grammarterm{initializer-clause}{s}, -where -\tcode{n} -shall be greater than zero, is defined as having -\tcode{n} -elements\iref{dcl.array}. -\begin{example} - -\begin{codeblock} -int x[] = { 1, 3, 5 }; -\end{codeblock} - -declares and initializes -\tcode{x} -as a one-dimensional array that has three elements -since no size was specified and there are three initializers. -\end{example} -An empty initializer list -\tcode{\{\}} -shall not be used as the \grammarterm{initializer-clause} -for an array of unknown bound.\footnote{The syntax provides for empty -\grammarterm{initializer-list}{s}, -but nonetheless \Cpp{} does not have zero length arrays.} -\begin{note} -A default member initializer does not determine the bound for a member -array of unknown bound. Since the default member initializer is -ignored if a suitable \grammarterm{mem-initializer} is present\iref{class.base.init}, -the default member initializer is not -considered to initialize the array of unknown bound. -\begin{example} -\begin{codeblock} -struct S { - int y[] = { 0 }; // error: non-static data member of incomplete type -}; -\end{codeblock} -\end{example} -\end{note} - -\pnum -\begin{note} -Static data members, -non-static data members of anonymous union members, -and -unnamed bit-fields -are not considered elements of the aggregate. -\begin{example} - -\begin{codeblock} -struct A { - int i; - static int s; - int j; - int :17; - int k; -} a = { 1, 2, 3 }; -\end{codeblock} - -Here, the second initializer 2 initializes -\tcode{a.j} -and not the static data member -\tcode{A::s}, and the third initializer 3 initializes \tcode{a.k} -and not the unnamed bit-field before it. -\end{example} -\end{note} - -\pnum -An -\grammarterm{initializer-list} -is ill-formed if the number of -\grammarterm{initializer-clause}{s} -exceeds the number of elements of the aggregate. -\begin{example} - -\begin{codeblock} -char cv[4] = { 'a', 's', 'd', 'f', 0 }; // error -\end{codeblock} - -is ill-formed. -\end{example} - -\pnum -If a reference member is initialized from its default member initializer -and a potentially-evaluated subexpression thereof is an aggregate -initialization that would use that default member initializer, -the program is ill-formed. -\begin{example} -\begin{codeblock} - struct A; - extern A a; - struct A { - const A& a1 { A{a,a} }; // OK - const A& a2 { A{} }; // error - }; - A a{a,a}; // OK -\end{codeblock} -\end{example} - -\pnum -If an aggregate class \tcode{C} contains a subaggregate element -\tcode{e} with no elements, -the \grammarterm{initializer-clause} for \tcode{e} shall not be -omitted from an \grammarterm{initializer-list} for an object of type -\tcode{C} unless the \grammarterm{initializer-clause}{s} for all -elements of \tcode{C} following \tcode{e} are also omitted. -\begin{example} -\begin{codeblock} -struct S { } s; -struct A { - S s1; - int i1; - S s2; - int i2; - S s3; - int i3; -} a = { - { }, // Required initialization - 0, - s, // Required initialization - 0 -}; // Initialization not required for \tcode{A::s3} because \tcode{A::i3} is also not initialized -\end{codeblock} -\end{example} - -\pnum -When initializing a multi-dimensional array, -the -\grammarterm{initializer-clause}{s} -initialize the elements with the last (rightmost) index of the array -varying the fastest\iref{dcl.array}. -\begin{example} - -\begin{codeblock} -int x[2][2] = { 3, 1, 4, 2 }; -\end{codeblock} - -initializes -\tcode{x[0][0]} -to -\tcode{3}, -\tcode{x[0][1]} -to -\tcode{1}, -\tcode{x[1][0]} -to -\tcode{4}, -and -\tcode{x[1][1]} -to -\tcode{2}. -On the other hand, - -\begin{codeblock} -float y[4][3] = { - { 1 }, { 2 }, { 3 }, { 4 } -}; -\end{codeblock} - -initializes the first column of -\tcode{y} -(regarded as a two-dimensional array) -and leaves the rest zero. -\end{example} - -\pnum -Braces can be elided in an -\grammarterm{initializer-list} -as follows. -If the -\grammarterm{initializer-list} -begins with a left brace, -then the succeeding comma-separated list of -\grammarterm{initializer-clause}{s} -initializes the elements of a subaggregate; -it is erroneous for there to be more -\grammarterm{initializer-clause}{s} -than elements. -If, however, the -\grammarterm{initializer-list} -for a subaggregate does not begin with a left brace, -then only enough -\grammarterm{initializer-clause}{s} -from the list are taken to initialize the elements of the subaggregate; -any remaining -\grammarterm{initializer-clause}{s} -are left to initialize the next element of the aggregate -of which the current subaggregate is an element. -\begin{example} - -\begin{codeblock} -float y[4][3] = { - { 1, 3, 5 }, - { 2, 4, 6 }, - { 3, 5, 7 }, -}; -\end{codeblock} - -is a completely-braced initialization: -1, 3, and 5 initialize the first row of the array -\tcode{y[0]}, -namely -\tcode{y[0][0]}, -\tcode{y[0][1]}, -and -\tcode{y[0][2]}. -Likewise the next two lines initialize -\tcode{y[1]} -and -\tcode{y[2]}. -The initializer ends early and therefore -\tcode{y[3]}s -elements are initialized as if explicitly initialized with an -expression of the form -\tcode{float()}, -that is, are initialized with -\tcode{0.0}. -In the following example, braces in the -\grammarterm{initializer-list} -are elided; -however the -\grammarterm{initializer-list} -has the same effect as the completely-braced -\grammarterm{initializer-list} -of the above example, - -\begin{codeblock} -float y[4][3] = { - 1, 3, 5, 2, 4, 6, 3, 5, 7 -}; -\end{codeblock} - -The initializer for -\tcode{y} -begins with a left brace, but the one for -\tcode{y[0]} -does not, -therefore three elements from the list are used. -Likewise the next three are taken successively for -\tcode{y[1]} -and -\tcode{y[2]}. -\end{example} - -\pnum -All implicit type conversions\iref{conv} are considered when -initializing the element with an \grammarterm{assignment-expression}. -If the -\grammarterm{assignment-expression} -can initialize an element, the element is initialized. -Otherwise, if the element is itself a subaggregate, -brace elision is assumed and the -\grammarterm{assignment-expression} -is considered for the initialization of the first element of the subaggregate. -\begin{note} As specified above, brace elision cannot apply to -subaggregates with no elements; an -\grammarterm{initializer-clause} for the entire subobject is -required.\end{note} - -\begin{example} - -\begin{codeblock} -struct A { - int i; - operator int(); -}; -struct B { - A a1, a2; - int z; -}; -A a; -B b = { 4, a, a }; -\end{codeblock} - -Braces are elided around the -\grammarterm{initializer-clause} -for -\tcode{b.a1.i}. -\tcode{b.a1.i} -is initialized with 4, -\tcode{b.a2} -is initialized with -\tcode{a}, -\tcode{b.z} -is initialized with whatever -\tcode{a.operator int()} -returns. -\end{example} - -\pnum -\indextext{initialization!array of class objects}% -\begin{note} -An aggregate array or an aggregate class may contain elements of a -class type with a user-provided constructor\iref{class.ctor}. -Initialization of these aggregate objects is described in~\ref{class.expl.init}. -\end{note} - -\pnum -\begin{note} -Whether the initialization of aggregates with static storage duration -is static or dynamic is specified -in~\ref{basic.start.static}, \ref{basic.start.dynamic}, and~\ref{stmt.dcl}. -\end{note} - -\pnum -\indextext{initialization!\idxcode{union}}% -When a union is initialized with an initializer list, -there shall not be more than one -explicitly initialized element. -\begin{example} -\begin{codeblock} -union u { int a; const char* b; }; -u a = { 1 }; -u b = a; -u c = 1; // error -u d = { 0, "asdf" }; // error -u e = { "asdf" }; // error -u f = { .b = "asdf" }; -u g = { .a = 1, .b = "asdf" }; // error -\end{codeblock} -\end{example} - -\pnum -\begin{note} -As described above, -the braces around the -\grammarterm{initializer-clause} -for a union member can be omitted if the -union is a member of another aggregate. -\end{note} - -\rSec2[dcl.init.string]{Character arrays}% -\indextext{initialization!character array} - -\pnum -An array of narrow character type\iref{basic.fundamental}, -\tcode{char16_t} array, -\tcode{char32_t} array, -or \tcode{wchar_t} array -can be initialized by a -narrow string literal, \tcode{char16_t} string literal, \tcode{char32_t} string -literal, or wide string literal, -respectively, or by an appropriately-typed string literal enclosed in -braces\iref{lex.string}. -\indextext{initialization!character array}% -Successive -characters of the -value of the string literal -initialize the elements of the array. -\begin{example} - -\begin{codeblock} -char msg[] = "Syntax error on line %s\n"; -\end{codeblock} - -shows a character array whose members are initialized -with a -\grammarterm{string-literal}. -Note that because -\tcode{'\textbackslash n'} -is a single character and -because a trailing -\tcode{'\textbackslash 0'} -is appended, -\tcode{sizeof(msg)} -is -\tcode{25}. -\end{example} - -\pnum -There shall not be more initializers than there are array elements. -\begin{example} - -\begin{codeblock} -char cv[4] = "asdf"; // error -\end{codeblock} - -is ill-formed since there is no space for the implied trailing -\tcode{'\textbackslash 0'}. -\end{example} - -\pnum -If there are fewer initializers than there are array elements, each element not -explicitly initialized shall be zero-initialized\iref{dcl.init}. - -\rSec2[dcl.init.ref]{References}% -\indextext{initialization!reference} - -\pnum -A variable whose declared type is -``reference to type \tcode{T}''\iref{dcl.ref} -shall be initialized. -\begin{example} - -\begin{codeblock} -int g(int) noexcept; -void f() { - int i; - int& r = i; // \tcode{r} refers to \tcode{i} - r = 1; // the value of \tcode{i} becomes \tcode{1} - int* p = &r; // \tcode{p} points to \tcode{i} - int& rr = r; // \tcode{rr} refers to what \tcode{r} refers to, that is, to \tcode{i} - int (&rg)(int) = g; // \tcode{rg} refers to the function \tcode{g} - rg(i); // calls function \tcode{g} - int a[3]; - int (&ra)[3] = a; // \tcode{ra} refers to the array \tcode{a} - ra[1] = i; // modifies \tcode{a[1]} -} -\end{codeblock} -\end{example} - -\pnum -A reference cannot be changed to refer to another object after initialization. -\indextext{assignment!reference}% -\begin{note} -Assignment to a reference assigns to the object referred to by the reference\iref{expr.ass}. -\end{note} -\indextext{argument passing!reference and}% -Argument passing\iref{expr.call} -\indextext{\idxcode{return}!reference and}% -and function value return\iref{stmt.return} are initializations. - -\pnum -The initializer can be omitted for a reference only in a parameter declaration\iref{dcl.fct}, -in the declaration of a function return type, in the declaration of -a class member within its class definition\iref{class.mem}, and where the -\tcode{extern} -specifier is explicitly used. -\indextext{declaration!extern@\tcode{extern} reference}% -\begin{example} - -\begin{codeblock} -int& r1; // error: initializer missing -extern int& r2; // OK -\end{codeblock} -\end{example} - -\pnum -Given types ``\cvqual{cv1} \tcode{T1}'' and ``\cvqual{cv2} \tcode{T2}'', -``\cvqual{cv1} \tcode{T1}'' is \defn{reference-related} to -``\cvqual{cv2} \tcode{T2}'' if -\tcode{T1} is the same type as \tcode{T2}, or -\tcode{T1} is a base class of \tcode{T2}. -``\cvqual{cv1} \tcode{T1}'' is \defn{reference-compatible} -with ``\cvqual{cv2} \tcode{T2}'' if -\begin{itemize} -\item \tcode{T1} is reference-related to \tcode{T2}, or -\item \tcode{T2} is ``\tcode{noexcept} function'' and \tcode{T1} is ``function'', -where the function types are otherwise the same, -\end{itemize} -and -\cvqual{cv1} -is the same cv-qualification as, or greater cv-qualification than, -\cvqual{cv2}. -In all cases where the reference-related or reference-compatible relationship -of two types is used to establish the validity of a reference binding, and -\tcode{T1} -is a base class of -\tcode{T2}, -a program that necessitates such a binding is ill-formed if -\tcode{T1} -is an inaccessible\iref{class.access} or ambiguous\iref{class.member.lookup} -base class of -\tcode{T2}. - -\pnum -A reference to type ``\cvqual{cv1} \tcode{T1}'' is initialized by -an expression of type ``\cvqual{cv2} \tcode{T2}'' as follows:% -\indextext{binding!reference} - -\begin{itemize} -\item -If the reference is an lvalue reference and the initializer expression - -\begin{itemize} -\item -is an lvalue (but is not a -bit-field), and -``\cvqual{cv1} \tcode{T1}'' is reference-compatible with -``\cvqual{cv2} \tcode{T2}'', or -\item -has a class type (i.e., -\tcode{T2} -is a class type), where \tcode{T1} is not reference-related to \tcode{T2}, and can be converted -to an lvalue of type ``\cvqual{cv3} \tcode{T3}'', where -``\cvqual{cv1} \tcode{T1}'' is reference-compatible with -``\cvqual{cv3} \tcode{T3}''\footnote{This requires a conversion -function\iref{class.conv.fct} returning a reference type.} -(this conversion is selected by enumerating the applicable conversion -functions\iref{over.match.ref} and choosing the best one through overload -resolution\iref{over.match}), -\end{itemize} -then the reference is bound to the initializer expression lvalue in the -first case and to the lvalue result of the conversion -in the second case (or, in either case, to the appropriate base class subobject of the object). -\begin{note} -The usual lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, -and function-to-pointer\iref{conv.func} standard -conversions are not needed, and therefore are suppressed, when such -direct bindings to lvalues are done. -\end{note} - -\begin{example} - -\begin{codeblock} -double d = 2.0; -double& rd = d; // \tcode{rd} refers to \tcode{d} -const double& rcd = d; // \tcode{rcd} refers to \tcode{d} - -struct A { }; -struct B : A { operator int&(); } b; -A& ra = b; // \tcode{ra} refers to \tcode{A} subobject in \tcode{b} -const A& rca = b; // \tcode{rca} refers to \tcode{A} subobject in \tcode{b} -int& ir = B(); // \tcode{ir} refers to the result of \tcode{B::operator int\&} -\end{codeblock} -\end{example} - -\item -Otherwise, -if the reference is an lvalue reference to a -type that is not const-qualified or is volatile-qualified, -the program is ill-formed. -\begin{example} - -\begin{codeblock} -double& rd2 = 2.0; // error: not an lvalue and reference not \tcode{const} -int i = 2; -double& rd3 = i; // error: type mismatch and reference not \tcode{const} -\end{codeblock} -\end{example} - -\item Otherwise, if the initializer expression - -\begin{itemize} -\item is an rvalue (but not a bit-field) or function lvalue and -``\cvqual{cv1} \tcode{T1}'' is -reference-compatible with ``\cvqual{cv2} \tcode{T2}'', or - -\item has a class type (i.e., \tcode{T2} is a class type), where \tcode{T1} -is not reference-related to \tcode{T2}, and can be converted to -an rvalue or function lvalue of type ``\cvqual{cv3} \tcode{T3}'', -where ``\cvqual{cv1} \tcode{T1}'' is -reference-compatible with ``\cvqual{cv3} \tcode{T3}'' (see~\ref{over.match.ref}), - -\end{itemize} - -then -the value of the initializer expression in the first case and -the result of the conversion in the second case -is called the converted initializer. -If the converted initializer is a prvalue, -its type \tcode{T4} is adjusted to type ``\cvqual{cv1} \tcode{T4}''\iref{conv.qual} -and the temporary materialization conversion\iref{conv.rval} is applied. -In any case, -the reference is bound to the resulting glvalue -(or to an appropriate base class subobject). - -\begin{example} - -\begin{codeblock} -struct A { }; -struct B : A { } b; -extern B f(); -const A& rca2 = f(); // bound to the \tcode{A} subobject of the \tcode{B} rvalue. -A&& rra = f(); // same as above -struct X { - operator B(); - operator int&(); -} x; -const A& r = x; // bound to the \tcode{A} subobject of the result of the conversion -int i2 = 42; -int&& rri = static_cast(i2); // bound directly to \tcode{i2} -B&& rrb = x; // bound directly to the result of \tcode{operator B} -\end{codeblock} -\end{example} - -\item -Otherwise: -\begin{itemize} -\item -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 -``\cvqual{cv1} \tcode{T1}'' by -user-defined conversion -(\ref{dcl.init}, \ref{over.match.copy}, \ref{over.match.conv}); -the program is ill-formed if the corresponding non-reference -copy-initialization would be ill-formed. The result of the call to the -conversion function, as described for the non-reference -copy-initialization, is then used to direct-initialize the reference. -For this direct-initialization, user-defined conversions are not considered. -\item -Otherwise, -the initializer expression is implicitly converted to a prvalue -of type ``\cvqual{cv1} \tcode{T1}''. -The temporary materialization conversion is applied and the reference is -bound to the result. -\end{itemize} - -If -\tcode{T1} -is reference-related to -\tcode{T2}: -\begin{itemize} -\item -\cvqual{cv1} -shall be the same cv-qualification as, or greater cv-qualification than, -\cvqual{cv2}; and -\item -if the reference is an rvalue reference, -the initializer expression shall not be an lvalue. -\end{itemize} - -\begin{example} -\begin{codeblock} -struct Banana { }; -struct Enigma { operator const Banana(); }; -struct Alaska { operator Banana&(); }; -void enigmatic() { - typedef const Banana ConstBanana; - Banana &&banana1 = ConstBanana(); // ill-formed - Banana &&banana2 = Enigma(); // ill-formed - Banana &&banana3 = Alaska(); // ill-formed -} - -const double& rcd2 = 2; // \tcode{rcd2} refers to temporary with value \tcode{2.0} -double&& rrd = 2; // \tcode{rrd} refers to temporary with value \tcode{2.0} -const volatile int cvi = 1; -const int& r2 = cvi; // error: cv-qualifier dropped -struct A { operator volatile int&(); } a; -const int& r3 = a; // error: cv-qualifier dropped - // from result of conversion function -double d2 = 1.0; -double&& rrd2 = d2; // error: initializer is lvalue of related type -struct X { operator int&(); }; -int&& rri2 = X(); // error: result of conversion function is lvalue of related type -int i3 = 2; -double&& rrd3 = i3; // \tcode{rrd3} refers to temporary with value \tcode{2.0} -\end{codeblock} -\end{example} -\end{itemize} - -In all cases except the last -(i.e., implicitly converting the initializer expression -to the underlying type of the reference), -the reference is said to \defn{bind directly} to the -initializer expression. - -\pnum -\begin{note} -\ref{class.temporary} describes the lifetime of temporaries bound to references. -\end{note} - -\rSec2[dcl.init.list]{List-initialization}% -\indextext{initialization!list-initialization|(} - -\pnum -\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 \grammarterm{initializer-list} -or -\grammarterm{designated-initializer-clause}{s} -of the \grammarterm{designated-initializer-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 -\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} -\item as the initializer in a variable definition\iref{dcl.init} -\item as the initializer in a \grammarterm{new-expression}\iref{expr.new} -\item in a \tcode{return} statement\iref{stmt.return} -\item as a \grammarterm{for-range-initializer}\iref{stmt.iter} -\item as a function argument\iref{expr.call} -\item as a subscript\iref{expr.sub} -\item as an argument to a constructor invocation~(\ref{dcl.init}, \ref{expr.type.conv}) -\item as an initializer for a non-static data member\iref{class.mem} -\item in a \grammarterm{mem-initializer}\iref{class.base.init} -\item on the right-hand side of an assignment\iref{expr.ass} -\end{itemize} - -\begin{example} -\begin{codeblock} -int a = {1}; -std::complex z{1,2}; -new std::vector{"once", "upon", "a", "time"}; // 4 string elements -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 \tcode{double} -std::map anim = { {"bear",4}, {"cassowary",2}, {"tiger",7} }; -\end{codeblock} -\end{example} \end{note} - -\pnum -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\iref{dcl.fct.default}. -\begin{note} Initializer-list constructors are favored over other constructors in -list-initialization\iref{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 -corresponding parameter to be a non-deduced context\iref{temp.deduct.call}. \end{note} -The template -\tcode{std::initializer_list} is not predefined; if the header -\tcode{} is not included prior to a use of -\tcode{std::initializer_list} --- even an implicit use in which the type is not -named\iref{dcl.spec.auto} --- the program is ill-formed. - -\pnum -List-initialization of an object or reference of type \tcode{T} is defined as follows: -\begin{itemize} -\item -If the \grammarterm{braced-init-list} -contains a \grammarterm{designated-initializer-list}, -\tcode{T} shall be an aggregate class. -The ordered \grammarterm{identifier}{s} -in the \grammarterm{designator}{s} -of the \grammarterm{designated-initializer-list} -shall form a subsequence -of the ordered \grammarterm{identifier}{s} -in the direct non-static data members of \tcode{T}. -Aggregate initialization is performed\iref{dcl.init.aggr}. -\begin{example} -\begin{codeblock} -struct A { int x; int y; int z; }; -A a{.y = 2, .x = 1}; // error: designator order does not match declaration order -A b{.x = 1, .z = 2}; // OK, \tcode{b.y} initialized to \tcode{0} -\end{codeblock} -\end{example} - -\item If \tcode{T} is an aggregate class and the initializer list has a single element -of type \cvqual{cv} \tcode{U}, -where \tcode{U} is \tcode{T} or a class derived from \tcode{T}, -the object is initialized from that element (by copy-initialization for -copy-list-initialization, or by direct-initialization for -direct-list-initialization). - -\item Otherwise, if \tcode{T} is a character array and the initializer list has a -single element that is an appropriately-typed string literal\iref{dcl.init.string}, -initialization is performed as described in that subclause. - -\item Otherwise, if \tcode{T} is an aggregate, aggregate initialization is -performed\iref{dcl.init.aggr}. - -\begin{example} -\begin{codeblock} -double ad[] = { 1, 2.0 }; // OK -int ai[] = { 1, 2.0 }; // error: narrowing - -struct S2 { - int m1; - double m2, m3; -}; -S2 s21 = { 1, 2, 3.0 }; // OK -S2 s22 { 1.0, 2, 3 }; // error: narrowing -S2 s23 { }; // OK: default to 0,0,0 -\end{codeblock} -\end{example} - -\item Otherwise, if the initializer list has no elements and \tcode{T} is a class type with a -default constructor, the object is value-initialized. - -\item Otherwise, if \tcode{T} is a specialization of \tcode{std::initializer_list}, -the object is constructed as described below. - -\item Otherwise, if \tcode{T} is a class type, constructors are considered. -The applicable constructors are enumerated and -the best one is chosen through overload resolution~(\ref{over.match}, \ref{over.match.list}). If a narrowing -conversion (see below) is required to convert any of the arguments, the program is -ill-formed. - -\begin{example} -\begin{codeblock} -struct S { - S(std::initializer_list); // \#1 - S(std::initializer_list); // \#2 - S(); // \#3 - // ... -}; -S s1 = { 1.0, 2.0, 3.0 }; // invoke \#1 -S s2 = { 1, 2, 3 }; // invoke \#2 -S s3 = { }; // invoke \#3 -\end{codeblock} -\end{example} - -\begin{example} -\begin{codeblock} -struct Map { - Map(std::initializer_list>); -}; -Map ship = {{"Sophie",14}, {"Surprise",28}}; -\end{codeblock} -\end{example} - -\begin{example} -\begin{codeblock} -struct S { - // no initializer-list constructors - S(int, double, double); // \#1 - S(); // \#2 - // ... -}; -S s1 = { 1, 2, 3.0 }; // OK: invoke \#1 -S s2 { 1.0, 2, 3 }; // error: narrowing -S s3 { }; // OK: invoke \#2 -\end{codeblock} -\end{example} - -\item Otherwise, if \tcode{T} is an enumeration -with a fixed underlying type\iref{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)}\iref{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 -reference-related to \tcode{E}, the object or reference is initialized -from that element (by copy-initialization for copy-list-initialization, -or by direct-initialization for direct-list-initialization); -if a narrowing conversion (see below) is required -to convert the element to \tcode{T}, the program is ill-formed. - -\begin{example} -\begin{codeblock} -int x1 {2}; // OK -int x2 {2.0}; // error: narrowing -\end{codeblock} -\end{example} - -\item Otherwise, if \tcode{T} is a reference type, a prvalue of the type -referenced by \tcode{T} is generated. -The prvalue initializes its result object by -copy-list-initialization or direct-list-initialization, -depending on the kind of initialization for the reference. -The prvalue is then used to direct-initialize the reference. -\begin{note} As usual, the binding will fail and the program is ill-formed if -the reference type is an lvalue reference to a non-const type. \end{note} - -\begin{example} -\begin{codeblock} -struct S { - S(std::initializer_list); // \#1 - S(const std::string&); // \#2 - // ... -}; -const S& r1 = { 1, 2, 3.0 }; // OK: invoke \#1 -const S& r2 { "Spinach" }; // OK: invoke \#2 -S& r3 = { 1, 2, 3 }; // error: initializer is not an lvalue -const int& i1 = { 1 }; // OK -const int& i2 = { 1.1 }; // error: narrowing -const int (&iar)[2] = { 1, 2 }; // OK: \tcode{iar} is bound to temporary array -\end{codeblock} -\end{example} - -\item Otherwise, if the initializer list has no elements, the object is -value-initialized. - -\begin{example} -\begin{codeblock} -int** pp {}; // initialized to null pointer -\end{codeblock} -\end{example} - -\item Otherwise, the program is ill-formed. - -\begin{example} -\begin{codeblock} -struct A { int i; int j; }; -A a1 { 1, 2 }; // aggregate initialization -A a2 { 1.2 }; // error: narrowing -struct B { - B(std::initializer_list); -}; -B b1 { 1, 2 }; // creates \tcode{initializer_list} and calls constructor -B b2 { 1, 2.0 }; // error: narrowing -struct C { - C(int i, double j); -}; -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 -int k { }; // initialize to 0 -\end{codeblock} -\end{example} - -\end{itemize} - -\pnum -Within the \grammarterm{initializer-list} of a \grammarterm{braced-init-list}, -the \grammarterm{initializer-clause}{s}, including any that result from pack -expansions\iref{temp.variadic}, are evaluated in the order in which they -appear. That is, every value computation and side effect associated with a -given \grammarterm{initializer-clause} is sequenced before every value -computation and side effect associated with any \grammarterm{initializer-clause} -that follows it in the comma-separated list of the \grammarterm{initializer-list}. -\begin{note} This evaluation ordering holds regardless of the semantics of the -initialization; for example, it applies when the elements of the -\grammarterm{initializer-list} are interpreted as arguments of a constructor -call, even though ordinarily there are no sequencing constraints on the -arguments of a call. \end{note} - -\pnum -An object of type \tcode{std::initializer_list} is constructed from -an initializer list as if -the implementation generated and materialized\iref{conv.rval} -a prvalue of type ``array of $N$ \tcode{const E}'', -where $N$ is the number of elements in the -initializer list. Each element of that array is copy-initialized with the -corresponding element of the initializer list, and the -\tcode{std::initializer_list} object is constructed to refer to that array. -\begin{note} A constructor or conversion function selected for the copy shall be -accessible\iref{class.access} in the context of the initializer list. -\end{note} -If a narrowing conversion is required to initialize any of the elements, the program is ill-formed. \begin{example} -\begin{codeblock} -struct X { - X(std::initializer_list v); -}; -X x{ 1,2,3 }; -\end{codeblock} - -The initialization will be implemented in a way roughly equivalent to this: - -\begin{codeblock} -const double __a[3] = {double{1}, double{2}, double{3}}; -X x(std::initializer_list(__a, __a+3)); -\end{codeblock} - -assuming that the implementation can construct an \tcode{initializer_list} object with a pair of pointers. \end{example} - -\pnum -The array has the same lifetime as any other temporary -object\iref{class.temporary}, except that initializing an -\tcode{initializer_list} object from the array extends the lifetime of -the array exactly like binding a reference to a temporary. -\begin{example} - -\begin{codeblock} -typedef std::complex cmplx; -std::vector v1 = { 1, 2, 3 }; - -void f() { - std::vector v2{ 1, 2, 3 }; - std::initializer_list i3 = { 1, 2, 3 }; -} - -struct A { - std::initializer_list i4; - A() : i4{ 1, 2, 3 } {} // ill-formed, would create a dangling reference -}; -\end{codeblock} - -For \tcode{v1} and \tcode{v2}, the \tcode{initializer_list} object -is a parameter in a function call, so the array created for -\tcode{\{ 1, 2, 3 \}} has full-expression lifetime. -For \tcode{i3}, the \tcode{initializer_list} object is a variable, -so the array persists for the lifetime of the variable. -For \tcode{i4}, the \tcode{initializer_list} object is initialized in -the constructor's \grammarterm{ctor-initializer} as if by binding -a temporary array to a reference member, so the program is -ill-formed\iref{class.base.init}. -\end{example} -\begin{note} -The implementation is free to allocate the array in read-only memory if an explicit array with the same initializer could be so allocated. \end{note} - -\pnum -A -\indextext{narrowing conversion}% -\indextext{conversion!narrowing}% -\term{narrowing conversion} is an implicit conversion - -\begin{itemize} -\item from a floating-point type to an integer type, or - -\item from \tcode{long double} to \tcode{double} or \tcode{float}, or from -\tcode{double} to \tcode{float}, except where the source is a constant expression and -the actual value after conversion -is within the range of values that can be represented (even if it cannot be represented exactly), -or - -\item from an integer type or unscoped enumeration type to a floating-point type, except -where the source is a constant expression and the actual value after conversion will fit -into the target type and will produce the original value when converted back to the -original type, or - -\item from an integer type or unscoped enumeration type to an integer type that cannot -represent all the values of the original type, except where the source is a constant -expression whose value after integral promotions will fit into the target type. -\end{itemize} - -\begin{note} As indicated above, such conversions are not allowed at the top level in -list-initializations.\end{note} \begin{example} - -\begin{codeblock} -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) -char c2{x}; // error: might narrow -char c3{y}; // error: narrows (assuming \tcode{char} is 8 bits) -char c4{z}; // OK: no narrowing needed -unsigned char uc1 = {5}; // OK: no narrowing needed -unsigned char uc2 = {-1}; // error: narrows -unsigned int ui1 = {-1}; // error: narrows -signed int si1 = - { (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 \tcode{float} -int f(int); -int a[] = { 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|)}% -\indextext{initialization|)}% -\indextext{declarator|)} diff --git a/source/derived.tex b/source/derived.tex deleted file mode 100644 index bd073cf63a..0000000000 --- a/source/derived.tex +++ /dev/null @@ -1,1023 +0,0 @@ -%!TEX root = std.tex -\rSec0[class.derived]{Derived classes}% -\indextext{derived class|(} - -\gramSec[gram.derived]{Derived classes} - -\indextext{virtual base class|see{base class, virtual}} -\indextext{virtual function|see{function, virtual}} -\indextext{dynamic binding|see{function, virtual}} - -\pnum -\indextext{base class}% -\indextext{inheritance}% -\indextext{multiple inheritance}% -A list of base classes can be specified in a class definition using -the notation: - -\begin{bnf} -\nontermdef{base-clause}\br - \terminal{:} base-specifier-list -\end{bnf} - - -\begin{bnf} -\nontermdef{base-specifier-list}\br - base-specifier \opt{\terminal{...}}\br - base-specifier-list \terminal{,} base-specifier \opt{\terminal{...}} -\end{bnf} - -\begin{bnf} -\nontermdef{base-specifier}\br - \opt{attribute-specifier-seq} class-or-decltype\br - \opt{attribute-specifier-seq} \terminal{virtual} \opt{access-specifier} class-or-decltype\br - \opt{attribute-specifier-seq} access-specifier \opt{\terminal{virtual}} class-or-decltype -\end{bnf} - -\begin{bnf} -\nontermdef{class-or-decltype}\br - \opt{nested-name-specifier} class-name\br - nested-name-specifier \terminal{template} simple-template-id\br - decltype-specifier -\end{bnf} - -\indextext{specifier access|see{access specifier}}% -% -\begin{bnf} -\nontermdef{access-specifier}\br - \terminal{private}\br - \terminal{protected}\br - \terminal{public} -\end{bnf} - -The optional \grammarterm{attribute-specifier-seq} appertains to the \grammarterm{base-specifier}. - -\pnum -\indextext{type!incomplete}% -A \grammarterm{class-or-decltype} shall denote -a class type that is not -an incompletely defined class\iref{class}. -The class denoted by the \grammarterm{class-or-decltype} of -a \grammarterm{base-specifier} is called a -\defnx{direct base class}{base class!direct} -for the class being defined. -\indextext{base class}% -\indextext{derivation|see{inheritance}}% -During the lookup for a base class name, non-type names are -ignored\iref{basic.scope.hiding}. If the name found is not a -\grammarterm{class-name}, the program is ill-formed. A class \tcode{B} is a -base class of a class \tcode{D} if it is a direct base class of -\tcode{D} or a direct base class of one of \tcode{D}'s base classes. -A class is an \defnx{indirect}{base class!indirect} base class of another if it is a base -class but not a direct base class. A class is said to be (directly or -indirectly) \term{derived} from its (direct or indirect) base -classes. -\begin{note} -See \ref{class.access} for the meaning of -\grammarterm{access-specifier}. -\end{note} -\indextext{access control!base class member}% -Unless redeclared in the derived class, members of a base class are also -considered to be members of the derived class. -Members of a base class other than constructors are said to be -\defnx{inherited}{inheritance} -by the derived class. Constructors of a base class -can also be inherited as described in~\ref{namespace.udecl}. -Inherited members can be referred to in -expressions in the same manner as other members of the derived class, -unless their names are hidden or ambiguous\iref{class.member.lookup}. -\indextext{operator!scope resolution}% -\begin{note} -The scope resolution operator \tcode{::}\iref{expr.prim.id.qual} can be used -to refer to a direct or indirect base member explicitly. This allows -access to a name that has been redeclared in the derived class. A -derived class can itself serve as a base class subject to access -control; see~\ref{class.access.base}. A pointer to a derived class can be -implicitly converted to a pointer to an accessible unambiguous base -class\iref{conv.ptr}. An lvalue of a derived class type can be bound -to a reference to an accessible unambiguous base -class\iref{dcl.init.ref}. -\end{note} - -\pnum -The \grammarterm{base-specifier-list} specifies the type of the -\term{base class subobjects} contained in an -object of the derived class type. -\begin{example} -\begin{codeblock} -struct Base { - int a, b, c; -}; -\end{codeblock} - -\begin{codeblock} -struct Derived : Base { - int b; -}; -\end{codeblock} - -\begin{codeblock} -struct Derived2 : Derived { - int c; -}; -\end{codeblock} - -Here, an object of class \tcode{Derived2} will have a subobject of class -\tcode{Derived} which in turn will have a subobject of class -\tcode{Base}. -\end{example} - -\pnum -A \grammarterm{base-specifier} followed by an ellipsis is a pack -expansion\iref{temp.variadic}. - -\pnum -The order in which the base class subobjects are allocated in the most -derived object\iref{intro.object} is unspecified. -\begin{note} -\indextext{directed acyclic graph|see{DAG}}% -\indextext{lattice|see{DAG, subobject}}% -A derived class and its base class subobjects can be represented by a -directed acyclic graph (DAG) where an arrow means ``directly derived -from''. An arrow need not have a physical representation in memory. -A DAG of subobjects is often referred to as a ``subobject lattice''. - -\begin{importgraphic} -{Directed acyclic graph} -{fig:dag} -{figdag.pdf} -\end{importgraphic} -\end{note} - -\pnum -\begin{note} -Initialization of objects representing base classes can be specified in -constructors; see~\ref{class.base.init}. -\end{note} - -\pnum -\begin{note} -A base class subobject might have a layout\iref{basic.stc} different -from the layout of a most derived object of the same type. A base class -subobject might have a polymorphic behavior\iref{class.cdtor} -different from the polymorphic behavior of a most derived object of the -same type. A base class subobject may be of zero size\iref{class}; -however, two subobjects that have the same class type and that belong to -the same most derived object must not be allocated at the same -address\iref{expr.eq}. -\end{note} - -\rSec1[class.mi]{Multiple base classes} -\indextext{multiple inheritance}% -\indextext{base class}% - -\pnum -A class can be derived from any number of base classes. -\begin{note} -The use of more than one direct base class is often called multiple inheritance. -\end{note} -\begin{example} -\begin{codeblock} -class A { @\commentellip@ }; -class B { @\commentellip@ }; -class C { @\commentellip@ }; -class D : public A, public B, public C { @\commentellip@ }; -\end{codeblock} -\end{example} - -\pnum -\indextext{layout!class object}% -\indextext{initialization!order of}% -\begin{note} -The order of derivation is not significant except as specified by the -semantics of initialization by constructor\iref{class.base.init}, -cleanup\iref{class.dtor}, and storage -layout~(\ref{class.mem}, \ref{class.access.spec}). -\end{note} - -\pnum -A class shall not be specified as a direct base class of a derived class -more than once. -\begin{note} -A class can be an indirect base class more than once and can be a direct -and an indirect base class. There are limited things that can be done -with such a class. The non-static data members and member functions of -the direct base class cannot be referred to in the scope of the derived -class. However, the static members, enumerations and types can be -unambiguously referred to. -\end{note} -\begin{example} -\begin{codeblock} -class X { @\commentellip@ }; -class Y : public X, public X { @\commentellip@ }; // ill-formed - -\end{codeblock} -\begin{codeblock} -class L { public: int next; @\commentellip@ }; -class A : public L { @\commentellip@ }; -class B : public L { @\commentellip@ }; -class C : public A, public B { void f(); @\commentellip@ }; // well-formed -class D : public A, public L { void f(); @\commentellip@ }; // well-formed -\end{codeblock} -\end{example} - -\pnum -\indextext{base class!virtual}% -A base class specifier that does not contain the keyword -\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\iref{intro.object} shall contain a -corresponding distinct base class subobject of that type. For each -distinct base class that is specified virtual, the most derived object -shall contain a single base class subobject of that type. - -\pnum -\begin{note} -For an object of class type \tcode{C}, each distinct occurrence of a -(non-virtual) base class \tcode{L} in the class lattice of \tcode{C} -corresponds one-to-one with a distinct \tcode{L} subobject within the -object of type \tcode{C}. Given the class \tcode{C} defined above, an -object of class \tcode{C} will have two subobjects of class \tcode{L} as -shown in Figure~\ref{fig:nonvirt}. - -\begin{importgraphic} -{Non-virtual base} -{fig:nonvirt} -{fignonvirt.pdf} -\end{importgraphic} - -In such lattices, explicit qualification can be used to specify which -subobject is meant. The body of function \tcode{C::f} could refer to the -member \tcode{next} of each \tcode{L} subobject: -\begin{codeblock} -void C::f() { A::next = B::next; } // well-formed -\end{codeblock} -Without the \tcode{A::} or \tcode{B::} qualifiers, the definition of -\tcode{C::f} above would be ill-formed because of -ambiguity\iref{class.member.lookup}. -\end{note} - -\pnum -\begin{note} -In contrast, consider the case with a virtual base class: -\begin{codeblock} -class V { @\commentellip@ }; -class A : virtual public V { @\commentellip@ }; -class B : virtual public V { @\commentellip@ }; -class C : public A, public B { @\commentellip@ }; -\end{codeblock} -\begin{importgraphic} -{Virtual base} -{fig:virt} -{figvirt.pdf} -\end{importgraphic} -For an object \tcode{c} of class type \tcode{C}, a single subobject of -type \tcode{V} is shared by every base class subobject of \tcode{c} that has a -\tcode{virtual} base class of type \tcode{V}. Given the class \tcode{C} -defined above, an object of class \tcode{C} will have one subobject of -class \tcode{V}, as shown in Figure~\ref{fig:virt}. -\indextext{DAG!multiple inheritance}% -\indextext{DAG!virtual base class}% -\end{note} - -\pnum -\begin{note} -A class can have both virtual and non-virtual base classes of a given -type. -\begin{codeblock} -class B { @\commentellip@ }; -class X : virtual public B { @\commentellip@ }; -class Y : virtual public B { @\commentellip@ }; -class Z : public B { @\commentellip@ }; -class AA : public X, public Y, public Z { @\commentellip@ }; -\end{codeblock} -For an object of class \tcode{AA}, all \tcode{virtual} occurrences of -base class \tcode{B} in the class lattice of \tcode{AA} correspond to a -single \tcode{B} subobject within the object of type \tcode{AA}, and -every other occurrence of a (non-virtual) base class \tcode{B} in the -class lattice of \tcode{AA} corresponds one-to-one with a distinct -\tcode{B} subobject within the object of type \tcode{AA}. Given the -class \tcode{AA} defined above, class \tcode{AA} has two subobjects of -class \tcode{B}: \tcode{Z}'s \tcode{B} and the virtual \tcode{B} shared -by \tcode{X} and \tcode{Y}, as shown in Figure~\ref{fig:virtnonvirt}. - -\indextext{DAG!virtual base class}% -\indextext{DAG!non-virtual base class}% -\indextext{DAG!multiple inheritance}% -\begin{importgraphic} -{Virtual and non-virtual base} -{fig:virtnonvirt} -{figvirtnonvirt.pdf} -\end{importgraphic} -\end{note} - -\rSec1[class.member.lookup]{Member name lookup}% -\indextext{lookup!member name}% -\indextext{ambiguity!base class member}% -\indextext{ambiguity!member access} - -\pnum -Member name lookup determines the meaning of a name -(\grammarterm{id-expression}) in a class scope\iref{basic.scope.class}. -Name lookup can result in an \term{ambiguity}, in which case the -program is ill-formed. For an \grammarterm{id-expression}, name lookup -begins in the class scope of \tcode{this}; for a -\grammarterm{qualified-id}, name lookup begins in the scope of the -\grammarterm{nested-name-specifier}. Name lookup takes place before access -control~(\ref{basic.lookup}, \ref{class.access}). - -\pnum -The following steps define the result of name lookup for a member name -\tcode{f} in a class scope \tcode{C}. - -\pnum -The \term{lookup set} for \tcode{f} in \tcode{C}, called $S(f,C)$, -consists of two component sets: the \term{declaration set}, a set of -members named \tcode{f}; and the \term{subobject set}, a set of -subobjects where declarations of these members (possibly including -\grammarterm{using-declaration}{s}) were found. In the declaration set, -\grammarterm{using-declaration}{s} are replaced by the -set of designated members that are not hidden or overridden by members of the -derived class\iref{namespace.udecl}, -and type declarations (including injected-class-names) are -replaced by the types they designate. $S(f,C)$ is calculated as follows: - -\pnum -If \tcode{C} contains a declaration of the name \tcode{f}, the -declaration set contains every declaration of \tcode{f} declared in -\tcode{C} that satisfies the requirements of the language construct in -which the lookup occurs. -\begin{note} -Looking up a name in an -\grammarterm{elaborated-type-specifier}\iref{basic.lookup.elab} or -\grammarterm{base-specifier}\iref{class.derived}, for instance, -ignores all non-type declarations, while looking up a name in a -\grammarterm{nested-name-specifier}\iref{basic.lookup.qual} ignores -function, variable, and enumerator declarations. As another example, -looking up a name in a -\grammarterm{using-declaration}\iref{namespace.udecl} includes the -declaration of a class or enumeration that would ordinarily be hidden by -another declaration of that name in the same scope. -\end{note} -If the resulting declaration set is not empty, the subobject set -contains \tcode{C} itself, and calculation is complete. - -\pnum -Otherwise (i.e., \tcode{C} does not contain a declaration of \tcode{f} -or the resulting declaration set is empty), $S(f,C)$ is initially empty. -If \tcode{C} has base classes, calculate the lookup set for \tcode{f} in -each direct base class subobject $B_i$, and merge each such lookup set -$S(f,B_i)$ in turn into $S(f,C)$. - -\pnum -The following steps define the result of merging lookup set $S(f,B_i)$ -into the intermediate $S(f,C)$: - -\begin{itemize} -\item If each of the subobject members of $S(f,B_i)$ is a base class -subobject of at least one of the subobject members of $S(f,C)$, or if -$S(f,B_i)$ is empty, $S(f,C)$ is unchanged and the merge is complete. -Conversely, if each of the subobject members of $S(f,C)$ is a base class -subobject of at least one of the subobject members of $S(f,B_i)$, or if -$S(f,C)$ is empty, the new $S(f,C)$ is a copy of $S(f,B_i)$. - -\item Otherwise, if the declaration sets of $S(f,B_i)$ and $S(f,C)$ -differ, the merge is ambiguous: the new $S(f,C)$ is a lookup set with an -invalid declaration set and the union of the subobject sets. In -subsequent merges, an invalid declaration set is considered different -from any other. - -\item Otherwise, the new $S(f,C)$ is a lookup set with the shared set of -declarations and the union of the subobject sets. -\end{itemize} - -\pnum -The result of name lookup for \tcode{f} in \tcode{C} is the declaration -set of $S(f,C)$. If it is an invalid set, the program is ill-formed. -\begin{example} -\begin{codeblock} -struct A { int x; }; // S(x,A) = \{ \{ \tcode{A::x} \}, \{ \tcode{A} \} \} -struct B { float x; }; // S(x,B) = \{ \{ \tcode{B::x} \}, \{ \tcode{B} \} \} -struct C: public A, public B { }; // S(x,C) = \{ invalid, \{ \tcode{A} in \tcode{C}, \tcode{B} in \tcode{C} \} \} -struct D: public virtual C { }; // S(x,D) = S(x,C) -struct E: public virtual C { char x; }; // S(x,E) = \{ \{ \tcode{E::x} \}, \{ \tcode{E} \} \} -struct F: public D, public E { }; // S(x,F) = S(x,E) -int main() { - F f; - f.x = 0; // OK, lookup finds \tcode{E::x} -} -\end{codeblock} - -$S(x,F)$ is unambiguous because the \tcode{A} and \tcode{B} base -class subobjects of \tcode{D} are also base class subobjects of \tcode{E}, so -$S(x,D)$ is discarded in the first merge step. -\end{example} - -\pnum -\indextext{access control!overload resolution and}% -If the name of an overloaded function is unambiguously found, -overload resolution\iref{over.match} also takes place before access -control. -\indextext{overloading!resolution!scoping ambiguity}% -Ambiguities can often be resolved by qualifying a name with its class name. -\begin{example} -\begin{codeblock} -struct A { - int f(); -}; - -\end{codeblock} -\begin{codeblock} -struct B { - int f(); -}; - -\end{codeblock} -\begin{codeblock} -struct C : A, B { - int f() { return A::f() + B::f(); } -}; -\end{codeblock} -\end{example} - -\pnum -\begin{note} -A static member, a nested type or an enumerator defined in a base class -\tcode{T} can unambiguously be found even if an object has more than one -base class subobject of type \tcode{T}. Two base class subobjects share -the non-static member subobjects of their common virtual base classes. -\end{note} -\begin{example} -\begin{codeblock} -struct V { - int v; -}; -struct A { - int a; - static int s; - enum { e }; -}; -struct B : A, virtual V { }; -struct C : A, virtual V { }; -struct D : B, C { }; - -void f(D* pd) { - pd->v++; // OK: only one \tcode{v} (virtual) - pd->s++; // OK: only one \tcode{s} (static) - int i = pd->e; // OK: only one \tcode{e} (enumerator) - pd->a++; // error, ambiguous: two \tcode{a}{s} in \tcode{D} -} -\end{codeblock} -\end{example} - -\pnum -\begin{note} -\indextext{dominance!virtual base class}% -When virtual base classes are used, a hidden declaration can be reached -along a path through the subobject lattice that does not pass through -the hiding declaration. This is not an ambiguity. The identical use with -non-virtual base classes is an ambiguity; in that case there is no -unique instance of the name that hides all the others. -\end{note} -\begin{example} -\begin{codeblock} -struct V { int f(); int x; }; -struct W { int g(); int y; }; -struct B : virtual V, W { - int f(); int x; - int g(); int y; -}; -struct C : virtual V, W { }; - -struct D : B, C { void glorp(); }; -\end{codeblock} - -\begin{importgraphic} -{Name lookup} -{fig:name} -{figname.pdf} -\end{importgraphic} - -The names declared in \tcode{V} and the left-hand instance of \tcode{W} -are hidden by those in \tcode{B}, but the names declared in the -right-hand instance of \tcode{W} are not hidden at all. -\begin{codeblock} -void D::glorp() { - x++; // OK: \tcode{B::x} hides \tcode{V::x} - f(); // OK: \tcode{B::f()} hides \tcode{V::f()} - y++; // error: \tcode{B::y} and \tcode{C}'s \tcode{W::y} - g(); // error: \tcode{B::g()} and \tcode{C}'s \tcode{W::g()} -} -\end{codeblock} -\end{example} -\indextext{ambiguity!class conversion}% - -\pnum -An explicit or implicit conversion from a pointer to or -an expression designating an object -of a -derived class to a pointer or reference to one of its base classes shall -unambiguously refer to a unique object representing the base class. -\begin{example} -\begin{codeblock} -struct V { }; -struct A { }; -struct B : A, virtual V { }; -struct C : A, virtual V { }; -struct D : B, C { }; - -void g() { - D d; - B* pb = &d; - A* pa = &d; // error, ambiguous: \tcode{C}'s \tcode{A} or \tcode{B}'s \tcode{A}? - V* pv = &d; // OK: only one \tcode{V} subobject -} -\end{codeblock} -\end{example} - -\pnum -\begin{note} -Even if the result of name lookup is unambiguous, use of a name found in -multiple subobjects might still be -ambiguous~(\ref{conv.mem}, \ref{expr.ref}, \ref{class.access.base}).\end{note} -\begin{example} -\begin{codeblock} -struct B1 { - void f(); - static void f(int); - int i; -}; -struct B2 { - void f(double); -}; -struct I1: B1 { }; -struct I2: B1 { }; - -struct D: I1, I2, B2 { - using B1::f; - using B2::f; - void g() { - f(); // Ambiguous conversion of \tcode{this} - f(0); // Unambiguous (static) - f(0.0); // Unambiguous (only one \tcode{B2}) - int B1::* mpB1 = &D::i; // Unambiguous - int D::* mpD = &D::i; // Ambiguous conversion - } -}; -\end{codeblock}\end{example} - -\rSec1[class.virtual]{Virtual functions}% -\indextext{function!virtual|(}% -\indextext{type!polymorphic}% - -\pnum -\begin{note} -Virtual functions support dynamic binding and object-oriented -programming. \end{note} A class that declares or inherits a virtual function is -called a \defnx{polymorphic class}{class!polymorphic}. - -\pnum -If a virtual member function \tcode{vf} is declared in a class -\tcode{Base} and in a class \tcode{Derived}, derived directly or -indirectly from \tcode{Base}, a member function \tcode{vf} with the same -name, parameter-type-list\iref{dcl.fct}, cv-qualification, and ref-qualifier -(or absence of same) as -\tcode{Base::vf} is declared, then \tcode{Derived::vf} is also virtual -(whether or not it is so declared) and it \term{overrides}\footnote{A function with the same name but a different parameter list\iref{over} -as a virtual function is not necessarily virtual and -does not override. The use of the \tcode{virtual} specifier in the -declaration of an overriding function is legal but redundant (has empty -semantics). Access control\iref{class.access} is not considered in -determining overriding.} -\tcode{Base::vf}. For convenience we say that any virtual function -overrides itself. -\indextext{overrider!final}% -A virtual member function \tcode{C::vf} of a class object \tcode{S} is a \defn{final -overrider} unless the most derived class\iref{intro.object} of which \tcode{S} is a -base class subobject (if any) declares or inherits another member function that overrides -\tcode{vf}. In a derived class, if a virtual member function of a base class subobject -has more than one final overrider the program is ill-formed. -\begin{example} -\begin{codeblock} -struct A { - virtual void f(); -}; -struct B : virtual A { - virtual void f(); -}; -struct C : B , virtual A { - using A::f; -}; - -void foo() { - C c; - c.f(); // calls \tcode{B::f}, the final overrider - c.C::f(); // calls \tcode{A::f} because of the using-declaration -} -\end{codeblock} -\end{example} - -\begin{example} -\begin{codeblock} -struct A { virtual void f(); }; -struct B : A { }; -struct C : A { void f(); }; -struct D : B, C { }; // OK: \tcode{A::f} and \tcode{C::f} are the final overriders - // for the \tcode{B} and \tcode{C} subobjects, respectively -\end{codeblock} -\end{example} - -\pnum -\begin{note} -A virtual member function does not have to be visible to be overridden, -for example, -\begin{codeblock} -struct B { - virtual void f(); -}; -struct D : B { - void f(int); -}; -struct D2 : D { - void f(); -}; -\end{codeblock} -the function \tcode{f(int)} in class \tcode{D} hides the virtual -function \tcode{f()} in its base class \tcode{B}; \tcode{D::f(int)} is -not a virtual function. However, \tcode{f()} declared in class -\tcode{D2} has the same name and the same parameter list as -\tcode{B::f()}, and therefore is a virtual function that overrides the -function \tcode{B::f()} even though \tcode{B::f()} is not visible in -class \tcode{D2}. -\end{note} - -\pnum -If a virtual function \tcode{f} in some class \tcode{B} is marked with the -\grammarterm{virt-specifier} \tcode{final} and in a class \tcode{D} derived from \tcode{B} -a function \tcode{D::f} overrides \tcode{B::f}, the program is ill-formed. \begin{example} -\begin{codeblock} -struct B { - virtual void f() const final; -}; - -struct D : B { - void f() const; // error: \tcode{D::f} attempts to override \tcode{final} \tcode{B::f} -}; -\end{codeblock} -\end{example} - -\pnum -If a virtual function is marked with the \grammarterm{virt-specifier} \tcode{override} and -does not override a member function of a base class, the program is ill-formed. \begin{example} -\begin{codeblock} -struct B { - virtual void f(int); -}; - -struct D : B { - virtual void f(long) override; // error: wrong signature overriding \tcode{B::f} - virtual void f(int) override; // OK -}; -\end{codeblock} -\end{example} - -\pnum -A virtual function shall not have a trailing \grammarterm{requires-clause}\iref{dcl.decl}. -\begin{example} -\begin{codeblock} -struct A { - virtual void f() requires true; // error: virtual function cannot be constrained\iref{temp.constr.decl} -}; -\end{codeblock} -\end{example} - -\pnum -Even though destructors are not inherited, a destructor in a derived -class overrides a base class destructor declared virtual; -see~\ref{class.dtor} and~\ref{class.free}. - -\pnum -The return type of an overriding function shall be either identical to -the return type of the overridden function or \defnx{covariant}{return type!covariant} with -the classes of the functions. If a function \tcode{D::f} overrides a -function \tcode{B::f}, the return types of the functions are covariant -if they satisfy the following criteria: -\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.% -} - -\item the class in the return type of \tcode{B::f} is the same class as -the class in the return type of \tcode{D::f}, or is an unambiguous and -accessible direct or indirect base class of the class in the return type -of \tcode{D::f} - -\item both pointers or references have the same cv-qualification and the -class type in the return type of \tcode{D::f} has the same -cv-qualification as or less cv-qualification than the class type in the -return type of \tcode{B::f}. -\end{itemize} - -\pnum -If the class type in the covariant return type of \tcode{D::f} differs from that of -\tcode{B::f}, the class type in the return type of \tcode{D::f} shall be -complete at the point of declaration of \tcode{D::f} or shall be the -class type \tcode{D}. When the overriding function is called as the -final overrider of the overridden function, its result is converted to -the type returned by the (statically chosen) overridden -function\iref{expr.call}. -\begin{example} -\begin{codeblock} -class B { }; -class D : private B { friend class Derived; }; -struct Base { - virtual void vf1(); - virtual void vf2(); - virtual void vf3(); - virtual B* vf4(); - virtual B* vf5(); - void f(); -}; - -struct No_good : public Base { - D* vf4(); // error: \tcode{B} (base class of \tcode{D}) inaccessible -}; - -class A; -struct Derived : public Base { - void vf1(); // virtual and overrides \tcode{Base::vf1()} - void vf2(int); // not virtual, hides \tcode{Base::vf2()} - char vf3(); // error: invalid difference in return type only - D* vf4(); // OK: returns pointer to derived class - A* vf5(); // error: returns pointer to incomplete class - void f(); -}; - -void g() { - Derived d; - Base* bp = &d; // standard conversion: - // \tcode{Derived*} to \tcode{Base*} - bp->vf1(); // calls \tcode{Derived::vf1()} - bp->vf2(); // calls \tcode{Base::vf2()} - bp->f(); // calls \tcode{Base::f()} (not virtual) - B* p = bp->vf4(); // calls \tcode{Derived::vf4()} and converts the - // result to \tcode{B*} - Derived* dp = &d; - D* q = dp->vf4(); // calls \tcode{Derived::vf4()} and does not - // convert the result to \tcode{B*} - dp->vf2(); // ill-formed: argument mismatch -} -\end{codeblock} -\end{example} - -\pnum -\begin{note} -The interpretation of the call of a virtual function depends on the type -of the object for which it is called (the dynamic type), whereas the -interpretation of a call of a non-virtual member function depends only -on the type of the pointer or reference denoting that object (the static -type)\iref{expr.call}. -\end{note} - -\pnum -\begin{note} -The \tcode{virtual} specifier implies membership, so a virtual function -cannot be a non-member\iref{dcl.fct.spec} function. Nor can a virtual -function be a static member, since a virtual function call relies on a -specific object for determining which function to invoke. A virtual -function declared in one class can be declared a friend~(\ref{class.friend}) in -another class. -\end{note} - -\pnum -\indextext{definition!virtual function}% -A virtual function declared in a class shall be defined, or declared -pure\iref{class.abstract} in that class, or both; no diagnostic is -required\iref{basic.def.odr}. -\indextext{friend!\tcode{virtual} and}% - -\pnum -\indextext{multiple inheritance!\tcode{virtual} and}% -\begin{example} -Here are some uses of virtual functions with multiple base classes: -\begin{codeblock} -struct A { - virtual void f(); -}; - -struct B1 : A { // note non-virtual derivation - void f(); -}; - -struct B2 : A { - void f(); -}; - -struct D : B1, B2 { // \tcode{D} has two separate \tcode{A} subobjects -}; - -void foo() { - D d; -//\tcode{ A* ap = \&d;} // would be ill-formed: ambiguous - B1* b1p = &d; - A* ap = b1p; - D* dp = &d; - ap->f(); // calls \tcode{D::B1::f} - dp->f(); // ill-formed: ambiguous -} -\end{codeblock} -In class \tcode{D} above there are two occurrences of class \tcode{A} -and hence two occurrences of the virtual member function \tcode{A::f}. -The final overrider of \tcode{B1::A::f} is \tcode{B1::f} and the final -overrider of \tcode{B2::A::f} is \tcode{B2::f}. -\end{example} - -\pnum -\begin{example} -The following example shows a function that does not have a unique final -overrider: -\begin{codeblock} -struct A { - virtual void f(); -}; - -struct VB1 : virtual A { // note virtual derivation - void f(); -}; - -struct VB2 : virtual A { - void f(); -}; - -struct Error : VB1, VB2 { // ill-formed -}; - -struct Okay : VB1, VB2 { - void f(); -}; -\end{codeblock} -Both \tcode{VB1::f} and \tcode{VB2::f} override \tcode{A::f} but there -is no overrider of both of them in class \tcode{Error}. This example is -therefore ill-formed. Class \tcode{Okay} is well-formed, however, -because \tcode{Okay::f} is a final overrider. -\end{example} - -\pnum -\begin{example} -The following example uses the well-formed classes from above. -\begin{codeblock} -struct VB1a : virtual A { // does not declare \tcode{f} -}; - -struct Da : VB1a, VB2 { -}; - -void foe() { - VB1a* vb1ap = new Da; - vb1ap->f(); // calls \tcode{VB2::f} -} -\end{codeblock} -\end{example} - -\pnum -\indextext{operator!scope resolution}% -\indextext{virtual function call}% -Explicit qualification with the scope operator\iref{expr.prim.id.qual} -suppresses the virtual call mechanism. -\begin{example} -\begin{codeblock} -class B { public: virtual void f(); }; -class D : public B { public: void f(); }; - -void D::f() { @\commentellip@ B::f(); } -\end{codeblock} - -Here, the function call in -\tcode{D::f} -really does call -\tcode{B::f} -and not -\tcode{D::f}. -\end{example} - -\pnum -A function with a deleted definition\iref{dcl.fct.def} shall -not override a function that does not have a deleted definition. Likewise, -a function that does not have a deleted definition shall not override a -function with a deleted definition.% -\indextext{function!virtual|)} - -\rSec1[class.abstract]{Abstract classes}% - -\pnum -\begin{note} -The abstract class mechanism supports the notion of a general concept, -such as a \tcode{shape}, of which only more concrete variants, such as -\tcode{circle} and \tcode{square}, can actually be used. An abstract -class can also be used to define an interface for which derived classes -provide a variety of implementations. -\end{note} - -\pnum -An \defnx{abstract class}{class!abstract} is a class that can be used only -as a base class of some other class; no objects of an abstract class can -be created except as subobjects of a class derived from it. A class is -abstract if it has at least one \term{pure virtual function}. -\begin{note} -Such a function might be inherited: see below. -\end{note} -A virtual function is specified \defnx{pure}{function!virtual!pure} by using a -\grammarterm{pure-specifier}\iref{class.mem} in the function declaration -in the class definition. -\indextext{definition!pure virtual function}% -A pure virtual function need be defined only if called with, or as if -with\iref{class.dtor}, the \grammarterm{qualified-id} -syntax\iref{expr.prim.id.qual}. -\begin{example} -\begin{codeblock} -class point { @\commentellip@ }; -class shape { // abstract class - point center; -public: - point where() { return center; } - void move(point p) { center=p; draw(); } - virtual void rotate(int) = 0; // pure virtual - virtual void draw() = 0; // pure virtual -}; -\end{codeblock} -\end{example} -\begin{note} -A function declaration cannot provide both a \grammarterm{pure-specifier} -and a definition -\end{note} -\begin{example} -\begin{codeblock} -struct C { - virtual void f() = 0 { }; // ill-formed -}; -\end{codeblock} -\end{example} - -\pnum -\indextext{class!pointer to abstract}% -An abstract class shall not be used as a parameter type, as a function -return type, or as the type of an explicit conversion. Pointers and -references to an abstract class can be declared. -\begin{example} -\begin{codeblock} -shape x; // error: object of abstract class -shape* p; // OK -shape f(); // error -void g(shape); // error -shape& h(shape&); // OK -\end{codeblock} -\end{example} - -\pnum -\indextext{function!virtual!pure}% -A class is abstract if it contains or inherits at least one pure virtual -function for which the final overrider is pure virtual. -\begin{example} -\begin{codeblock} -class ab_circle : public shape { - int radius; -public: - void rotate(int) { } - // \tcode{ab_circle::draw()} is a pure virtual -}; -\end{codeblock} - -Since \tcode{shape::draw()} is a pure virtual function -\tcode{ab_circle::draw()} is a pure virtual by default. The alternative -declaration, -\begin{codeblock} -class circle : public shape { - int radius; -public: - void rotate(int) { } - void draw(); // a definition is required somewhere -}; -\end{codeblock} -would make class \tcode{circle} non-abstract and a definition of -\tcode{circle::draw()} must be provided. -\end{example} - -\pnum -\begin{note} -An abstract class can be derived from a class that is not abstract, and -a pure virtual function may override a virtual function which is not -pure. -\end{note} - -\pnum -\indextext{class!constructor and abstract}% -Member functions can be called from a constructor (or destructor) of an -abstract class; -\indextext{virtual function call!undefined pure}% -the effect of making a virtual call\iref{class.virtual} to a pure -virtual function directly or indirectly for the object being created (or -destroyed) from such a constructor (or destructor) is undefined.% -\indextext{derived class|)} diff --git a/source/diagnostics.tex b/source/diagnostics.tex index deceed9aeb..5018ef47ec 100644 --- a/source/diagnostics.tex +++ b/source/diagnostics.tex @@ -918,13 +918,13 @@ \pnum The \tcode{is_error_code_enum} and \tcode{is_error_condition_enum} may be -specialized for user-defined types to indicate that such types are eligible +specialized for program-defined types to indicate that such types are eligible for \tcode{class error_code} and \tcode{class error_condition} automatic conversions, respectively. \rSec2[syserr.errcat]{Class \tcode{error_category}} -\rSec3[syserr.errcat.overview]{Class \tcode{error_category} overview} +\rSec3[syserr.errcat.overview]{Overview} \pnum The class \tcode{error_category} serves as a base class for types used @@ -965,7 +965,7 @@ } \end{codeblock} -\rSec3[syserr.errcat.virtuals]{Class \tcode{error_category} virtual members} +\rSec3[syserr.errcat.virtuals]{Virtual members} \indexlibrary{\idxcode{error_category}!destructor}% \begin{itemdecl} @@ -1028,7 +1028,7 @@ \returns A string that describes the error condition denoted by \tcode{ev}. \end{itemdescr} -\rSec3[syserr.errcat.nonvirtuals]{Class \tcode{error_category} non-virtual members} +\rSec3[syserr.errcat.nonvirtuals]{Non-virtual members} \indexlibrary{\idxcode{error_category}!constructor}% \begin{itemdecl} @@ -1072,7 +1072,7 @@ \begin{note} \tcode{less}\iref{comparisons} provides a total ordering for pointers. \end{note} \end{itemdescr} -\rSec3[syserr.errcat.derived]{Program defined classes derived from \tcode{error_category}} +\rSec3[syserr.errcat.derived]{Program-defined classes derived from \tcode{error_category}} \indexlibrarymember{name}{error_category}% \begin{itemdecl} @@ -1157,7 +1157,7 @@ \rSec2[syserr.errcode]{Class \tcode{error_code}} -\rSec3[syserr.errcode.overview]{Class \tcode{error_code} overview} +\rSec3[syserr.errcode.overview]{Overview} \pnum The class \tcode{error_code} describes an object used to hold error code @@ -1203,7 +1203,7 @@ } \end{codeblock} -\rSec3[syserr.errcode.constructors]{Class \tcode{error_code} constructors} +\rSec3[syserr.errcode.constructors]{Constructors} \indexlibrary{\idxcode{error_code}!constructor}% \begin{itemdecl} @@ -1249,7 +1249,7 @@ \tcode{is_error_code_enum_v} is \tcode{true}. \end{itemdescr} -\rSec3[syserr.errcode.modifiers]{Class \tcode{error_code} modifiers} +\rSec3[syserr.errcode.modifiers]{Modifiers} \indexlibrarymember{assign}{error_code}% \begin{itemdecl} @@ -1290,7 +1290,7 @@ \end{itemdescr} -\rSec3[syserr.errcode.observers]{Class \tcode{error_code} observers} +\rSec3[syserr.errcode.observers]{Observers} \indexlibrarymember{value}{error_code}% \begin{itemdecl} @@ -1342,7 +1342,7 @@ \returns \tcode{value() != 0}. \end{itemdescr} -\rSec3[syserr.errcode.nonmembers]{Class \tcode{error_code} non-member functions} +\rSec3[syserr.errcode.nonmembers]{Non-member functions} \indexlibrarymember{make_error_code}{errc}% \begin{itemdecl} @@ -1369,7 +1369,7 @@ \rSec2[syserr.errcondition]{Class \tcode{error_condition}} -\rSec3[syserr.errcondition.overview]{Class \tcode{error_condition} overview} +\rSec3[syserr.errcondition.overview]{Overview} \pnum The class \tcode{error_condition} describes an object used to hold values identifying @@ -1406,7 +1406,7 @@ } \end{codeblock} -\rSec3[syserr.errcondition.constructors]{Class \tcode{error_condition} constructors} +\rSec3[syserr.errcondition.constructors]{Constructors} \indexlibrary{\idxcode{error_condition}!constructor}% \begin{itemdecl} @@ -1453,7 +1453,7 @@ \end{itemdescr} -\rSec3[syserr.errcondition.modifiers]{Class \tcode{error_condition} modifiers} +\rSec3[syserr.errcondition.modifiers]{Modifiers} \indexlibrarymember{assign}{error_condition}% \begin{itemdecl} @@ -1493,7 +1493,7 @@ \postconditions \tcode{value() == 0} and \tcode{category() == generic_category()}. \end{itemdescr} -\rSec3[syserr.errcondition.observers]{Class \tcode{error_condition} observers} +\rSec3[syserr.errcondition.observers]{Observers} \indexlibrarymember{value}{error_condition}% \begin{itemdecl} @@ -1535,7 +1535,7 @@ \returns \tcode{value() != 0}. \end{itemdescr} -\rSec3[syserr.errcondition.nonmembers]{Class \tcode{error_condition} non-member functions} +\rSec3[syserr.errcondition.nonmembers]{Non-member functions} \indexlibrarymember{make_error_condition}{errc}% \begin{itemdecl} @@ -1659,7 +1659,7 @@ \rSec2[syserr.syserr]{Class \tcode{system_error}} -\rSec3[syserr.syserr.overview]{Class \tcode{system_error} overview} +\rSec3[syserr.syserr.overview]{Overview} \pnum The class \tcode{system_error} describes an exception object used to @@ -1690,7 +1690,7 @@ } \end{codeblock} -\rSec3[syserr.syserr.members]{Class \tcode{system_error} members} +\rSec3[syserr.syserr.members]{Members} \indexlibrary{\idxcode{system_error}!constructor}% \begin{itemdecl} diff --git a/source/exceptions.tex b/source/exceptions.tex index f6d0e279f2..22947b9438 100644 --- a/source/exceptions.tex +++ b/source/exceptions.tex @@ -254,15 +254,17 @@ \pnum Throwing an exception -copy-initializes~(\ref{dcl.init}, \ref{class.copy}) a temporary object, +copy-initializes~(\ref{dcl.init}, \ref{class.copy.ctor}) a temporary object, called the \defnx{exception object}{exception handling!exception object}. An lvalue denoting the temporary is used to initialize the variable declared in the matching \grammarterm{handler}\iref{except.handle}. -If the type of the exception object would -be an incomplete type or a pointer to an incomplete -type other than \cv{}~\tcode{void} the program is ill-formed. +If the type of the exception object would be +an incomplete type, +an abstract class type\iref{class.abstract}, +or a pointer to an incomplete type other than \cv{}~\tcode{void} +the program is ill-formed. \pnum \indextext{exception handling!memory}% @@ -309,7 +311,7 @@ the copy-initialization as well as the constructor selected for a copy-initialization considering the thrown object as an lvalue shall be non-deleted and accessible, even if the copy/move operation is -elided\iref{class.copy}. +elided\iref{class.copy.elision}. The destructor is potentially invoked\iref{class.dtor}. \pnum @@ -328,7 +330,7 @@ If the exception handling mechanism handling an uncaught exception\iref{except.uncaught} directly invokes a function that exits via an -exception, \tcode{std::terminate} is called\iref{except.terminate}. +exception, the function \tcode{std::terminate} is called\iref{except.terminate}. \begin{example} \begin{codeblock} struct C { @@ -342,14 +344,15 @@ int main() { try { - throw C(); // calls \tcode{std::terminate()} if construction of the handler's - // \grammarterm{exception-declaration} object is not elided\iref{class.copy} + throw C(); // calls \tcode{std::terminate} if construction of the handler's + // \grammarterm{exception-declaration} object is not elided\iref{class.copy.elision} } catch(C) { } } \end{codeblock} \end{example} \begin{note} -Consequently, destructors should generally catch exceptions and not let them propagate. +\setlength{\emergencystretch}{1em} +Consequently, destructors should generally catch exceptions and not let them propa\-gate. \end{note} @@ -592,7 +595,7 @@ The stack will have been unwound at that point. \end{note} Also, an implicit handler is considered active when -\tcode{std::terminate()} +the function \tcode{std::terminate} is entered due to a throw. A handler is no longer considered active when the catch clause exits. @@ -605,12 +608,12 @@ \pnum If no matching handler is found, the function -\tcode{std::terminate()} +\tcode{std::terminate} is called; whether or not the stack is unwound before this call to -\tcode{std::terminate()} +\tcode{std::terminate} is \impldef{stack unwinding before call to -\tcode{std::terminate()}}\iref{except.terminate}. +\tcode{std::terminate}}\iref{except.terminate}. \pnum Referring to any non-static member or base class of an object @@ -703,7 +706,6 @@ \nontermdef{noexcept-specifier}\br \terminal{noexcept} \terminal{(} constant-expression \terminal{)}\br \terminal{noexcept}\br - \terminal{throw} \terminal{(} \terminal{)} \end{bnf} \pnum @@ -721,10 +723,6 @@ is equivalent to the \grammarterm{noexcept-specifier} \tcode{noexcept(true)}. -The \grammarterm{noexcept-specifier} \tcode{throw()} -is deprecated\iref{depr.except.spec}, and -equivalent to the \grammarterm{noexcept-specifier} -\tcode{noexcept(true)}. \pnum If a declaration of a function @@ -787,7 +785,7 @@ and the search for a handler\iref{except.handle} encounters the outermost block of a function with a non-throwing exception specification, -the function \tcode{std::terminate()} is called\iref{except.terminate}. +the function \tcode{std::terminate} is called\iref{except.terminate}. \begin{note} An implementation shall not reject an expression merely because, when executed, it throws or might @@ -874,7 +872,7 @@ their exception specifications do not contribute to the exception specification of the constructor, because an exception thrown from such a destructor -would call \tcode{std::terminate} +would call the function \tcode{std::terminate} rather than escape the constructor~(\ref{except.throw}, \ref{except.terminate}). \end{note} @@ -918,7 +916,7 @@ ~A(); }; struct B { - B() throw(); + B() noexcept; B(const B&) = default; // implicit exception specification is \tcode{noexcept(true)} B(B&&, int = (throw Y(), 0)) noexcept; ~B() noexcept(false); @@ -978,7 +976,7 @@ \rSec1[except.special]{Special functions} \pnum -The function \tcode{std::terminate()}\iref{except.terminate} +The function \tcode{std::terminate}\iref{except.terminate} is used by the exception handling mechanism for coping with errors related to the exception handling mechanism itself. The function @@ -986,7 +984,7 @@ \tcode{std::nested_exception}\iref{except.nested} can be used by a program to capture the currently handled exception. -\rSec2[except.terminate]{The \tcode{std::terminate()} function} +\rSec2[except.terminate]{The \tcode{std::terminate} function} \pnum \indextext{\idxcode{terminate}}% @@ -1028,6 +1026,19 @@ \tcode{std::atexit} or \tcode{std::at_quick_exit} exits via an exception\iref{support.start.term}, or +\item% +when evaluation of the predicate of a contract\iref{dcl.attr.contract} +exits via an exception, or + +\item% +when the violation handler invoked +for a failed contract condition check\iref{dcl.attr.contract} +on a \tcode{noexcept} function exits via an exception, or + +\item% +when the violation handler has completed after a failed contract check +and the continuation mode is \term{off}, or + \item% when a \grammarterm{throw-expression}\iref{expr.throw} @@ -1065,29 +1076,29 @@ \pnum \indextext{\idxcode{terminate}}% In such cases, -\tcode{std::terminate()} +the function \tcode{std::terminate} is called\iref{exception.terminate}. In the situation where no matching handler is found, it is -\impldef{stack unwinding before call to \tcode{std::terminate()}} whether or not the +\impldef{stack unwinding before call to \tcode{std::terminate}} whether or not the stack is unwound before -\tcode{std::terminate()} +\tcode{std::terminate} is called. In the situation where the search for a handler\iref{except.handle} encounters the outermost block of a function with a non-throwing exception specification\iref{except.spec}, it is -\impldef{whether stack is unwound before calling \tcode{std::ter\-mi\-nate()} +\impldef{whether stack is unwound before calling the function \tcode{std::terminate} when a \tcode{noexcept} specification is violated} whether the stack is unwound, unwound partially, or not unwound at all -before \tcode{std::terminate()} is called. +before the function \tcode{std::terminate} is called. In all other situations, the stack shall not be unwound before -\tcode{std::terminate()} +the function \tcode{std::terminate} is called. An implementation is not permitted to finish stack unwinding prematurely based on a determination that the unwind process -will eventually cause a call to -\tcode{std::terminate()}. +will eventually cause a call to the function +\tcode{std::terminate}. \rSec2[except.uncaught]{The \tcode{std::uncaught_exceptions()} function}% \indexlibrary{\idxcode{uncaught_exceptions}} diff --git a/source/expressions.tex b/source/expressions.tex index cea2b06139..bfe65b4683 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -181,7 +181,7 @@ The \defnx{result}{result!glvalue} of a glvalue is the entity denoted by the expression. \pnum -Whenever a glvalue expression appears as an operand of an operator that +Whenever a glvalue appears as an operand of an operator that expects a prvalue for that operand, the lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, or function-to-pointer\iref{conv.func} standard conversions are @@ -192,8 +192,8 @@ \begin{note} Because cv-qualifiers are removed from the type of an expression of non-class type when the expression is converted to a prvalue, an lvalue -expression of type \tcode{const int} can, for example, be used where -a prvalue expression of type \tcode{int} is required. +of type \tcode{const int} can, for example, be used where +a prvalue of type \tcode{int} is required. \end{note} \begin{note} There are no prvalue bit-fields; if a bit-field is converted to a @@ -202,7 +202,7 @@ \end{note} \pnum -Whenever a prvalue expression appears as an operand of an operator that +Whenever a prvalue appears as an operand of an operator that expects a glvalue for that operand, the temporary materialization conversion\iref{conv.rval} is applied to convert the expression to an xvalue. @@ -213,8 +213,10 @@ and rvalues in other significant contexts. \pnum -Unless otherwise indicated\iref{expr.call}, -a prvalue shall always have complete type or the \tcode{void} type. +Unless otherwise indicated\iref{dcl.type.simple}, +a prvalue shall always have complete type or the \tcode{void} type; +if it has a class type or (possibly multi-dimensional) array of class type, +that class shall not be an abstract class\iref{class.abstract}. A glvalue shall not have type \cv{}~\tcode{void}. \begin{note} A glvalue may have complete or incomplete non-\tcode{void} type. @@ -227,7 +229,7 @@ or is a function type. \begin{note} A program that attempts -to modify an object through a nonmodifiable lvalue expression or through an rvalue expression +to modify an object through a nonmodifiable lvalue or through an rvalue is ill-formed~(\ref{expr.ass}, \ref{expr.post.incr}, \ref{expr.pre.incr}). \end{note} @@ -417,6 +419,615 @@ conversion. \end{note} The glvalue expression is evaluated and its value is discarded. +\rSec1[conv]{Standard conversions} + +\indextext{implicit conversion|see{conversion, implicit}} +\indextext{contextually converted to bool|see{conversion, contextual}} +\indextext{rvalue!lvalue conversion to|see{conversion, lvalue-to-rvalue}}% + +\pnum +\indextext{conversion!standard|(}% +\indextext{conversion!implicit}% +Standard conversions are implicit conversions with built-in meaning. +\ref{conv} enumerates the full set of such conversions. A +\defnx{standard conversion sequence}{conversion sequence!standard} is a sequence of standard +conversions in the following order: + +\begin{itemize} +\item Zero or one conversion from the following set: lvalue-to-rvalue +conversion, array-to-pointer conversion, and function-to-pointer +conversion. + +\item Zero or one conversion from the following set: integral +promotions, floating-point promotion, integral conversions, floating-point +conversions, floating-integral conversions, pointer conversions, +pointer-to-member conversions, and boolean conversions. + +\item Zero or one function pointer conversion. + +\item Zero or one qualification conversion. +\end{itemize} + +\begin{note} +A standard conversion sequence can be empty, i.e., it can consist of no +conversions. \end{note} A standard conversion sequence will be applied to +an expression if necessary to convert it to a required destination type. + +\pnum +\begin{note} +Expressions with a given type will be implicitly converted to other +types in several contexts: + +\begin{itemize} +\item When used as operands of operators. The operator's requirements +for its operands dictate the destination type\iref{expr.compound}. + +\item When used in the condition of an \tcode{if} statement\iref{stmt.if} or +iteration statement\iref{stmt.iter}. The destination type is +\tcode{bool}. + +\item When used in the expression of a \tcode{switch} statement\iref{stmt.switch}. +The destination type is integral. + +\item When used as the source expression for an initialization (which +includes use as an argument in a function call and use as the expression +in a \tcode{return} statement). The type of the entity being initialized +is (generally) the destination type. +See~\ref{dcl.init}, \ref{dcl.init.ref}. +\end{itemize} +\end{note} + +\pnum +An expression \tcode{e} can be +\defnx{implicitly converted}{conversion!implicit} to a type \tcode{T} if and only if the +declaration \tcode{T t=e;} is well-formed, for some invented temporary +variable \tcode{t}\iref{dcl.init}. + +\pnum +Certain language constructs require that an expression be converted to a Boolean +value. An expression \tcode{e} appearing in such a context is said to be +\defnx{contextually converted to \tcode{bool}}{conversion!contextual to \tcode{bool}} and is well-formed if and only if +the declaration \tcode{bool t(e);} is well-formed, for some invented temporary +variable \tcode{t}\iref{dcl.init}. + +\pnum +Certain language constructs require conversion to a value having +one of a specified set of types appropriate to the construct. An +expression \tcode{e} of class type \tcode{E} appearing in such a +context is said to be +\indextext{conversion!contextual}% +\defn{contextually implicitly converted} to a specified type \tcode{T} and is +well-formed if and only if \tcode{e} can be implicitly converted to a type \tcode{T} +that is determined as follows: +\tcode{E} is searched for non-explicit conversion functions +whose return type is \cv{} \tcode{T} or reference to \cv{} +\tcode{T} such that \tcode{T} is allowed by the context. +There shall be exactly one such \tcode{T}. + +\pnum +The effect of any implicit +conversion is the same as performing the corresponding declaration and initialization +and then using the temporary variable as the result of the conversion. +The result is an lvalue if \tcode{T} is an lvalue reference +type or an rvalue reference to function type\iref{dcl.ref}, +an xvalue if \tcode{T} is an rvalue reference to object type, +and a prvalue otherwise. The expression \tcode{e} +is used as a glvalue if and only if the initialization uses it as a glvalue. + +\pnum +\begin{note} +For class types, user-defined conversions are considered as well; +see~\ref{class.conv}. In general, an implicit conversion +sequence\iref{over.best.ics} consists of a standard conversion +sequence followed by a user-defined conversion followed by another +standard conversion sequence. +\end{note} + +\pnum +\begin{note} +There are some contexts where certain conversions are suppressed. For +example, the lvalue-to-rvalue conversion is not done on the operand of +the unary \tcode{\&} operator. Specific exceptions are given in the +descriptions of those operators and contexts. +\end{note} + +\rSec2[conv.lval]{Lvalue-to-rvalue conversion} + +\pnum +\indextext{conversion!lvalue-to-rvalue}% +\indextext{type!incomplete}% +A glvalue\iref{basic.lval} of a non-function, non-array type \tcode{T} +can be converted to +a prvalue.\footnote{For historical reasons, this conversion is called the ``lvalue-to-rvalue'' +conversion, even though that name does not accurately reflect the taxonomy +of expressions described in~\ref{basic.lval}.} +If \tcode{T} is an incomplete type, a +program that necessitates this conversion is ill-formed. If \tcode{T} +is a non-class type, the type of the prvalue is +the cv-unqualified version of \tcode{T}. Otherwise, the type of the +prvalue is \tcode{T}.% +\footnote{In \Cpp{} class and array prvalues can have cv-qualified types. +This differs from ISO C, in which non-lvalues never have +cv-qualified types.} + +\pnum +When an lvalue-to-rvalue conversion +is applied to an expression \tcode{e}, and either +\begin{itemize} +\item \tcode{e} is not potentially evaluated, or +\item the evaluation of \tcode{e} results in the evaluation of a member + \tcode{ex} of the set of potential results of \tcode{e}, and \tcode{ex} + names a variable \tcode{x} that is not odr-used by + \tcode{ex}\iref{basic.def.odr}, +\end{itemize} +the value contained in the referenced object is not accessed. +\begin{example} +\begin{codeblock} +struct S { int n; }; +auto f() { + S x { 1 }; + constexpr S y { 2 }; + return [&](bool b) { return (b ? y : x).n; }; +} +auto g = f(); +int m = g(false); // undefined behavior due to access of \tcode{x.n} outside its lifetime +int n = g(true); // OK, does not access \tcode{y.n} +\end{codeblock} +\end{example} + +\pnum +The result of the conversion is determined according to the +following rules: + +\begin{itemize} + +\item If \tcode{T} is \cv{}~\tcode{std::nullptr_t}, the result is a +null pointer constant\iref{conv.ptr}. +\begin{note} +Since no value is fetched from memory, +there is no side effect for a volatile access\iref{intro.execution}, and +an inactive member of a union\iref{class.union} may be accessed. +\end{note} + +\item Otherwise, if \tcode{T} has a class +type, the conversion copy-initializes the result object from +the glvalue. + +\item Otherwise, if the object to which the glvalue refers contains an invalid +pointer value~(\ref{basic.stc.dynamic.deallocation}, +\ref{basic.stc.dynamic.safety}), the behavior is +\impldef{lvalue-to-rvalue conversion of an invalid pointer value}. + +\item Otherwise, the value contained in the object indicated by the +glvalue is the prvalue result. + +\end{itemize} + +\pnum +\begin{note} +See also~\ref{basic.lval}.\end{note} + +\rSec2[conv.array]{Array-to-pointer conversion} + +\pnum +\indextext{conversion!array-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}''. +The temporary materialization conversion\iref{conv.rval} is applied. +The result is a pointer to the first element of the array. + +\rSec2[conv.func]{Function-to-pointer conversion} + +\pnum +\indextext{conversion!function-to-pointer}% +An lvalue of function type \tcode{T} can be converted to a prvalue of +type ``pointer to \tcode{T}''. The result is a pointer to the +function.\footnote{This conversion never applies to non-static member functions because an +lvalue that refers to a non-static member function cannot be obtained.} + +\pnum +\begin{note} +See~\ref{over.over} for additional rules for the case where the function +is overloaded. +\end{note} + +\rSec2[conv.rval]{Temporary materialization conversion} +\indextext{conversion!temporary materialization}% + +\pnum +A prvalue of type \tcode{T} can be converted to an xvalue of type \tcode{T}. +This conversion initializes a temporary object\iref{class.temporary} of type \tcode{T} from the prvalue +by evaluating the prvalue with the temporary object as its result object, +and produces an xvalue denoting the temporary object. +\tcode{T} shall be a complete type. +\begin{note} +If \tcode{T} is a class type (or array thereof), +it must have an accessible and non-deleted destructor; +see~\ref{class.dtor}. +\end{note} +\begin{example} +\begin{codeblock} +struct X { int n; }; +int k = X().n; // OK, \tcode{X()} prvalue is converted to xvalue +\end{codeblock} +\end{example} + +\rSec2[conv.qual]{Qualification conversions} + +\indextext{conversion!qualification|(}% +\pnum +A \defn{cv-decomposition} of a type \tcode{T} +is a sequence of +$\cv{}_i$ and $P_i$ +such that \tcode{T} is +\begin{indented} +``$\cv{}_0$ $P_0$ $\cv{}_1$ $P_1$ $\cdots$ $\cv{}_{n-1}$ $P_{n-1}$ $\cv{}_n$ \tcode{U}'' for $n > 0$, +\end{indented} +where +each $\cv{}_i$ is a set of cv-qualifiers\iref{basic.type.qualifier}, and +each $P_i$ is +``pointer to''\iref{dcl.ptr}, +``pointer to member of class $C_i$ of type''\iref{dcl.mptr}, +``array of $N_i$'', or +``array of unknown bound of''\iref{dcl.array}. +If $P_i$ designates an array, +the cv-qualifiers $\cv{}_{i+1}$ on the element type are also taken as +the cv-qualifiers $\cv{}_i$ of the array. +\begin{example} +The type denoted by the \grammarterm{type-id} \tcode{const int **} +has two cv-decompositions, +taking \tcode{U} as ``\tcode{int}'' and as ``pointer to \tcode{const int}''. +\end{example} +The $n$-tuple of cv-qualifiers after the first one +in the longest cv-decomposition of \tcode{T}, that is, +$\cv{}_1, \cv{}_2, \dotsc, \cv{}_n$, is called the +\defn{cv-qualification signature} of \tcode{T}. + +\pnum +\indextext{type!similar|see{similar types}}% +Two types $\tcode{T}_1$ and $\tcode{T}_2$ are \defnx{similar}{similar types} if +they have cv-decompositions with the same $n$ +such that corresponding $P_i$ components are the same +and the types denoted by \tcode{U} are the same. + +\pnum +A prvalue of type $\tcode{T}_1$ +can be converted to type $\tcode{T}_2$ +if the following conditions are satisfied, +% NB: forbid line break between 'where' and 'cv' +% to stop superscript j from running into +% descender of p on the previous line. +where~$\cv{}_i^j$ denotes the cv-qualifiers in the cv-qualification signature of $\tcode{T}_j$:% +\footnote{These rules ensure that const-safety is preserved by the conversion.} + +\begin{itemize} +\item $\tcode{T}_1$ and $\tcode{T}_2$ are similar. + +\item For every $i > 0$, if \tcode{const} is in $\cv{}_i^1$ then \tcode{const} is in $\cv{}_i^2$, and similarly for \tcode{volatile}. + +\item If the $\cv{}_i^1$ and $\cv{}_i^2$ are different, +then \tcode{const} is in every $\cv{}_k^2$ for $0 < k < i$. +\end{itemize} + +\begin{note} +If a program could assign a pointer of type \tcode{T**} to a pointer of +type \tcode{const} \tcode{T**} (that is, if line \#1 below were +allowed), a program could inadvertently modify a const object +(as it is done on line \#2). For example, + +\begin{codeblock} +int main() { + const char c = 'c'; + char* pc; + const char** pcc = &pc; // \#1: not allowed + *pcc = &c; + *pc = 'C'; // \#2: modifies a const object +} +\end{codeblock} +\end{note} + +\pnum +\begin{note} +A prvalue of type ``pointer to \cvqual{cv1} \tcode{T}'' can be +converted to a prvalue of type ``pointer to \cvqual{cv2} \tcode{T}'' if +``\cvqual{cv2} \tcode{T}'' is more cv-qualified than ``\cvqual{cv1} +\tcode{T}''. +A prvalue of type ``pointer to member of \tcode{X} of type \cvqual{cv1} +\tcode{T}'' can be converted to a prvalue of type ``pointer to member +of \tcode{X} of type \cvqual{cv2} \tcode{T}'' if ``\cvqual{cv2} +\tcode{T}'' is more cv-qualified than ``\cvqual{cv1} \tcode{T}''. +\end{note} + +\pnum +\begin{note} +Function types (including those used in pointer to member function +types) are never cv-qualified\iref{dcl.fct}. +\end{note} +\indextext{conversion!qualification|)} + +\rSec2[conv.prom]{Integral promotions} + +\pnum +\indextext{promotion!integral}% +A prvalue of an integer type other than \tcode{bool}, \tcode{char16_t}, +\tcode{char32_t}, or \tcode{wchar_t} whose integer conversion +rank\iref{conv.rank} is less than the rank of \tcode{int} can be +converted to a prvalue of type \tcode{int} if \tcode{int} can represent +all the values of the source type; otherwise, the source prvalue can be +converted to a prvalue of type \tcode{unsigned int}. + +\pnum +\indextext{type!underlying!\idxcode{wchar_t}}% +\indextext{type!underlying!\idxcode{char16_t}}% +\indextext{type!underlying!\idxcode{char32_t}}% +A prvalue of type \tcode{char16_t}, \tcode{char32_t}, or +\tcode{wchar_t}\iref{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 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 +to a prvalue of its underlying type. + +\pnum +\indextext{type!underlying!enumeration}% +A prvalue of an unscoped enumeration type whose underlying type is not +fixed\iref{dcl.enum} can be converted to a prvalue of the first of the following +types that can represent all the values of the enumeration (i.e., the values in the +range $b_\text{min}$ to $b_\text{max}$ as described in~\ref{dcl.enum}): \tcode{int}, +\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\iref{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 +A prvalue of an unscoped enumeration type whose underlying type is +fixed\iref{dcl.enum} can be converted to a prvalue of its underlying type. Moreover, +if integral promotion can be applied to its underlying type, a prvalue of an unscoped +enumeration type whose underlying type is fixed can also be converted to a prvalue of +the promoted underlying type. + +\pnum +A prvalue for an integral bit-field\iref{class.bit} can be converted +to a prvalue of type \tcode{int} if \tcode{int} can represent all the +values of the bit-field; otherwise, it can be converted to +\tcode{unsigned int} if \tcode{unsigned int} can represent all the +values of the bit-field. If the bit-field is larger yet, no integral +promotion applies to it. If the bit-field has an enumerated type, it is +treated as any other value of that type for promotion purposes. + +\pnum +\indextext{promotion!bool to int}% +A prvalue of type \tcode{bool} can be converted to a prvalue of type +\tcode{int}, with \tcode{false} becoming zero and \tcode{true} becoming +one. + +\pnum +These conversions are called \defnx{integral promotions}{integral promotion}. + +\rSec2[conv.fpprom]{Floating-point promotion} + +\pnum +\indextext{promotion!floating-point}% +A prvalue of type \tcode{float} can be converted to a prvalue of type +\tcode{double}. The value is unchanged. + +\pnum +This conversion is called \defn{floating-point promotion}. + +\rSec2[conv.integral]{Integral conversions} + +\pnum +\indextext{conversion!integral}% +A prvalue of an integer type can be converted to a prvalue of another +integer type. A prvalue of an unscoped enumeration type can be converted to +a prvalue of an integer type. + +\pnum +\indextext{conversion!to unsigned}% +If the destination type is unsigned, the resulting value is the least +unsigned integer congruent to the source integer (modulo $2^n$ where $n$ +is the number of bits used to represent the unsigned type). +\indextext{signed integer representation!two's complement}% +\begin{note} +In a two's complement representation, this conversion is conceptual and +there is no change in the bit pattern (if there is no truncation). +\end{note} + +\pnum +\indextext{conversion!to signed}% +If the destination type is signed, the value is unchanged if it can be +represented in the destination type; otherwise, +the value is \impldef{value of result of unsigned to signed conversion}. + +\pnum +\indextext{conversion!bool@\tcode{bool}}% +If the destination type is \tcode{bool}, see~\ref{conv.bool}. If the +source type is \tcode{bool}, the value \tcode{false} is converted to +zero and the value \tcode{true} is converted to one. + +\pnum +The conversions allowed as integral promotions are excluded from the set +of integral conversions. + +\rSec2[conv.double]{Floating-point conversions} + +\pnum +\indextext{conversion!floating-point}% +A prvalue of floating-point type can be converted to a prvalue of +another floating-point type. If the source value can be exactly +represented in the destination type, the result of the conversion is +that exact representation. If the source value is between two adjacent +destination values, the result of the conversion is an +\impldef{result of inexact floating-point conversion} choice of either of those values. +Otherwise, the behavior is undefined. + +\pnum +The conversions allowed as floating-point promotions are excluded from +the set of floating-point conversions. + +\rSec2[conv.fpint]{Floating-integral conversions} + +\pnum +\indextext{conversion!floating to integral}% +A prvalue of a floating-point type can be converted to a prvalue of an +integer type. The conversion truncates; that is, the fractional part is +discarded. +\indextext{value!undefined unrepresentable integral}% +The behavior is undefined if the truncated value cannot be represented +in the destination type. +\begin{note} +If the destination type is \tcode{bool}, see~\ref{conv.bool}. +\end{note} + +\pnum +\indextext{conversion!integral to floating}% +\indextext{truncation}% +\indextext{rounding}% +A prvalue of an integer type or of an unscoped enumeration type can be converted to +a prvalue of a floating-point type. The result is exact if possible. If the value being +converted is in the range of values that can be represented but the value cannot be +represented exactly, it is an \impldef{value of result of inexact integer to +floating-point conversion} choice of either the next lower or higher representable +value. \begin{note} Loss of precision occurs if the integral value cannot be represented +exactly as a value of the floating-point type. \end{note} If the value being converted is +outside the range of values that can be represented, the behavior is undefined. If the +source type is \tcode{bool}, the value \tcode{false} is converted to zero and the value +\tcode{true} is converted to one. + +\rSec2[conv.ptr]{Pointer conversions} + +\pnum +\indextext{conversion!pointer}% +\indextext{null pointer conversion|see{conversion, null pointer}}% +\indextext{pointer!zero|see{value, null pointer}}% +\indextext{value!null pointer}% +A \defnx{null pointer constant}{constant!null pointer} is an integer literal\iref{lex.icon} with +value zero +or a prvalue of type \tcode{std::nullptr_t}. A null pointer constant can be +converted to a pointer type; the +result is the null pointer value of that type\iref{basic.compound} and is +distinguishable from every other value of +object pointer or function pointer +type. +Such a conversion is called a \defnx{null pointer conversion}{conversion!null pointer}. +Two null pointer values of the same type shall compare +equal. The conversion of a null pointer constant to a pointer to +cv-qualified type is a single conversion, and not the sequence of a +pointer conversion followed by a qualification +conversion\iref{conv.qual}. A null pointer constant of integral type +can be converted to a prvalue of type \tcode{std::nullptr_t}. +\begin{note} The resulting prvalue is not a null pointer value. \end{note} + +\pnum +A prvalue of type ``pointer to \cv{} \tcode{T}'', where \tcode{T} +is an object type, can be converted to a prvalue of type ``pointer to +\cv{} \tcode{void}''. +The pointer value\iref{basic.compound} is unchanged by this conversion. + +\pnum +A prvalue of type ``pointer to \cv{} \tcode{D}'', where \tcode{D} +is a class type, can be converted to a prvalue of type ``pointer to +\cv{} \tcode{B}'', where \tcode{B} is a base class\iref{class.derived} +of \tcode{D}. If \tcode{B} is an +inaccessible\iref{class.access} or +ambiguous\iref{class.member.lookup} base class of \tcode{D}, a program +that necessitates this conversion is ill-formed. The result of the +conversion is a pointer to the base class subobject of the derived class +object. The null pointer value is converted to the null pointer value of +the destination type. + +\rSec2[conv.mem]{Pointer-to-member conversions} + +\pnum +\indextext{conversion!pointer-to-member}% +\indextext{null member pointer conversion|see{conversion, null member pointer}}% +\indextext{constant!null pointer}% +A null pointer constant\iref{conv.ptr} can be converted to a +pointer-to-member +type; the result is the \defnx{null member pointer value}{value!null member pointer} +of that type and is distinguishable from any pointer to member not +created from a null pointer constant. +Such a conversion is called a \defnx{null member pointer conversion}{conversion!null member pointer}. +Two null member pointer values of +the same type shall compare equal. The conversion of a null pointer +constant to a pointer to member of cv-qualified type is a single +conversion, and not the sequence of a pointer-to-member conversion +followed by a qualification conversion\iref{conv.qual}. + +\pnum +A prvalue of type ``pointer to member of \tcode{B} of type \cv{} +\tcode{T}'', where \tcode{B} is a class type, can be converted to +a prvalue of type ``pointer to member of \tcode{D} of type \cv{} +\tcode{T}'', where \tcode{D} is a derived class\iref{class.derived} +of \tcode{B}. If \tcode{B} is an +inaccessible\iref{class.access}, +ambiguous\iref{class.member.lookup}, or virtual\iref{class.mi} base +class of \tcode{D}, or a base class of a virtual base class of +\tcode{D}, a program that necessitates this conversion is ill-formed. +The result of the conversion refers to the same member as the pointer to +member before the conversion took place, but it refers to the base class +member as if it were a member of the derived class. The result refers to +the member in \tcode{D}'s instance of \tcode{B}. Since the result has +type ``pointer to member of \tcode{D} of type \cv{} \tcode{T}'', +indirection through it with a \tcode{D} object is valid. The result is the same +as if indirecting through the pointer to member of \tcode{B} with the +\tcode{B} subobject of \tcode{D}. The null member pointer value is +converted to the null member pointer value of the destination +type.\footnote{The rule for conversion of pointers to members (from pointer to member +of base to pointer to member of derived) appears inverted compared to +the rule for pointers to objects (from pointer to derived to pointer to +base)~(\ref{conv.ptr}, \ref{class.derived}). This inversion is +necessary to ensure type safety. Note that a pointer to member is not +an object pointer or a function pointer +and the rules for conversions +of such pointers do not apply to pointers to members. +\indextext{conversion!pointer-to-member!\idxcode{void*}}% +In particular, a pointer to member cannot be converted to a +\tcode{void*}.} + +\rSec2[conv.fctptr]{Function pointer conversions} + +\pnum +\indextext{conversion!function pointer}% +A prvalue of type ``pointer to \tcode{noexcept} function'' +can be converted to a prvalue of type ``pointer to function''. +The result is a pointer to the function. +A prvalue of type ``pointer to member of type \tcode{noexcept} function'' +can be converted to a prvalue of type ``pointer to member of type function''. +The result designates the member function. + +\begin{example} +\begin{codeblock} + void (*p)(); + void (**pp)() noexcept = &p; // error: cannot convert to pointer to \tcode{noexcept} function + + struct S { typedef void (*p)(); operator p(); }; + void (*q)() noexcept = S(); // error: cannot convert to pointer to \tcode{noexcept} function +\end{codeblock} +\end{example} + +\rSec2[conv.bool]{Boolean conversions} + +\pnum +\indextext{conversion!boolean}% +A prvalue of arithmetic, unscoped enumeration, pointer, or pointer-to-member +type can be converted to a prvalue of type \tcode{bool}. A zero value, null +pointer value, or null member pointer value is converted to \tcode{false}; any +other value is converted to \tcode{true}. For +direct-initialization\iref{dcl.init}, a prvalue of type +\tcode{std::nullptr_t} can be converted to a prvalue of type +\tcode{bool}; the resulting value is \tcode{false}. + +\indextext{conversion!standard|)} + \rSec1[expr.arith.conv]{Usual arithmetic conversions} \pnum @@ -472,6 +1083,13 @@ \end{itemize} \end{itemize} +\pnum +If one operand is of enumeration type +and the other operand is of +a different enumeration type or +a floating-point type, +this behavior is deprecated\iref{depr.arith.conv.enum}. + \rSec1[expr.prim]{Primary expressions}% \indextext{expression!primary|(} @@ -677,8 +1295,10 @@ \pnum \indextext{identifier}% -An \grammarterm{identifier} is an \grammarterm{id-expression} provided it has -been suitably declared\iref{dcl.dcl}. +An \grammarterm{identifier} is only +an \grammarterm{id-expression} if it has +been suitably declared\iref{dcl.dcl} +or if it appears as part of a \grammarterm{declarator-id}\iref{dcl.decl}. \begin{note} For \grammarterm{operator-function-id}{s}, see~\ref{over.oper}; for \grammarterm{conversion-function-id}{s}, see~\ref{class.conv.fct}; for @@ -708,15 +1328,19 @@ If that \grammarterm{lambda-expression} is not declared \tcode{mutable}, the type of such an identifier will typically be \tcode{const} qualified. \end{note} +If the entity is a template parameter object for +a template parameter of type \tcode{T}\iref{temp.param}, +the type of the expression is \tcode{const T}. Otherwise, the type of the expression is the type of the result. \begin{note} The type will be adjusted as described in \ref{expr.type} if it is cv-qualified or is a reference type. \end{note} The expression is an lvalue -if the entity is a function, variable, or data member +if the entity is a function, variable, structured binding\iref{dcl.struct.bind}, data member, or +template parameter object and a prvalue otherwise\iref{basic.lval}; -it is a bit-field if the identifier designates a bit-field\iref{dcl.struct.bind}. +it is a bit-field if the identifier designates a bit-field. \begin{example} \begin{codeblock} void f() { @@ -797,7 +1421,7 @@ \grammarterm{qualified-id};~\ref{namespace.qual} describes name lookup for 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. +is an lvalue if the member is a function, a variable, or a structured binding\iref{dcl.struct.bind} and a prvalue otherwise. \pnum A \grammarterm{nested-name-specifier} that denotes an @@ -839,7 +1463,8 @@ \end{bnf} \pnum -Lambda expressions provide a concise way to create simple function objects. +A \grammarterm{lambda-expression} provides +a concise way to create a simple function object. \begin{example} \begin{codeblock} #include @@ -1194,10 +1819,10 @@ default constructor if the \grammarterm{lambda-expression} has a \grammarterm{lambda-capture} and a defaulted default constructor otherwise. -It has a defaulted copy constructor and a defaulted move constructor\iref{class.copy}. +It has a defaulted copy constructor and a defaulted move constructor\iref{class.copy.ctor}. It has a deleted copy assignment operator if the \grammarterm{lambda-expression} has a \grammarterm{lambda-capture} and defaulted copy and move assignment -operators otherwise. +operators otherwise\iref{class.copy.assign}. \begin{note} These special member functions are implicitly defined as usual, and might therefore be defined as deleted. \end{note} @@ -1292,16 +1917,13 @@ \end{example} \pnum -A \grammarterm{lambda-expression} -is a \defn{local lambda expression} -if its innermost enclosing scope is a block scope\iref{basic.scope.block}, -or if it appears within a default member initializer +A \grammarterm{lambda-expression} shall not have +a \grammarterm{capture-default} or \grammarterm{simple-capture} +in its \grammarterm{lambda-introducer} +unless its innermost enclosing scope is a block scope\iref{basic.scope.block} +or it appears within a default member initializer and its innermost enclosing scope is -the corresponding class scope\iref{basic.scope.class}; -any other -\grammarterm{lambda-expression} shall not have a \grammarterm{capture-default} or -\grammarterm{simple-capture} in its -\grammarterm{lambda-introducer}. +the corresponding class scope\iref{basic.scope.class}. \pnum The \grammarterm{identifier} in a \grammarterm{simple-capture} is looked up using the @@ -1390,6 +2012,8 @@ the entity is said to be \defnx{implicitly captured}{capture!implicit} by each intervening \grammarterm{lambda-expression} with an associated \grammarterm{capture-default} that does not explicitly capture it. +The implicit capture of \tcode{*this} is deprecated when the +\grammarterm{capture-default} is \tcode{=}; see \ref{depr.capture.this}. \begin{example} \begin{codeblock} void f(int, const int (&)[2] = {}); // \#1 @@ -1605,7 +2229,8 @@ \tcode{m2} captures the same entity captured by \tcode{m1}. \end{itemize} -\begin{example} The nested lambda expressions and invocations below will output +\begin{example} +The nested \grammarterm{lambda-expression}s and invocations below will output \tcode{123234}. \begin{codeblock} int a = 1, b = 1, c = 1; @@ -2237,12 +2862,21 @@ \indextext{function argument|see{argument}}% \indextext{function parameter|see{parameter}}% \indextext{initialization!parameter}% -When a function is called, each parameter\iref{dcl.fct} shall be -initialized~(\ref{dcl.init}, \ref{class.copy}, \ref{class.ctor}) with +When a function is called, each parameter\iref{dcl.fct} is +initialized~(\ref{dcl.init}, \ref{class.copy.ctor}) with its corresponding argument. +If there is no corresponding argument, +the default argument for the parameter is used; +the program is ill-formed if one is not present. +\begin{example} +\begin{codeblock} + template int f(int n = 0, T ...t); + int x = f(); // error: no argument for second function parameter +\end{codeblock} +\end{example} If the function is a non-static member function, the \tcode{this} parameter of the function\iref{class.this} -shall be initialized with a pointer to the object of the call, converted +is initialized with a pointer to the object of the call, converted as if by an explicit type conversion\iref{expr.cast}. \begin{note} There is no access or ambiguity checking on this conversion; the access @@ -2251,12 +2885,12 @@ See~\ref{class.member.lookup}, \ref{class.access.base}, and~\ref{expr.ref}. \end{note} -When a function is called, the parameters that have object type shall -have completely-defined object type. +When a function is called, the type of any parameter +shall not be a class type that is either incomplete or abstract. \begin{note} -this still allows a parameter to be a pointer or reference to an -incomplete class type. However, it prevents a passed-by-value parameter -to have an incomplete class type. +This still allows a parameter to be a pointer or reference to such +a type. However, it prevents a passed-by-value parameter +to have an incomplete or abstract class type. \end{note} It is \impldef{whether the lifetime of a parameter ends when the callee returns or at the end of the enclosing full-expression} whether the @@ -2431,7 +3065,7 @@ expression\iref{expr.cast}. \indextext{type!incomplete}% Otherwise, if the type is \cv{}~\tcode{void} -and the initializer is \tcode{()} +and the initializer is \tcode{()} or \tcode{\{\}} (after pack expansion, if any), the expression is a prvalue of the specified type that performs no initialization. @@ -2777,7 +3411,7 @@ \end{codeblock} \end{example} \begin{note} -\ref{class.cdtor} describes the behavior of a \tcode{dynamic_cast} +Subclause \ref{class.cdtor} describes the behavior of a \tcode{dynamic_cast} applied to an object under construction or destruction. \end{note} @@ -2800,11 +3434,11 @@ \tcode{std::type_info} object at the end of the program is unspecified. \pnum -When \tcode{typeid} is applied to a glvalue expression whose type is a +When \tcode{typeid} is applied to a glvalue whose type is a polymorphic class type\iref{class.virtual}, the result refers to a \tcode{std::type_info} object representing the type of the most derived object\iref{intro.object} (that is, the dynamic type) to which the -glvalue refers. If the glvalue expression is obtained by applying the +glvalue refers. If the glvalue is obtained by applying the unary \tcode{*} operator to a pointer\footnote{If \tcode{p} is an expression of pointer type, then \tcode{*p}, \tcode{(*p)}, \tcode{*(p)}, \tcode{((*p))}, \tcode{*((p))}, and so on @@ -2864,8 +3498,8 @@ \pnum \begin{note} -\ref{class.cdtor} describes the behavior of \tcode{typeid} applied to an -object under construction or destruction. +Subclause \ref{class.cdtor} describes the behavior of \tcode{typeid} +applied to an object under construction or destruction. \end{note} \rSec3[expr.static.cast]{Static cast} @@ -3239,7 +3873,7 @@ \pnum \indextext{cast!reinterpret!reference}% \indextext{cast!reference}% -A glvalue expression of type \tcode{T1}, +A glvalue of type \tcode{T1}, designating an object \placeholder{x}, can be cast to the type ``reference to \tcode{T2}'' if an expression of type ``pointer to \tcode{T1}'' @@ -4122,9 +4756,6 @@ \indextext{\idxcode{new}!initialization and}% \indextext{\idxcode{new}!constructor and}% \indextext{\idxcode{new}!default constructor and}% -\indextext{default constructor|see{constructor, default}}% -\indextext{trivial type}% -\indextext{trivial class type}% A \grammarterm{new-expression} that creates an object of type \tcode{T} initializes that object as follows: @@ -4246,10 +4877,10 @@ \defnx{single-object delete expression}{delete!single-object}, and the second is an \defnx{array delete expression}{delete!array}. Whenever the \tcode{delete} keyword is immediately followed by empty square -brackets, it shall be interpreted as the second alternative.\footnote{A lambda -expression with a \grammarterm{lambda-introducer} that consists of empty square -brackets can follow the \tcode{delete} keyword if the lambda expression is -enclosed in parentheses.} +brackets, it shall be interpreted as the second alternative.\footnote{A +\grammarterm{lambda-expression} with a \grammarterm{lambda-introducer} +that consists of empty square brackets can follow the \tcode{delete} keyword +if the \grammarterm{lambda-expression} is enclosed in parentheses.} The operand shall be of pointer to object type or of class type. If of class type, the operand is contextually implicitly converted\iref{conv} to a pointer to object @@ -4294,7 +4925,10 @@ \pnum \indextext{\idxcode{delete}!undefined}% In a single-object delete expression, if the static type of the object to be -deleted is different from its dynamic type, the static type shall be a base +deleted is different from its dynamic type +and the selected deallocation function (see below) +is not a destroying operator delete, +the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined. In an array delete expression, if the dynamic type of the object to be deleted differs from its @@ -4313,7 +4947,10 @@ \pnum \indextext{\idxcode{delete}!destructor and}% If the value of the operand of the \grammarterm{delete-expression} is not a -null pointer value, the \grammarterm{delete-expression} will invoke the +null pointer value +and the selected deallocation function (see below) +is not a destroying operator delete, +the \grammarterm{delete-expression} will invoke the destructor (if any) for the object or the elements of the array being deleted. In the case of an array, the elements will be destroyed in order of decreasing address (that is, in reverse order of the completion @@ -4379,19 +5016,25 @@ the function to be called is selected as follows: \begin{itemize} \item +If any of the deallocation functions is a destroying operator delete, +all deallocation functions that are not destroying operator deletes +are eliminated from further consideration. +\item If the type has new-extended alignment, 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. -If more than one preferred function is found, +If any preferred functions are found, all non-preferred functions are eliminated from further consideration. \item +If exactly one function remains, +that function is selected and the selection process terminates. +\item If the deallocation functions have class scope, 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 +If the type is complete +and if, for an array delete expression 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::size_t} is selected. \item @@ -4401,31 +5044,54 @@ \end{itemize} \pnum +For a single-object delete expression, +the deleted object is +the object denoted by the operand +if its static type does not have a virtual destructor, +and its most-derived object otherwise. +\begin{note} +If the deallocation function is not a destroying operator delete +and the deleted object is not the most derived object in the former case, +the behavior is undefined, +as stated above. +\end{note} +For an array delete expression, +the deleted object is +the array object. When a \grammarterm{delete-expression} is executed, the selected deallocation function shall be called with -the address of the most-derived object in a single-object delete expression, or -the address of the object suitably adjusted for the array allocation +the address of the deleted object +in a single-object delete expression, or +the address of the deleted object +suitably adjusted for the array allocation overhead\iref{expr.new} in an array delete expression, as its first argument. +\begin{note} +Any cv-qualifiers in the type of the deleted object +are ignored when forming this argument. +\end{note} +If a destroying operator delete is used, +an unspecified value +is passed as the argument +corresponding to the parameter of type \tcode{std::destroying_delete_t}. If a deallocation function with a parameter of type \tcode{std::align_val_t} is used, -the alignment of the type of the object to be deleted +the alignment of the type of the deleted object is passed as the corresponding argument. If a deallocation function 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.} +the size of the deleted object +in a single-object delete expression, or +of the array plus allocation overhead +in an array delete expression, +is passed as the corresponding argument. \begin{note} -If this results in a call to a usual deallocation function, and either +If this results in a call to a replaceable 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, +a prior call to a replaceable allocation function or +the second or third argument was not the corresponding argument in said call, the behavior is undefined~(\ref{new.delete.single}, \ref{new.delete.array}). \end{note} @@ -4913,6 +5579,8 @@ \pnum If both operands have arithmetic types, +or one operand has integral type and +the other operand has unscoped enumeration type, the usual arithmetic conversions\iref{expr.arith.conv} are applied to the operands. Then: @@ -4993,7 +5661,7 @@ \tcode{std::strong_equality::equal} if the (possibly converted) operands compare equal\iref{expr.eq} and -\tcode{std::strong_equality::unequal} +\tcode{std::strong_equality::nonequal} if they compare unequal, otherwise the result of the operator is unspecified. @@ -5041,7 +5709,7 @@ \tcode{a=} compare-expression \end{bnf} +% +The +lvalue-to-rvalue\iref{conv.lval}, +array-to-pointer\iref{conv.array}, +and function-to-pointer\iref{conv.func} +standard conversions are performed on the operands. +The comparison is deprecated if +both operands were of array type +prior to these conversions\iref{depr.array.comp}. -The operands shall have arithmetic, enumeration, or pointer type. The +\pnum +The converted operands shall have arithmetic, enumeration, or pointer type. +The operators \tcode{<} (less than), \tcode{>} (greater than), \tcode{<=} (less than or equal to), and \tcode{>=} (greater than or equal to) all yield \tcode{false} or \tcode{true}. The type of the result is @@ -5127,7 +5806,18 @@ \pnum The \tcode{==} (equal to) and the \tcode{!=} (not equal to) operators -group left-to-right. The operands shall have arithmetic, enumeration, pointer, +group left-to-right. +The +lvalue-to-rvalue\iref{conv.lval}, +array-to-pointer\iref{conv.array}, +and function-to-pointer\iref{conv.func} +standard conversions are performed on the operands. +The comparison is deprecated if +both operands were of array type +prior to these conversions\iref{depr.array.comp}. + +\pnum +The converted operands shall have arithmetic, enumeration, pointer, or pointer-to-member type, or type \tcode{std::nullptr_t}. The operators \tcode{==} and \tcode{!=} both yield \tcode{true} or \tcode{false}, i.e., a result of type \tcode{bool}. In each case below, the operands shall have the @@ -5434,10 +6124,14 @@ \begin{itemize} \item if \tcode{T1} and \tcode{T2} are the same class type -(ignoring cv-qualification), or one is a base class of the other, and +(ignoring cv-qualification) and \tcode{T2} is at least as cv-qualified as \tcode{T1}, the target type is \tcode{T2}, +\item otherwise, if \tcode{T2} is a base class of \tcode{T1}, +the target type is \cvqual{cv1} \tcode{T2}, where \cvqual{cv1} +denotes the cv-qualifiers of \tcode{T1}, + \item otherwise, the target type is the type that \tcode{E2} would have after applying the lvalue-to-rvalue\iref{conv.lval}, @@ -5630,12 +6324,12 @@ \indextext{type!incomplete}% If the left operand is of class type, the class shall be complete. Assignment to objects of a class is defined by the copy/move assignment -operator~(\ref{class.copy}, \ref{over.ass}). +operator~(\ref{class.copy.assign}, \ref{over.ass}). \pnum \begin{note} For class objects, assignment is not in general the same as -initialization~(\ref{dcl.init}, \ref{class.ctor}, \ref{class.init}, \ref{class.copy}). +initialization~(\ref{dcl.init}, \ref{class.copy.ctor}, \ref{class.copy.assign}, \ref{class.init}). \end{note} \pnum @@ -5810,7 +6504,9 @@ \item a non-volatile glvalue that refers to a non-volatile object - defined with \tcode{constexpr}, or that refers to a non-mutable subobject + defined with \tcode{constexpr} or + a template parameter object\iref{temp.param}, + or that refers to a non-mutable subobject of such an object, or \item @@ -5831,7 +6527,7 @@ \item an assignment expression\iref{expr.ass} -or invocation of an assignment operator\iref{class.copy} +or invocation of an assignment operator\iref{class.copy.assign} that would change the active member of a union; \item @@ -5847,6 +6543,10 @@ its lifetime began within the evaluation of \tcode{e}; \end{itemize} +\item +a checked contract\iref{dcl.attr.contract} +whose predicate evaluates to \tcode{false}; + \item in a \grammarterm{lambda-expression}, a reference to \tcode{this} or to a variable with diff --git a/source/future.tex b/source/future.tex index 751897ab77..48744a49e9 100644 --- a/source/future.tex +++ b/source/future.tex @@ -14,6 +14,65 @@ An implementation may declare library names and entities described in this Clause with the \tcode{deprecated} attribute\iref{dcl.attr.deprecated}. +\rSec1[depr.arith.conv.enum]{Arithmetic conversion on enumerations} + +\pnum +The ability to apply the usual arithmetic conversions\iref{expr.arith.conv} +on operands where one is of enumeration type +and the other is of a different enumeration type +or a floating-point type +is deprecated. +\begin{note} +Three-way comparisons\iref{expr.spaceship} between such operands are ill-formed. +\end{note} +\begin{example} +\begin{codeblock} +enum E1 { e }; +enum E2 { f }; +bool b = e <= 3.7; // deprecated +int k = f - e; // deprecated +auto cmp = e <=> f; // ill-formed +\end{codeblock} +\end{example} + +\rSec1[depr.capture.this]{Implicit capture of \tcode{*this} by reference} + +\pnum +For compatibility with prior \Cpp{} International Standards, +a \grammarterm{lambda-expression} with \grammarterm{capture-default} +\tcode{=}\iref{expr.prim.lambda.capture} may implicitly capture +\tcode{*this} by reference. +\begin{example} +\begin{codeblock} +struct X { + int x; + void foo(int n) { + auto f = [=]() { x = n; }; // deprecated: \tcode{x} means \tcode{this->x}, not a copy thereof + auto g = [=, this]() { x = n; }; // recommended replacement + } +}; +\end{codeblock} +\end{example} + +\rSec1[depr.array.comp]{Array comparisons} + +\pnum +Equality and relational comparisons (\ref{expr.eq}, \ref{expr.rel}) +between two operands of array type +are deprecated. +\begin{note} +Three-way comparisons\iref{expr.spaceship} between such operands are ill-formed. +\end{note} +\begin{example} +\begin{codeblock} +int arr1[5]; +int arr2[5]; +bool same = arr1 == arr2; // deprecated, same as \tcode{\&arr[0] == \&arr[1]}, + // does not compare array contents +auto cmp = arr1 <=> arr2; // ill-formed +\end{codeblock} +\end{example} + \rSec1[depr.static_constexpr]{Redeclaration of \tcode{static constexpr} data members} \pnum @@ -33,65 +92,117 @@ \rSec1[depr.impldec]{Implicit declaration of copy functions} \pnum -The implicit definition of a copy constructor -as defaulted -is deprecated if the class has a -user-declared copy assignment operator or a user-declared destructor. The implicit -definition of a copy assignment operator -as defaulted is deprecated if the class has a user-declared -copy constructor or a user-declared destructor~(\ref{class.dtor}, \ref{class.copy}). +The implicit definition of a copy constructor\iref{class.copy.ctor} +as defaulted is deprecated if the class has +a user-declared copy assignment operator or +a user-declared destructor\iref{class.dtor}. +The implicit definition of a copy assignment operator\iref{class.copy.assign} +as defaulted is deprecated if the class has +a user-declared copy constructor or +a user-declared destructor. In a future revision of this International Standard, these implicit definitions could become deleted\iref{dcl.fct.def}. -\rSec1[depr.except.spec]{Deprecated exception specifications} - -\pnum -The \grammarterm{noexcept-specifier} \tcode{throw()} is deprecated. - -\rSec1[depr.cpp.headers]{\Cpp{} standard library headers} +\rSec1[depr.c.headers]{C standard library headers} \pnum -For compatibility with prior \Cpp{} International Standards, -the \Cpp{} standard library provides headers -\tcode{}\iref{depr.ccomplex.syn}, -\tcode{}\iref{depr.cstdalign.syn}, -\tcode{}\iref{depr.cstdbool.syn}, -and \tcode{}\iref{depr.ctgmath.syn}. -The use of these headers is deprecated. - -\rSec2[depr.ccomplex.syn]{Header \tcode{} synopsis} -\indexhdr{ccomplex}% +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 \tref{future.c.headers}. +\begin{multicolfloattable}{C headers}{tab:future.c.headers} +{lllll} +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\columnbreak +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\columnbreak +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\columnbreak +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\columnbreak +\tcode{} \\ +\tcode{} \\ +\end{multicolfloattable} + +\rSec2[depr.complex.h.syn]{Header \tcode{} synopsis} + +\indexhdr{complex.h}% \begin{codeblock} #include \end{codeblock} \pnum -The header \tcode{} +The header \tcode{} behaves as if it simply includes the header \tcode{}\iref{complex.syn}. -\rSec2[depr.cstdalign.syn]{Header \tcode{} synopsis} +\pnum +\begin{note} +Names introduced by \tcode{} in namespace \tcode{std} +are not placed into the global namespace scope by \tcode{}. +\end{note} + +\rSec2[depr.iso646.h.syn]{Header \tcode{} synopsis} + +\indexhdr{iso646.h}% +\pnum +The \Cpp{} header \tcode{} is empty. +\begin{note} +\tcode{and}, +\tcode{and_eq}, +\tcode{bitand}, +\tcode{bitor}, +\tcode{compl}, +\tcode{not_eq}, +\tcode{not}, +\tcode{or}, +\tcode{or_eq}, +\tcode{xor}, and +\tcode{xor_eq} +are keywords in this International Standard\iref{lex.key}. +\end{note} + +\rSec2[depr.stdalign.h.syn]{Header \tcode{} synopsis} \indexlibrary{\idxcode{__alignas_is_defined}}% -\indexhdr{cstdalign}% +\indexhdr{stdalign.h}% \begin{codeblock} #define @\xname{alignas_is_defined}@ 1 \end{codeblock} \pnum -\indexhdr{cstdalign}% \indexhdr{stdalign.h}% -The contents of the header \tcode{} are the same as the C +The contents of the \Cpp{} 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 +The header \tcode{} does not define a macro named \tcode{alignas}. \xrefc{7.15} -\rSec2[depr.cstdbool.syn]{Header \tcode{} synopsis} +\rSec2[depr.stdbool.h.syn]{Header \tcode{} synopsis} -\indexhdr{cstdbool}% +\indexhdr{stdbool.h}% \indexlibrary{\idxcode{__bool_true_false_are_defined}}% \begin{codeblock} #define @\xname{bool_true_false_are_defined}@ 1 @@ -99,89 +210,56 @@ \pnum \indexhdr{stdbool.h}% -The contents of the header \tcode{} are the same as the C +The contents of the \Cpp{} 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 +The header \tcode{} does not define macros named \tcode{bool}, \tcode{true}, or \tcode{false}. \xrefc{7.18} -\rSec2[depr.ctgmath.syn]{Header \tcode{} synopsis} +\rSec2[depr.tgmath.h.syn]{Header \tcode{} synopsis} -\indexhdr{ctgmath}% +\indexhdr{tgmath.h}% \begin{codeblock} -#include #include +#include \end{codeblock} \pnum -The header \tcode{} simply includes the headers -\tcode{}\iref{complex.syn} -and \tcode{}\iref{cmath.syn}. +The header \tcode{} +behaves as if it simply includes the headers +\tcode{}\iref{cmath.syn} and +\tcode{}\iref{complex.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 -\indextext{library!C standard}% -C standard library, the \Cpp{} standard library provides -the \defnx{C headers}{headers!C library} shown in \tref{future.c.headers}. - -\begin{floattable}{C headers}{tab:future.c.headers} -{lllll} -\topline - -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} \\ - -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} \\ - -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} & \\ - -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} & \\ - -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} & \\ - -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} & \\ +\begin{note} +Names introduced by \tcode{} or \tcode{} +in namespace \tcode{std} +are not placed into the global namespace scope by \tcode{}. +\end{note} -\end{floattable} +\rSec2[depr.c.headers.other]{Other C headers} \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 +Every C header +other than +\tcode{}, +\tcode{}, +\tcode{}, +\tcode{}, and +\tcode{}, +each of which has a name of the form \indextext{header!C}% -\tcode{name.h}, +\tcode{<\placeholder{name}.h>}, behaves as if each name placed in the standard library namespace by the corresponding -\tcode{c\textit{name}} +\tcode{} header is placed within the global namespace scope, except for the functions described in \ref{sf.cmath}, @@ -209,7 +287,6 @@ much as in the C Standard. It may also provide these names within the namespace \tcode{std}. \end{example} - \rSec1[depr.relops]{Relational operators} \pnum @@ -239,7 +316,7 @@ \begin{itemdescr} \pnum \requires -Type \tcode{T} is \tcode{EqualityComparable} (\tref{equalitycomparable}). +Type \tcode{T} is \oldconcept{EqualityComparable} (\tref{equalitycomparable}). \pnum \returns @@ -254,7 +331,7 @@ \begin{itemdescr} \pnum \requires -Type \tcode{T} is \tcode{LessThanComparable} (\tref{lessthancomparable}). +Type \tcode{T} is \oldconcept{LessThanComparable} (\tref{lessthancomparable}). \pnum \returns @@ -269,7 +346,7 @@ \begin{itemdescr} \pnum \requires -Type \tcode{T} is \tcode{LessThanComparable} (\tref{lessthancomparable}). +Type \tcode{T} is \oldconcept{LessThanComparable} (\tref{lessthancomparable}). \pnum \returns @@ -284,7 +361,7 @@ \begin{itemdescr} \pnum \requires -Type \tcode{T} is \tcode{LessThanComparable} (\tref{lessthancomparable}). +Type \tcode{T} is \oldconcept{LessThanComparable} (\tref{lessthancomparable}). \pnum \returns @@ -318,7 +395,8 @@ namespace std { class strstreambuf : public basic_streambuf { public: - explicit strstreambuf(streamsize alsize_arg = 0); + strstreambuf() : strstreambuf(0) {} + explicit strstreambuf(streamsize alsize_arg); strstreambuf(void* (*palloc_arg)(size_t), void (*pfree_arg)(void*)); strstreambuf(char* gnext_arg, streamsize n, char* pbeg_arg = nullptr); strstreambuf(const char* gnext_arg, streamsize n); @@ -427,7 +505,7 @@ \indexlibrary{\idxcode{strstreambuf}!constructor}% \begin{itemdecl} -explicit strstreambuf(streamsize alsize_arg = 0); +explicit strstreambuf(streamsize alsize_arg); \end{itemdecl} \begin{itemdescr} @@ -1341,813 +1419,6 @@ \tcode{rdbuf()->pcount()}. \end{itemdescr} -\rSec1[depr.uncaught]{\tcode{uncaught_exception}} - -\pnum -The header -\indexhdr{exception}% -\tcode{} has the following addition: - -\indexlibrary{\idxcode{iterator}}% -\begin{codeblock} -namespace std { - bool uncaught_exception() noexcept; -} -\end{codeblock} - -\indexlibrary{\idxcode{uncaught_exception}}% -\begin{itemdecl} -bool uncaught_exception() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{uncaught_exceptions() > 0}. -\end{itemdescr} - -\rSec1[depr.func.adaptor.binding]{Old adaptable function bindings} - -\rSec2[depr.weak.result_type]{Weak result types} - -\pnum -A call wrapper\iref{func.def} may have a \defn{weak result type}. -If it does, the type of its member type \tcode{result_type} -is based on the type \tcode{T} of the wrapper's target object: -\begin{itemize} -\item if \tcode{T} is a pointer to function type, -\tcode{result_type} shall be a synonym for the return type of \tcode{T}; -\item if \tcode{T} is a pointer to member function, -\tcode{result_type} shall be a synonym for the return type of \tcode{T}; -\item if \tcode{T} is a class type -and the \grammarterm{qualified-id} \tcode{T::result_type} is valid and denotes a type\iref{temp.deduct}, -then \tcode{result_type} shall be a synonym for \tcode{T::result_type}; -\item otherwise \tcode{result_type} shall not be defined. -\end{itemize} - -\rSec2[depr.func.adaptor.typedefs]{Typedefs to support function binders} - -\pnum -To enable old function adaptors to manipulate function objects -that take one or two arguments, -many of the function objects in this document -correspondingly provide \grammarterm{typedef-name}{s} -\tcode{argument_type} and \tcode{result_type} -for function objects that take one argument and -\tcode{first_argument_type}, \tcode{second_argument_type}, and \tcode{result_type} -for function objects that take two arguments. - -\pnum -The following member names are defined in addition to names specified in \ref{function.objects}: - -\indexlibrarymember{result_type}{owner_less}% -\indexlibrarymember{first_argument_type}{owner_less}% -\indexlibrarymember{second_argument_type}{owner_less}% -\indexlibrarymember{result_type}{owner_less}% -\indexlibrarymember{first_argument_type}{owner_less}% -\indexlibrarymember{second_argument_type}{owner_less}% -\indexlibrarymember{result_type}{plus}% -\indexlibrarymember{first_argument_type}{plus}% -\indexlibrarymember{second_argument_type}{plus}% -\indexlibrarymember{result_type}{minus}% -\indexlibrarymember{first_argument_type}{minus}% -\indexlibrarymember{second_argument_type}{minus}% -\indexlibrarymember{result_type}{multiplies}% -\indexlibrarymember{first_argument_type}{multiplies}% -\indexlibrarymember{second_argument_type}{multiplies}% -\indexlibrarymember{result_type}{divides}% -\indexlibrarymember{first_argument_type}{divides}% -\indexlibrarymember{second_argument_type}{divides}% -\indexlibrarymember{result_type}{modulus}% -\indexlibrarymember{first_argument_type}{modulus}% -\indexlibrarymember{second_argument_type}{modulus}% -\indexlibrarymember{result_type}{negate}% -\indexlibrarymember{argument_type}{negate}% -\indexlibrarymember{result_type}{equal_to}% -\indexlibrarymember{first_argument_type}{equal_to}% -\indexlibrarymember{second_argument_type}{equal_to}% -\indexlibrarymember{result_type}{not_equal_to}% -\indexlibrarymember{first_argument_type}{not_equal_to}% -\indexlibrarymember{second_argument_type}{not_equal_to}% -\indexlibrarymember{result_type}{greater}% -\indexlibrarymember{first_argument_type}{greater}% -\indexlibrarymember{second_argument_type}{greater}% -\indexlibrarymember{result_type}{less}% -\indexlibrarymember{first_argument_type}{less}% -\indexlibrarymember{second_argument_type}{less}% -\indexlibrarymember{result_type}{greater_equal}% -\indexlibrarymember{first_argument_type}{greater_equal}% -\indexlibrarymember{second_argument_type}{greater_equal}% -\indexlibrarymember{result_type}{less_equal}% -\indexlibrarymember{first_argument_type}{less_equal}% -\indexlibrarymember{second_argument_type}{less_equal}% -\indexlibrarymember{result_type}{logical_and}% -\indexlibrarymember{first_argument_type}{logical_and}% -\indexlibrarymember{second_argument_type}{logical_and}% -\indexlibrarymember{result_type}{logical_or}% -\indexlibrarymember{first_argument_type}{logical_or}% -\indexlibrarymember{second_argument_type}{logical_or}% -\indexlibrarymember{result_type}{logical_not}% -\indexlibrarymember{argument_type}{logical_not}% -\indexlibrarymember{result_type}{bit_and}% -\indexlibrarymember{first_argument_type}{bit_and}% -\indexlibrarymember{second_argument_type}{bit_and}% -\indexlibrarymember{result_type}{bit_or}% -\indexlibrarymember{first_argument_type}{bit_or}% -\indexlibrarymember{second_argument_type}{bit_or}% -\indexlibrarymember{result_type}{bit_xor}% -\indexlibrarymember{first_argument_type}{bit_xor}% -\indexlibrarymember{second_argument_type}{bit_xor}% -\indexlibrarymember{result_type}{bit_not}% -\indexlibrarymember{argument_type}{bit_not}% -\indexlibrarymember{result_type}{function}% -\indexlibrarymember{argument_type}{function}% -\indexlibrarymember{first_argument_type}{function}% -\indexlibrarymember{second_argument_type}{function}% -\begin{codeblock} -namespace std { - template struct owner_less> { - using result_type = bool; - using first_argument_type = shared_ptr; - using second_argument_type = shared_ptr; - }; - - template struct owner_less> { - using result_type = bool; - using first_argument_type = weak_ptr; - using second_argument_type = weak_ptr; - }; - - template class reference_wrapper { - public: - using result_type = @\seebelow@; // not always defined - using argument_type = @\seebelow@; // not always defined - using first_argument_type = @\seebelow@; // not always defined - using second_argument_type = @\seebelow@; // not always defined - }; - - template struct plus { - using first_argument_type = T; - using second_argument_type = T; - using result_type = T; - }; - - template struct minus { - using first_argument_type = T; - using second_argument_type = T; - using result_type = T; - }; - - template struct multiplies { - using first_argument_type = T; - using second_argument_type = T; - using result_type = T; - }; - - template struct divides { - using first_argument_type = T; - using second_argument_type = T; - using result_type = T; - }; - - template struct modulus { - using first_argument_type = T; - using second_argument_type = T; - using result_type = T; - }; - - template struct negate { - using argument_type = T; - using result_type = T; - }; - - template struct equal_to { - using first_argument_type = T; - using second_argument_type = T; - using result_type = bool; - }; - - template struct not_equal_to { - using first_argument_type = T; - using second_argument_type = T; - using result_type = bool; - }; - - template struct greater { - using first_argument_type = T; - using second_argument_type = T; - using result_type = bool; - }; - - template struct less { - using first_argument_type = T; - using second_argument_type = T; - using result_type = bool; - }; - - template struct greater_equal { - using first_argument_type = T; - using second_argument_type = T; - using result_type = bool; - }; - - template struct less_equal { - using first_argument_type = T; - using second_argument_type = T; - using result_type = bool; - }; - - template struct logical_and { - using first_argument_type = T; - using second_argument_type = T; - using result_type = bool; - }; - - template struct logical_or { - using first_argument_type = T; - using second_argument_type = T; - using result_type = bool; - }; - - template struct logical_not { - using argument_type = T; - using result_type = bool; - }; - - template struct bit_and { - using first_argument_type = T; - using second_argument_type = T; - using result_type = T; - }; - - template struct bit_or { - using first_argument_type = T; - using second_argument_type = T; - using result_type = T; - }; - - template struct bit_xor { - using first_argument_type = T; - using second_argument_type = T; - using result_type = T; - }; - - template struct bit_not { - using argument_type = T; - using result_type = T; - }; - - template class function { - public: - using argument_type = T1; - }; - - template class function { - public: - using first_argument_type = T1; - using second_argument_type = T2; - }; -} -\end{codeblock} - -\indexlibrary{\idxcode{reference_wrapper}!weak result type}% -\pnum -\tcode{reference_wrapper} has a weak result type\iref{depr.weak.result_type}. -If \tcode{T} is a function type, -\tcode{result_type} shall be a synonym for the return type of \tcode{T}. - -\indexlibrarymember{argument_type}{reference_wrapper}% -\pnum -The template specialization \tcode{reference_wrapper} -shall define a nested type named \tcode{argument_type} -as a synonym for \tcode{T1} -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} -\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\iref{temp.deduct}; -the type \tcode{T1} is \tcode{T::argument_type}. -\end{itemize} - -\indexlibrarymember{first_argument_type}{reference_wrapper}% -\indexlibrarymember{second_argument_type}{reference_wrapper}% -\pnum -The template instantiation \tcode{reference_wrapper} -shall define two nested types -named \tcode{first_argument_type} and \tcode{second_argument_type} -as synonyms for \tcode{T1} and \tcode{T2}, respectively, -only if the type \tcode{T} is any of the following: -\begin{itemize} -\item a function type or a pointer to function type taking two arguments of types \tcode{T1} and \tcode{T2} -\item a pointer to member function \tcode{R T0::f(T2)} \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}{s} -\tcode{T::first_argument_type} and \tcode{T::second_argument_type} -are both valid and both denote types\iref{temp.deduct}; -the type \tcode{T1} is \tcode{T::first_argument_type} and -the type \tcode{T2} is \tcode{T::second_argument_type}. -\end{itemize} - -\indexlibrarymember{result_type}{hash}% -\indexlibrarymember{argument_type}{hash}% -\pnum -All enabled specializations \tcode{hash} of \tcode{hash}\iref{unord.hash} -provide two nested types, \tcode{result_type} and \tcode{argument_type}, -which shall be synonyms for \tcode{size_t} and \tcode{Key}, respectively. - -\indexlibrary{\idxcode{bind}!weak result type}% -\pnum -The forwarding call wrapper \tcode{g} -returned by a call to \tcode{bind(f, bound_args...)}\iref{func.bind.bind} -shall have a weak result type\iref{depr.weak.result_type}. - -\pnum -The forwarding call wrapper \tcode{g} -returned by a call to \tcode{bind(f, bound_args...)}\iref{func.bind.bind} -shall have a nested type \tcode{result_type} defined as a synonym for \tcode{R}. - -\indexlibrarymember{result_type}{mem_fn}% -\pnum -The simple call wrapper -returned from a call to \tcode{mem_fn(pm)} -shall have a nested type \tcode{result_type} -that is a synonym for -the return type of \tcode{pm} -when \tcode{pm} is a pointer to member function. - -\indexlibrarymember{result_type}{mem_fn}% -\indexlibrarymember{argument_type}{mem_fn}% -\pnum -The simple call wrapper -returned from a call to \tcode{mem_fn(pm)} -shall define two nested types -named \tcode{argument_type} and \tcode{result_type} -as synonyms for \cv{}~\tcode{T*} and \tcode{Ret}, respectively, -when \tcode{pm} is a pointer to member function -with cv-qualifier \cv{} -and taking no arguments, -where \tcode{Ret} is \tcode{pm}{'s} return type. - -\indexlibrarymember{result_type}{mem_fn}% -\indexlibrarymember{first_argument_type}{mem_fn}% -\indexlibrarymember{second_argument_type}{mem_fn}% -\pnum -The simple call wrapper -returned from a call to \tcode{mem_fn(pm)} -shall define three nested types -named \tcode{first_argument_type}, \tcode{second_argument_type}, and \tcode{result_type} -as synonyms for \cv{}~\tcode{T*}, \tcode{T1}, and \tcode{Ret}, respectively, -when \tcode{pm} is a pointer to member function -with cv-qualifier \cv{} -and taking one argument of type \tcode{T1}, -where \tcode{Ret} is \tcode{pm}{'s} return type. - -\pnum -The following member names are defined in addition to names specified in \ref{containers}: - -\indexlibrarymember{result_type}{map::value_compare}% -\indexlibrarymember{first_argument_type}{map::value_compare}% -\indexlibrarymember{second_argument_type}{map::value_compare}% -\indexlibrarymember{result_type}{multimap::value_compare}% -\indexlibrarymember{first_argument_type}{multimap::value_compare}% -\indexlibrarymember{second_argument_type}{multimap::value_compare}% -\begin{codeblock} -namespace std { - template - class map::value_compare { - public: - using result_type = bool; - using first_argument_type = value_type; - using second_argument_type = value_type; - }; - - template - class multimap::value_compare { - public: - using result_type = bool; - using first_argument_type = value_type; - using second_argument_type = value_type; - }; -} -\end{codeblock} - -\rSec2[depr.negators]{Negators} - -\pnum -The header -\indexhdr{functional}% -\tcode{} has the following additions: - -\indexlibrary{\idxcode{unary_negate}}% -\indexlibrary{\idxcode{not1}}% -\indexlibrary{\idxcode{binary_negate}}% -\indexlibrary{\idxcode{not2}}% -\begin{codeblock} -namespace std { - template class unary_negate; - template - constexpr unary_negate not1(const Predicate&); - template class binary_negate; - template - constexpr binary_negate not2(const Predicate&); -} -\end{codeblock} - -\pnum -Negators \tcode{not1} and \tcode{not2} -take a unary and a binary predicate, respectively, -and return their logical negations\iref{expr.unary.op}. - -\indexlibrary{\idxcode{unary_negate}}% -\indexlibrarymember{argument_type}{unary_negate}% -\indexlibrarymember{result_type}{unary_negate}% -\begin{codeblock} -template -class unary_negate { -public: - constexpr explicit unary_negate(const Predicate& pred); - constexpr bool operator()(const typename Predicate::argument_type& x) const; - using argument_type = typename Predicate::argument_type; - using result_type = bool; -}; -\end{codeblock} - -\indexlibrarymember{operator()}{unary_negate}% -\begin{itemdecl} -constexpr bool operator()(const typename Predicate::argument_type& x) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum \returns \tcode{!pred(x)}. -\end{itemdescr} - -\indexlibrary{\idxcode{not1}}% -\begin{itemdecl} -template - constexpr unary_negate not1(const Predicate& pred); -\end{itemdecl} - -\begin{itemdescr} -\pnum \returns \tcode{unary_negate(pred)}. -\end{itemdescr} - -\indexlibrary{\idxcode{binary_negate}}% -\indexlibrarymember{first_argument_type}{binary_negate}% -\indexlibrarymember{second_argument_type}{binary_negate}% -\indexlibrarymember{result_type}{binary_negate}% -\begin{codeblock} -template -class binary_negate { -public: - constexpr explicit binary_negate(const Predicate& pred); - constexpr bool operator()(const typename Predicate::first_argument_type& x, - const typename Predicate::second_argument_type& y) const; - using first_argument_type = typename Predicate::first_argument_type; - using second_argument_type = typename Predicate::second_argument_type; - using result_type = bool; - -}; -\end{codeblock} - -\indexlibrarymember{operator()}{binary_negate}% -\begin{itemdecl} -constexpr bool operator()(const typename Predicate::first_argument_type& x, - const typename Predicate::second_argument_type& y) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum \returns \tcode{!pred(x,y)}. -\end{itemdescr} - -\indexlibrary{\idxcode{not2}}% -\begin{itemdecl} -template - constexpr binary_negate not2(const Predicate& pred); -\end{itemdecl} - -\begin{itemdescr} -\pnum \returns \tcode{binary_negate(pred)}. -\end{itemdescr} - -\rSec1[depr.default.allocator]{The default allocator} - -\pnum -The following members and explicit class template specialization are defined in -addition to those specified in \ref{default.allocator}: - -\indexlibrary{\idxcode{allocator}}% -\begin{codeblock} -namespace std { - // specialization for \tcode{void} - template<> class allocator { - public: - using value_type = void; - using pointer = void*; - using const_pointer = const void*; - // reference-to-\tcode{void} members are impossible. - - template struct rebind { using other = allocator; }; - }; - - template class allocator { - public: - using size_type = size_t; - using difference_type = ptrdiff_t; - using pointer = T*; - using const_pointer = const T*; - using reference = T&; - using const_reference = const T&; - template struct rebind { using other = allocator; }; - - T* address(T& x) const noexcept; - const T* address(const T& x) const noexcept; - - T* allocate(size_t n, const void* hint); - - template - void construct(U* p, Args&&... args); - template - void destroy(U* p); - - size_t max_size() const noexcept; - }; -} -\end{codeblock} - -\indexlibrarymember{address}{allocator}% -\begin{itemdecl} -T* address(T& x) const noexcept; -const T* address(const T& x) const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{addressof(x)}. -\end{itemdescr} - -\indexlibrarymember{allocate}{allocator}% -\begin{itemdecl} -T* allocate(size_t n, const void* hint); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -A pointer to the initial element of an array of storage of size \tcode{n} -\tcode{* sizeof(T)}, aligned appropriately for objects of type \tcode{T}. -It is \impldef{support for over-aligned types} whether over-aligned types are -supported\iref{basic.align}. - -\pnum -\remarks -The storage is obtained by calling \tcode{::operator new(std::size_t)}\iref{new.delete}, -but it is unspecified when or how often this function is called. - -\pnum -\throws -\tcode{bad_alloc} if the storage cannot be obtained. -\end{itemdescr} - -\indexlibrarymember{construct}{allocator}% -\begin{itemdecl} -template - void construct(U* p, Args&&... args); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -As if by: \tcode{::new((void *)p) U(std::forward(args)...);} -\end{itemdescr} - -\indexlibrarymember{destroy}{allocator}% -\begin{itemdecl} -template - void destroy(U* p); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -As if by \tcode{p->\~{}U()}. -\end{itemdescr} - -\indexlibrarymember{max_size}{allocator}% -\begin{itemdecl} -size_t max_size() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -The largest value \textit{N} for which the call \tcode{allocate(N, 0)} -might succeed. -\end{itemdescr} - -\rSec1[depr.storage.iterator]{Raw storage iterator} - -\pnum -The header -\indexhdr{memory}% -\tcode{} has the following addition: - -\indexlibrary{\idxcode{raw_storage_iterator}}% -\begin{codeblock} -namespace std { - template - class raw_storage_iterator { - public: - using iterator_category = output_iterator_tag; - using value_type = void; - using difference_type = void; - using pointer = void; - using reference = void; - - explicit raw_storage_iterator(OutputIterator x); - - raw_storage_iterator& operator*(); - raw_storage_iterator& operator=(const T& element); - raw_storage_iterator& operator=(T&& element); - raw_storage_iterator& operator++(); - raw_storage_iterator operator++(int); - OutputIterator base() const; - }; -} -\end{codeblock} - -\pnum -\tcode{raw_storage_iterator} is provided to enable algorithms to store their -results into uninitialized memory. The template parameter -\tcode{OutputIterator} is required to have its \tcode{operator*} return an -object for which \tcode{operator\&} is defined and returns a pointer to -\tcode{T}, and is also required to satisfy the requirements of an output -iterator\iref{output.iterators}. - -\indexlibrary{\idxcode{raw_storage_iterator}!constructor}% -\begin{itemdecl} -explicit raw_storage_iterator(OutputIterator x); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Initializes the iterator to point to the same value to which \tcode{x} points. -\end{itemdescr} - -\indexlibrarymember{operator*}{raw_storage_iterator}% -\begin{itemdecl} -raw_storage_iterator& operator*(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{*this} -\end{itemdescr} - -\indexlibrarymember{operator=}{raw_storage_iterator}% -\begin{itemdecl} -raw_storage_iterator& operator=(const T& element); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -\tcode{T} shall be \tcode{CopyConstructible}. - -\pnum -\effects -Constructs a value from \tcode{element} at the location to which the iterator points. - -\pnum -\returns -A reference to the iterator. -\end{itemdescr} - -\indexlibrarymember{operator=}{raw_storage_iterator}% -\begin{itemdecl} -raw_storage_iterator& operator=(T&& element); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -\tcode{T} shall be \tcode{MoveConstructible}. - -\pnum -\effects -Constructs a value from \tcode{std::move(element)} at the location to which -the iterator points. - -\pnum -\returns -A reference to the iterator. -\end{itemdescr} - -\indexlibrarymember{operator++}{raw_storage_iterator}% -\begin{itemdecl} -raw_storage_iterator& operator++(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Pre-increment: advances the iterator and returns a reference to the updated iterator. -\end{itemdescr} - -\indexlibrarymember{operator++}{raw_storage_iterator}% -\begin{itemdecl} -raw_storage_iterator operator++(int); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Post-increment: advances the iterator and returns the old value of the iterator. -\end{itemdescr} - -\indexlibrarymember{base}{raw_storage_iterator}% -\begin{itemdecl} -OutputIterator base() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -An iterator of type \tcode{OutputIterator} that points to the same value as -\tcode{*this} points to. -\end{itemdescr} - -\rSec1[depr.temporary.buffer]{Temporary buffers} - -\pnum -The header -\indexhdr{memory}% -\tcode{} has the following additions: - -\begin{codeblock} -namespace std { - template - pair get_temporary_buffer(ptrdiff_t n) noexcept; - template - void return_temporary_buffer(T* p); -} -\end{codeblock} - -\indexlibrary{\idxcode{get_temporary_buffer}}% -\begin{itemdecl} -template - pair get_temporary_buffer(ptrdiff_t n) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Obtains a pointer to uninitialized, contiguous storage for $N$ adjacent -objects of type \tcode{T}, for some non-negative number $N$. -It is \impldef{support for over-aligned types} whether over-aligned types are -supported\iref{basic.align}. - -\pnum -\remarks -Calling \tcode{get_temporary_buffer} with a positive number \tcode{n} is -a non-binding request to return storage for \tcode{n} objects of type \tcode{T}. -In this case, an implementation is permitted to return instead storage for -a non-negative number $N$ of such objects, -where \tcode{$N$ != n} (including \tcode{$N$ == 0}). -\begin{note} The request is non-binding to allow latitude for -implementation-specific optimizations of its memory management. \end{note} - -\pnum -\returns -If \tcode{n <= 0} or if no storage could be obtained, -returns a pair \tcode{P} such that -\tcode{P.first} is a null pointer value and \tcode{P.second == 0}; -otherwise returns a pair \tcode{P} such that -\tcode{P.first} refers to the address of the uninitialized storage and -\tcode{P.second} refers to its capacity $N$ (in the units of \tcode{sizeof(T)}). -\end{itemdescr} - -\indexlibrary{\idxcode{return_temporary_buffer}}% -\begin{itemdecl} -template void return_temporary_buffer(T* p); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Deallocates the storage referenced by \tcode{p}. - -\pnum -\requires -\tcode{p} shall be a pointer value returned by an earlier call to -\tcode{get_temporary_buffer} that has not been invalidated by -an intervening call to \tcode{return_temporary_buffer(T*)}. - -\pnum -\throws -Nothing. -\end{itemdescr} - \rSec1[depr.meta.types]{Deprecated type traits} \pnum @@ -2158,13 +1429,6 @@ \indexlibrary{\idxcode{is_literal_type}}% \begin{codeblock} namespace std { - template struct is_literal_type; - template inline constexpr bool is_literal_type_v = is_literal_type::value; - - template struct result_of; // not defined - template struct result_of; - template using result_of_t = typename result_of::type; - template struct is_pod; template inline constexpr bool is_pod_v = is_pod::value; } @@ -2175,39 +1439,6 @@ any of the templates defined in this subclause is undefined, unless explicitly permitted by the specification of the corresponding template. -\begin{itemdecl} -template struct is_literal_type; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -\tcode{remove_all_extents_t} shall be a complete type or \cv{}~\tcode{void}. - -\pnum -\tcode{is_literal_type} is a \tcode{UnaryTypeTrait}\iref{meta.rqmts} -with a base characteristic of \tcode{true_type} -if \tcode{T} is a literal type\iref{basic.types}, and -\tcode{false_type} otherwise. -\end{itemdescr} - -\begin{itemdecl} -template struct result_of; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -\tcode{Fn} and all types in the template parameter pack \tcode{ArgTypes} shall be complete types, -\cv{}~\tcode{void}, or arrays of unknown bound. - -\pnum -The partial specialization \tcode{result_of} is a -\tcode{TransformationTrait}\iref{meta.rqmts} whose member typedef \tcode{type} is defined -if and only if \tcode{invoke_result::type}\iref{func.invoke} is defined. -If \tcode{type} is defined, it names the same type as \tcode{invoke_result_t}. -\end{itemdescr} - \begin{itemdecl} template struct is_pod; \end{itemdecl} @@ -2218,7 +1449,7 @@ \tcode{remove_all_extents_t} shall be a complete type or \cv{} \tcode{void}. \pnum -\tcode{is_pod} is a \tcode{UnaryTypeTrait}\iref{meta.rqmts} +\tcode{is_pod} is a \oldconcept{UnaryTypeTrait}\iref{meta.rqmts} with a base characteristic of \tcode{true_type} if \tcode{T} is a POD type, and \tcode{false_type} otherwise. @@ -2283,31 +1514,6 @@ \end{codeblock} \end{example} -\rSec1[depr.util.smartptr.shared.obs]{Deprecated \tcode{shared_ptr} observers} - -\pnum -The following member is defined in addition to those members specified -in \ref{util.smartptr.shared}: - -\indexlibrary{\idxcode{shared_ptr}}% -\begin{codeblock} -namespace std { - template class shared_ptr { - public: - bool unique() const noexcept; - }; -} -\end{codeblock} - -\indexlibrarymember{unique}{shared_ptr}% -\begin{itemdecl} -bool unique() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum\returns \tcode{use_count() == 1}. -\end{itemdescr} - \rSec1[depr.util.smartptr.shared.atomic]{Deprecated \tcode{shared_ptr} atomic access} \pnum @@ -2654,7 +1860,7 @@ \begin{itemize} \item The facet shall convert between UTF-8 multibyte sequences - and UCS2 or UCS4 (depending on the size of \tcode{Elem}) + and UCS-2 or UTF-32 (depending on the size of \tcode{Elem}) within the program. \item Endianness shall not affect how multibyte sequences are read or written. @@ -2667,7 +1873,7 @@ \begin{itemize} \item The facet shall convert between UTF-16 multibyte sequences - and UCS2 or UCS4 (depending on the size of \tcode{Elem}) + and UCS-2 or UTF-32 (depending on the size of \tcode{Elem}) within the program. \item Multibyte sequences shall be read or written @@ -2689,7 +1895,9 @@ The multibyte sequences may be written as either a text or a binary file. \end{itemize} -\xref ISO/IEC 10646-1:1993. +\pnum +The encoding forms UTF-8, UTF-16, and UTF-32 are specified in ISO/IEC 10646. +The encoding form UCS-2 is specified in ISO/IEC 10646-1:1993. \rSec1[depr.conversions]{Deprecated convenience conversion interfaces} @@ -2739,7 +1947,8 @@ 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() : wstring_convert(new Codecvt) {} + explicit wstring_convert(Codecvt* pcvt); wstring_convert(Codecvt* pcvt, state_type state); explicit wstring_convert(const byte_string& byte_err, const wide_string& wide_err = wide_string()); @@ -2933,7 +2142,7 @@ \indexlibrary{\idxcode{wstring_convert}!constructor}% \begin{itemdecl} -explicit wstring_convert(Codecvt* pcvt = new Codecvt); +explicit wstring_convert(Codecvt* pcvt); wstring_convert(Codecvt* pcvt, state_type state); explicit wstring_convert(const byte_string& byte_err, const wide_string& wide_err = wide_string()); @@ -2987,7 +2196,8 @@ public: using state_type = typename Codecvt::state_type; - explicit wbuffer_convert(streambuf* bytebuf = nullptr, + wbuffer_convert() : wbuffer_convert(nullptr) {} + explicit wbuffer_convert(streambuf* bytebuf, Codecvt* pcvt = new Codecvt, state_type state = state_type()); @@ -3074,7 +2284,7 @@ \indexlibrary{\idxcode{wbuffer_convert}!constructor}% \begin{itemdecl} explicit wbuffer_convert( - streambuf* bytebuf = nullptr, + streambuf* bytebuf, Codecvt* pcvt = new Codecvt, state_type state = state_type()); \end{itemdecl} diff --git a/source/intro.tex b/source/intro.tex index d8d103fff0..d1564c0661 100644 --- a/source/intro.tex +++ b/source/intro.tex @@ -50,6 +50,8 @@ \item ISO/IEC 9899:2011, \doccite{Programming languages --- C} \item ISO/IEC 9945:2003, \doccite{Information Technology --- Portable Operating System Interface (POSIX)} +\item ISO/IEC 10646, \doccite{Information technology --- +Universal Coded Character Set (UCS)} \item ISO/IEC 10646-1:1993, \doccite{Information technology --- Universal Multiple-Octet Coded Character Set (UCS) --- Part 1: Architecture and Basic Multilingual Plane} @@ -77,6 +79,12 @@ hereinafter called \defn{ECMA-262}. \indextext{references!normative|)} +\pnum +\begin{note} +References to ISO/IEC 10646-1:1993 are used only +to support deprecated features\iref{depr.locale.stdcvt}. +\end{note} + \rSec0[intro.defs]{Terms and definitions} \pnum @@ -93,7 +101,7 @@ for use in standardization at the following addresses: \begin{itemize} -\item ISO Online browsing platform: available at \url{http://www.iso.org/obp} +\item ISO Online browsing platform: available at \url{https://www.iso.org/obp} \item IEC Electropedia: available at \url{http://www.electropedia.org/} \end{itemize} @@ -477,8 +485,8 @@ side effects affecting the observable behavior of the program are produced.} -\indextext{behavior!implementation-defined}% \pnum +\indextext{behavior!implementation-defined}% Certain aspects and operations of the abstract machine are described in this document as implementation-defined (for example, \tcode{sizeof(int)}). These constitute the parameters of the abstract machine. @@ -489,8 +497,8 @@ abstract machine that corresponds to that implementation (referred to as the ``corresponding instance'' below). -\indextext{behavior!unspecified}% \pnum +\indextext{behavior!unspecified}% Certain other aspects and operations of the abstract machine are described in this document as unspecified (for example, order of evaluation of arguments in a function call\iref{expr.call}). @@ -500,17 +508,17 @@ of the abstract machine can thus have more than one possible execution for a given program and a given input. -\indextext{behavior!undefined}% \pnum +\indextext{behavior!undefined}% Certain other operations are described in this document as undefined (for example, the effect of attempting to modify a const object). \begin{note} This document imposes no requirements on the behavior of programs that contain undefined behavior. \end{note} +\pnum \indextext{program!well-formed}% \indextext{behavior!observable}% -\pnum 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 @@ -521,8 +529,8 @@ (not even with regard to operations preceding the first undefined operation). -\indextext{conformance requirements} \pnum +\indextext{conformance requirements}% The least requirements on a conforming implementation are: \begin{itemize} \item diff --git a/source/iostreams.tex b/source/iostreams.tex index bde3cbbf1f..2bebcfeb3a 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -1105,7 +1105,9 @@ class ios_base::Init { public: Init(); + Init(const Init&) = default; ~Init(); + Init& operator=(const Init&) = default; private: static int init_cnt; // \expos }; @@ -1436,6 +1438,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\requires +\tcode{idx} is a value obtained by a call to \tcode{xalloc}. + \pnum \effects If \tcode{iarray} is a null pointer, allocates an array of @@ -1482,6 +1488,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\requires +\tcode{idx} is a value obtained by a call to \tcode{xalloc}. + \pnum \effects If \tcode{parray} is a null pointer, allocates an array of @@ -1647,15 +1657,37 @@ \pnum \indexlibrary{\idxcode{fpos}}% \indexlibrary{\idxcode{streamoff}}% -Operations specified in \tref{iostreams.position.requirements} are permitted. +An \tcode{fpos} type specifies file position information. +It holds a state object +whose type is equal to the template parameter \tcode{stateT}. +Type \tcode{stateT} shall meet +the \oldconcept{DefaultConstructible} (\tref{defaultconstructible}), +\oldconcept{CopyConstructible} (\tref{copyconstructible}), +\oldconcept{CopyAssignable} (\tref{copyassignable}), and +\oldconcept{Destructible} (\tref{destructible}) requirements. +If \tcode{is_trivially_copy_constructible_v} is \tcode{true}, +then \tcode{fpos} has a trivial copy constructor. +If \tcode{is_trivially_copy_assignable} is \tcode{true}, +then \tcode{fpos} has a trivial copy assignment operator. +If \tcode{is_trivially_destructible_v} is \tcode{true}, +then \tcode{fpos} has a trivial destructor. +All specializations of \tcode{fpos} satisfy +the \oldconcept{DefaultConstructible}, +\oldconcept{CopyConstructible}, +\oldconcept{CopyAssignable}, +\oldconcept{Destructible}, +and \oldconcept{EqualityComparable} (\tref{equalitycomparable}) requirements. +In addition, the expressions shown in \tref{iostreams.position.requirements} +are valid and have the indicated semantics. In that table, \begin{itemize} \item \tcode{P} refers to an instance of \tcode{fpos}, -\item \tcode{p} and \tcode{q} refer to values of type \tcode{P}, -\item \tcode{O} refers to type \tcode{streamoff}, -\item \tcode{o} refers to a value of type \tcode{streamoff}, -\item \tcode{sz} refers to a value of type \tcode{streamsize} and -\item \tcode{i} refers to a value of type \tcode{int}. +\item \tcode{p} and \tcode{q} refer to values +of type \tcode{P} or \tcode{const P}, +\item \tcode{pl} and \tcode{ql} refer to modifiable lvalues of type \tcode{P}, +\item \tcode{O} refers to type \tcode{streamoff}, and +\item \tcode{o} refers to a value +of type \tcode{streamoff} or \tcode{const streamoff}. \end{itemize} \begin{libreqtab4c} @@ -1670,65 +1702,59 @@ \lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep \endhead -\tcode{P(i)} & - & - & - \tcode{p == P(i)}\br - note: a destructor is assumed. \\ \rowsep -\tcode{P p(i);}\br -\tcode{P p = i;} & - & - & - \postconditions \tcode{p == P(i)}. \\ \rowsep \tcode{P(o)} & - \tcode{fpos} & - converts from \tcode{offset} & \\ \rowsep + \tcode{P} & + converts from \tcode{offset} & + \effects Value-initializes the state object. \\ \rowsep +\tcode{P p(o);}\br +\tcode{P p = o;} & + & + & + \effects Value-initializes the state object. \br + \postconditions \tcode{p == P(o)} \\ \rowsep +\tcode{P()} & + \tcode{P} & + \tcode{P(0)} & + \\ \rowsep +\tcode{P p;} & + & + \tcode{P p(0);} & + \\ \rowsep \tcode{O(p)} & \tcode{streamoff} & converts to \tcode{offset} & \tcode{P(O(p)) == p} \\ \rowsep -\tcode{p == q} & - convertible to \tcode{bool} & - & - \tcode{==} is an equivalence relation \\ \rowsep \tcode{p != q} & convertible to \tcode{bool} & \tcode{!(p == q)} & \\ \rowsep -\tcode{q = p + o}\br -\tcode{p += o} & - \tcode{fpos} & +\tcode{p + o} & + \tcode{P} & \tcode{+} offset & - \tcode{q - o == p} \\ \rowsep -\tcode{q = p - o}\br -\tcode{p -= o} & - \tcode{fpos} & + \remarks With \tcode{ql = p + o;}, then: \tcode{ql - o == p} \\ \rowsep +\tcode{pl += o} & + \tcode{P\&} & + \tcode{+=} offset & + \remarks With \tcode{ql = pl;} before the \tcode{+=}, then: + \tcode{pl - o == ql} \\ \rowsep +\tcode{p - o} & + \tcode{P} & \tcode{-} offset & - \tcode{q + o == p} \\ \rowsep -\tcode{o = p - q} & + \remarks With \tcode{ql = p - o;}, then: \tcode{ql + o == p} \\ \rowsep +\tcode{pl -= o} & + \tcode{P\&} & + \tcode{-=} offset & + \remarks With \tcode{ql = pl;} before the \tcode{-=}, then: + \tcode{pl + o == ql} \\ \rowsep +\tcode{o + p} & + convertible to \tcode{P} & + \tcode{p + o} & + \tcode{P(o + p) == p + o} \\ \rowsep +\tcode{p - q} & \tcode{streamoff} & distance & - \tcode{q + o == p} \\ \rowsep -\tcode{streamsize(o)}\br -\tcode{O(sz)} & - \tcode{streamsize}\br - \tcode{streamoff} & - converts\br - converts & - \tcode{streamsize(O(sz)) == sz}\br - \tcode{streamsize(O(sz)) == sz} \\ + \tcode{p == q + (p - q)} \\ \rowsep \end{libreqtab4c} -\pnum -\begin{note} -Every implementation is required to supply overloaded operators on -\tcode{fpos} -objects to satisfy the requirements of~\ref{fpos.operations}. -It is unspecified whether these operators are members of -\tcode{fpos}, -global operators, -or provided in some other way. -\end{note} - \pnum Stream operations that return a value of type \tcode{traits::pos_type} @@ -7347,8 +7373,8 @@ using allocator_type = Allocator; // \ref{stringbuf.cons}, constructors - explicit basic_stringbuf( - ios_base::openmode which = ios_base::in | ios_base::out); + basic_stringbuf() : basic_stringbuf(ios_base::in | ios_base::out) {} + explicit basic_stringbuf(ios_base::openmode which); explicit basic_stringbuf( const basic_string& str, ios_base::openmode which = ios_base::in | ios_base::out); @@ -7415,8 +7441,7 @@ \indexlibrary{\idxcode{basic_stringbuf}!constructor}% \begin{itemdecl} -explicit basic_stringbuf( - ios_base::openmode which = ios_base::in | ios_base::out); +explicit basic_stringbuf(ios_base::openmode which); \end{itemdecl} \begin{itemdescr} @@ -7867,8 +7892,8 @@ using allocator_type = Allocator; // \ref{istringstream.cons}, constructors - explicit basic_istringstream( - ios_base::openmode which = ios_base::in); + basic_istringstream() : basic_istringstream(ios_base::in) {} + explicit basic_istringstream(ios_base::openmode which); explicit basic_istringstream( const basic_string& str, ios_base::openmode which = ios_base::in); @@ -7913,7 +7938,7 @@ \indexlibrary{\idxcode{basic_istringstream}!constructor}% \begin{itemdecl} -explicit basic_istringstream(ios_base::openmode which = ios_base::in); +explicit basic_istringstream(ios_base::openmode which); \end{itemdecl} \begin{itemdescr} @@ -7924,7 +7949,7 @@ initializing the base class with \tcode{basic_istream(\&sb)}\iref{istream} and initializing \tcode{sb} with -\tcode{basic_string\-buf(which | ios_base::in))}\iref{stringbuf.cons}. +\tcode{basic_string\-buf(which | ios_base::in)}\iref{stringbuf.cons}. \end{itemdescr} \indexlibrary{\idxcode{basic_istringstream}!constructor}% @@ -7942,7 +7967,7 @@ initializing the base class with \tcode{basic_istream(\&sb)}\iref{istream} and initializing \tcode{sb} with -\tcode{basic_string\-buf(str, which | ios_base::in))}\iref{stringbuf.cons}. +\tcode{basic_string\-buf(str, which | ios_base::in)}\iref{stringbuf.cons}. \end{itemdescr} \indexlibrary{\idxcode{basic_istringstream}!constructor}% @@ -8054,8 +8079,8 @@ using allocator_type = Allocator; // \ref{ostringstream.cons}, constructors - explicit basic_ostringstream( - ios_base::openmode which = ios_base::out); + basic_ostringstream() : basic_ostringstream(ios_base::out) {} + explicit basic_ostringstream(ios_base::openmode which); explicit basic_ostringstream( const basic_string& str, ios_base::openmode which = ios_base::out); @@ -8100,8 +8125,7 @@ \indexlibrary{\idxcode{basic_ostringstream}!constructor}% \begin{itemdecl} -explicit basic_ostringstream( - ios_base::openmode which = ios_base::out); +explicit basic_ostringstream(ios_base::openmode which); \end{itemdecl} \begin{itemdescr} @@ -8112,7 +8136,7 @@ initializing the base class with \tcode{basic_ostream(\&sb)}\iref{ostream} and initializing \tcode{sb} with -\tcode{basic_string\-buf(which | ios_base::out))}\iref{stringbuf.cons}. +\tcode{basic_string\-buf(which | ios_base::out)}\iref{stringbuf.cons}. \end{itemdescr} \indexlibrary{\idxcode{basic_ostringstream}!constructor}% @@ -8130,7 +8154,7 @@ initializing the base class with \tcode{basic_ostream(\&sb)}\iref{ostream} and initializing \tcode{sb} with -\tcode{basic_string\-buf(str, which | ios_base::out))}\iref{stringbuf.cons}. +\tcode{basic_string\-buf(str, which | ios_base::out)}\iref{stringbuf.cons}. \end{itemdescr} \indexlibrary{\idxcode{basic_ostringstream}!constructor}% @@ -8242,8 +8266,8 @@ using allocator_type = Allocator; // \ref{stringstream.cons}, constructors - explicit basic_stringstream( - ios_base::openmode which = ios_base::out | ios_base::in); + basic_stringstream() : basic_stringstream(ios_base::out | ios_base::in) {} + explicit basic_stringstream(ios_base::openmode which); explicit basic_stringstream( const basic_string& str, ios_base::openmode which = ios_base::out | ios_base::in); @@ -8289,8 +8313,7 @@ \indexlibrary{\idxcode{basic_stringstream}!constructor}% \begin{itemdecl} -explicit basic_stringstream( - ios_base::openmode which = ios_base::out | ios_base::in); +explicit basic_stringstream(ios_base::openmode which); \end{itemdecl} \begin{itemdescr} @@ -9334,7 +9357,7 @@ initializing the base class with \tcode{basic_istream(\&sb)}\iref{istream.cons} and initializing \tcode{sb} with -\tcode{basic_filebuf())}\iref{filebuf.cons}. +\tcode{basic_filebuf()}\iref{filebuf.cons}. \end{itemdescr} \indexlibrary{\idxcode{basic_ifstream}!constructor}% @@ -9353,7 +9376,7 @@ initializing the base class with \tcode{basic_istream(\&sb)}\iref{istream.cons} and initializing \tcode{sb} with -\tcode{basic_filebuf())}\iref{filebuf.cons}, +\tcode{basic_filebuf()}\iref{filebuf.cons}, then calls \tcode{rdbuf()->open(s, mode | ios_base::in)}. If that function returns a null pointer, calls @@ -9582,7 +9605,7 @@ initializing the base class with \tcode{basic_ostream(\&sb)}\iref{ostream.cons} and initializing \tcode{sb} with -\tcode{basic_filebuf())}\iref{filebuf.cons}. +\tcode{basic_filebuf()}\iref{filebuf.cons}. \end{itemdescr} \indexlibrary{\idxcode{basic_ofstream}!constructor}% @@ -9601,7 +9624,7 @@ initializing the base class with \tcode{basic_ostream(\&sb)}\iref{ostream.cons} and initializing \tcode{sb} with -\tcode{basic_filebuf())}\iref{filebuf.cons}, +\tcode{basic_filebuf()}\iref{filebuf.cons}, then calls \tcode{rdbuf()->open(s, mode | ios_base::out)}. If that function returns a null pointer, calls @@ -10418,7 +10441,7 @@ \end{codeblock} \pnum -\tcode{Allocator} shall satisfy the \tcode{Allocator} requirements +\tcode{Allocator} shall satisfy the \oldconcept{Allocator} requirements (\tref{utilities.allocator.requirements}). \pnum @@ -10750,7 +10773,7 @@ \pnum Template parameters named \tcode{InputIterator} shall satisfy the -input iterator requirements\iref{input.iterators} and shall +\oldconcept{InputIterator} requirements\iref{input.iterators} and shall have a value type that is one of the encoded character types. \pnum @@ -10762,7 +10785,7 @@ \pnum Template parameters named \tcode{Allocator} shall satisfy the -\tcode{Allocator} requirements (\tref{utilities.allocator.requirements}). +\oldconcept{Allocator} requirements (\tref{utilities.allocator.requirements}). \rSec3[fs.req.namespace]{Namespaces and headers} @@ -10987,7 +11010,7 @@ \pnum \tcode{\textit{trivial-clock}} is an \impldef{type of filesystem trivial clock} type -that satisfies the \tcode{TrivialClock} requirements\iref{time.clock.req} +that satisfies the \oldconcept{TrivialClock} requirements\iref{time.clock.req} and that is capable of representing and measuring file time values. Implementations should ensure that the resolution and range of \tcode{file_time_type} reflect the operating system dependent resolution and range @@ -11550,7 +11573,7 @@ \item \tcode{basic_string_view}. A function argument \tcode{const Source\&} \tcode{source} shall have an effective range \range{source.begin()}{source.end()}. -\item A type meeting the input iterator requirements that iterates over a NTCTS. +\item A type meeting the \oldconcept{InputIterator} requirements that iterates over a NTCTS. The value type shall be an encoded character type. A function argument \tcode{const Source\&} \tcode{source} shall have an effective range \range{source}{end} where \tcode{end} is the first @@ -13865,8 +13888,8 @@ \end{codeblock} \pnum - \tcode{directory_iterator} satisfies the requirements of an input -iterator\iref{input.iterators}. + \tcode{directory_iterator} satisfies the + \oldconcept{InputIterator} requirements\iref{input.iterators}. \pnum If an iterator of type \tcode{directory_iterator} reports an error or @@ -14337,6 +14360,11 @@ Otherwise, cease iteration of the directory currently being iterated over, and continue iteration over the parent directory. +\pnum +\postconditions Any copies of the previous value of \tcode{*this} +are no longer required +to be dereferenceable nor to be in the domain of \tcode{==}. + \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} @@ -14795,11 +14823,11 @@ \begin{itemdescr} \pnum -\effects Establishes the postcondition by attempting to create the +\effects Creates the directory \tcode{p} resolves to, with attributes copied from directory \tcode{existing_p}. The set of attributes - copied is operating system dependent. Creation failure because \tcode{p} resolves to an existing directory shall not be - treated as an error. + copied is operating system dependent. + Creation failure because \tcode{p} already exists is not an error. \begin{note} For POSIX-based operating systems, the attributes are those copied by native API \tcode{stat(existing_p.c_str(), \&attributes_stat)} followed by \tcode{mkdir(p.c_str(), attributes_stat.st_mode)}. For @@ -14807,9 +14835,6 @@ API \tcode{CreateDirectoryExW(existing_p.c_str(), p.c_str(), 0)}. \end{note} -\pnum -\postconditions \tcode{is_directory(p)}. - \pnum \returns \tcode{true} if a new directory was created, otherwise \tcode{false}. The signature with argument \tcode{ec} returns \tcode{false} if an error occurs. diff --git a/source/iterators.tex b/source/iterators.tex index 02d8434837..2d86d12ff4 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -75,12 +75,12 @@ This document defines five categories of iterators, according to the operations defined on them: -\techterm{input iterators}, -\techterm{output iterators}, -\techterm{forward iterators}, -\techterm{bidirectional iterators} +\term{input iterators}, +\term{output iterators}, +\term{forward iterators}, +\term{bidirectional iterators} and -\techterm{random access iterators}, +\term{random access iterators}, as shown in \tref{iterators.relations}. \begin{floattable}{Relations among iterator categories}{tab:iterators.relations} @@ -156,7 +156,7 @@ the only exceptions are destroying an iterator that holds a singular value, the assignment of a non-singular value to an iterator that holds a singular value, and, for iterators that satisfy the -\tcode{DefaultConstructible} requirements, using a value-initialized iterator +\oldconcept{DefaultConstructible} requirements, using a value-initialized iterator as the source of a copy or move operation. \begin{note} This guarantee is not offered for default-initialization, although the distinction only matters for types with trivial default constructors such as pointers or aggregates holding pointers. @@ -216,19 +216,18 @@ \pnum An -\techterm{invalid} +\term{invalid} iterator is an iterator that may be singular.\footnote{This definition applies to pointers, since pointers are iterators. The effect of dereferencing an iterator that has been invalidated is undefined. } \pnum -\indextext{iterator!constexpr} +\indextext{iterator!constexpr}% Iterators are called \defn{constexpr iterators} if all operations provided to satisfy iterator category operations are constexpr functions, except for \begin{itemize} -\item \tcode{swap}, \item a pseudo-destructor call\iref{expr.pseudo}, and \item the construction of an iterator with a singular value. \end{itemize} @@ -238,7 +237,7 @@ \end{note} \pnum -In the following sections, +In the following subclauses, \tcode{a} and \tcode{b} @@ -266,11 +265,11 @@ \begin{note} For an iterator type \tcode{X} there must be an instantiation of \tcode{iterator_traits}\iref{iterator.traits}. \end{note} -\rSec2[iterator.iterators]{Iterator} +\rSec2[iterator.iterators]{\oldconcept{Iterator}} \pnum -The \tcode{Iterator} requirements form the basis of the iterator -taxonomy; every iterator satisfies the \tcode{Iterator} requirements. This +The \oldconcept{Iterator} requirements form the basis of the iterator +taxonomy; every iterator satisfies the \oldconcept{Iterator} requirements. This set of requirements specifies operations for dereferencing and incrementing an iterator. Most algorithms will require additional operations to read\iref{input.iterators} or write\iref{output.iterators} values, or @@ -278,11 +277,11 @@ \ref{bidirectional.iterators}, \ref{random.access.iterators}). \pnum -A type \tcode{X} satisfies the \tcode{Iterator} requirements if: +A type \tcode{X} satisfies the \oldconcept{Iterator} requirements if: \begin{itemize} -\item \tcode{X} satisfies the \tcode{CopyConstructible}, \tcode{CopyAssignable}, and -\tcode{Destructible} requirements\iref{utility.arg.requirements} and lvalues +\item \tcode{X} satisfies the \oldconcept{CopyConstructible}, \oldconcept{CopyAssignable}, and +\oldconcept{Destructible} requirements\iref{utility.arg.requirements} and lvalues of type \tcode{X} are swappable\iref{swappable.requirements}, and \item the expressions in \tref{iterator.requirements} are valid and have @@ -290,7 +289,7 @@ \end{itemize} \begin{libreqtab4b} -{Iterator requirements} +{\oldconcept{Iterator} requirements} {tab:iterator.requirements} \\ \topline \lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ @@ -322,14 +321,14 @@ satisfies the requirements of an input iterator for the value type \tcode{T} if -\tcode{X} satisfies the \tcode{Iterator}\iref{iterator.iterators} and -\tcode{EqualityComparable} (\tref{equalitycomparable}) requirements and +\tcode{X} satisfies the \oldconcept{Iterator}\iref{iterator.iterators} and +\oldconcept{EqualityComparable} (\tref{equalitycomparable}) requirements and the expressions in \tref{iterator.input.requirements} are valid and have the indicated semantics. \pnum In \tref{iterator.input.requirements}, the term -\techterm{the domain of \tcode{==}} +\term{the domain of \tcode{==}} is used in the ordinary mathematical sense to denote the set of values over which \tcode{==} is (required to be) defined. @@ -357,7 +356,7 @@ \end{example} \begin{libreqtab4b} -{Input iterator requirements (in addition to Iterator)} +{\oldconcept{InputIterator} requirements (in addition to \oldconcept{Iterator})} {tab:iterator.input.requirements} \\ \topline \lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ @@ -390,7 +389,7 @@ \requires \tcode{r} is dereferenceable.\br \postconditions \tcode{r} is dereferenceable or \tcode{r} is past-the-end;\br any copies of the previous value of \tcode{r} are no longer - required either to be dereferenceable or to be in the domain of \tcode{==}. \\ \rowsep + required to be dereferenceable nor to be in the domain of \tcode{==}. \\ \rowsep \tcode{(void)r++} & & @@ -415,7 +414,7 @@ They should be \term{single pass} algorithms. -Value type \tcode{T} is not required to be a \tcode{CopyAssignable} type (\tref{copyassignable}). +Value type \tcode{T} is not required to be a \oldconcept{CopyAssignable} type (\tref{copyassignable}). These algorithms can be used with istreams as the source of the input data through the \tcode{istream_iterator} class template. @@ -427,12 +426,12 @@ A class or pointer type \tcode{X} satisfies the requirements of an output iterator -if \tcode{X} satisfies the \tcode{Iterator} requirements\iref{iterator.iterators} +if \tcode{X} satisfies the \oldconcept{Iterator} requirements\iref{iterator.iterators} and the expressions in \tref{iterator.output.requirements} are valid and have the indicated semantics. \begin{libreqtab4b} -{Output iterator requirements (in addition to Iterator)} +{\oldconcept{OutputIterator} requirements (in addition to \oldconcept{Iterator})} {tab:iterator.output.requirements} \\ \topline \lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ @@ -481,10 +480,6 @@ \term{single pass} algorithms. Equality and inequality might not be defined. -Algorithms that take output iterators can be used with ostreams as the destination -for placing data through the -\tcode{ostream_iterator} -class as well as with insert iterators and insert pointers. \end{note} \rSec2[forward.iterators]{Forward iterators} @@ -495,9 +490,9 @@ satisfies the requirements of a forward iterator if \begin{itemize} -\item \tcode{X} satisfies the requirements of an input iterator\iref{input.iterators}, +\item \tcode{X} satisfies the \oldconcept{InputIterator} requirements\iref{input.iterators}, -\item \tcode{X} satisfies the \tcode{DefaultConstructible} +\item \tcode{X} satisfies the \oldconcept{DefaultConstructible} requirements\iref{utility.arg.requirements}, \item if \tcode{X} is a mutable iterator, \tcode{reference} is a reference to \tcode{T}; @@ -540,7 +535,7 @@ \end{note} \begin{libreqtab4b} -{Forward iterator requirements (in addition to input iterator)} +{\oldconcept{ForwardIterator} requirements (in addition to \oldconcept{InputIterator})} {tab:iterator.forward.requirements} \\ \topline \lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ @@ -577,11 +572,11 @@ A class or pointer type \tcode{X} satisfies the requirements of a bidirectional iterator if, -in addition to satisfying the requirements for forward iterators, +in addition to satisfying the \oldconcept{ForwardIterator} requirements, the following expressions are valid as shown in \tref{iterator.bidirectional.requirements}. \begin{libreqtab4b} -{Bidirectional iterator requirements (in addition to forward iterator)} +{\oldconcept{BidirectionalIterator} requirements (in addition to \oldconcept{ForwardIterator})} {tab:iterator.bidirectional.requirements} \\ \topline \lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ @@ -622,11 +617,11 @@ A class or pointer type \tcode{X} satisfies the requirements of a random access iterator if, -in addition to satisfying the requirements for bidirectional iterators, +in addition to satisfying the \oldconcept{BidirectionalIterator} requirements, the following expressions are valid as shown in \tref{iterator.random.access.requirements}. \begin{libreqtab4b} -{Random access iterator requirements (in addition to bidirectional iterator)} +{\oldconcept{RandomAccessIterator} requirements (in addition to \oldconcept{BidirectionalIterator})} {tab:iterator.random.access.requirements} \\ \topline \lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ @@ -992,7 +987,7 @@ argument, so that the function can select the most efficient algorithm at compile time. To facilitate this, the library introduces -\techterm{category tag} +\term{category tag} classes which are used as compile time tags for algorithm selection. They are: \tcode{input_iterator_tag}, @@ -1128,7 +1123,7 @@ \begin{itemdescr} \pnum \effects -If \tcode{InputIterator} meets the requirements of random access iterator, +If \tcode{InputIterator} meets the \oldconcept{RandomAccessIterator} requirements, returns \tcode{(last - first)}; otherwise, returns the number of increments needed to get from \tcode{first} @@ -1137,7 +1132,7 @@ \pnum \requires -If \tcode{InputIterator} meets the requirements of random access iterator, +If \tcode{InputIterator} meets the \oldconcept{RandomAccessIterator} requirements, \tcode{last} shall be reachable from \tcode{first} or \tcode{first} shall be reachable from \tcode{last}; otherwise, \tcode{last} @@ -1262,12 +1257,12 @@ \pnum The template parameter \tcode{Iterator} -shall satisfy all the requirements of a Bidirectional Iterator\iref{bidirectional.iterators}. +shall satisfy all the requirements of a \oldconcept{BidirectionalIterator}\iref{bidirectional.iterators}. \pnum Additionally, \tcode{Iterator} -shall satisfy the requirements of a random access iterator\iref{random.access.iterators} +shall satisfy the requirements of a \oldconcept{RandomAccessIterator}\iref{random.access.iterators} if any of the members \tcode{operator+}, \tcode{operator-}, @@ -1647,7 +1642,7 @@ \pnum To make it possible to deal with insertion in the same way as writing into an array, a special kind of iterator adaptors, called -\techterm{insert iterators}, +\term{insert iterators}, are provided in the library. With regular iterator classes, @@ -1662,8 +1657,8 @@ being an insert iterator will insert corresponding elements into the container. This device allows all of the copying algorithms in the library to work in the -\techterm{insert mode} -instead of the \techterm{regular overwrite} mode. +\term{insert mode} +instead of the \term{regular overwrite} mode. \pnum An insert iterator is constructed from a container and possibly one of its iterators pointing to where @@ -2149,15 +2144,13 @@ \pnum The template parameter \tcode{Iterator} shall satisfy -the requirements of an input iterator\iref{input.iterators}. +the \oldconcept{InputIterator} requirements\iref{input.iterators}. Additionally, if any of the bidirectional or random access traversal functions are instantiated, the template parameter shall satisfy the -requirements for a Bidirectional Iterator\iref{bidirectional.iterators} -or a Random Access Iterator\iref{random.access.iterators}, respectively. - -\rSec3[move.iter.ops]{\tcode{move_iterator} operations} +\oldconcept{BidirectionalIterator} requirements\iref{bidirectional.iterators} +or \oldconcept{RandomAccessIterator} requirements\iref{random.access.iterators}, respectively. -\rSec4[move.iter.op.const]{\tcode{move_iterator} constructors} +\rSec3[move.iter.cons]{\tcode{move_iterator} construction and assignment} \indexlibrary{\idxcode{move_iterator}!constructor}% \begin{itemdecl} @@ -2200,8 +2193,6 @@ \tcode{Iterator}. \end{itemdescr} -\rSec4[move.iter.op=]{\tcode{move_iterator::operator=}} - \indexlibrarymember{operator=}{move_iterator}% \begin{itemdecl} template constexpr move_iterator& operator=(const move_iterator& u); @@ -2217,7 +2208,7 @@ \tcode{Iterator}. \end{itemdescr} -\rSec4[move.iter.op.conv]{\tcode{move_iterator} conversion} +\rSec3[move.iter.op.conv]{\tcode{move_iterator} conversion} \indexlibrarymember{base}{move_iterator}% \begin{itemdecl} @@ -2229,7 +2220,7 @@ \returns \tcode{current}. \end{itemdescr} -\rSec4[move.iter.op.star]{\tcode{move_iterator::operator*}} +\rSec3[move.iter.elem]{\tcode{move_iterator} element access} \indexlibrarymember{operator*}{move_iterator}% \begin{itemdecl} @@ -2241,8 +2232,6 @@ \returns \tcode{static_cast(*current)}. \end{itemdescr} -\rSec4[move.iter.op.ref]{\tcode{move_iterator::operator->}} - \indexlibrarymember{operator->}{move_iterator}% \begin{itemdecl} constexpr pointer operator->() const; @@ -2253,7 +2242,17 @@ \returns \tcode{current}. \end{itemdescr} -\rSec4[move.iter.op.incr]{\tcode{move_iterator::operator++}} +\indexlibrarymember{operator[]}{move_iterator}% +\begin{itemdecl} +constexpr @\unspec@ operator[](difference_type n) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{std::move(current[n])}. +\end{itemdescr} + +\rSec3[move.iter.nav]{\tcode{move_iterator} navigation} \indexlibrarymember{operator++}{move_iterator}% \begin{itemdecl} @@ -2284,8 +2283,6 @@ \end{codeblock} \end{itemdescr} -\rSec4[move.iter.op.decr]{\tcode{move_iterator::operator-{-}}} - \indexlibrarymember{operator\dcr}{move_iterator}% \begin{itemdecl} constexpr move_iterator& operator--(); @@ -2315,8 +2312,6 @@ \end{codeblock} \end{itemdescr} -\rSec4[move.iter.op.+]{\tcode{move_iterator::operator+}} - \indexlibrarymember{operator+}{move_iterator}% \begin{itemdecl} constexpr move_iterator operator+(difference_type n) const; @@ -2327,8 +2322,6 @@ \returns \tcode{move_iterator(current + n)}. \end{itemdescr} -\rSec4[move.iter.op.+=]{\tcode{move_iterator::operator+=}} - \indexlibrarymember{operator+=}{move_iterator}% \begin{itemdecl} constexpr move_iterator& operator+=(difference_type n); @@ -2342,8 +2335,6 @@ \returns \tcode{*this}. \end{itemdescr} -\rSec4[move.iter.op.-]{\tcode{move_iterator::operator-}} - \indexlibrarymember{operator-}{move_iterator}% \begin{itemdecl} constexpr move_iterator operator-(difference_type n) const; @@ -2354,8 +2345,6 @@ \returns \tcode{move_iterator(current - n)}. \end{itemdescr} -\rSec4[move.iter.op.-=]{\tcode{move_iterator::operator-=}} - \indexlibrarymember{operator-=}{move_iterator}% \begin{itemdecl} constexpr move_iterator& operator-=(difference_type n); @@ -2369,19 +2358,7 @@ \returns \tcode{*this}. \end{itemdescr} -\rSec4[move.iter.op.index]{\tcode{move_iterator::operator[]}} - -\indexlibrarymember{operator[]}{move_iterator}% -\begin{itemdecl} -constexpr @\unspec@ operator[](difference_type n) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{std::move(current[n])}. -\end{itemdescr} - -\rSec4[move.iter.op.comp]{\tcode{move_iterator} comparisons} +\rSec3[move.iter.op.comp]{\tcode{move_iterator} comparisons} \indexlibrarymember{operator==}{move_iterator}% \begin{itemdecl} @@ -2449,7 +2426,7 @@ \returns \tcode{!(x < y)}. \end{itemdescr} -\rSec4[move.iter.nonmember]{\tcode{move_iterator} non-member functions} +\rSec3[move.iter.nonmember]{\tcode{move_iterator} non-member functions} \indexlibrarymember{operator-}{move_iterator}% \begin{itemdecl} @@ -2549,8 +2526,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 satisfy the \tcode{DefaultConstructible}, -\tcode{CopyConstructible}, and \tcode{CopyAssignable} requirements. +The type \tcode{T} shall satisfy the \oldconcept{DefaultConstructible}, +\oldconcept{CopyConstructible}, and \oldconcept{CopyAssignable} requirements. \pnum Two end-of-stream iterators are always equal. @@ -2577,6 +2554,7 @@ istream_iterator(istream_type& s); istream_iterator(const istream_iterator& x) = default; ~istream_iterator() = default; + istream_iterator& operator=(const istream_iterator&) = default; const T& operator*() const; const T* operator->() const; @@ -2660,7 +2638,7 @@ \effects The iterator is destroyed. If \tcode{is_trivially_destructible_v} is \tcode{true}, -then this destructor is a trivial destructor. +then this destructor is trivial. \end{itemdescr} \rSec3[istream.iterator.ops]{\tcode{istream_iterator} operations} @@ -2795,6 +2773,7 @@ ostream_iterator(ostream_type& s, const charT* delimiter); ostream_iterator(const ostream_iterator& x); ~ostream_iterator(); + ostream_iterator& operator=(const ostream_iterator&) = default; ostream_iterator& operator=(const T& value); ostream_iterator& operator*(); @@ -2965,6 +2944,7 @@ istreambuf_iterator(istream_type& s) noexcept; istreambuf_iterator(streambuf_type* s) noexcept; istreambuf_iterator(const proxy& p) noexcept; + istreambuf_iterator& operator=(const istreambuf_iterator&) noexcept = default; charT operator*() const; istreambuf_iterator& operator++(); proxy operator++(int); @@ -2983,12 +2963,12 @@ } \end{codeblock} -\rSec3[istreambuf.iterator.proxy]{Class template \tcode{istreambuf_iterator::proxy}} +\rSec3[istreambuf.iterator.proxy]{Class \tcode{istreambuf_iterator::proxy}} \indexlibrary{\idxcode{proxy}!\idxcode{istreambuf_iterator}}% \begin{codeblock} namespace std { - template> + template class istreambuf_iterator::proxy { // \expos charT keep_; basic_streambuf* sbuf_; diff --git a/source/lex.tex b/source/lex.tex index 37b4af9268..78ea6c21d2 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -544,7 +544,7 @@ \indextext{name}% An identifier is an arbitrarily long sequence of letters and digits. Each \grammarterm{universal-character-name} in an identifier shall designate a -character whose encoding in ISO 10646 falls into one of the ranges +character whose encoding in ISO/IEC 10646 falls into one of the ranges specified in \tref{charname.allowed}. The initial element shall not be a \grammarterm{universal-character-name} designating a character whose encoding falls into one of the ranges @@ -629,10 +629,12 @@ token as a regular \grammarterm{identifier}. \begin{floattable}{Identifiers with special meaning}{tab:identifiers.special} -{ll} +{llll} \topline -\tcode{override} & -\tcode{final} \\ +\tcode{audit} & +\tcode{axiom} & +\tcode{final} & +\tcode{override} \\ \end{floattable} \pnum @@ -1139,7 +1141,7 @@ is a character literal of type \tcode{char}, known as a \defn{UTF-8 character literal}. The value of a UTF-8 character literal -is equal to its ISO 10646 code point value, +is equal to its ISO/IEC 10646 code point value, provided that the code point value is representable with a single UTF-8 code unit (that is, provided it is in the C0 Controls and Basic Latin Unicode block). @@ -1156,7 +1158,7 @@ \indextext{prefix!\idxcode{u}}% is a character literal of type \tcode{char16_t}. The value of a \tcode{char16_t} character literal containing a single \grammarterm{c-char} is -equal to its ISO 10646 code point value, provided that the code point value is +equal to its ISO/IEC 10646 code point value, provided that the code point value is representable with a single 16-bit code unit (that is, provided it is in the basic multi-lingual plane). If the value is not representable with a single 16-bit code unit, the program is ill-formed. A \tcode{char16_t} character literal @@ -1171,7 +1173,7 @@ \indextext{prefix!\idxcode{U}}% is a character literal of type \tcode{char32_t}. The value of a \tcode{char32_t} character literal containing a single \grammarterm{c-char} is equal -to its ISO 10646 code point value. A \tcode{char32_t} character literal containing +to its ISO/IEC 10646 code point value. A \tcode{char32_t} character literal containing multiple \grammarterm{c-char}{s} is ill-formed. \pnum @@ -1785,17 +1787,17 @@ operator "" @\placeholder{X}@(@\placeholder{n}@ULL) \end{codeblock} -Otherwise, \placeholder{S} shall contain a raw literal operator or a literal operator -template\iref{over.literal} but not both. If \placeholder{S} contains a raw literal operator, +Otherwise, \placeholder{S} shall contain a raw literal operator +or a numeric literal operator template\iref{over.literal} but not both. +If \placeholder{S} contains a raw literal operator, the literal \placeholder{L} is treated as a call of the form \begin{codeblock} operator "" @\placeholder{X}@(@"\placeholder{n}{"}@) \end{codeblock} -Otherwise (\placeholder{S} contains a literal operator template), \placeholder{L} is treated as a call -of the form - +Otherwise (\placeholder{S} contains a numeric literal operator template), +\placeholder{L} is treated as a call of the form \begin{codeblock} operator "" @\placeholder{X}@<'@$c_1$@', '@$c_2$@', ... '@$c_k$@'>() @@ -1815,16 +1817,17 @@ operator "" @\placeholder{X}@(@\placeholder{f}@L) \end{codeblock} -Otherwise, \placeholder{S} shall contain a raw literal operator or a literal operator -template\iref{over.literal} but not both. If \placeholder{S} contains a raw literal operator, +Otherwise, \placeholder{S} shall contain a raw literal operator +or a numeric literal operator template\iref{over.literal} but not both. +If \placeholder{S} contains a raw literal operator, the \grammarterm{literal} \placeholder{L} is treated as a call of the form \begin{codeblock} operator "" @\placeholder{X}@(@"\placeholder{f}{"}@) \end{codeblock} -Otherwise (\placeholder{S} contains a literal operator template), \placeholder{L} is treated as a call -of the form +Otherwise (\placeholder{S} contains a numeric literal operator template), +\placeholder{L} is treated as a call of the form \begin{codeblock} operator "" @\placeholder{X}@<'@$c_1$@', '@$c_2$@', ... '@$c_k$@'>() @@ -1835,12 +1838,20 @@ \end{note} \pnum -If \placeholder{L} is a \grammarterm{user-defined-string-literal}, let \placeholder{str} be the -literal without its \grammarterm{ud-suffix} and let \placeholder{len} be -the number of -code units in \placeholder{str} (i.e., its length excluding the terminating -null character). - The literal \placeholder{L} is treated as a call of the form +If \placeholder{L} is a \grammarterm{user-defined-string-literal}, +let \placeholder{str} be the literal without its \grammarterm{ud-suffix} +and let \placeholder{len} be the number of code units in \placeholder{str} +(i.e., its length excluding the terminating null character). +If \placeholder{S} contains a literal operator template with +a non-type template parameter for which \placeholder{str} is +a well-formed \grammarterm{template-argument}, +the literal \placeholder{L} is treated as a call of the form + +\begin{codeblock} +operator "" @\placeholder{X}@<@\placeholder{str}{}@>() +\end{codeblock} + +Otherwise, the literal \placeholder{L} is treated as a call of the form \begin{codeblock} operator "" @\placeholder{X}@(@\placeholder{str}{}@, @\placeholder{len}{}@) diff --git a/source/lib-intro.tex b/source/lib-intro.tex index e32456d7a8..600ee4026a 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -24,6 +24,7 @@ \begin{libsumtabbase}{Library categories}{tab:library.categories}{Clause}{Category} \ref{language.support} & & Language support library \\ +\ref{concepts} & & Concepts library \\ \ref{diagnostics} & & Diagnostics library \\ \ref{utilities} & & General utilities library \\ \ref{strings} & & Strings library \\ @@ -43,6 +44,11 @@ required by certain parts of the \Cpp{} language, such as memory allocation~(\ref{expr.new}, \ref{expr.delete}) and exception processing\iref{except}. +\pnum +The concepts library\iref{concepts} describes library components that \Cpp{} +programs may use to perform compile-time validation of template arguments and +perform function dispatch based on properties of types. + \pnum The diagnostics library\iref{diagnostics} provides a consistent framework for reporting errors in a \Cpp{} program, including predefined exception classes. @@ -219,6 +225,28 @@ direct-initialization\iref{dcl.init} that is not list-initialization\iref{dcl.init.list} +\definition{expression-equivalent}{defns.expression-equivalent} +\indexdefn{expression-equivalent}% +expressions that all have the same effects, +either +are all potentially-throwing\iref{except.spec} or +are all not potentially-throwing, +and +either +are all constant subexpressions or +are all not constant subexpressions + +\begin{example} +For a value \tcode{x} of type \tcode{int} +and a function \tcode{f} that accepts integer arguments, +the expressions +\tcode{f(x + 2)}, +\tcode{f(2 + x)}, +and +\tcode{f(1 + x + 1)} +are expression-equivalent. +\end{example} + \definition{handler function}{defns.handler} \indexdefn{function!handler}% non-reserved function whose definition may be provided by a \Cpp{} program @@ -283,6 +311,24 @@ member functions\iref{class.this}. \end{defnote} +\definition{program-defined specialization}{defns.prog.def.spec} +\indexdefn{specialization!program-defined}% +explicit template specialization or partial specialization +that is not part of the C++ standard library and +not defined by the implementation + +\definition{program-defined type}{defns.prog.def.type} +\indexdefn{type!program-defined}% +class type or enumeration type +that is not part of the C++ standard library and +not defined by the implementation, +or an instantiation of a program-defined specialization + +\begin{defnote} +Types defined by the implementation include +extensions\iref{intro.compliance} and internal types used by the library. +\end{defnote} + \definition{referenceable type}{defns.referenceable} \indexdefn{type!referenceable}% type that is either an @@ -401,6 +447,7 @@ \item classes and class templates \item functions and function templates \item objects +\item concepts \end{itemize} \rSec3[structure.requirements]{Requirements} @@ -413,7 +460,8 @@ \begin{itemize} \item Template arguments \item Derived classes -\item Containers, iterators, and algorithms that meet an interface convention +\item Containers, iterators, and algorithms that meet an interface convention or + satisfy a concept \end{itemize} \pnum @@ -430,11 +478,23 @@ \pnum Requirements are stated in terms of well-defined expressions that define valid terms of the types that satisfy the requirements. For every set of well-defined expression -requirements there is a table that specifies an initial set of the valid expressions and +requirements there is either a named concept or a table that specifies an initial set of the valid expressions and their semantics. Any generic algorithm\iref{algorithms} that uses the well-defined expression requirements is described in terms of the valid expressions for its template type parameters. +\pnum +The library specification uses a typographical convention for naming +requirements. Names in \textit{italic} type that begin with the prefix +\oldconcept{} refer to sets of well-defined expression requirements typically +presented in tabular form, possibly with additional prose semantic requirements. +For example, \oldconcept{Destructible}~(\tref{destructible}) is such a named +requirement. Names in \tcode{constant width} type refer to library concepts +which are presented as a concept definition\iref{temp}, possibly with additional +prose semantic requirements. For example, +\libconcept{Destructible}\iref{concept.destructible} +is such a named requirement. + \pnum Template argument requirements are sometimes referenced by name. See~\ref{type.descriptions}. @@ -447,6 +507,23 @@ must be implemented.\footnote{Although in some cases the code given is unambiguously the optimum implementation.} +\pnum +Required operations of any concept defined in this document need not be +total functions; that is, some arguments to a required operation may +result in the required semantics failing to be satisfied. +\begin{example} +The required \tcode{<} operator of the \libconcept{StrictTotallyOrdered} +concept\iref{concept.stricttotallyordered} does not meet the +semantic requirements of that concept when operating on NaNs. +\end{example} +This does not affect whether a type satisfies the concept. + +\pnum +A declaration may explicitly impose requirements through its associated +constraints\iref{temp.constr.decl}. When the associated constraints refer to a +concept\iref{temp.concept}, the semantic constraints specified for that concept +are additionally imposed on the use of the declaration. + \rSec3[structure.specifications]{Detailed specifications} \pnum @@ -477,37 +554,92 @@ \pnum Descriptions of function semantics contain the following elements (as -appropriate):\footnote{To save space, items that do not apply to a function are omitted. -For example, if a function does not specify any -further -preconditions, there will be no \requires paragraph.} +appropriate):\footnote{To save space, elements that do not apply to a function are omitted. +For example, if a function specifies no +preconditions, there will be no \expects element.} \begin{itemize} -\item \requires the preconditions for calling the function -\item \effects the actions performed by the function -\item \sync the synchronization operations\iref{intro.multithread} applicable to the function -\item \postconditions the observable results established by the function -\item \returns a description of the value(s) returned by the function -\item \throws any exceptions thrown by the function, and the conditions that would cause the exception -\item \complexity the time and/or space complexity of the function -\item \remarks additional semantic constraints on the function -\item \errors the error conditions for error codes reported by the function +\item +\requires the preconditions for calling the function. + +\item +\constraints the conditions for the function's participation +in overload resolution\iref{over.match}. +\begin{note} +Failure to meet such a condition results in the function's silent non-viability. +\end{note} +\begin{example} +An implementation might express such a condition +via a \grammarterm{constraint-expression}\iref{temp.constr.decl}. +\end{example} + +\item +\mandates the conditions that, if not met, render the program ill-formed. +\begin{example} +An implementation might express such a condition +via the \grammarterm{constant-expression} +in a \grammarterm{static_assert-declaration}\iref{dcl.dcl}. +If the diagnostic is to be emitted only after the function +has been selected by overload resolution, +an implementation might express such a condition +via a \grammarterm{constraint-expression}\iref{temp.constr.decl} +and also define the function as deleted. +\end{example} + +\item +\expects the conditions (sometimes termed preconditions) +that the function assumes to hold whenever it is called. +\begin{example} +An implementation might express such conditions +via an attribute such as \tcode{[[expects]]}\iref{dcl.attr.contract}. +However, some such conditions might not lend themselves +to expression via code. +\end{example} + +\item +\effects the actions performed by the function. + +\item +\sync the synchronization operations\iref{intro.multithread} applicable to the function. + +\item +\ensures the conditions (sometimes termed observable results or postconditions) +established by the function. + +\item +\returns a description of the value(s) returned by the function. + +\item +\throws any exceptions thrown by the function, and the conditions that would cause the exception. + +\item +\complexity the time and/or space complexity of the function. + +\item +\remarks additional semantic constraints on the function. + +\item +\errors the error conditions for error codes reported by the function. \end{itemize} \pnum Whenever the \Fundescx{Effects} element specifies that the semantics of some function -\tcode{F} are \techterm{Equivalent to} some code sequence, then the various elements are -interpreted as follows. If \tcode{F}'s semantics specifies a \Fundescx{Requires} element, then -that requirement is logically imposed prior to the \techterm{equivalent-to} semantics. -Next, the semantics of the code sequence are determined by the \Fundescx{Requires}, \Fundescx{Effects}, -\Fundescx{Synchronization}, \Fundescx{Postconditions}, \Fundescx{Returns}, \Fundescx{Throws}, \Fundescx{Complexity}, \Fundescx{Remarks}, and \Fundescx{Error conditions} -specified for the function invocations contained in the code sequence. The value -returned from \tcode{F} is specified by \tcode{F}'s \Fundescx{Returns} element, or if \tcode{F} -has no \Fundescx{Returns} element, a non-\tcode{void} return from \tcode{F} is specified by the +\tcode{F} are \term{Equivalent to} some code sequence, then the various elements are +interpreted as follows. +If \tcode{F}'s semantics specifies any \Fundescx{Constraints} or \Fundescx{Mandates} elements, +then those requirements are logically imposed prior to the \term{equivalent-to} semantics. +Next, the semantics of the code sequence are determined by the +\Fundescx{Constraints}, \Fundescx{Mandates}, \Fundescx{Expects}, \Fundescx{Effects}, +\Fundescx{Synchronization}, \Fundescx{Ensures}, \Fundescx{Returns}, \Fundescx{Throws}, +\Fundescx{Complexity}, \Fundescx{Remarks}, and \Fundescx{Error conditions} +specified for the function invocations contained in the code sequence. +The value returned from \tcode{F} is specified by \tcode{F}'s \Fundescx{Returns} element, +or if \tcode{F} has no \Fundescx{Returns} element, +a non-\tcode{void} return from \tcode{F} is specified by the \tcode{return} statements\iref{stmt.return} in the code sequence. If \tcode{F}'s semantics contains a \Fundescx{Throws}, -\Fundescx{Postconditions}, or \Fundescx{Complexity} element, then that supersedes any occurrences of that -element in the code sequence. +\Fundescx{Ensures}, or \Fundescx{Complexity} element, +then that supersedes any occurrences of that element in the code sequence. \pnum For non-reserved replacement and handler functions, @@ -560,12 +692,12 @@ The Requirements subclauses may describe names that are used to specify constraints on template arguments.\footnote{Examples from~\ref{utility.requirements} include: -\tcode{EqualityComparable}, -\tcode{LessThanComparable}, -\tcode{CopyConstructible}. +\oldconcept{EqualityComparable}, +\oldconcept{LessThanComparable}, +\oldconcept{CopyConstructible}. Examples from~\ref{iterator.requirements} include: -\tcode{InputIterator}, -\tcode{ForwardIterator}.} +\oldconcept{InputIterator}, +\oldconcept{ForwardIterator}.} These names are used in library Clauses to describe the types that may be supplied as arguments by a \Cpp{} program when instantiating template components from @@ -820,13 +952,56 @@ A \defnx{static \ntmbs{}}{NTMBS@\ntmbs{}!static} is an \ntmbs{} with static storage duration. +\rSec4[customization.point.object]{Customization Point Object types} + +\pnum +A \term{customization point object} is a function object\iref{function.objects} +with a literal class type that interacts with program-defined types while +enforcing semantic requirements on that interaction. + +\pnum +The type of a customization point object shall satisfy +\libconcept{Semiregular}\iref{concepts.object}. + +\pnum +All instances of a specific customization point object type shall +be equal\iref{concepts.equality}. + +\pnum +The type \tcode{T} of a customization point object shall satisfy +\tcode{\libconcept{Invocable}}\iref{concept.invocable} +when the types in \tcode{Args...} meet the requirements specified in that +customization point object's definition. When the types of \tcode{Args...} do +not meet the customization point object's requirements, \tcode{T} shall not have +a function call operator that participates in overload resolution. + +\pnum +Each customization point object type constrains its return type to satisfy a +particular concept. + +\pnum +\begin{note} +Many of the customization point objects in the library evaluate function call +expressions with an unqualified name which results in a call to a +program-defined function found by argument dependent name +lookup\iref{basic.lookup.argdep}. To preclude such an expression resulting in a +call to unconstrained functions with the same name in namespace \tcode{std}, +customization point objects specify that lookup for these expressions is +performed in a context that includes deleted overloads matching the signatures +of overloads defined in namespace \tcode{std}. When the deleted overloads are +viable, program-defined overloads need be more specialized\iref{temp.func.order} +or more constrained\iref{temp.constr.order} to be used by a customization point +object. +\end{note} + \rSec3[functions.within.classes]{Functions within classes} \pnum For the sake of exposition, \ref{\firstlibchapter} through \ref{\lastlibchapter} and \ref{depr} do not describe copy/move constructors, assignment operators, or (non-virtual) destructors with the same apparent -semantics as those that can be generated by default~(\ref{class.ctor}, \ref{class.dtor}, \ref{class.copy}). +semantics as those that can be generated +by default~(\ref{class.copy.ctor}, \ref{class.copy.assign}, \ref{class.dtor}). \indextext{constructor!copy}% \indextext{operator!assignment}% \indextext{destructor}% @@ -834,13 +1009,6 @@ the implementation provides explicit definitions for such member function signatures, or for virtual destructors that can be generated by default. -\pnum -For the sake of exposition, the library clauses sometimes annotate -constructors with \EXPLICIT{}. Such a constructor is conditionally declared -as either explicit or non-explicit\iref{class.conv.ctor}. -\begin{note} This is typically implemented by declaring two such constructors, -of which at most one participates in overload resolution. \end{note} - \rSec3[operators]{Operators} \pnum @@ -858,7 +1026,7 @@ \begin{itemdescr} \pnum \requires -Type \tcode{T} is \tcode{EqualityComparable} (\tref{equalitycomparable}). +Type \tcode{T} is \oldconcept{EqualityComparable} (\tref{equalitycomparable}). \pnum \returns @@ -873,7 +1041,7 @@ \begin{itemdescr} \pnum \requires -Type \tcode{T} is \tcode{LessThanComparable} (\tref{lessthancomparable}). +Type \tcode{T} is \oldconcept{LessThanComparable} (\tref{lessthancomparable}). \pnum \returns @@ -888,7 +1056,7 @@ \begin{itemdescr} \pnum \requires -Type \tcode{T} is \tcode{LessThanComparable} (\tref{lessthancomparable}). +Type \tcode{T} is \oldconcept{LessThanComparable} (\tref{lessthancomparable}). \pnum \returns @@ -903,7 +1071,7 @@ \begin{itemdescr} \pnum \requires -Type \tcode{T} is \tcode{LessThanComparable} (\tref{lessthancomparable}). +Type \tcode{T} is \oldconcept{LessThanComparable} (\tref{lessthancomparable}). \pnum \returns @@ -1009,95 +1177,81 @@ \defnx{\Cpp{} library headers}{header!C++ library}, shown in \tref{cpp.library.headers}. -\begin{floattable}{\Cpp{} library headers}{tab:cpp.library.headers} +\begin{multicolfloattable}{\Cpp{} library headers}{tab:cpp.library.headers} {llll} -\topline -\tcode{} & -\tcode{} & -\tcode{} & +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\columnbreak +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\columnbreak +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ \tcode{} \\ - -\tcode{} & -\tcode{} & -\tcode{} & +\columnbreak +\tcode{} \\ \tcode{} \\ - -\tcode{} & -\tcode{} & -\tcode{} & \tcode{} \\ - -\tcode{} & -\tcode{} & -\tcode{} & \tcode{} \\ - -\tcode{} & -\tcode{} & -\tcode{} & \tcode{} \\ - -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} \\ - -\tcode{} & -\tcode{} & -\tcode{} & \tcode{} \\ - -\tcode{} & -\tcode{} & -\tcode{} & \tcode{} \\ - -\tcode{} & -\tcode{} & -\tcode{} & +\tcode{} \\ \tcode{} \\ - -\tcode{} & -\tcode{} & -\tcode{} & \tcode{} \\ - -\tcode{} & -\tcode{} & -\tcode{} & \tcode{} \\ - -\tcode{} & -\tcode{} & -\tcode{} & \tcode{} \\ - -\tcode{} & -\tcode{} & -\tcode{} & \tcode{} \\ - -\tcode{} & -\tcode{} & -\tcode{} & \tcode{} \\ - -\tcode{} & -\tcode{} & -\tcode{} & \tcode{} \\ - -\tcode{} & -\tcode{} & -\tcode{} & -\\ - -\tcode{} & -\tcode{} & -\tcode{} & -\\ -\end{floattable} - +\end{multicolfloattable} \pnum The facilities of the C standard library are provided in the @@ -1109,44 +1263,36 @@ \tcode{}\indextext{\idxhdr{stdnoreturn.h}!absence thereof}, \tcode{}\indextext{\idxhdr{threads.h}!absence thereof}.} -\begin{floattable}{\Cpp{} headers for C library facilities}{tab:cpp.c.headers} -{lllll} -\topline - -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} \\ - -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} \\ - -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} & \\ - -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} & \\ - -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} & \\ - -\tcode{} & -\tcode{} & -\tcode{} & -\tcode{} & \\ - - -\end{floattable} +\begin{multicolfloattable}{\Cpp{} headers for C library facilities}{tab:cpp.c.headers} +{lllllll} +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\columnbreak +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\columnbreak +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\columnbreak +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\columnbreak +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\columnbreak +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\columnbreak +\tcode{} \\ +\tcode{} \\ +\tcode{} \\ +\end{multicolfloattable} \pnum Except as noted in \ref{library} through \ref{\lastlibchapter} @@ -1179,7 +1325,7 @@ \pnum Identifiers that are keywords or operators in \Cpp{} shall not be defined as macros in \Cpp{} standard library headers.\footnote{In particular, including the -standard header \tcode{} or \tcode{} has no effect.} +standard header \tcode{} has no effect.} \pnum \ref{depr.c.headers}, C standard library headers, describes the effects of using @@ -1211,102 +1357,86 @@ that may be declared in some header. These names are also subject to the restrictions of~\ref{macro.names}. -\begin{floattable}{C standard Annex K names}{tab:c.annex.k.names} +\begin{multicolfloattable}{C standard Annex K names}{tab:c.annex.k.names} {llll} -\topline -\tcode{abort_handler_s} & -\tcode{mbstowcs_s} & -\tcode{strncat_s} & +\tcode{abort_handler_s} \\ +\tcode{asctime_s} \\ +\tcode{bsearch_s} \\ +\tcode{constraint_handler_t} \\ +\tcode{ctime_s} \\ +\tcode{errno_t} \\ +\tcode{fopen_s} \\ +\tcode{fprintf_s} \\ +\tcode{freopen_s} \\ +\tcode{fscanf_s} \\ +\tcode{fwprintf_s} \\ +\tcode{fwscanf_s} \\ +\tcode{getenv_s} \\ +\tcode{gets_s} \\ +\tcode{gmtime_s} \\ +\tcode{ignore_handler_s} \\ +\tcode{localtime_s} \\ +\tcode{L_tmpnam_s} \\ +\tcode{mbsrtowcs_s} \\ +\columnbreak +\tcode{mbstowcs_s} \\ +\tcode{memcpy_s} \\ +\tcode{memmove_s} \\ +\tcode{memset_s} \\ +\tcode{printf_s} \\ +\tcode{qsort_s} \\ +\tcode{RSIZE_MAX} \\ +\tcode{rsize_t} \\ +\tcode{scanf_s} \\ +\tcode{set_constraint_handler_s} \\ +\tcode{snprintf_s} \\ +\tcode{snwprintf_s} \\ +\tcode{sprintf_s} \\ +\tcode{sscanf_s} \\ +\tcode{strcat_s} \\ +\tcode{strcpy_s} \\ +\tcode{strerrorlen_s} \\ +\tcode{strerror_s} \\ +\tcode{strlen_s} \\ +\columnbreak +\tcode{strncat_s} \\ +\tcode{strncpy_s} \\ +\tcode{strtok_s} \\ +\tcode{swprintf_s} \\ +\tcode{swscanf_s} \\ +\tcode{tmpfile_s} \\ +\tcode{TMP_MAX_S} \\ +\tcode{tmpnam_s} \\ +\tcode{vfprintf_s} \\ +\tcode{vfscanf_s} \\ +\tcode{vfwprintf_s} \\ +\tcode{vfwscanf_s} \\ +\tcode{vprintf_s} \\ +\tcode{vscanf_s} \\ +\tcode{vsnprintf_s} \\ +\tcode{vsnwprintf_s} \\ +\tcode{vsprintf_s} \\ +\tcode{vsscanf_s} \\ +\tcode{vswprintf_s} \\ +\columnbreak \tcode{vswscanf_s} \\ - -\tcode{asctime_s} & -\tcode{memcpy_s} & -\tcode{strncpy_s} & \tcode{vwprintf_s} \\ - -\tcode{bsearch_s} & -\tcode{memmove_s} & -\tcode{strtok_s} & \tcode{vwscanf_s} \\ - -\tcode{constraint_handler_t} & -\tcode{memset_s} & -\tcode{swprintf_s} & \tcode{wcrtomb_s} \\ - -\tcode{ctime_s} & -\tcode{printf_s} & -\tcode{swscanf_s} & \tcode{wcscat_s} \\ - -\tcode{errno_t} & -\tcode{qsort_s} & -\tcode{tmpfile_s} & \tcode{wcscpy_s} \\ - -\tcode{fopen_s} & -\tcode{RSIZE_MAX} & -\tcode{TMP_MAX_S} & \tcode{wcsncat_s} \\ - -\tcode{fprintf_s} & -\tcode{rsize_t} & -\tcode{tmpnam_s} & \tcode{wcsncpy_s} \\ - -\tcode{freopen_s} & -\tcode{scanf_s} & -\tcode{vfprintf_s} & \tcode{wcsnlen_s} \\ - -\tcode{fscanf_s} & -\tcode{set_constraint_handler_s} & -\tcode{vfscanf_s} & \tcode{wcsrtombs_s} \\ - -\tcode{fwprintf_s} & -\tcode{snprintf_s} & -\tcode{vfwprintf_s} & \tcode{wcstok_s} \\ - -\tcode{fwscanf_s} & -\tcode{snwprintf_s} & -\tcode{vfwscanf_s} & \tcode{wcstombs_s} \\ - -\tcode{getenv_s} & -\tcode{sprintf_s} & -\tcode{vprintf_s} & \tcode{wctomb_s} \\ - -\tcode{gets_s} & -\tcode{sscanf_s} & -\tcode{vscanf_s} & \tcode{wmemcpy_s} \\ - -\tcode{gmtime_s} & -\tcode{strcat_s} & -\tcode{vsnprintf_s} & \tcode{wmemmove_s} \\ - -\tcode{ignore_handler_s} & -\tcode{strcpy_s} & -\tcode{vsnwprintf_s} & \tcode{wprintf_s} \\ - -\tcode{L_tmpnam_s} & -\tcode{strerror_s} & -\tcode{vsprintf_s} & \tcode{wscanf_s} \\ - -\tcode{localtime_s} & -\tcode{strerrorlen_s} & -\tcode{vsscanf_s} & \\ - -\tcode{mbsrtowcs_s} & -\tcode{strlen_s} & -\tcode{vswprintf_s} & \\ -\end{floattable} +\end{multicolfloattable} \rSec3[compliance]{Freestanding implementations} @@ -1324,7 +1454,6 @@ include at least the headers shown in \tref{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{} \tcode{} \\ \rowsep \ref{cstdint} & Integer types & \tcode{} \\ \rowsep @@ -1335,8 +1464,8 @@ \ref{support.initlist} & Initializer lists & \tcode{} \\ \rowsep \ref{support.runtime} & Other runtime support & \tcode{} \\ \rowsep \ref{meta} & Type traits & \tcode{} \\ \rowsep +\ref{bit} & Bit manipulation & \tcode{} \\ \rowsep \ref{atomics} & Atomics & \tcode{} \\ \rowsep -\ref{depr.cstdalign.syn}, \ref{depr.cstdbool.syn} & Deprecated headers & \tcode{} \tcode{} \\ \end{libsumtab} \pnum @@ -1476,8 +1605,8 @@ \tcode{T()} shall be a well-defined expression\iref{dcl.init} if one of those signatures is called using the default argument\iref{dcl.fct.default}. -\indextext{requirements!\idxcode{EqualityComparable}}% -\begin{concepttable}{\tcode{EqualityComparable} requirements}{equalitycomparable} +\indextext{requirements!\idxoldconcept{EqualityComparable}}% +\begin{concepttable}{\oldconcept{EqualityComparable} requirements}{equalitycomparable} {x{1in}x{1in}p{3in}} \topline \hdstyle{Expression} & \hdstyle{Return type} & \rhdr{Requirement} \\ \capsep @@ -1495,8 +1624,8 @@ \end{itemize} \\ \end{concepttable} -\indextext{requirements!\idxcode{LessThanComparable}}% -\begin{concepttable}{\tcode{LessThanComparable} requirements}{lessthancomparable} +\indextext{requirements!\idxoldconcept{LessThanComparable}}% +\begin{concepttable}{\oldconcept{LessThanComparable} requirements}{lessthancomparable} {x{1in}x{1in}p{3in}} \topline \hdstyle{Expression} & \hdstyle{Return type} & \hdstyle{Requirement} \\ \capsep @@ -1506,8 +1635,8 @@ \end{concepttable} \enlargethispage{-3\baselineskip} -\indextext{requirements!\idxcode{DefaultConstructible}}% -\begin{concepttable}{\tcode{DefaultConstructible} requirements}{defaultconstructible} +\indextext{requirements!\idxoldconcept{DefaultConstructible}}% +\begin{concepttable}{\oldconcept{DefaultConstructible} requirements}{defaultconstructible} {x{2.15in}p{3in}} \topline \hdstyle{Expression} & \hdstyle{Post-condition} \\ \capsep @@ -1517,8 +1646,8 @@ or aggregate-initialized \\ \end{concepttable} -\indextext{requirements!\idxcode{MoveConstructible}}% -\begin{concepttable}{\tcode{MoveConstructible} requirements}{moveconstructible} +\indextext{requirements!\idxoldconcept{MoveConstructible}}% +\begin{concepttable}{\oldconcept{MoveConstructible} requirements}{moveconstructible} {p{1in}p{4.15in}} \topline \hdstyle{Expression} & \hdstyle{Post-condition} \\ \capsep @@ -1532,8 +1661,8 @@ work as specified whether \tcode{rv} has been moved from or not. \end{note}}\\ \end{concepttable} -\indextext{requirements!\idxcode{CopyConstructible}}% -\begin{concepttable}{\tcode{CopyConstructible} requirements (in addition to \tcode{MoveConstructible})}{copyconstructible} +\indextext{requirements!\idxoldconcept{CopyConstructible}}% +\begin{concepttable}{\oldconcept{CopyConstructible} requirements (in addition to \oldconcept{MoveConstructible})}{copyconstructible} {p{1in}p{4.15in}} \topline \hdstyle{Expression} & \hdstyle{Post-condition} \\ \capsep @@ -1542,8 +1671,8 @@ the value of \tcode{v} is unchanged and is equivalent to \tcode{T(v)} \\ \end{concepttable} -\indextext{requirements!\idxcode{MoveAssignable}}% -\begin{concepttable}{\tcode{MoveAssignable} requirements}{moveassignable} +\indextext{requirements!\idxoldconcept{MoveAssignable}}% +\begin{concepttable}{\oldconcept{MoveAssignable} requirements}{moveassignable} {p{1in}p{1in}p{1in}p{1.9in}} \topline \hdstyle{Expression} & \hdstyle{Return type} & \hdstyle{Return value} & \hdstyle{Post-condition} \\ \capsep @@ -1558,16 +1687,16 @@ work as specified whether \tcode{rv} has been moved from or not. \end{note}}\\ \end{concepttable} -\indextext{requirements!\idxcode{CopyAssignable}}% -\begin{concepttable}{\tcode{CopyAssignable} requirements (in addition to \tcode{MoveAssignable})}{copyassignable} +\indextext{requirements!\idxoldconcept{CopyAssignable}}% +\begin{concepttable}{\oldconcept{CopyAssignable} requirements (in addition to \oldconcept{MoveAssignable})}{copyassignable} {p{1in}p{1in}p{1in}p{1.9in}} \topline \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} -\indextext{requirements!\idxcode{Destructible}} -\begin{concepttable}{\tcode{Destructible} requirements}{destructible} +\indextext{requirements!\idxoldconcept{Destructible}} +\begin{concepttable}{\oldconcept{Destructible} requirements}{destructible} {p{1in}p{4.15in}} \topline \hdstyle{Expression} & \hdstyle{Post-condition} \\ \capsep @@ -1624,7 +1753,7 @@ \pnum A type \tcode{X} satisfying any of the iterator requirements\iref{iterator.requirements} -satisfies the \tcode{ValueSwappable} requirements if, +satisfies the \oldconcept{ValueSwappable} requirements if, for any dereferenceable object \tcode{x} of type \tcode{X}, \tcode{*x} is swappable. @@ -1673,16 +1802,16 @@ \end{codeblock} \end{example} -\rSec3[nullablepointer.requirements]{\tcode{NullablePointer} requirements} +\rSec3[nullablepointer.requirements]{\oldconcept{NullablePointer} requirements} \pnum -A \tcode{NullablePointer} type is a pointer-like type that supports null values. -A type \tcode{P} satisfies the \tcode{Nullable\-Pointer} requirements if: +A \oldconcept{NullablePointer} type is a pointer-like type that supports null values. +A type \tcode{P} satisfies the \oldconcept{\-Nullable\-Pointer} requirements if: \begin{itemize} -\item \tcode{P} satisfies the \tcode{EqualityComparable}, -\tcode{DefaultConstructible}, \tcode{CopyConstructible}, \tcode{CopyAssignable}, -and \tcode{Destructible} requirements, +\item \tcode{P} satisfies the \oldconcept{EqualityComparable}, +\oldconcept{DefaultConstructible}, \oldconcept{CopyConstructible}, \oldconcept{\-Copy\-Assign\-able}, +and \oldconcept{Destructible} requirements, \item lvalues of type \tcode{P} are swappable\iref{swappable.requirements}, @@ -1704,7 +1833,7 @@ had been evaluated in place of \tcode{p}. \pnum -No operation which is part of the \tcode{NullablePointer} requirements shall exit +No operation which is part of the \oldconcept{NullablePointer} requirements shall exit via an exception. \pnum @@ -1713,8 +1842,8 @@ denote values of type (possibly \tcode{const}) \tcode{P}, and \tcode{np} denotes a value of type (possibly \tcode{const}) \tcode{std::nullptr_t}. -\indextext{requirements!\idxcode{NullablePointer}}% -\begin{concepttable}{\tcode{NullablePointer} requirements}{nullablepointer} +\indextext{requirements!\idxoldconcept{NullablePointer}}% +\begin{concepttable}{\oldconcept{NullablePointer} requirements}{nullablepointer} {lll} \topline Expression & Return type & Operational semantics \\ \capsep @@ -1751,16 +1880,16 @@ \\ \rowsep \end{concepttable} -\rSec3[hash.requirements]{Hash requirements} +\rSec3[hash.requirements]{\oldconcept{Hash} requirements} -\indextext{requirements!\idxcode{Hash}} +\indextext{requirements!\idxoldconcept{Hash}} \pnum -A type \tcode{H} meets the \tcode{Hash} requirements if: +A type \tcode{H} meets the \oldconcept{Hash} requirements if: \begin{itemize} \item it is a function object type\iref{function.objects}, -\item it satisfies the \tcode{CopyConstructible} (\tref{copyconstructible}) and - \tcode{Destructible} (\tref{destructible}) requirements, and +\item it satisfies the \oldconcept{CopyConstructible} (\tref{copyconstructible}) and + \oldconcept{Destructible} (\tref{destructible}) requirements, and \item the expressions shown in \tref{hash} are valid and have the indicated semantics. \end{itemize} @@ -1771,7 +1900,7 @@ \tcode{u} is an lvalue of type \tcode{Key}, and \tcode{k} is a value of a type convertible to (possibly \tcode{const}) \tcode{Key}. -\begin{concepttable}{\tcode{Hash} requirements}{hash} +\begin{concepttable}{\oldconcept{Hash} requirements}{hash} {llp{.55\hsize}} \topline Expression & Return type & Requirement \\ \capsep @@ -1789,11 +1918,11 @@ Shall not modify \tcode{u}. \\ \end{concepttable} -\rSec3[allocator.requirements]{Allocator requirements} +\rSec3[allocator.requirements]{\oldconcept{Allocator} requirements} -\indextext{requirements!\idxcode{Allocator}}% +\indextext{requirements!\idxoldconcept{Allocator}}% \pnum -The library describes a standard set of requirements for \techterm{allocators}, +The library describes a standard set of requirements for \term{allocators}, which are class-type objects that encapsulate the information about an allocation model. This information includes the knowledge of pointer types, the type of their difference, the type of the size of objects in this allocation model, as well @@ -1833,8 +1962,8 @@ \lhdr{Variable} & \rhdr{Definition} \\ \capsep \endhead \tcode{T, U, C} & any \cv-unqualified object type\iref{basic.types} \\ \rowsep -\tcode{X} & an Allocator class for type \tcode{T} \\ \rowsep -\tcode{Y} & the corresponding Allocator class for type \tcode{U} \\ \rowsep +\tcode{X} & an allocator class for type \tcode{T} \\ \rowsep +\tcode{Y} & the corresponding allocator class for type \tcode{U} \\ \rowsep \tcode{XX} & the type \tcode{allocator_traits} \\ \rowsep \tcode{YY} & the type \tcode{allocator_traits} \\ \rowsep \tcode{a, a1, a2} & lvalues of type \tcode{X} \\ \rowsep @@ -1860,7 +1989,7 @@ \end{libreqtab2} \begin{libreqtab4d} -{Allocator requirements} +{\oldconcept{Allocator} requirements} {tab:utilities.allocator.requirements} \\ \topline \lhdr{Expression} & \chdr{Return type} & \chdr{Assertion/note} & \rhdr{Default} \\ @@ -2073,11 +2202,11 @@ Note B: If \tcode{X::propagate_on_container_copy_assignment::value} is \tcode{true}, \tcode{X} shall satisfy the -\tcode{CopyAssign\-able} requirements (\tref{copyassignable}) +\oldconcept{\-Copy\-Assign\-able} requirements (\tref{copyassignable}) and the copy operation shall not throw exceptions. If \tcode{X::propagate_on_container_move_assignment::value} is \tcode{true}, \tcode{X} shall satisfy the -\tcode{MoveAssignable} requirements (\tref{moveassignable}) +\oldconcept{\-Move\-Assign\-able} requirements (\tref{moveassignable}) and the move operation shall not throw exceptions. If \tcode{X::propagate_on_container_swap::value} is \tcode{true}, lvalues of type \tcode{X} shall be swappable\iref{swappable.requirements} @@ -2085,10 +2214,10 @@ \pnum An allocator type \tcode{X} shall satisfy the -\tcode{CopyConstructible} requirements (\tref{copyconstructible}). +\oldconcept{CopyConstructible} requirements (\tref{copyconstructible}). The \tcode{X::pointer}, \tcode{X::const_pointer}, \tcode{X::void_pointer}, and \tcode{X::const_void_pointer} types shall satisfy the -\tcode{Nullable\-Pointer} requirements (\tref{nullablepointer}). +\oldconcept{Nullable\-Pointer} requirements (\tref{nullablepointer}). No constructor, comparison function, copy operation, move operation, or swap operation on these pointer types shall exit via an exception. \tcode{X::pointer} and \tcode{X::const_pointer} shall also @@ -2212,7 +2341,7 @@ to namespace \tcode{std} provided that (a) the added declaration -depends on at least one user-defined type +depends on at least one program-defined type and (b) the specialization meets the standard library requirements for the original template.\footnote{Any @@ -2245,7 +2374,7 @@ A program may explicitly instantiate a class template defined in the standard library only if the declaration -(a) depends on the name of at least one user-defined type +(a) depends on the name of at least one program-defined type and (b) the instantiation meets the standard library requirements for the original template. @@ -2374,7 +2503,9 @@ In namespace \tcode{std}, the following names are reserved for previous standardization: \begin{itemize} \item \indexlibrary{\idxcode{auto_ptr}!zombie} \tcode{auto_ptr}, +\item \indexlibrary{\idxcode{auto_ptr_ref}!zombie} \tcode{auto_ptr_ref}, \item \indexlibrary{\idxcode{binary_function}!zombie} \tcode{binary_function}, +\item \indexlibrary{\idxcode{binary_negate}!zombie} \tcode{binary_negate}, \item \indexlibrary{\idxcode{bind1st}!zombie} \tcode{bind1st}, \item \indexlibrary{\idxcode{bind2nd}!zombie} \tcode{bind2nd}, \item \indexlibrary{\idxcode{binder1st}!zombie} \tcode{binder1st}, @@ -2383,24 +2514,58 @@ \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_temporary_buffer}!zombie} \tcode{get_temporary_buffer}, \item \indexlibrary{\idxcode{get_unexpected}!zombie} \tcode{get_unexpected}, +\item \indexlibrary{\idxcode{gets}!zombie} \tcode{gets}, +\item \indexlibrary{\idxcode{is_literal_type}!zombie} \tcode{is_literal_type}, +\item \indexlibrary{\idxcode{is_literal_type_v}!zombie} \tcode{is_literal_type_v}, \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{not1}!zombie} \tcode{not1}, +\item \indexlibrary{\idxcode{not2}!zombie} \tcode{not2}, \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{raw_storage_iterator}!zombie} \tcode{raw_storage_iterator}, +\item \indexlibrary{\idxcode{result_of}!zombie} \tcode{result_of}, +\item \indexlibrary{\idxcode{result_of_t}!zombie} \tcode{result_of_t}, +\item \indexlibrary{\idxcode{return_temporary_buffer}!zombie} \tcode{return_temporary_buffer}, \item \indexlibrary{\idxcode{set_unexpected}!zombie} \tcode{set_unexpected}, \item \indexlibrary{\idxcode{unary_function}!zombie} \tcode{unary_function}, +\item \indexlibrary{\idxcode{unary_negate}!zombie} \tcode{unary_negate}, +\item \indexlibrary{\idxcode{uncaught_exception}!zombie} \tcode{uncaught_exception}, \item \indexlibrary{\idxcode{unexpected}!zombie} \tcode{unexpected}, and \item \indexlibrary{\idxcode{unexpected_handler}!zombie} \tcode{unexpected_handler}. \end{itemize} +\pnum +The following names are reserved as member types for previous standardization, +and may not be used as a name for object-like macros in portable code: +\begin{itemize} +\item \indexlibrary{\idxcode{argument_type}!zombie} \tcode{argument_type}, +\item \indexlibrary{\idxcode{first_argument_type}!zombie} \tcode{first_argument_type}, +\item \indexlibrary{\idxcode{io_state}!zombie} \tcode{io_state}, +\item \indexlibrary{\idxcode{open_mode}!zombie} \tcode{open_mode}, +\item \indexlibrary{\idxcode{second_argument_type}!zombie} \tcode{second_argument_type}, +and +\item \indexlibrary{\idxcode{seek_dir}!zombie} \tcode{seek_dir}, +\end{itemize} + +\pnum +The name \indexlibrary{\idxcode{stossc}!zombie} \tcode{stossc} is reserved as a +member function for previous standardization, and may not be used as a name for +function-like macros in portable code. + +\pnum +The header names \tcode{}, \tcode{}, \tcode{}, +\tcode{}, and \tcode{} are reserved for previous standardization. + \rSec4[macro.names]{Macro names} \pnum @@ -2689,7 +2854,7 @@ paragraph. \item if an incomplete type\iref{basic.types} is used as a template -argument when instantiating a template component, unless specifically +argument when instantiating a template component or evaluating a concept, unless specifically allowed for that component. \end{itemize} @@ -2761,11 +2926,22 @@ \pnum \indextext{restriction}% -Violation of the preconditions specified in a function's +Violation of any preconditions specified in a function's \requires -paragraph results in undefined behavior unless the function's +element results in undefined behavior unless the function's \throws -paragraph specifies throwing an exception when the precondition is violated. +element specifies throwing an exception when the precondition is violated. + +\pnum +Violation of any preconditions specified +in a function's \expects element +results in undefined behavior. + +\rSec3[res.on.requirements]{Semantic requirements} +\pnum +If the semantic requirements of a declaration's +constraints\iref{structure.requirements} are not satisfied at the point of use, +the program is ill-formed, no diagnostic required. \rSec2[conforming]{Conforming implementations} @@ -3115,6 +3291,6 @@ \pnum Objects of types defined in the \Cpp{} standard library may be moved -from\iref{class.copy}. Move operations may be explicitly specified or +from\iref{class.copy.ctor}. Move operations may be explicitly specified or implicitly generated. Unless otherwise specified, such moved-from objects shall be placed in a valid but unspecified state. diff --git a/source/locales.tex b/source/locales.tex index 00f081882e..f47093a319 100644 --- a/source/locales.tex +++ b/source/locales.tex @@ -440,7 +440,8 @@ \tcode{OutputIterator} indicates the set of all possible specializations on parameters that satisfy the -requirements of an Input Iterator or an Output Iterator, respectively\iref{iterator.requirements}. +\oldconcept{InputIterator} requirements or \oldconcept{OutputIterator} +requirements, respectively\iref{iterator.requirements}. A template parameter with name \tcode{C} represents the set @@ -1908,7 +1909,7 @@ Specializations on \tcode{mbstate_t} perform conversion between encodings known to the library implementer. -Other encodings can be converted by specializing on a user-defined +Other encodings can be converted by specializing on a program-defined \tcode{stateT} type. Objects of type diff --git a/source/macros.tex b/source/macros.tex index 952301f2ca..b371dc8ef9 100644 --- a/source/macros.tex +++ b/source/macros.tex @@ -165,6 +165,7 @@ \newcommand{\idxcode}[1]{#1@\tcode{#1}} \newcommand{\idxhdr}[1]{#1@\tcode{<#1>}} \newcommand{\idxgram}[1]{#1@\gterm{#1}} +\newcommand{\idxxname}[1]{__#1@\xname{#1}} % class member library index \newcommand{\indexlibrarymember}[2]{\indexlibrary{\idxcode{#1}!\idxcode{#2}}\indexlibrary{\idxcode{#2}!\idxcode{#1}}} @@ -180,16 +181,23 @@ % Code and definitions embedded in text. \newcommand{\tcode}[1]{\CodeStylex{#1}} -\newcommand{\techterm}[1]{\textit{#1}} -\newcommand{\defnx}[2]{\indexdefn{#2}\textit{#1}} -\newcommand{\defn}[1]{\defnx{#1}{#1}} \newcommand{\term}[1]{\textit{#1}} \newcommand{\gterm}[1]{\GrammarStylex{#1}} \newcommand{\fakegrammarterm}[1]{\gterm{#1}} \newcommand{\grammarterm}[1]{\indexgram{\idxgram{#1}}\gterm{#1}} -\newcommand{\grammartermnc}[1]{\indexgram{\idxgram{#1}}\gterm{#1}\nocorr} +\newcommand{\grammartermnc}[1]{\indexgram{\idxgram{#1}}\gterm{#1\nocorr}} \newcommand{\placeholder}[1]{\textit{#1}} \newcommand{\placeholdernc}[1]{\textit{#1\nocorr}} +\newcommand{\defnxname}[1]{\indextext{\idxxname{#1}}\xname{#1}} +\newcommand{\defnlibxname}[1]{\indexlibrary{\idxxname{#1}}\xname{#1}} + +% Non-compound defined term. +\newcommand{\defn}[1]{\defnx{#1}{#1}} +% Defined term with different index entry. +\newcommand{\defnx}[2]{\indexdefn{#2}\textit{#1}} +% Compound defined term with 'see' for primary term. +% Usage: \defnadj{trivial}{class} +\newcommand{\defnadj}[2]{\indextext{#1 #2|see{#2, #1}}\indexdefn{#2!#1}\textit{#1 #2}} %%-------------------------------------------------- %% allow line break if needed for justification @@ -215,15 +223,15 @@ %%-------------------------------------------------- %% States and operators \newcommand{\state}[2]{\tcode{#1}\ensuremath{_{#2}}} -\newcommand{\bitand}{\ensuremath{\, \mathsf{bitand} \,}} -\newcommand{\bitor}{\ensuremath{\, \mathsf{bitor} \,}} -\newcommand{\xor}{\ensuremath{\, \mathsf{xor} \,}} -\newcommand{\rightshift}{\ensuremath{\, \mathsf{rshift} \,}} -\newcommand{\leftshift}[1]{\ensuremath{\, \mathsf{lshift}_#1 \,}} +\newcommand{\bitand}{\ensuremath{\mathbin{\mathsf{bitand}}}} +\newcommand{\bitor}{\ensuremath{\mathbin{\mathsf{bitor}}}} +\newcommand{\xor}{\ensuremath{\mathbin{\mathsf{xor}}}} +\newcommand{\rightshift}{\ensuremath{\mathbin{\mathsf{rshift}}}} +\newcommand{\leftshift}[1]{\ensuremath{\mathbin{\mathsf{lshift}_{#1}}}} %% Notes and examples -\newcommand{\noteintro}[1]{[\,\textit{#1:}\space} -\newcommand{\noteoutro}[1]{\textit{\,---\,end #1}\,]} +\newcommand{\noteintro}[1]{[\textit{#1}:\space} +\newcommand{\noteoutro}[1]{\textit{\,---\,end #1}\kern.5pt]} \newenvironment{note}[1][Note]{\noteintro{#1}}{\noteoutro{note}\space} \newenvironment{example}[1][Example]{\noteintro{#1}}{\noteoutro{example}\space} @@ -232,8 +240,12 @@ \newcommand{\Fundesc}[1]{\Fundescx{#1:}\space} \newcommand{\required}{\Fundesc{Required behavior}} \newcommand{\requires}{\Fundesc{Requires}} +\newcommand{\constraints}{\Fundesc{Constraints}} +\newcommand{\mandates}{\Fundesc{Mandates}} +\newcommand{\expects}{\Fundesc{Expects}} \newcommand{\effects}{\Fundesc{Effects}} -\newcommand{\postconditions}{\Fundesc{Postconditions}} +\newcommand{\ensures}{\Fundesc{Ensures}} +\newcommand{\postconditions}{\ensures} \newcommand{\returns}{\Fundesc{Returns}} \newcommand{\throws}{\Fundesc{Throws}} \newcommand{\default}{\Fundesc{Default behavior}} @@ -288,8 +300,6 @@ \newcommand{\unspecuniqtype}{\UNSP{unspecified unique type}} \newcommand{\unspecalloctype}{\UNSP{unspecified allocator type}} -\newcommand{\EXPLICIT}{\textit{\texttt{EXPLICIT}\nocorr}} - %% Manual insertion of italic corrections, for aligning in the presence %% of the above annotations. \newlength{\itcorrwidth} @@ -312,6 +322,12 @@ %% Produces 9 output characters. \newcommand{\commentellip}{\tcode{/* ...\ */}} +%% Concepts +\newcommand{\oldconcept}[1]{\textit{Cpp17#1}} +\newcommand{\oldconceptdefn}[1]{\defn{Cpp17#1}} +\newcommand{\idxoldconcept}[1]{Cpp17#1@\textit{Cpp17#1}} +\newcommand{\libconcept}[1]{\tcode{#1}} + %% Ranges \newcommand{\Range}[4]{\tcode{#1#3,\penalty2000{} #4#2}} \newcommand{\crange}[2]{\Range{[}{]}{#1}{#2}} @@ -323,6 +339,8 @@ \newcommand{\diffdef}[1]{\hfill\break\textbf{#1:}\space} \newcommand{\diffref}[1]{\pnum\textbf{Affected subclause:} \ref{#1}} \newcommand{\diffrefs}[2]{\pnum\textbf{Affected subclauses:} \ref{#1}, \ref{#2}} +% \nodiffref swallows a following \change and removes the preceding line break. +\def\nodiffref\change{\pnum\textbf{Change:}\space} \newcommand{\change}{\diffdef{Change}} \newcommand{\rationale}{\diffdef{Rationale}} \newcommand{\effect}{\diffdef{Effect on original feature}} @@ -360,14 +378,13 @@ % 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, - midpenalty=500, endpenalty=-50, - emptylinepenalty=-250, semicolonpenalty=0} - \renewcommand{\tcode}[1]{\textup{\CodeStylex{##1}}} - \renewcommand{\techterm}[1]{\textit{\CodeStylex{##1}}} - \renewcommand{\term}[1]{\textit{##1}} - \renewcommand{\grammarterm}[1]{\gterm{##1}} +\newcommand{\CodeBlockSetup}{% +\lstset{escapechar=@, aboveskip=\parskip, belowskip=0pt, + midpenalty=500, endpenalty=-50, + emptylinepenalty=-250, semicolonpenalty=0}% +\renewcommand{\tcode}[1]{\textup{\CodeStylex{##1}}}% +\renewcommand{\term}[1]{\textit{##1}}% +\renewcommand{\grammarterm}[1]{\gterm{##1}}% } \lstnewenvironment{codeblock}{\CodeBlockSetup}{} diff --git a/source/numerics.tex b/source/numerics.tex index c1762a98db..24773dae2a 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -21,9 +21,9 @@ \ref{numeric.requirements} & Requirements & \\ \rowsep \ref{cfenv} & Floating-point environment & \tcode{} \\ \rowsep \ref{complex.numbers} & Complex numbers & \tcode{} \\ \rowsep +\ref{bit} & Bit manipulation & \tcode{} \\ \rowsep \ref{rand} & Random number generation & \tcode{} \\ \rowsep \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{} \\ \end{libsumtab} @@ -179,16 +179,16 @@ \indexlibrary{\idxcode{FE_DFL_ENV}}% \begin{codeblock} #define FE_ALL_EXCEPT @\seebelow@ -#define FE_DIVBYZERO @\seebelow@ -#define FE_INEXACT @\seebelow@ -#define FE_INVALID @\seebelow@ -#define FE_OVERFLOW @\seebelow@ -#define FE_UNDERFLOW @\seebelow@ +#define FE_DIVBYZERO @\seebelow@ // optional +#define FE_INEXACT @\seebelow@ // optional +#define FE_INVALID @\seebelow@ // optional +#define FE_OVERFLOW @\seebelow@ // optional +#define FE_UNDERFLOW @\seebelow@ // optional -#define FE_DOWNWARD @\seebelow@ -#define FE_TONEAREST @\seebelow@ -#define FE_TOWARDZERO @\seebelow@ -#define FE_UPWARD @\seebelow@ +#define FE_DOWNWARD @\seebelow@ // optional +#define FE_TONEAREST @\seebelow@ // optional +#define FE_TOWARDZERO @\seebelow@ // optional +#define FE_UPWARD @\seebelow@ // optional #define FE_DFL_ENV @\seebelow@ @@ -269,7 +269,7 @@ undefined. \pnum -If \tcode{z} is an lvalue expression of type \cv{} \tcode{complex} then: +If \tcode{z} is an lvalue of type \cv{} \tcode{complex} then: \begin{itemize} \item the expression \tcode{reinterpret_cast<\cv{} T(\&)[2]>(z)} shall be well-formed, @@ -437,6 +437,7 @@ using value_type = float; constexpr complex(float re = 0.0f, float im = 0.0f); + constexpr complex(const complex&) = default; constexpr explicit complex(const complex&); constexpr explicit complex(const complex&); @@ -465,6 +466,7 @@ constexpr complex(double re = 0.0, double im = 0.0); constexpr complex(const complex&); + constexpr complex(const complex&) = default; constexpr explicit complex(const complex&); constexpr double real() const; @@ -493,6 +495,7 @@ constexpr complex(long double re = 0.0L, long double im = 0.0L); constexpr complex(const complex&); constexpr complex(const complex&); + constexpr complex(const complex&) = default; constexpr long double real() const; constexpr void real(long double); @@ -1191,7 +1194,7 @@ \begin{itemdescr} \pnum \returns -The complex power of base \tcode{x} raised to the \tcode{y}$^\text{th}$ power, +The complex power of base \tcode{x} raised to the $\tcode{y}^\text{th}$ power, defined as \tcode{exp(y * log(x))}. The value returned for @@ -1360,6 +1363,152 @@ \tcode{complex\{0.0f, static_cast(d)\}}. \end{itemdescr} + +\rSec1[bit]{Bit manipulation} + +\rSec2[bit.general]{General} + +\pnum +The header \tcode{} provides components to access, +manipulate and process both individual bits and bit sequences. + +\rSec2[bit.syn]{Header \tcode{} synopsis} +\indexhdr{bit}% +\begin{codeblock} +namespace std { + // \ref{bit.cast}, \tcode{bit_cast} + template + constexpr To bit_cast(const From& from) noexcept; + + // \ref{bit.pow.two}, integral powers of 2 + template + constexpr bool ispow2(T x) noexcept; + template + constexpr T ceil2(T x) noexcept; + template + constexpr T floor2(T x) noexcept; + template + constexpr T log2p1(T x) noexcept; +} +\end{codeblock} + +\rSec2[bit.cast]{Function template \tcode{bit_cast}} + +\indexlibrary{\idxcode{bit_cast}}% +\begin{itemdecl} +template + constexpr To bit_cast(const From& from) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +An object of type \tcode{To}. +Each bit of the value representation of the result +is equal to the corresponding bit in the object representation +of \tcode{from}. Padding bits of the \tcode{To} object are unspecified. +If there is no value of type \tcode{To} corresponding to the +value representation produced, the behavior is undefined. +If there are multiple such values, which value is produced is unspecified. + +\pnum +\remarks +This function shall not participate in overload resolution unless: +\begin{itemize} +\item \tcode{sizeof(To) == sizeof(From)} is \tcode{true}; +\item \tcode{is_trivially_copyable_v} is \tcode{true}; and +\item \tcode{is_trivially_copyable_v} is \tcode{true}. +\end{itemize} +This function shall be \tcode{constexpr} if and only if +\tcode{To}, \tcode{From}, and the types of all subobjects +of \tcode{To} and \tcode{From} are types \tcode{T} such that: +\begin{itemize} +\item \tcode{is_union_v} is \tcode{false}; +\item \tcode{is_pointer_v} is \tcode{false}; +\item \tcode{is_member_pointer_v} is \tcode{false}; +\item \tcode{is_volatile_v} is \tcode{false}; and +\item \tcode{T} has no non-static data members of reference type. +\end{itemize} +\end{itemdescr} + +\rSec2[bit.pow.two]{Integral powers of 2} + +\indexlibrary{\idxcode{ispow2}}% +\begin{itemdecl} +template + constexpr bool ispow2(T x) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if \tcode{x} is an integral power of two; +\tcode{false} otherwise. + +\pnum +\remarks +This function shall not participate in overload resolution +unless \tcode{T} is an unsigned integer type\iref{basic.fundamental}. +\end{itemdescr} + +\indexlibrary{\idxcode{ceil2}}% +\begin{itemdecl} +template + constexpr T ceil2(T x) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The minimal value \tcode{y} such that +\tcode{ispow2(y)} is \tcode{true} and \tcode{y >= x}; +if \tcode{y} is not representable as a value of type \tcode{T}, +the result is an unspecified value. + +\pnum +\remarks +This function shall not participate in overload resolution +unless \tcode{T} is an unsigned integer type\iref{basic.fundamental}. +\end{itemdescr} + +\indexlibrary{\idxcode{floor2}}% +\begin{itemdecl} +template + constexpr T floor2(T x) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If \tcode{x == 0}, \tcode{0}; +otherwise the maximal value \tcode{y} +such that \tcode{ispow2(y)} is \tcode{true} and \tcode{y <= x}. + +\pnum +\remarks +This function shall not participate in overload resolution +unless \tcode{T} is an unsigned integer type\iref{basic.fundamental}. +\end{itemdescr} + +\indexlibrary{\idxcode{log2p1}}% +\begin{itemdecl} +template + constexpr T log2p1(T x) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If \tcode{x == 0}, \tcode{0}; +otherwise one plus the base-2 logarithm of \tcode{x}, +with any fractional part discarded. + +\pnum +\remarks +This function shall not participate in overload resolution +unless \tcode{T} is an unsigned integer type\iref{basic.fundamental}. +\end{itemdescr} + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1373,7 +1522,6 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - \rSec1[rand]{Random number generation} \indextext{random number generation|(}% @@ -1389,11 +1537,11 @@ \pnum In addition to a few utilities, four categories of entities are described: -\techterm{uniform random bit generators}, -\techterm{random number engines}, -\techterm{random number engine adaptors}, +\term{uniform random bit generators}, +\term{random number engines}, +\term{random number engine adaptors}, and -\techterm{random number distributions}. +\term{random number distributions}. These categorizations are applicable to types that satisfy the corresponding requirements, to objects instantiated from such types, @@ -1419,20 +1567,20 @@ that entity is characterized: \begin{enumeratea} \item - as \techterm{boolean} or equivalently as \techterm{boolean-valued}, + as \term{boolean} or equivalently as \term{boolean-valued}, if \tcode{T} is \tcode{bool}; \item otherwise - as \techterm{integral} or equivalently as \techterm{integer-valued}, + as \term{integral} or equivalently as \term{integer-valued}, if \tcode{numeric_limits::is_integer} is \tcode{true}; \item otherwise - as \techterm{floating} or equivalently as \techterm{real-valued}. + as \term{floating} or equivalently as \term{real-valued}. \end{enumeratea} \noindent If integer-valued, an entity may optionally be further characterized as -\techterm{signed} or \techterm{unsigned}, +\term{signed} or \term{unsigned}, according to \tcode{numeric_limits::is_signed}. \pnum @@ -1444,7 +1592,7 @@ \pnum Throughout this subclause, the operators -\bitand, \bitor, and \xor +\bitand, \bitor, and \xor{} denote the respective conventional bitwise operations. Further: @@ -1459,6 +1607,160 @@ \end{enumeratea} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% Header synopsis subclause +%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +\rSec2[rand.synopsis]{Header \tcode{} synopsis}% +\indexhdr{random} +\indextext{random number generation!synopsis|(} + +\begin{codeblock} +#include + +namespace std { + // \ref{rand.req.urng}, uniform random bit generator requirements + template + concept UniformRandomBitGenerator = @\seebelow@; + + // \ref{rand.eng.lcong}, class template \tcode{linear_congruential_engine} + template + class linear_congruential_engine; + + // \ref{rand.eng.mers}, class template \tcode{mersenne_twister_engine} + template + class mersenne_twister_engine; + + // \ref{rand.eng.sub}, class template \tcode{subtract_with_carry_engine} + template + class subtract_with_carry_engine; + + // \ref{rand.adapt.disc}, class template \tcode{discard_block_engine} + template + class discard_block_engine; + + // \ref{rand.adapt.ibits}, class template \tcode{independent_bits_engine} + template + class independent_bits_engine; + + // \ref{rand.adapt.shuf}, class template \tcode{shuffle_order_engine} + template + class shuffle_order_engine; + + // \ref{rand.predef}, engines and engine adaptors with predefined parameters + using minstd_rand0 = @\seebelow@; + using minstd_rand = @\seebelow@; + using mt19937 = @\seebelow@; + using mt19937_64 = @\seebelow@; + using ranlux24_base = @\seebelow@; + using ranlux48_base = @\seebelow@; + using ranlux24 = @\seebelow@; + using ranlux48 = @\seebelow@; + using knuth_b = @\seebelow@; + + using default_random_engine = @\seebelow@; + + // \ref{rand.device}, class \tcode{random_device} + class random_device; + + // \ref{rand.util.seedseq}, class \tcode{seed_seq} + class seed_seq; + + // \ref{rand.util.canonical}, function template \tcode{generate_canonical} + template + RealType generate_canonical(URBG& g); + + // \ref{rand.dist.uni.int}, class template \tcode{uniform_int_distribution} + template + class uniform_int_distribution; + + // \ref{rand.dist.uni.real}, class template \tcode{uniform_real_distribution} + template + class uniform_real_distribution; + + // \ref{rand.dist.bern.bernoulli}, class \tcode{bernoulli_distribution} + class bernoulli_distribution; + + // \ref{rand.dist.bern.bin}, class template \tcode{binomial_distribution} + template + class binomial_distribution; + + // \ref{rand.dist.bern.geo}, class template \tcode{geometric_distribution} + template + class geometric_distribution; + + // \ref{rand.dist.bern.negbin}, class template \tcode{negative_binomial_distribution} + template + class negative_binomial_distribution; + + // \ref{rand.dist.pois.poisson}, class template \tcode{poisson_distribution} + template + class poisson_distribution; + + // \ref{rand.dist.pois.exp}, class template \tcode{exponential_distribution} + template + class exponential_distribution; + + // \ref{rand.dist.pois.gamma}, class template \tcode{gamma_distribution} + template + class gamma_distribution; + + // \ref{rand.dist.pois.weibull}, class template \tcode{weibull_distribution} + template + class weibull_distribution; + + // \ref{rand.dist.pois.extreme}, class template \tcode{extreme_value_distribution} + template + class extreme_value_distribution; + + // \ref{rand.dist.norm.normal}, class template \tcode{normal_distribution} + template + class normal_distribution; + + // \ref{rand.dist.norm.lognormal}, class template \tcode{lognormal_distribution} + template + class lognormal_distribution; + + // \ref{rand.dist.norm.chisq}, class template \tcode{chi_squared_distribution} + template + class chi_squared_distribution; + + // \ref{rand.dist.norm.cauchy}, class template \tcode{cauchy_distribution} + template + class cauchy_distribution; + + // \ref{rand.dist.norm.f}, class template \tcode{fisher_f_distribution} + template + class fisher_f_distribution; + + // \ref{rand.dist.norm.t}, class template \tcode{student_t_distribution} + template + class student_t_distribution; + + // \ref{rand.dist.samp.discrete}, class template \tcode{discrete_distribution} + template + class discrete_distribution; + + // \ref{rand.dist.samp.pconst}, class template \tcode{piecewise_constant_distribution} + template + class piecewise_constant_distribution; + + // \ref{rand.dist.samp.plinear}, class template \tcode{piecewise_linear_distribution} + template + class piecewise_linear_distribution; +} +\end{codeblock}% +\indextext{random number generation!synopsis|)}% + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% @@ -1560,7 +1862,7 @@ \indextext{requirements!seed sequence|(} \pnum - A \techterm{seed sequence}\indextext{seed sequence} + A \term{seed sequence}\indextext{seed sequence} is an object that consumes a sequence of integer-valued data @@ -1701,7 +2003,7 @@ \indextext{requirements!uniform random bit generator|(} \pnum -A \techterm{uniform random bit generator} +A \term{uniform random bit generator} \tcode{g} of type \tcode{G} is a function object returning unsigned integer values @@ -1715,76 +2017,38 @@ is often determined statistically. \end{note} +\begin{codeblock} +template + concept UniformRandomBitGenerator = + Invocable && UnsignedIntegral> && + requires { + G::min(); requires Same>; + G::max(); requires Same>; + }; +\end{codeblock} + \pnum -A class \tcode{G} -satisfies the requirements -of a \techterm{uniform random bit generator} -if the expressions shown -in \tref{UniformRandomBitGenerator} -are valid and have the indicated semantics, -and if \tcode{G} also satisfies all other requirements -of this subclause \ref{rand.req.urng}. -In that Table and throughout this subclause: -\begin{enumeratea} - \item - \tcode{T} is the type named by - \tcode{G}'s associated \tcode{result_type}, - and - \item - \tcode{g} is a value of \tcode{G}. -\end{enumeratea} +Let \tcode{g} be an object of type \tcode{G}. \tcode{G} models +\libconcept{UniformRandomBitGenerator} only if -\begin{libreqtab4d} - {Uniform random bit generator requirements} - {tab:UniformRandomBitGenerator} -\\ \topline -\lhdr{Expression} - & \chdr{Return type} - & \chdr{Pre/post-condition} - & \rhdr{Complexity} - \\ \capsep -\endfirsthead -\hline -\lhdr{Expression} - & \chdr{Return type} - & \chdr{Pre/post-condition} - & \rhdr{Complexity} - \\ \capsep -\endhead -\indextext{\idxcode{result_type}!uniform random bit generator requirement}% -\tcode{G::result_type} - & \tcode{T} - & \tcode{T} is an unsigned integer type\iref{basic.fundamental}. - & compile-time - \\ \rowsep -\tcode{g()}% -\indextext{\idxcode{operator()}!uniform random bit generator requirement} - & \tcode{T} - & Returns a value in the closed interval - $[$\tcode{G::min()}, \tcode{G::max()}$]$. - & amortized constant - \\ \rowsep -\tcode{G::min()}% -\indextext{\idxcode{min}!uniform random bit generator requirement} - & \tcode{T} - & Denotes the least value potentially returned - by \tcode{operator()}. - & compile-time - \\ \rowsep -\tcode{G::max()} -\indextext{\idxcode{max}!uniform random bit generator requirement} - & \tcode{T} - & Denotes the greatest value potentially returned - by \tcode{operator()}. - & compile-time - \\ -\end{libreqtab4d} +\begin{itemize} +\item both \tcode{G::min()} and \tcode{G::max()} are constant + expressions\iref{expr.const}, +\item \tcode{G::min() < G::max()}, +\item \tcode{G::min() <= g()}, +\item \tcode{g() <= G::max()}, and +\item \tcode{g()} has amortized constant complexity. +\end{itemize} -\pnum -The following relation shall hold: -\tcode{G::min() < G::max()}. \indextext{requirements!uniform random bit generator|)}% -\indextext{uniform random bit generator!requirements|)} +\indextext{uniform random bit generator!requirements|)}% +\pnum +A class \tcode{G} meets the \term{uniform random bit generator} requirements if +\tcode{G} models \libconcept{UniformRandomBitGenerator}, +\tcode{invoke_result_t} is an unsigned integer type\iref{basic.fundamental}, +and +\tcode{G} provides a nested \grammarterm{typedef-name} \tcode{result_type} +that denotes the same type as \tcode{invoke_result_t}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1795,8 +2059,8 @@ \indextext{requirements!random number engine|(} \pnum -A \techterm{random number engine} -(commonly shortened to \techterm{engine}) +A \term{random number engine} +(commonly shortened to \term{engine}) \tcode{e} of type \tcode{E} is a uniform random bit generator that additionally meets the requirements @@ -1824,14 +2088,14 @@ in multiples of the size of \tcode{result_type}, given as an integral constant expression; \item - the \techterm{transition algorithm} + the \term{transition algorithm} $\mathsf{TA}$ by which \tcode{e}'s state \state{e}{i} - is advanced to its \techterm{successor state} + is advanced to its \term{successor state} \state{e}{i+1}; and \item - the \techterm{generation algorithm} + the \term{generation algorithm} $\mathsf{GA}$ by which an engine's state is mapped to a value of type \tcode{result_type}. @@ -1842,7 +2106,7 @@ that satisfies the requirements of a uniform random bit generator\iref{rand.req.urng} also satisfies the requirements -of a \techterm{random number engine} +of a \term{random number engine} if the expressions shown in \tref{RandomEngine} are valid and have the indicated semantics, @@ -1961,7 +2225,7 @@ \state{e}{i+1} $= \mathsf{TA}($\state{e}{i}$)$ and returns $\mathsf{GA}($\state{e}{i}$)$. - & per \tref{UniformRandomBitGenerator} + & per \ref{rand.req.urng} \\ \rowsep \tcode{e.discard(z)}% \indextext{\idxcode{discard}!random number engine requirement} @@ -2052,8 +2316,8 @@ \pnum \tcode{E} shall satisfy the -\tcode{CopyConstructible} (\tref{copyconstructible}) -and \tcode{CopyAssignable} (\tref{copyassignable}) requirements. +\oldconcept{CopyConstructible} (\tref{copyconstructible}) +and \oldconcept{CopyAssignable} (\tref{copyassignable}) requirements. These operations shall each be of complexity no worse than \bigoh{\text{size of state}}. @@ -2068,8 +2332,8 @@ \rSec3[rand.req.adapt]{Random number engine adaptor requirements}% \pnum -A \techterm{random number engine adaptor} -(commonly shortened to \techterm{adaptor}) +A \term{random number engine adaptor} +(commonly shortened to \term{adaptor}) \tcode{a} of type \tcode{A} is a random number engine that takes values @@ -2078,7 +2342,7 @@ in order to deliver a sequence of values with different randomness properties. An engine \tcode{b} of type \tcode{B} adapted in this way -is termed a \techterm{base engine} +is termed a \term{base engine} in this context. The expression \tcode{a.base()} shall be valid and shall return a const reference to \tcode{a}'s base engine. @@ -2194,16 +2458,16 @@ \indextext{requirements!random number distribution|(} \pnum -A \techterm{random number distribution} -(commonly shortened to \techterm{distribution}) +A \term{random number distribution} +(commonly shortened to \term{distribution}) \tcode{d} of type \tcode{D} is a function object returning values that are distributed according to -an associated mathematical \techterm{probability density function} +an associated mathematical \term{probability density function} $p(z)$ or according to -an associated \techterm{discrete probability function} +an associated \term{discrete probability function} $P(z_i)$. A distribution's specification identifies its associated probability function @@ -2212,7 +2476,7 @@ \pnum An associated probability function is typically expressed using certain externally-supplied quantities -known as the \techterm{parameters of the distribution}. +known as the \term{parameters of the distribution}. Such distribution parameters are identified in this context by writing, for example, $p(z\,|\,a,b)$ or $P(z_i\,|\,a,b)$, @@ -2225,7 +2489,7 @@ \pnum A class \tcode{D} satisfies the requirements -of a \techterm{random number distribution} +of a \term{random number distribution} if the expressions shown in \tref{RandomDistribution} are valid and have the indicated semantics, @@ -2431,8 +2695,8 @@ \pnum \tcode{D} shall satisfy the -\tcode{CopyConstructible} (\tref{copyconstructible}) -and \tcode{CopyAssignable} (\tref{copyassignable}) requirements. +\oldconcept{CopyConstructible} (\tref{copyconstructible}) +and \oldconcept{CopyAssignable} (\tref{copyassignable}) requirements. \pnum The sequence of numbers @@ -2463,10 +2727,10 @@ \pnum \tcode{P} shall satisfy the -\tcode{CopyConstructible} (\tref{copyconstructible}), -\tcode{CopyAssignable} (\tref{copyassignable}), +\oldconcept{CopyConstructible} (\tref{copyconstructible}), +\oldconcept{CopyAssignable} (\tref{copyassignable}), and -\tcode{EqualityComparable} (\tref{equalitycomparable}) requirements. +\oldconcept{Equality\-Comp\-arable} (\tref{equalitycomparable}) requirements. \pnum For each of the constructors of \tcode{D} @@ -2491,156 +2755,6 @@ \indextext{random number generation!requirements|)} -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% -%% Header synopsis subclause -%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - -\rSec2[rand.synopsis]{Header \tcode{} synopsis}% -\indexhdr{random} -\indextext{random number generation!synopsis|(} - -\begin{codeblock} -#include - -namespace std { - // \ref{rand.eng.lcong}, class template \tcode{linear_congruential_engine} - template - class linear_congruential_engine; - - // \ref{rand.eng.mers}, class template \tcode{mersenne_twister_engine} - template - class mersenne_twister_engine; - - // \ref{rand.eng.sub}, class template \tcode{subtract_with_carry_engine} - template - class subtract_with_carry_engine; - - // \ref{rand.adapt.disc}, class template \tcode{discard_block_engine} - template - class discard_block_engine; - - // \ref{rand.adapt.ibits}, class template \tcode{independent_bits_engine} - template - class independent_bits_engine; - - // \ref{rand.adapt.shuf}, class template \tcode{shuffle_order_engine} - template - class shuffle_order_engine; - - // \ref{rand.predef}, engines and engine adaptors with predefined parameters - using minstd_rand0 = @\seebelow@; - using minstd_rand = @\seebelow@; - using mt19937 = @\seebelow@; - using mt19937_64 = @\seebelow@; - using ranlux24_base = @\seebelow@; - using ranlux48_base = @\seebelow@; - using ranlux24 = @\seebelow@; - using ranlux48 = @\seebelow@; - using knuth_b = @\seebelow@; - - using default_random_engine = @\seebelow@; - - // \ref{rand.device}, class \tcode{random_device} - class random_device; - - // \ref{rand.util.seedseq}, class \tcode{seed_seq} - class seed_seq; - - // \ref{rand.util.canonical}, function template \tcode{generate_canonical} - template - RealType generate_canonical(URBG& g); - - // \ref{rand.dist.uni.int}, class template \tcode{uniform_int_distribution} - template - class uniform_int_distribution; - - // \ref{rand.dist.uni.real}, class template \tcode{uniform_real_distribution} - template - class uniform_real_distribution; - - // \ref{rand.dist.bern.bernoulli}, class \tcode{bernoulli_distribution} - class bernoulli_distribution; - - // \ref{rand.dist.bern.bin}, class template \tcode{binomial_distribution} - template - class binomial_distribution; - - // \ref{rand.dist.bern.geo}, class template \tcode{geometric_distribution} - template - class geometric_distribution; - - // \ref{rand.dist.bern.negbin}, class template \tcode{negative_binomial_distribution} - template - class negative_binomial_distribution; - - // \ref{rand.dist.pois.poisson}, class template \tcode{poisson_distribution} - template - class poisson_distribution; - - // \ref{rand.dist.pois.exp}, class template \tcode{exponential_distribution} - template - class exponential_distribution; - - // \ref{rand.dist.pois.gamma}, class template \tcode{gamma_distribution} - template - class gamma_distribution; - - // \ref{rand.dist.pois.weibull}, class template \tcode{weibull_distribution} - template - class weibull_distribution; - - // \ref{rand.dist.pois.extreme}, class template \tcode{extreme_value_distribution} - template - class extreme_value_distribution; - - // \ref{rand.dist.norm.normal}, class template \tcode{normal_distribution} - template - class normal_distribution; - - // \ref{rand.dist.norm.lognormal}, class template \tcode{lognormal_distribution} - template - class lognormal_distribution; - - // \ref{rand.dist.norm.chisq}, class template \tcode{chi_squared_distribution} - template - class chi_squared_distribution; - - // \ref{rand.dist.norm.cauchy}, class template \tcode{cauchy_distribution} - template - class cauchy_distribution; - - // \ref{rand.dist.norm.f}, class template \tcode{fisher_f_distribution} - template - class fisher_f_distribution; - - // \ref{rand.dist.norm.t}, class template \tcode{student_t_distribution} - template - class student_t_distribution; - - // \ref{rand.dist.samp.discrete}, class template \tcode{discrete_distribution} - template - class discrete_distribution; - - // \ref{rand.dist.samp.pconst}, class template \tcode{piecewise_constant_distribution} - template - class piecewise_constant_distribution; - - // \ref{rand.dist.samp.plinear}, class template \tcode{piecewise_linear_distribution} - template - class piecewise_linear_distribution; -} -\end{codeblock}% -\indextext{random number generation!synopsis|)}% - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% @@ -2767,7 +2881,8 @@ static constexpr result_type default_seed = 1u; // constructors and seeding functions - explicit linear_congruential_engine(result_type s = default_seed); + linear_congruential_engine() : linear_congruential_engine(default_seed) {} + explicit linear_congruential_engine(result_type s); template explicit linear_congruential_engine(Sseq& q); void seed(result_type s = default_seed); template void seed(Sseq& q); @@ -2805,7 +2920,7 @@ \indexlibrary{\idxcode{linear_congruential_engine}!constructor}% \begin{itemdecl} -explicit linear_congruential_engine(result_type s = default_seed); +explicit linear_congruential_engine(result_type s); \end{itemdecl} \begin{itemdescr} @@ -2868,7 +2983,7 @@ defined by shift values $n$ and $m$, a twist value $r$, and a conditional xor-mask $a$. To improve the uniformity of the result, -the bits of the raw shift register are additionally \techterm{tempered} +the bits of the raw shift register are additionally \term{tempered} (i.e., scrambled) according to a bit-scrambling matrix defined by values $u$, $d$, $s$, $b$, $t$, $c$, and $\ell$. @@ -2883,7 +2998,7 @@ \item With $\alpha = a \cdot (Y \bitand 1)$, set $X_i$ to - $X_{i+m-n} \, \xor \, (Y \rightshift 1) \, \xor \, \alpha$. + $X_{i+m-n} \xor (Y \rightshift 1) \xor \alpha$. \end{enumeratea} The sequence $X$ is initialized with the help of an initialization multiplier $f$. @@ -2898,9 +3013,9 @@ \item Let $z_1 = X_i \xor \bigl(( X_i \rightshift u ) \bitand d\bigr)$. \item - Let $z_2 = z_1 \xor \bigl( (z_1 \leftshift{w} \, s) \bitand b \bigr)$. + Let $z_2 = z_1 \xor \bigl( (z_1 \leftshift{w} s) \bitand b \bigr)$. \item - Let $z_3 = z_2 \xor \bigl( (z_2 \leftshift{w} \, t) \bitand c \bigr)$. + Let $z_3 = z_2 \xor \bigl( (z_2 \leftshift{w} t) \bitand c \bigr)$. \item Let $z_4 = z_3 \xor ( z_3 \rightshift \ell )$. \end{enumeratea} @@ -2935,7 +3050,8 @@ static constexpr result_type default_seed = 5489u; // constructors and seeding functions - explicit mersenne_twister_engine(result_type value = default_seed); + mersenne_twister_engine() : mersenne_twister_engine(default_seed) {} + explicit mersenne_twister_engine(result_type value); template explicit mersenne_twister_engine(Sseq& q); void seed(result_type value = default_seed); template void seed(Sseq& q); @@ -2973,7 +3089,7 @@ \indexlibrary{\idxcode{mersenne_twister_engine}!constructor}% \begin{itemdecl} -explicit mersenne_twister_engine(result_type value = default_seed); +explicit mersenne_twister_engine(result_type value); \end{itemdecl} \begin{itemdescr} @@ -3039,7 +3155,7 @@ all subscripts applied to $X$ are to be taken modulo $r$. The state \state{x}{i} additionally consists of an integer $c$ -(known as the \techterm{carry})% +(known as the \term{carry})% \indextext{\idxcode{subtract_with_carry_engine}!carry}% \indextext{carry!\idxcode{subtract_with_carry_engine}} whose value is either $0$ or $1$. @@ -3092,7 +3208,8 @@ static constexpr result_type default_seed = 19780503u; // constructors and seeding functions - explicit subtract_with_carry_engine(result_type value = default_seed); + subtract_with_carry_engine() : subtract_with_carry_engine(default_seed) {} + explicit subtract_with_carry_engine(result_type value); template explicit subtract_with_carry_engine(Sseq& q); void seed(result_type value = default_seed); template void seed(Sseq& q); @@ -3122,7 +3239,7 @@ \indexlibrary{\idxcode{subtract_with_carry_engine}!constructor}% \begin{itemdecl} -explicit subtract_with_carry_engine(result_type value = default_seed); +explicit subtract_with_carry_engine(result_type value); \end{itemdecl} \begin{itemdescr} @@ -3607,7 +3724,7 @@ \begin{itemdescr} \pnum\required - The $10000^{\,\mathrm{th}}$ consecutive invocation + The $10000^\text{th}$ consecutive invocation of a default-constructed object of type \tcode{minstd_rand0} shall produce the value $1043618065$. @@ -3622,7 +3739,7 @@ \begin{itemdescr} \pnum\required - The $10000^{\,\mathrm{th}}$ consecutive invocation + The $10000^\text{th}$ consecutive invocation of a default-constructed object of type \tcode{minstd_rand} shall produce the value $399268537$. @@ -3638,7 +3755,7 @@ \begin{itemdescr} \pnum\required - The $10000^{\,\mathrm{th}}$ consecutive invocation + The $10000^\text{th}$ consecutive invocation of a default-constructed object of type \tcode{mt19937} shall produce the value $4123659995$. @@ -3658,7 +3775,7 @@ \begin{itemdescr} \pnum\required - The $10000^{\,\mathrm{th}}$ consecutive invocation + The $10000^\text{th}$ consecutive invocation of a default-constructed object of type \tcode{mt19937_64} shall produce the value $9981545732273789042$. @@ -3673,7 +3790,7 @@ \begin{itemdescr} \pnum\required - The $10000^{\,\mathrm{th}}$ consecutive invocation + The $10000^\text{th}$ consecutive invocation of a default-constructed object of type \tcode{ran\-lux24_base} shall produce the value @@ -3689,7 +3806,7 @@ \begin{itemdescr} \pnum\required - The $10000^{\,\mathrm{th}}$ consecutive invocation + The $10000^\text{th}$ consecutive invocation of a default-constructed object of type \tcode{ran\-lux48_base} shall produce the value @@ -3704,7 +3821,7 @@ \begin{itemdescr} \pnum\required - The $10000^{\,\mathrm{th}}$ consecutive invocation + The $10000^\text{th}$ consecutive invocation of a default-constructed object of type \tcode{ranlux24} shall produce the value @@ -3719,7 +3836,7 @@ \begin{itemdescr} \pnum\required - The $10000^{\,\mathrm{th}}$ consecutive invocation + The $10000^\text{th}$ consecutive invocation of a default-constructed object of type \tcode{ranlux48} shall produce the value @@ -3734,7 +3851,7 @@ \begin{itemdescr} \pnum\required - The $10000^{\,\mathrm{th}}$ consecutive invocation + The $10000^\text{th}$ consecutive invocation of a default-constructed object of type \tcode{knuth_b} shall produce the value $1112339016$. @@ -3806,7 +3923,8 @@ static constexpr result_type max() { return numeric_limits::max(); } // constructors - explicit random_device(const string& token = @\textit{implementation-defined}@); + random_device() : random_device(@\textit{implementation-defined}@) {} + explicit random_device(const string& token); // generating functions result_type operator()(); @@ -3823,15 +3941,15 @@ \indexlibrary{\idxcode{random_device}!constructor}% \begin{itemdecl} -explicit random_device(const string& token = @\textit{implementation-defined}@); +explicit random_device(const string& token); \end{itemdecl} \begin{itemdescr} \pnum\effects Constructs a \tcode{random_device} nondeterministic uniform random bit generator object. - The semantics and default value of the \tcode{token} - parameter are - \impldef{semantics and default value of \tcode{token} parameter to \tcode{random_device} constructor}.% + The semantics of the \tcode{token} parameter + and the token value used by the default constructor are + \impldef{semantics of \tcode{token} parameter and default token value used by \tcode{random_device} constructors}.% \footnote{The parameter is intended to allow an implementation to differentiate between different sources of randomness. @@ -3969,8 +4087,8 @@ \begin{itemdescr} \pnum\requires - \tcode{InputIterator} shall satisfy the requirements - of an input iterator (\tref{iterator.input.requirements}) type. + \tcode{InputIterator} shall satisfy the + \oldconcept{InputIterator} requirements\iref{input.iterators}. Moreover, \tcode{iterator_traits::value_type} shall denote an integer type. @@ -3991,9 +4109,11 @@ \begin{itemdescr} \pnum\requires \tcode{RandomAccessIterator} - shall satisfy the requirements of a mutable random access iterator\iref{random.access.iterators}. + shall satisfy the + \oldconcept{RandomAccessIterator} requirements\iref{random.access.iterators} + and the requirements of a mutable iterator. Moreover, - \tcode{iterator_traits::value_type} + \tcode{iterator_traits::\brk{}value_type} shall denote an unsigned integer type capable of accommodating 32-bit quantities. @@ -4007,7 +4127,7 @@ in which each operation is to be carried out modulo $2^{32}$, each indexing operator applied to \tcode{begin} is to be taken modulo $n$, - and $T(x)$ is defined as $x \, \xor \, (x \, \rightshift \, 27)$: + and $T(x)$ is defined as $x \xor (x \rightshift 27)$: \begin{enumeratea} \item @@ -4096,8 +4216,8 @@ \begin{itemdescr} \pnum\requires - \tcode{OutputIterator} shall satisfy the requirements - of an output iterator\iref{output.iterators}. + \tcode{OutputIterator} shall satisfy the + \oldconcept{OutputIterator} requirements\iref{output.iterators}. Moreover, the expression \tcode{*dest = rt} @@ -4267,7 +4387,8 @@ using param_type = @\unspec@; // constructors and reset functions - explicit uniform_int_distribution(IntType a = 0, IntType b = numeric_limits::max()); + uniform_int_distribution() : uniform_int_distribution(0) {} + explicit uniform_int_distribution(IntType a, IntType b = numeric_limits::max()); explicit uniform_int_distribution(const param_type& parm); void reset(); @@ -4290,7 +4411,7 @@ \indexlibrary{\idxcode{uniform_int_distribution}!constructor}% \begin{itemdecl} -explicit uniform_int_distribution(IntType a = 0, IntType b = numeric_limits::max()); +explicit uniform_int_distribution(IntType a, IntType b = numeric_limits::max()); \end{itemdecl} \begin{itemdescr} @@ -4352,7 +4473,8 @@ using param_type = @\unspec@; // constructors and reset functions - explicit uniform_real_distribution(RealType a = 0.0, RealType b = 1.0); + uniform_real_distribution() : uniform_real_distribution(0.0) {} + explicit uniform_real_distribution(RealType a, RealType b = 1.0); explicit uniform_real_distribution(const param_type& parm); void reset(); @@ -4375,7 +4497,7 @@ \indexlibrary{\idxcode{uniform_real_distribution}!constructor}% \begin{itemdecl} -explicit uniform_real_distribution(RealType a = 0.0, RealType b = 1.0); +explicit uniform_real_distribution(RealType a, RealType b = 1.0); \end{itemdecl} \begin{itemdescr} @@ -4451,7 +4573,8 @@ using param_type = @\unspec@; // constructors and reset functions - explicit bernoulli_distribution(double p = 0.5); + bernoulli_distribution() : bernoulli_distribution(0.5) {} + explicit bernoulli_distribution(double p); explicit bernoulli_distribution(const param_type& parm); void reset(); @@ -4473,7 +4596,7 @@ \indexlibrary{\idxcode{bernoulli_distribution}!constructor}% \begin{itemdecl} -explicit bernoulli_distribution(double p = 0.5); +explicit bernoulli_distribution(double p); \end{itemdecl} \begin{itemdescr} @@ -4521,7 +4644,8 @@ using param_type = @\unspec@; // constructors and reset functions - explicit binomial_distribution(IntType t = 1, double p = 0.5); + binomial_distribution() : binomial_distribution(1) {} + explicit binomial_distribution(IntType t, double p = 0.5); explicit binomial_distribution(const param_type& parm); void reset(); @@ -4544,7 +4668,7 @@ \indexlibrary{\idxcode{binomial_distribution}!constructor}% \begin{itemdecl} -explicit binomial_distribution(IntType t = 1, double p = 0.5); +explicit binomial_distribution(IntType t, double p = 0.5); \end{itemdecl} \begin{itemdescr} @@ -4601,7 +4725,8 @@ using param_type = @\unspec@; // constructors and reset functions - explicit geometric_distribution(double p = 0.5); + geometric_distribution() : geometric_distribution(0.5) {} + explicit geometric_distribution(double p); explicit geometric_distribution(const param_type& parm); void reset(); @@ -4623,7 +4748,7 @@ \indexlibrary{\idxcode{geometric_distribution}!constructor}% \begin{itemdecl} -explicit geometric_distribution(double p = 0.5); +explicit geometric_distribution(double p); \end{itemdecl} \begin{itemdescr} @@ -4675,7 +4800,8 @@ using param_type = @\unspec@; // constructor and reset functions - explicit negative_binomial_distribution(IntType k = 1, double p = 0.5); + negative_binomial_distribution() : negative_binomial_distribution(1) {} + explicit negative_binomial_distribution(IntType k, double p = 0.5); explicit negative_binomial_distribution(const param_type& parm); void reset(); @@ -4698,7 +4824,7 @@ \indexlibrary{\idxcode{negative_binomial_distribution}!constructor}% \begin{itemdecl} -explicit negative_binomial_distribution(IntType k = 1, double p = 0.5); +explicit negative_binomial_distribution(IntType k, double p = 0.5); \end{itemdecl} \begin{itemdescr} @@ -4760,7 +4886,7 @@ \indextext{\idxcode{poisson_distribution}!discrete probability function}% \[ P(i\,|\,\mu) = \frac{e^{-\mu} \mu^{i}}{i\,!} \text{ .} \] The distribution parameter $\mu$ -is also known as this distribution's \techterm{mean}% +is also known as this distribution's \term{mean}% \indextext{mean!\idxcode{poisson_distribution}}% \indextext{\idxcode{poisson_distribution}!mean}% . @@ -4776,7 +4902,8 @@ using param_type = @\unspec@; // constructors and reset functions - explicit poisson_distribution(double mean = 1.0); + poisson_distribution() : poisson_distribution(1.0) {} + explicit poisson_distribution(double mean); explicit poisson_distribution(const param_type& parm); void reset(); @@ -4797,7 +4924,7 @@ \indexlibrary{\idxcode{poisson_distribution}!constructor}% \begin{itemdecl} -explicit poisson_distribution(double mean = 1.0); +explicit poisson_distribution(double mean); \end{itemdecl} \begin{itemdescr} @@ -4845,7 +4972,8 @@ using param_type = @\unspec@; // constructors and reset functions - explicit exponential_distribution(RealType lambda = 1.0); + exponential_distribution() : exponential_distribution(1.0) {} + explicit exponential_distribution(RealType lambda); explicit exponential_distribution(const param_type& parm); void reset(); @@ -4867,7 +4995,7 @@ \indexlibrary{\idxcode{exponential_distribution}!constructor}% \begin{itemdecl} -explicit exponential_distribution(RealType lambda = 1.0); +explicit exponential_distribution(RealType lambda); \end{itemdecl} \begin{itemdescr} @@ -4917,7 +5045,8 @@ using param_type = @\unspec@; // constructors and reset functions - explicit gamma_distribution(RealType alpha = 1.0, RealType beta = 1.0); + gamma_distribution() : gamma_distribution(1.0) {} + explicit gamma_distribution(RealType alpha, RealType beta = 1.0); explicit gamma_distribution(const param_type& parm); void reset(); @@ -4940,7 +5069,7 @@ \indexlibrary{\idxcode{gamma_distribution}!constructor}% \begin{itemdecl} -explicit gamma_distribution(RealType alpha = 1.0, RealType beta = 1.0); +explicit gamma_distribution(RealType alpha, RealType beta = 1.0); \end{itemdecl} \begin{itemdescr} @@ -5003,7 +5132,8 @@ using param_type = @\unspec@; // constructor and reset functions - explicit weibull_distribution(RealType a = 1.0, RealType b = 1.0); + weibull_distribution() : weibull_distribution(1.0) {} + explicit weibull_distribution(RealType a, RealType b = 1.0); explicit weibull_distribution(const param_type& parm); void reset(); @@ -5025,7 +5155,7 @@ \indexlibrary{\idxcode{weibull_distribution}!constructor}% \begin{itemdecl} -explicit weibull_distribution(RealType a = 1.0, RealType b = 1.0); +explicit weibull_distribution(RealType a, RealType b = 1.0); \end{itemdecl}% \begin{itemdescr} @@ -5094,7 +5224,8 @@ using param_type = @\unspec@; // constructor and reset functions - explicit extreme_value_distribution(RealType a = 0.0, RealType b = 1.0); + extreme_value_distribution() : extreme_value_distribution(0.0) {} + explicit extreme_value_distribution(RealType a, RealType b = 1.0); explicit extreme_value_distribution(const param_type& parm); void reset(); @@ -5117,7 +5248,7 @@ \indexlibrary{\idxcode{extreme_value_distribution}!constructor}% \begin{itemdecl} -explicit extreme_value_distribution(RealType a = 0.0, RealType b = 1.0); +explicit extreme_value_distribution(RealType a, RealType b = 1.0); \end{itemdecl} \begin{itemdescr} @@ -5189,10 +5320,10 @@ \text{ .} \] The distribution parameters $\mu$ and $\sigma$ -are also known as this distribution's \techterm{mean}% +are also known as this distribution's \term{mean}% \indextext{mean!\idxcode{normal_distribution}}% \indextext{\idxcode{normal_distribution}!mean} -and \techterm{standard deviation}% +and \term{standard deviation}% \indextext{standard deviation!\idxcode{normal_distribution}}% \indextext{\idxcode{normal_distribution}!standard deviation}% . @@ -5207,7 +5338,8 @@ using param_type = @\unspec@; // constructors and reset functions - explicit normal_distribution(RealType mean = 0.0, RealType stddev = 1.0); + normal_distribution() : normal_distribution(0.0) {} + explicit normal_distribution(RealType mean, RealType stddev = 1.0); explicit normal_distribution(const param_type& parm); void reset(); @@ -5230,7 +5362,7 @@ \indexlibrary{\idxcode{normal_distribution}!constructor}% \begin{itemdecl} -explicit normal_distribution(RealType mean = 0.0, RealType stddev = 1.0); +explicit normal_distribution(RealType mean, RealType stddev = 1.0); \end{itemdecl} \begin{itemdescr} @@ -5292,7 +5424,8 @@ using param_type = @\unspec@; // constructor and reset functions - explicit lognormal_distribution(RealType m = 0.0, RealType s = 1.0); + lognormal_distribution() : lognormal_distribution(0.0) {} + explicit lognormal_distribution(RealType m, RealType s = 1.0); explicit lognormal_distribution(const param_type& parm); void reset(); @@ -5315,7 +5448,7 @@ \indexlibrary{\idxcode{lognormal_distribution}!constructor}% \begin{itemdecl} -explicit lognormal_distribution(RealType m = 0.0, RealType s = 1.0); +explicit lognormal_distribution(RealType m, RealType s = 1.0); \end{itemdecl} \begin{itemdescr} @@ -5375,7 +5508,8 @@ using param_type = @\unspec@; // constructor and reset functions - explicit chi_squared_distribution(RealType n = 1); + chi_squared_distribution() : chi_squared_distribution(1) {} + explicit chi_squared_distribution(RealType n); explicit chi_squared_distribution(const param_type& parm); void reset(); @@ -5397,7 +5531,7 @@ \indexlibrary{\idxcode{chi_squared_distribution}!constructor}% \begin{itemdecl} -explicit chi_squared_distribution(RealType n = 1); +explicit chi_squared_distribution(RealType n); \end{itemdecl} \begin{itemdescr} @@ -5446,7 +5580,8 @@ using param_type = @\unspec@; // constructor and reset functions - explicit cauchy_distribution(RealType a = 0.0, RealType b = 1.0); + cauchy_distribution() : cauchy_distribution(0.0) {} + explicit cauchy_distribution(RealType a, RealType b = 1.0); explicit cauchy_distribution(const param_type& parm); void reset(); @@ -5469,7 +5604,7 @@ \indexlibrary{\idxcode{cauchy_distribution}!constructor}% \begin{itemdecl} -explicit cauchy_distribution(RealType a = 0.0, RealType b = 1.0); +explicit cauchy_distribution(RealType a, RealType b = 1.0); \end{itemdecl} \begin{itemdescr} @@ -5533,7 +5668,8 @@ using param_type = @\unspec@; // constructor and reset functions - explicit fisher_f_distribution(RealType m = 1, RealType n = 1); + fisher_f_distribution() : fisher_f_distribution(1) {} + explicit fisher_f_distribution(RealType m, RealType n = 1); explicit fisher_f_distribution(const param_type& parm); void reset(); @@ -5556,7 +5692,7 @@ \indexlibrary{\idxcode{fisher_f_distribution}!constructor}% \begin{itemdecl} -explicit fisher_f_distribution(RealType m = 1, RealType n = 1); +explicit fisher_f_distribution(RealType m, RealType n = 1); \end{itemdecl} \begin{itemdescr} @@ -5619,7 +5755,8 @@ using param_type = @\unspec@; // constructor and reset functions - explicit student_t_distribution(RealType n = 1); + student_t_distribution() : student_t_distribution(1) {} + explicit student_t_distribution(RealType n); explicit student_t_distribution(const param_type& parm); void reset(); @@ -5641,7 +5778,7 @@ \indexlibrary{\idxcode{student_t_distribution}!constructor}% \begin{itemdecl} -explicit student_t_distribution(RealType n = 1); +explicit student_t_distribution(RealType n); \end{itemdecl} \begin{itemdescr} @@ -5699,7 +5836,7 @@ the distribution parameters are calculated as: $p_k = {w_k / S}$ for $k = 0, \dotsc, n - 1$, in which the values $w_k$, -commonly known as the \techterm{weights}% +commonly known as the \term{weights}% \indextext{\idxcode{discrete_distribution}!weights}% \indextext{weights!\idxcode{discrete_distribution}}% , shall be non-negative, non-NaN, and non-infinity. @@ -5763,8 +5900,8 @@ \begin{itemdescr} \pnum \requires - \tcode{InputIterator} shall satisfy the requirements - of an input iterator\iref{input.iterators}. + \tcode{InputIterator} shall satisfy the + \oldconcept{InputIterator} requirements\iref{input.iterators}. Moreover, \tcode{iterator_traits::value_type} shall denote a type that is convertible to \tcode{double}. @@ -5857,7 +5994,7 @@ \pnum The $n + 1$ distribution parameters $b_i$, -also known as this distribution's \techterm{interval boundaries}% +also known as this distribution's \term{interval boundaries}% \indextext{\idxcode{piecewise_constant_distribution}!interval boundaries}% \indextext{interval boundaries!\idxcode{piecewise_constant_distribution}}% , shall satisfy the relation @@ -5866,7 +6003,7 @@ the remaining $n$ distribution parameters are calculated as: \[ \rho_k = \frac{w_k}{S \cdot (b_{k+1}-b_k)} \text{ for } k = 0, \dotsc, n - 1 \text{ ,} \] in which the values $w_k$, -commonly known as the \techterm{weights}% +commonly known as the \term{weights}% \indextext{\idxcode{piecewise_constant_distribution}!weights}% \indextext{weights!\idxcode{piecewise_constant_distribution}}% , shall be non-negative, non-NaN, and non-infinity. @@ -5936,11 +6073,11 @@ \begin{itemdescr} \pnum\requires \tcode{InputIteratorB} and \tcode{InputIteratorW} - shall each satisfy the requirements - of an input iterator (\tref{iterator.input.requirements}) type. + shall each satisfy the + \oldconcept{InputIterator} requirements\iref{input.iterators}. Moreover, \tcode{iterator_traits::value_type} and - \tcode{iterator_traits::value_type} + \tcode{iterator_traits::value_type} shall each denote a type that is convertible to \tcode{double}. If \tcode{firstB == lastB} or \tcode{++firstB == lastB}, @@ -6072,14 +6209,14 @@ \pnum The $n + 1$ distribution parameters $b_i$, -also known as this distribution's \techterm{interval boundaries}% +also known as this distribution's \term{interval boundaries}% \indextext{\idxcode{piecewise_linear_distribution}!interval boundaries}% \indextext{interval boundaries!\idxcode{piecewise_linear_distribution}}% , shall satisfy the relation $b_i < b_{i+1}$ for $i = 0, \dotsc, n - 1$. Unless specified otherwise, the remaining $n + 1$ distribution parameters are calculated as $\rho_k = {w_k / S}$ for $k = 0, \dotsc, n$, in which the values $w_k$, -commonly known as the \techterm{weights at boundaries}% +commonly known as the \term{weights at boundaries}% \indextext{\idxcode{piecewise_linear_distribution}!weights at boundaries}% \indextext{weights at boundaries!\idxcode{piecewise_linear_distribution}}% , shall be non-negative, non-NaN, and non-infinity. @@ -6146,11 +6283,11 @@ \begin{itemdescr} \pnum\requires \tcode{InputIteratorB} and \tcode{InputIteratorW} - shall each satisfy the requirements - of an input iterator (\tref{iterator.input.requirements}) type. + shall each satisfy the + \oldconcept{InputIterator} requirements\iref{input.iterators}. Moreover, \tcode{iterator_traits::value_type} and - \tcode{iterator_traits::value_type} + \tcode{iterator_traits::value_type} shall each denote a type that is convertible to \tcode{double}. If \tcode{firstB == lastB} or \tcode{++firstB == lastB}, @@ -6327,72 +6464,108 @@ template void swap(valarray&, valarray&) noexcept; template valarray operator* (const valarray&, const valarray&); - template valarray operator* (const valarray&, const T&); - template valarray operator* (const T&, const valarray&); + template valarray operator* (const valarray&, + const typename valarray::value_type&); + template valarray operator* (const typename valarray::value_type&, + const valarray&); template valarray operator/ (const valarray&, const valarray&); - template valarray operator/ (const valarray&, const T&); - template valarray operator/ (const T&, const valarray&); + template valarray operator/ (const valarray&, + const typename valarray::value_type&); + template valarray operator/ (const typename valarray::value_type&, + const valarray&); template valarray operator% (const valarray&, const valarray&); - template valarray operator% (const valarray&, const T&); - template valarray operator% (const T&, const valarray&); + template valarray operator% (const valarray&, + const typename valarray::value_type&); + template valarray operator% (const typename valarray::value_type&, + const valarray&); template valarray operator+ (const valarray&, const valarray&); - template valarray operator+ (const valarray&, const T&); - template valarray operator+ (const T&, const valarray&); + template valarray operator+ (const valarray&, + const typename valarray::value_type&); + template valarray operator+ (const typename valarray::value_type&, + const valarray&); template valarray operator- (const valarray&, const valarray&); - template valarray operator- (const valarray&, const T&); - template valarray operator- (const T&, const valarray&); + template valarray operator- (const valarray&, + const typename valarray::value_type&); + template valarray operator- (const typename valarray::value_type&, + const valarray&); template valarray operator^ (const valarray&, const valarray&); - template valarray operator^ (const valarray&, const T&); - template valarray operator^ (const T&, const valarray&); + template valarray operator^ (const valarray&, + const typename valarray::value_type&); + template valarray operator^ (const typename valarray::value_type&, + const valarray&); template valarray operator& (const valarray&, const valarray&); - template valarray operator& (const valarray&, const T&); - template valarray operator& (const T&, const valarray&); + template valarray operator& (const valarray&, + const typename valarray::value_type&); + template valarray operator& (const typename valarray::value_type&, + const valarray&); template valarray operator| (const valarray&, const valarray&); - template valarray operator| (const valarray&, const T&); - template valarray operator| (const T&, const valarray&); + template valarray operator| (const valarray&, + const typename valarray::value_type&); + template valarray operator| (const typename valarray::value_type&, + const valarray&); template valarray operator<<(const valarray&, const valarray&); - template valarray operator<<(const valarray&, const T&); - template valarray operator<<(const T&, const valarray&); + template valarray operator<<(const valarray&, + const typename valarray::value_type&); + template valarray operator<<(const typename valarray::value_type&, + const valarray&); template valarray operator>>(const valarray&, const valarray&); - template valarray operator>>(const valarray&, const T&); - template valarray operator>>(const T&, const valarray&); + template valarray operator>>(const valarray&, + const typename valarray::value_type&); + template valarray operator>>(const typename valarray::value_type&, + const valarray&); template valarray operator&&(const valarray&, const valarray&); - template valarray operator&&(const valarray&, const T&); - template valarray operator&&(const T&, const valarray&); + template valarray operator&&(const valarray&, + const typename valarray::value_type&); + template valarray operator&&(const typename valarray::value_type&, + const valarray&); template valarray operator||(const valarray&, const valarray&); - template valarray operator||(const valarray&, const T&); - template valarray operator||(const T&, const valarray&); + template valarray operator||(const valarray&, + const typename valarray::value_type&); + template valarray operator||(const typename valarray::value_type&, + const valarray&); template valarray operator==(const valarray&, const valarray&); - template valarray operator==(const valarray&, const T&); - template valarray operator==(const T&, const valarray&); + template valarray operator==(const valarray&, + const typename valarray::value_type&); + template valarray operator==(const typename valarray::value_type&, + const valarray&); template valarray operator!=(const valarray&, const valarray&); - template valarray operator!=(const valarray&, const T&); - template valarray operator!=(const T&, const valarray&); + template valarray operator!=(const valarray&, + const typename valarray::value_type&); + template valarray operator!=(const typename valarray::value_type&, + const valarray&); template valarray operator< (const valarray&, const valarray&); - template valarray operator< (const valarray&, const T&); - template valarray operator< (const T&, const valarray&); + template valarray operator< (const valarray&, + const typename valarray::value_type&); + template valarray operator< (const typename valarray::value_type&, + const valarray&); template valarray operator> (const valarray&, const valarray&); - template valarray operator> (const valarray&, const T&); - template valarray operator> (const T&, const valarray&); + template valarray operator> (const valarray&, + const typename valarray::value_type&); + template valarray operator> (const typename valarray::value_type&, + const valarray&); template valarray operator<=(const valarray&, const valarray&); - template valarray operator<=(const valarray&, const T&); - template valarray operator<=(const T&, const valarray&); + template valarray operator<=(const valarray&, + const typename valarray::value_type&); + template valarray operator<=(const typename valarray::value_type&, + const valarray&); template valarray operator>=(const valarray&, const valarray&); - template valarray operator>=(const valarray&, const T&); - template valarray operator>=(const T&, const valarray&); + template valarray operator>=(const valarray&, + const typename valarray::value_type&); + template valarray operator>=(const typename valarray::value_type&, + const valarray&); template valarray abs (const valarray&); template valarray acos (const valarray&); @@ -6400,8 +6573,10 @@ template valarray atan (const valarray&); template valarray atan2(const valarray&, const valarray&); - template valarray atan2(const valarray&, const T&); - template valarray atan2(const T&, const valarray&); + template valarray atan2(const valarray&, + const typename valarray::value_type&); + template valarray atan2(const typename valarray::value_type&, + const valarray&); template valarray cos (const valarray&); template valarray cosh (const valarray&); @@ -6410,8 +6585,8 @@ template valarray log10(const valarray&); template valarray pow(const valarray&, const valarray&); - template valarray pow(const valarray&, const T&); - template valarray pow(const T&, const valarray&); + template valarray pow(const valarray&, const typename valarray::value_type&); + template valarray pow(const typename valarray::value_type&, const valarray&); template valarray sin (const valarray&); template valarray sinh (const valarray&); @@ -7406,26 +7581,46 @@ \indexlibrarymember{operator<<}{valarray}% \indexlibrarymember{operator>>}{valarray}% \begin{itemdecl} -template valarray operator* (const valarray&, const T&); -template valarray operator* (const T&, const valarray&); -template valarray operator/ (const valarray&, const T&); -template valarray operator/ (const T&, const valarray&); -template valarray operator% (const valarray&, const T&); -template valarray operator% (const T&, const valarray&); -template valarray operator+ (const valarray&, const T&); -template valarray operator+ (const T&, const valarray&); -template valarray operator- (const valarray&, const T&); -template valarray operator- (const T&, const valarray&); -template valarray operator^ (const valarray&, const T&); -template valarray operator^ (const T&, const valarray&); -template valarray operator& (const valarray&, const T&); -template valarray operator& (const T&, const valarray&); -template valarray operator| (const valarray&, const T&); -template valarray operator| (const T&, const valarray&); -template valarray operator<<(const valarray&, const T&); -template valarray operator<<(const T&, const valarray&); -template valarray operator>>(const valarray&, const T&); -template valarray operator>>(const T&, const valarray&); +template valarray operator* (const valarray&, + const typename valarray::value_type&); +template valarray operator* (const typename valarray::value_type&, + const valarray&); +template valarray operator/ (const valarray&, + const typename valarray::value_type&); +template valarray operator/ (const typename valarray::value_type&, + const valarray&); +template valarray operator% (const valarray&, + const typename valarray::value_type&); +template valarray operator% (const typename valarray::value_type&, + const valarray&); +template valarray operator+ (const valarray&, + const typename valarray::value_type&); +template valarray operator+ (const typename valarray::value_type&, + const valarray&); +template valarray operator- (const valarray&, + const typename valarray::value_type&); +template valarray operator- (const typename valarray::value_type&, + const valarray&); +template valarray operator^ (const valarray&, + const typename valarray::value_type&); +template valarray operator^ (const typename valarray::value_type&, + const valarray&); +template valarray operator& (const valarray&, + const typename valarray::value_type&); +template valarray operator& (const typename valarray::value_type&, + const valarray&); +template valarray operator| (const valarray&, + const typename valarray::value_type&); +template valarray operator| (const typename valarray::value_type&, + const valarray&); +template valarray operator<<(const valarray&, + const typename valarray::value_type&); +template valarray operator<<(const typename valarray::value_type&, + const valarray&); +template valarray operator>>(const valarray&, + const typename valarray::value_type&); +template valarray operator>>(const typename valarray::value_type&, + const valarray&); \end{itemdecl} \begin{itemdescr} @@ -7494,22 +7689,38 @@ \indexlibrarymember{operator\&\&}{valarray}% \indexlibrarymember{operator"|"|}{valarray}% \begin{itemdecl} -template valarray operator==(const valarray&, const T&); -template valarray operator==(const T&, const valarray&); -template valarray operator!=(const valarray&, const T&); -template valarray operator!=(const T&, const valarray&); -template valarray operator< (const valarray&, const T&); -template valarray operator< (const T&, const valarray&); -template valarray operator> (const valarray&, const T&); -template valarray operator> (const T&, const valarray&); -template valarray operator<=(const valarray&, const T&); -template valarray operator<=(const T&, const valarray&); -template valarray operator>=(const valarray&, const T&); -template valarray operator>=(const T&, const valarray&); -template valarray operator&&(const valarray&, const T&); -template valarray operator&&(const T&, const valarray&); -template valarray operator||(const valarray&, const T&); -template valarray operator||(const T&, const valarray&); +template valarray operator==(const valarray&, + const typename valarray::value_type&); +template valarray operator==(const typename valarray::value_type&, + const valarray&); +template valarray operator!=(const valarray&, + const typename valarray::value_type&); +template valarray operator!=(const typename valarray::value_type&, + const valarray&); +template valarray operator< (const valarray&, + const typename valarray::value_type&); +template valarray operator< (const typename valarray::value_type&, + const valarray&); +template valarray operator> (const valarray&, + const typename valarray::value_type&); +template valarray operator> (const typename valarray::value_type&, + const valarray&); +template valarray operator<=(const valarray&, + const typename valarray::value_type&); +template valarray operator<=(const typename valarray::value_type&, + const valarray&); +template valarray operator>=(const valarray&, + const typename valarray::value_type&); +template valarray operator>=(const typename valarray::value_type&, + const valarray&); +template valarray operator&&(const valarray&, + const typename valarray::value_type&); +template valarray operator&&(const typename valarray::value_type&, + const valarray&); +template valarray operator||(const valarray&, + const typename valarray::value_type&); +template valarray operator||(const typename valarray::value_type&, + const valarray&); \end{itemdecl} \begin{itemdescr} @@ -7553,16 +7764,16 @@ template valarray asin (const valarray&); template valarray atan (const valarray&); template valarray atan2(const valarray&, const valarray&); -template valarray atan2(const valarray&, const T&); -template valarray atan2(const T&, const valarray&); +template valarray atan2(const valarray&, const typename valarray::value_type&); +template valarray atan2(const typename valarray::value_type&, const valarray&); template valarray cos (const valarray&); template valarray cosh (const valarray&); template valarray exp (const valarray&); template valarray log (const valarray&); template valarray log10(const valarray&); template valarray pow (const valarray&, const valarray&); -template valarray pow (const valarray&, const T&); -template valarray pow (const T&, const valarray&); +template valarray pow (const valarray&, const typename valarray::value_type&); +template valarray pow (const typename valarray::value_type&, const valarray&); template valarray sin (const valarray&); template valarray sinh (const valarray&); template valarray sqrt (const valarray&); @@ -8396,1177 +8607,6 @@ \returns An iterator referencing one past the last value in the array. \end{itemdescr} - -\rSec1[numeric.ops]{Generalized numeric operations} - -\rSec2[numeric.ops.overview]{Header \tcode{} synopsis} - -\indexhdr{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); - template - T reduce(InputIterator first, InputIterator last, T init); - template - T reduce(InputIterator first, InputIterator last, T init, BinaryOperation binary_op); - template - typename iterator_traits::value_type - reduce(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last); - template - T reduce(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, T init); - template - T reduce(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, T init, BinaryOperation binary_op); - - // \ref{inner.product}, inner product - template - T inner_product(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); - - // \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, - OutputIterator result); - template - OutputIterator partial_sum(InputIterator first, - InputIterator last, - OutputIterator result, - BinaryOperation binary_op); - - // \ref{exclusive.scan}, exclusive scan - template - OutputIterator exclusive_scan(InputIterator first, InputIterator last, - OutputIterator result, - T init); - template - OutputIterator exclusive_scan(InputIterator first, InputIterator last, - OutputIterator result, - T init, BinaryOperation binary_op); - template - ForwardIterator2 exclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, - T init); - template - 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); - template - OutputIterator inclusive_scan(InputIterator first, InputIterator last, - OutputIterator result, - BinaryOperation binary_op); - template - OutputIterator inclusive_scan(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); - template - ForwardIterator2 inclusive_scan(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, - BinaryOperation binary_op); - 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, - 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, - BinaryOperation binary_op, - UnaryOperation unary_op); - template - 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, - OutputIterator result); - template - OutputIterator adjacent_difference(InputIterator first, - InputIterator last, - OutputIterator result, - BinaryOperation binary_op); - template - ForwardIterator2 adjacent_difference(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator1 first, - ForwardIterator1 last, - ForwardIterator2 result); - template - 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); - - // \ref{numeric.ops.gcd}, greatest common divisor - template - constexpr common_type_t gcd(M m, N n); - - // \ref{numeric.ops.lcm}, least common multiple - template - constexpr common_type_t lcm(M m, N n); -} -\end{codeblock} - -\pnum -The requirements on the types of algorithms' arguments that are -described in the introduction to \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\iref{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}}% -\begin{itemdecl} -template - T accumulate(InputIterator first, InputIterator last, T init); -template - T accumulate(InputIterator first, InputIterator last, T init, - BinaryOperation binary_op); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -\tcode{T} shall satisfy the \tcode{CopyConstructible} (\tref{copyconstructible}) -and \tcode{CopyAssignable} (\tref{copyassignable}) requirements. -In the range -\crange{first}{last}, -\tcode{binary_op} -shall neither modify elements nor invalidate iterators or subranges.\footnote{The use of fully closed ranges is intentional.} - -\pnum -\effects -Computes its result by initializing the accumulator -\tcode{acc} -with the initial value -\tcode{init} -and then modifies it with -\tcode{acc = std::move(acc) + *i} -or -\tcode{acc = binary_op(std::move(acc), *i)} -for every iterator -\tcode{i} -in the range \range{first}{last} -in order.\footnote{\tcode{accumulate} -is similar to the APL reduction operator and Common Lisp reduce function, but -it avoids the difficulty of defining the result of reduction on an empty -sequence by always requiring an initial value.} -\end{itemdescr} - -\rSec2[reduce]{Reduce} - -\indexlibrary{\idxcode{reduce}}% -\begin{itemdecl} -template - typename iterator_traits::value_type - reduce(InputIterator first, InputIterator last); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Equivalent to: -\begin{codeblock} -return reduce(first, last, - typename iterator_traits::value_type{}); -\end{codeblock} -\end{itemdescr} - -\indexlibrary{\idxcode{reduce}}% -\begin{itemdecl} -template - typename iterator_traits::value_type - reduce(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Equivalent to: -\begin{codeblock} -return reduce(std::forward(exec), first, last, - typename iterator_traits::value_type{}); -\end{codeblock} -\end{itemdescr} - - -\indexlibrary{\idxcode{reduce}}% -\begin{itemdecl} -template - T reduce(InputIterator first, InputIterator last, T init); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Equivalent to: -\begin{codeblock} -return reduce(first, last, init, plus<>()); -\end{codeblock} -\end{itemdescr} - -\indexlibrary{\idxcode{reduce}}% -\begin{itemdecl} -template - T reduce(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, T init); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Equivalent to: -\begin{codeblock} -return reduce(std::forward(exec), first, last, init, plus<>()); -\end{codeblock} -\end{itemdescr} - - -\indexlibrary{\idxcode{reduce}}% -\begin{itemdecl} -template - T reduce(InputIterator first, InputIterator last, T init, - BinaryOperation binary_op); -template - T reduce(ExecutionPolicy&& exec, - ForwardIterator first, ForwardIterator last, T init, - BinaryOperation binary_op); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -\begin{itemize} -\item \tcode{T} shall be \tcode{MoveConstructible} (\tref{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{\placeholdernc{GENERALIZED_SUM}(binary_op, init, *i, ...)} for every \tcode{i} in \range{first}{last}. - -\pnum -\complexity -\bigoh{\tcode{last - first}} applications of \tcode{binary_op}. - -\pnum -\begin{note} -The difference between \tcode{reduce} and \tcode{accumulate} is that -\tcode{reduce} applies \tcode{binary_op} in an unspecified order, which yields -a nondeterministic result for non-associative or non-commutative -\tcode{binary_op} such as floating-point addition. -\end{note} -\end{itemdescr} - -\rSec2[inner.product]{Inner product} - -\indexlibrary{\idxcode{inner_product}}% -\begin{itemdecl} -template - T inner_product(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); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -\tcode{T} shall satisfy the \tcode{CopyConstructible} (\tref{copyconstructible}) -and \tcode{CopyAssignable} (\tref{copyassignable}) requirements. -In the ranges -\crange{first1}{last1} -and -\crange{first2}{first2 + (last1 - first1)} -\tcode{binary_op1} -and -\tcode{binary_op2} -shall neither modify elements nor invalidate iterators or subranges.\footnote{The use of fully closed ranges is intentional.} - -\pnum -\effects -Computes its result by initializing the accumulator -\tcode{acc} -with the initial value -\tcode{init} -and then modifying it with -\tcode{acc = std::move(acc) + (*i1) * (*i2)} -or -\tcode{acc = binary_op1(std::move(acc), binary_op2(*i1, *i2))} -for every iterator -\tcode{i1} -in the range \range{first1}{last1} -and iterator -\tcode{i2} -in the range -\range{first2}{first2 + (last1 - first1)} -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); -\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(ExecutionPolicy&& exec, - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, - T init); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Equivalent to: -\begin{codeblock} -return transform_reduce(std::forward(exec), - 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} (\tref{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} (\tref{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}}% -\begin{itemdecl} -template - OutputIterator partial_sum( - InputIterator first, InputIterator last, - OutputIterator result); -template - OutputIterator partial_sum( - InputIterator first, InputIterator last, - OutputIterator result, BinaryOperation binary_op); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -\tcode{InputIterator}'s value type shall be constructible from the type of \tcode{*first}. -The result of the expression \tcode{std::move(acc) + *i} or \tcode{binary_op(std::move(acc), *i)} shall be -implicitly convertible to \tcode{InputIterator}'s value type. \tcode{acc} -shall be writable\iref{iterator.requirements.general} to the \tcode{result} output iterator. -In the ranges -\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. -} - -\pnum -\effects For 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} -in order, \tcode{acc} is then modified by \tcode{acc = std::move(acc) + *i} or \tcode{acc = binary_op(std::move(acc), *i)} -and the result is assigned to \tcode{*(result + (i - first))}. - -\pnum -\returns -\tcode{result + (last - first)}. - -\pnum -\complexity -Exactly -\tcode{(last - first) - 1} -applications of -the binary operation. - -\pnum -\remarks -\tcode{result} -may be equal to -\tcode{first}. -\end{itemdescr} - -\rSec2[exclusive.scan]{Exclusive scan} - -\indexlibrary{\idxcode{exclusive_scan}}% -\begin{itemdecl} -template - OutputIterator exclusive_scan(InputIterator first, InputIterator last, - OutputIterator result, T init); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Equivalent to: -\begin{codeblock} -return exclusive_scan(first, last, result, init, plus<>()); -\end{codeblock} -\end{itemdescr} - -\indexlibrary{\idxcode{exclusive_scan}}% -\begin{itemdecl} -template - ForwardIterator2 exclusive_scan(ExecutionPolicy&& exec, - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, T init); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Equivalent to: -\begin{codeblock} -return exclusive_scan(std::forward(exec), - first, last, result, init, plus<>()); -\end{codeblock} -\end{itemdescr} - - -\indexlibrary{\idxcode{exclusive_scan}}% -\begin{itemdecl} -template - OutputIterator exclusive_scan(InputIterator first, InputIterator last, - OutputIterator result, T init, BinaryOperation binary_op); -template - ForwardIterator2 exclusive_scan(ExecutionPolicy&& exec, - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, T init, BinaryOperation binary_op); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -\begin{itemize} -\item \tcode{T} shall be \tcode{MoveConstructible} (\tref{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 -For each integer \tcode{K} in \range{0}{last - first} -assigns through \tcode{result + K} the value of: -\begin{codeblock} -@\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}@( - binary_op, init, *(first + 0), *(first + 1), ..., *(first + K - 1)) -\end{codeblock} - -\pnum -\returns -The end of the resulting range beginning at \tcode{result}. - -\pnum -\complexity -\bigoh{\tcode{last - first}} applications of \tcode{binary_op}. - -\pnum -\remarks -\tcode{result} may be equal to \tcode{first}. - -\pnum -\begin{note} -The difference between \tcode{exclusive_scan} and \tcode{inclusive_scan} is -that \tcode{exclusive_scan} excludes the $i^\text{th}$ input element from the -$i^\text{th}$ sum. If \tcode{binary_op} is not mathematically associative, the -behavior of \tcode{exclusive_scan} may be nondeterministic. -\end{note} -\end{itemdescr} - -\rSec2[inclusive.scan]{Inclusive scan} - -\indexlibrary{\idxcode{inclusive_scan}}% -\begin{itemdecl} -template - OutputIterator inclusive_scan(InputIterator first, InputIterator last, OutputIterator result); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Equivalent to: -\begin{codeblock} -return inclusive_scan(first, last, result, plus<>()); -\end{codeblock} -\end{itemdescr} - -\indexlibrary{\idxcode{inclusive_scan}}% -\begin{itemdecl} -template - ForwardIterator2 inclusive_scan(ExecutionPolicy&& exec, - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Equivalent to: -\begin{codeblock} -return inclusive_scan(std::forward(exec), first, last, result, plus<>()); -\end{codeblock} -\end{itemdescr} - - -\indexlibrary{\idxcode{inclusive_scan}}% -\begin{itemdecl} -template - OutputIterator inclusive_scan(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 - ForwardIterator2 inclusive_scan(ExecutionPolicy&& exec, - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, BinaryOperation binary_op, T init); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -\begin{itemize} -\item If \tcode{init} is provided, \tcode{T} shall be \tcode{MoveConstructible} -(\tref{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 -For each integer \tcode{K} in \range{0}{last - first} -assigns through \tcode{result + K} the value of -\begin{itemize} -\item - \tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(\\\phantom{\tcode{\ \ \ \ }}binary_op, - init, *(first + 0), *(first + 1), ..., *(first + K))}\\if \tcode{init} is provided, or -\item - \tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(\\\phantom{\tcode{\ \ \ \ }}binary_op, - *(first + 0), *(first + 1), ..., *(first + K))}\\otherwise. -\end{itemize} - -\pnum -\returns -The end of the resulting range beginning at \tcode{result}. - -\pnum -\complexity -\bigoh{\tcode{last - first}} applications of \tcode{binary_op}. - -\pnum -\remarks -\tcode{result} may be equal to \tcode{first}. - -\pnum -\begin{note} -The difference between \tcode{exclusive_scan} and \tcode{inclusive_scan} is -that \tcode{inclusive_scan} includes the $i^\text{th}$ input element in the -$i^\text{th}$ sum. If \tcode{binary_op} is not mathematically associative, the -behavior of \tcode{inclusive_scan} may be nondeterministic. -\end{note} -\end{itemdescr} - -\rSec2[transform.exclusive.scan]{Transform exclusive scan} - -\indexlibrary{\idxcode{transform_exclusive_scan}}% -\begin{itemdecl} -template - OutputIterator transform_exclusive_scan(InputIterator first, InputIterator last, - OutputIterator result, 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 -\begin{itemize} -\item \tcode{T} shall be \tcode{MoveConstructible} (\tref{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 -\crange{first}{last} or -\crange{result}{result + (last - first)}. -\end{itemize} - -\pnum -\effects -For each integer \tcode{K} in \range{0}{last - first} -assigns through \tcode{result + K} the value of: -\begin{codeblock} -@\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}@( - binary_op, init, - unary_op(*(first + 0)), unary_op(*(first + 1)), ..., unary_op(*(first + K - 1))) -\end{codeblock} - -\pnum -\returns -The end of the resulting range beginning at \tcode{result}. - -\pnum -\complexity -\bigoh{\tcode{last - first}} applications each of \tcode{unary_op} and -\tcode{binary_op}. - -\pnum -\remarks -\tcode{result} may be equal to \tcode{first}. - -\pnum -\begin{note} -The difference between \tcode{transform_exclusive_scan} and -\tcode{transform_inclusive_scan} is that \tcode{transform_exclusive_scan} -excludes the $i^\text{th}$ input element from the $i^\text{th}$ sum. If \tcode{binary_op} is not -mathematically associative, the behavior of \tcode{transform_exclusive_scan} -may be nondeterministic. \tcode{transform_exclusive_scan} does not apply -\tcode{unary_op} to \tcode{init}. -\end{note} -\end{itemdescr} - -\rSec2[transform.inclusive.scan]{Transform inclusive scan} - -\indexlibrary{\idxcode{transform_inclusive_scan}}% -\begin{itemdecl} -template - OutputIterator transform_inclusive_scan(InputIterator first, InputIterator last, - OutputIterator result, - 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 - 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, - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, - BinaryOperation binary_op, UnaryOperation unary_op, - T init); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -\begin{itemize} -\item If \tcode{init} is provided, \tcode{T} shall be \tcode{MoveConstructible} -(\tref{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 -For each integer \tcode{K} in \range{0}{last - first} -assigns through \tcode{result + K} the value of -\begin{itemize} -\item - \tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(\\\phantom{\tcode{\ \ \ \ }}binary_op, init,\\\phantom{\tcode{\ \ \ \ }}unary_op(*(first + 0)), unary_op(*(first + 1)), ..., unary_op(*(first + K)))}\\ - if \tcode{init} is provided, or -\item - \tcode{\placeholdernc{GENERALIZED_NONCOMMUTATIVE_SUM}(\\\phantom{\tcode{\ \ \ \ }}binary_op,\\\phantom{\tcode{\ \ \ \ }}unary_op(*(first + 0)), unary_op(*(first + 1)), ..., unary_op(*(first + K)))}\\ - otherwise. -\end{itemize} - -\pnum -\returns -The end of the resulting range beginning at \tcode{result}. - -\pnum -\complexity -\bigoh{\tcode{last - first}} applications each of \tcode{unary_op} and -\tcode{binary_op}. - -\pnum -\remarks -\tcode{result} may be equal to \tcode{first}. - -\pnum -\begin{note} -The difference between \tcode{transform_exclusive_scan} and -\tcode{transform_inclusive_scan} is that \tcode{transform_inclusive_scan} -includes the $i^\text{th}$ input element in the $i^\text{th}$ sum. If \tcode{binary_op} is not -mathematically associative, the behavior of \tcode{transform_inclusive_scan} -may be nondeterministic. \tcode{transform_inclusive_scan} does not apply -\tcode{unary_op} to \tcode{init}. -\end{note} -\end{itemdescr} - -\rSec2[adjacent.difference]{Adjacent difference} - -\indexlibrary{\idxcode{adjacent_difference}}% -\begin{itemdecl} -template - OutputIterator - adjacent_difference(InputIterator first, InputIterator last, OutputIterator result); -template - ForwardIterator2 - adjacent_difference(ExecutionPolicy&& exec, - ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); - -template - OutputIterator - adjacent_difference(InputIterator first, InputIterator last, - OutputIterator result, BinaryOperation binary_op); -template - ForwardIterator2 - adjacent_difference(ExecutionPolicy&& exec, - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, BinaryOperation binary_op); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -\begin{itemize} -\item -For the overloads with no \tcode{ExecutionPolicy}, \tcode{InputIterator}'s value -type shall be \tcode{MoveAssignable} (\tref{moveassignable}) and shall -be constructible from the type of \tcode{*first}. \tcode{acc} (defined below) -shall be writable\iref{iterator.requirements.general} to the \tcode{result} -output iterator. The result of the expression \tcode{val - std::move(acc)} or -\tcode{binary_op(val, std::move(acc))} shall be writable to the \tcode{result} output iterator. - -\item -For the overloads with an \tcode{ExecutionPolicy}, the value type of -\tcode{ForwardIterator1} -shall be \tcode{CopyConstructible} (\tref{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 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} -in order, creates an object \tcode{val} whose type is \tcode{InputIterator}'s value type, initializes it -with \tcode{*i}, computes \tcode{val - std::move(acc)} or \tcode{binary_op(val, std::move(acc))}, assigns the result -to \tcode{*(result + (i - first))}, and move assigns from \tcode{val} to \tcode{acc}. - -\pnum -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)}. - -\pnum -\complexity -Exactly -\tcode{(last - first) - 1} -applications of -the binary operation. - -\pnum -\remarks -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} - -\indexlibrary{\idxcode{iota}}% -\begin{itemdecl} -template - void iota(ForwardIterator first, ForwardIterator last, T value); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires \tcode{T} shall be convertible to \tcode{ForwardIterator}'s value -type. The expression \tcode{++val}, where \tcode{val} has type \tcode{T}, shall -be well-formed. - -\pnum -\effects For each element referred to by the iterator \tcode{i} in the range -\range{first}{last}, assigns \tcode{*i = value} and increments \tcode{value} as -if by \tcode{++value}. - -\pnum -\complexity Exactly \tcode{last - first} increments and assignments. -\end{itemdescr} - -\rSec2[numeric.ops.gcd]{Greatest common divisor} - -\indexlibrary{\idxcode{gcd}}% -\begin{itemdecl} -template - constexpr common_type_t gcd(M m, N n); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -$|\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)} = |\tcode{m}|$ is representable as a value of type \tcode{M}. \end{note} - -\pnum -\remarks -If either \tcode{M} or \tcode{N} is not an integer type, or -if either is \cv{}~\tcode{bool}, the program is ill-formed. - -\pnum -\returns -Zero when \tcode{m} and \tcode{n} are both zero. -Otherwise, returns the greatest common divisor of $|\tcode{m}|$ and $|\tcode{n}|$. - -\pnum -\throws -Nothing. -\end{itemdescr} - -\rSec2[numeric.ops.lcm]{Least common multiple} - -\indexlibrary{\idxcode{lcm}}% -\begin{itemdecl} -template - constexpr common_type_t lcm(M m, N n); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -$|\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}. - -\pnum -\remarks -If either \tcode{M} or \tcode{N} is not an integer type, or -if either is \cv{}~\tcode{bool} the program is ill-formed. - -\pnum -\returns -Zero when either \tcode{m} or \tcode{n} is zero. -Otherwise, returns the least common multiple of $|\tcode{m}|$ and $|\tcode{n}|$. - -\pnum -\throws -Nothing. -\end{itemdescr} - - \rSec1[c.math]{Mathematical functions for floating-point types} \rSec2[cmath.syn]{Header \tcode{} synopsis} diff --git a/source/overloading.tex b/source/overloading.tex index c0977774d4..c4cc3c6eaf 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -609,6 +609,13 @@ function template specializations are generated using template argument deduction~(\ref{temp.over}, \ref{temp.deduct}). +If a constructor template or conversion function template +has an \grammarterm{explicit-specifier} +whose \grammarterm{constant-expression} is value-dependent\iref{temp.dep}, +template argument deduction is performed first and then, +if the context requires a candidate that +is not explicit and the generated specialization is explicit\iref{dcl.fct.spec}, +it will be removed from the candidate set. Those candidates are then handled as candidate functions in the usual way.\footnote{The process of argument deduction fully determines the parameter types of @@ -629,9 +636,38 @@ with the set of non-template candidate functions. \pnum -A defaulted move special function\iref{class.copy} that is -defined as deleted is excluded from the set of candidate functions in all -contexts. +A +defaulted move special function~(\ref{class.copy.ctor}, \ref{class.copy.assign}) +that is defined as deleted +is excluded from the set of candidate functions in all contexts. +A constructor inherited from class type \tcode{C}\iref{class.inhctor.init} +that has a first parameter of type ``reference to \cvqual{cv1} \tcode{P}'' +(including such a constructor instantiated from a template) +is excluded from the set of candidate functions +when constructing an object of type \cvqual{cv2} \tcode{D} +if the argument list has exactly one argument and +\tcode{C} is reference-related to \tcode{P} and +\tcode{P} is reference-related to \tcode{D}. +\begin{example} +\begin{codeblock} +struct A { + A(); + A(A &&); // \#1 + template A(T &&); // \#2 +}; +struct B : A { + using A::A; + B(const B &); // \#3 + B(B &&) = default; // \#4, implicitly deleted + + struct X { X(X &&) = delete; } x; +}; +extern B b1; +B b2 = static_cast(b1); // calls \#3: \#1, \#2, and \#4 are not viable +struct C { operator B&&(); }; +B b3 = C(); // calls \#3 +\end{codeblock} +\end{example} \rSec3[over.match.call]{Function call syntax}% \indextext{overloading!resolution!function call syntax|(} @@ -1219,7 +1255,8 @@ candidate functions are all the constructors of the class of the object being initialized. -For copy-initialization, the candidate functions are all +For copy-initialization (including default initialization +in the context of copy-initialization), the candidate functions are all the converting constructors\iref{class.conv.ctor} of that class. The argument list is the @@ -1408,7 +1445,7 @@ If the initializer list has no elements and \tcode{T} has a default constructor, the first phase is omitted. -In copy-list-initialization, if an \tcode{explicit} constructor is +In copy-list-initialization, if an explicit constructor is chosen, the initialization is ill-formed. \begin{note} This differs from other situations~(\ref{over.match.ctor}, \ref{over.match.copy}), where only converting constructors are considered for copy-initialization. @@ -1486,10 +1523,11 @@ a single expression of type \cv{}~\tcode{U}, where \tcode{U} is a specialization of \tcode{C} or a class derived from a specialization of \tcode{C}. -Each such notional constructor -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}. +If the function or function template was generated from +a constructor or \grammarterm{deduction-guide} +that had an \grammarterm{explicit-specifier}, +each such notional constructor is considered to have +that same \grammarterm{explicit-specifier}. All such notional constructors are considered to be public members of the hypothetical class type. @@ -1571,11 +1609,11 @@ \textit{m} parameters is viable only if the -\textit{(m+1)}-st +$\textit{(m+1)}^\text{st}$ parameter has a default argument\iref{dcl.fct.default}.\footnote{According to~\ref{dcl.fct.default}, parameters following the -\textit{(m+1)}-st +$\textit{(m+1)}^\text{st}$ parameter must also have default arguments.} For the purposes of overload resolution, the parameter list is truncated on the right, so @@ -1585,8 +1623,8 @@ \end{itemize} \pnum -Second, for a function to be viable, if it has associated constraints, -those constraints shall be satisfied\iref{temp.constr.decl}. +Second, for a function to be viable, if it has associated constraints\iref{temp.constr.decl}, +those constraints shall be satisfied\iref{temp.constr.constr}. \pnum Third, for @@ -3244,7 +3282,8 @@ exactly one parameter. Because a copy assignment operator \tcode{operator=} -is implicitly declared for a class if not declared by the user\iref{class.copy}, +is implicitly declared for a class +if not declared by the user\iref{class.copy.assign}, a base class assignment operator is always hidden by the copy assignment operator of the derived class. @@ -3515,11 +3554,19 @@ whose type is \tcode{const char*}. \pnum -The declaration of a literal operator template shall have an empty -\grammarterm{parameter-declaration-clause} and its -\grammarterm{template-parameter-list} shall have a single -\grammarterm{template-parameter} that is a non-type template parameter -pack\iref{temp.variadic} with element type \tcode{char}. +A \defnx{numeric literal operator template}{literal!operator!template numeric} +is a literal operator template whose \grammarterm{template-parameter-list} +has a single \grammarterm{template-parameter} +that is a non-type template parameter pack\iref{temp.variadic} +with element type \tcode{char}. +A \defnx{string literal operator template}{literal!operator!template string} +is a literal operator template whose \grammarterm{template-parameter-list} +comprises +a single non-type \grammarterm{template-parameter} of class type. +The declaration of a literal operator template +shall have an empty \grammarterm{parameter-declaration-clause} +and shall declare either a numeric literal operator template +or a string literal operator template. \pnum Literal operators and literal operator templates shall not have C language linkage. diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 2edf938079..8b89401d34 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -205,7 +205,7 @@ h-pp-tokens h-preprocessing-token \end{bnf} -\indextext{__HAS_INCLUDE@\xname{has_include}}% +\indextext{\idxxname{has_include}}% \begin{bnf} \nontermdef{has-include-expression}\br \terminal{\xname{has_include} ( <} h-char-sequence \terminal{> )}\br @@ -214,6 +214,12 @@ \terminal{\xname{has_include} ( <} h-pp-tokens \terminal{> )} \end{bnf} +\indextext{\idxxname{has_cpp_attribute}}% +\begin{bnf} +\nontermdef{has-attribute-expression}\br + \terminal{\xname{has_cpp_attribute} (} pp-tokens \terminal{)} +\end{bnf} + \pnum The expression that controls conditional inclusion shall be an integral constant expression except that @@ -224,7 +230,8 @@ all identifiers either are or are not macro names --- there simply are no keywords, enumeration constants, etc.} and it may contain zero or more \grammarterm{defined-macro-expression}{s} and/or -\grammarterm{has-include-expression}{s} as unary operator expressions. +\grammarterm{has-include-expression}{s} and/or +\grammarterm{has-attribute-expression}{s} as unary operator expressions. \pnum A \grammarterm{defined-macro-expression} evaluates to \tcode{1} @@ -256,12 +263,55 @@ to \tcode{1} if the search for the source file succeeds, and to \tcode{0} if the search fails. +\pnum +Each \grammarterm{has-attribute-expression} is replaced by +a non-zero \grammarterm{pp-number} +matching the form of an \grammarterm{integer-literal} +if the implementation supports an attribute +with the name specified by interpreting +the \grammarterm{pp-tokens} as an \grammarterm{attribute-token}, +and by \tcode{0} otherwise. +The program is ill-formed if the \grammarterm{pp-tokens} +do not match the form of an \grammarterm{attribute-token}. + +\pnum +For an attribute specified in this document, +the value of the \grammarterm{has-attribute-expression} +is given by \tref{cpp.cond.ha}. +For other attributes recognized by the implementation, +the value is +\impldef{value of \grammarterm{has-attribute-expression} +for non-standard attributes}. +\begin{note} +It is expected +that the availability of an attribute can be detected by any non-zero result. +\end{note} + +\begin{floattable}{\xname{has_cpp_attribute} values}{tab:cpp.cond.ha} +{ll} +\topline +\lhdr{Attribute} & \rhdr{Value} \\ \rowsep +\tcode{assert} & \tcode{201806L} \\ +\tcode{carries_depencency} & \tcode{200809L} \\ +\tcode{deprecated} & \tcode{201309L} \\ +\tcode{ensures} & \tcode{201806L} \\ +\tcode{expects} & \tcode{201806L} \\ +\tcode{fallthrough} & \tcode{201603L} \\ +\tcode{likely} & \tcode{201803L} \\ +\tcode{maybe_unused} & \tcode{201603L} \\ +\tcode{no_unique_address} & \tcode{201803L} \\ +\tcode{nodiscard} & \tcode{201603L} \\ +\tcode{noreturn} & \tcode{200809L} \\ +\tcode{unlikely} & \tcode{201803L} \\ +\end{floattable} + \pnum The \tcode{\#ifdef} and \tcode{\#ifndef} directives, and the \tcode{defined} conditional inclusion operator, -shall treat \xname{has_include} as if it were the name of a defined macro. -The identifier \xname{has_include} shall not appear -in any context not mentioned in this subclause. +shall treat \xname{has_include} and \xname{has_cpp_attribute} +as if they were the names of defined macros. +The identifiers \xname{has_include} and \xname{has_cpp_attribute} +shall not appear in any context not mentioned in this subclause. \pnum Each preprocessing token that remains (in the list of preprocessing tokens that @@ -417,6 +467,7 @@ comments may appear anywhere in a source file, including within a preprocessing directive.} +\pnum \begin{example} This demonstrates a way to include a library \tcode{optional} facility only if it is available: @@ -424,17 +475,36 @@ \begin{codeblock} #if __has_include() # include -# define have_optional 1 +# if __cpp_lib_optional >= 201603 +# define have_optional 1 +# endif #elif __has_include() # include -# define have_optional 1 -# define experimental_optional 1 -#else +# if __cpp_lib_experimental_optional >= 201411 +# define have_optional 1 +# define experimental_optional 1 +# endif +#endif +#ifndef have_optional # define have_optional 0 #endif \end{codeblock} \end{example} +\pnum +\begin{example} +This demonstrates a way to use the attribute \tcode{[[acme::deprecated]]} +only if it is available. +\begin{codeblock} +#if __has_cpp_attribute(acme::deprecated) +# define ATTR_DEPRECATED(msg) [[acme::deprecated(msg)]] +#else +# define ATTR_DEPRECATED(msg) [[deprecated(msg)]] +#endif +ATTR_DEPRECATED("This function is deprecated") void anvil(); +\end{codeblock} +\end{example} + \rSec1[cpp.include]{Source file inclusion} \indextext{preprocessing directive!header inclusion} \indextext{preprocessing directive!source-file inclusion} @@ -743,20 +813,32 @@ \pnum After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. -A parameter in the replacement list, unless preceded by a -\tcode{\#} -or -\tcode{\#\#} -preprocessing token or followed by a -\tcode{\#\#} -preprocessing token (see below), -is replaced by the corresponding argument after all macros -contained therein have been expanded. -Before being substituted, -each argument's preprocessing tokens are completely -macro replaced as if they formed the rest of the -preprocessing file; -no other preprocessing tokens are available. +For each parameter in the replacement list that is neither +preceded by a \tcode{\#} or \tcode{\#\#} preprocessing token nor +followed by a \tcode{\#\#} preprocessing token, the preprocessing tokens +naming the parameter are replaced by a token sequence determined as follows: +\begin{itemize} +\item + If the parameter is of the form + \mname{VA_OPT}\tcode{(}\placeholder{content}\tcode{)}, + the replacement preprocessing tokens are the + preprocessing token sequence for the corresponding argument. +\item + Otherwise, the replacement preprocessing tokens are the + preprocessing tokens of corresponding argument after all + macros contained therein have been expanded. The argument's + preprocessing tokens are completely macro replaced before + being substituted as if they formed the rest of the preprocessing + file with no other preprocessing tokens being available. +\end{itemize} +\begin{example} +\begin{codeblock} +#define LPAREN() ( +#define G(Q) 42 +#define F(R, X, ...) __VA_OPT__(G R X) ) +int x = F(LPAREN(), 0, <:-); // replaced by \tcode{int x = 42;} +\end{codeblock} +\end{example} \pnum \indextext{__VA_ARGS__@\mname{VA_ARGS}}% @@ -767,8 +849,8 @@ \pnum \indextext{__VA_OPT__@\mname{VA_OPT}}% The identifier \mname{VA_OPT} -shall always occur as part of the token sequence -\mname{VA_OPT}\tcode{(}\placeholder{content}\tcode{)}, +shall always occur as part of the preprocessing token sequence +\mname{VA_OPT}\tcode{(}\placeholder{cont\-ent}\tcode{)}, where \placeholder{content} is an arbitrary sequence of \grammarterm{preprocessing-token}s other than \mname{VA_OPT}, @@ -777,26 +859,33 @@ If \placeholder{content} would be ill-formed as the replacement list of the current function-like macro, the program is ill-formed. -The token sequence +The preprocessing token sequence \mname{VA_OPT}\tcode{(}\placeholder{content}\tcode{)} shall be treated as if it were a parameter, -and the preprocessing tokens used to replace it -are defined as follows. -If the variable arguments consist of no tokens, -the replacement consists of +and the preprocessing token sequence for the corresponding +argument is defined as follows. +If the substitution of \mname{VA_ARGS} as neither an operand +of \tcode{\#} nor \tcode{\#\#} consists of no preprocessing tokens, +the argument consists of a single placemarker preprocessing token~(\ref{cpp.concat}, \ref{cpp.rescan}). -Otherwise, the replacement consists of +Otherwise, the argument consists of the results of the expansion of \placeholder{content} as the replacement list of the current function-like macro -before rescanning and further replacement. +before removal of placemarker tokens, rescanning, and further replacement. +\begin{note} +The placemarker tokens are removed before stringization\iref{cpp.stringize}, +and can be removed by rescanning and further replacement\iref{cpp.rescan}. +\end{note} \begin{example} \begin{codeblock} #define F(...) f(0 __VA_OPT__(,) __VA_ARGS__) #define G(X, ...) f(0, X __VA_OPT__(,) __VA_ARGS__) #define SDEF(sname, ...) S sname __VA_OPT__(= { __VA_ARGS__ }) +#define EMP F(a, b, c) // replaced by \tcode{f(0, a, b, c)} F() // replaced by \tcode{f(0)} +F(EMP) // replaced by \tcode{f(0)} G(a, b, c) // replaced by \tcode{f(0, a, b, c)} G(a, ) // replaced by \tcode{f(0, a)} @@ -807,9 +896,20 @@ #define H1(X, ...) X __VA_OPT__(##) __VA_ARGS__ // ill-formed: \tcode{\#\#} may not appear at // the beginning of a replacement list\iref{cpp.concat} -#define H2(X, Y, ...) __VA_OPT__(X ## Y,) __VA_ARGS__ +#define H2(X, Y, ...) __VA_OPT__(X ## Y,) __VA_ARGS__ H2(a, b, c, d) // replaced by \tcode{ab, c, d} + +#define H3(X, ...) #__VA_OPT__(X##X X##X) +H3(, 0) // replaced by \tcode{""} + +#define H4(X, ...) __VA_OPT__(a X ## X) ## b +H4(, 1) // replaced by \tcode{a b} + +#define H5A(...) __VA_OPT__()@\tcode{/**/}@__VA_OPT__() +#define H5B(X) a ## X ## b +#define H5C(X) H5B(X) +H5C(H5A()) // replaced by \tcode{ab} \end{codeblock} \end{example} @@ -832,13 +932,15 @@ preprocessing token, both are replaced by a single character string literal preprocessing token that contains the spelling of the preprocessing token sequence for the -corresponding argument. -Each occurrence of white space between the argument's preprocessing +corresponding argument (excluding placemarker tokens). +Let the \defn{stringizing argument} be the preprocessing token sequence +for the corresponding argument with placemarker tokens removed. +Each occurrence of white space between the stringizing argument's preprocessing tokens becomes a single space character in the character string literal. White space before the first preprocessing token and after the last -preprocessing token comprising the argument is deleted. +preprocessing token comprising the stringizing argument is deleted. Otherwise, the original spelling of each preprocessing token in the -argument is retained in the character string literal, +stringizing argument is retained in the character string literal, except for special handling for producing the spelling of string literals and character literals: a @@ -853,7 +955,7 @@ characters). If the replacement that results is not a valid character string literal, the behavior is undefined. The character string literal corresponding to -an empty argument is \tcode{""}. +an empty stringizing argument is \tcode{""}. The order of evaluation of \tcode{\#} and @@ -1349,8 +1451,72 @@ function. If the time of translation is not available, an \impldef{text of \mname{TIME} when time of translation is not available} valid time shall be supplied. + +\item The names listed in \tref{cpp.predefined.ft}.\\ +The macros defined in \tref{cpp.predefined.ft} shall be defined to +the corresponding integer literal. +\begin{note} +Future versions of this International Standard might replace +the values of these macros with greater values. +\end{note} \end{description} +\begin{LongTable}{Feature-test macros}{tab:cpp.predefined.ft}{ll} +\\ \topline +\lhdr{Macro name} & \rhdr{Value} \\ \capsep +\endfirsthead +\continuedcaption \\ +\hline +\lhdr{Name} & \rhdr{Value} \\ \capsep +\endhead +\defnxname{cpp_aggregate_bases} & \tcode{201603L} \\ \rowsep +\defnxname{cpp_aggregate_nsdmi} & \tcode{201304L} \\ \rowsep +\defnxname{cpp_alias_templates} & \tcode{200704L} \\ \rowsep +\defnxname{cpp_aligned_new} & \tcode{201606L} \\ \rowsep +\defnxname{cpp_attributes} & \tcode{200809L} \\ \rowsep +\defnxname{cpp_binary_literals} & \tcode{201304L} \\ \rowsep +\defnxname{cpp_capture_star_this} & \tcode{201603L} \\ \rowsep +\defnxname{cpp_constexpr} & \tcode{201603L} \\ \rowsep +\defnxname{cpp_decltype} & \tcode{200707L} \\ \rowsep +\defnxname{cpp_decltype_auto} & \tcode{201304L} \\ \rowsep +\defnxname{cpp_deduction_guides} & \tcode{201703L} \\ \rowsep +\defnxname{cpp_delegating_constructors} & \tcode{200604L} \\ \rowsep +\defnxname{cpp_enumerator_attributes} & \tcode{201411L} \\ \rowsep +\defnxname{cpp_explicit_bool} & \tcode{201806L} \\ \rowsep +\defnxname{cpp_fold_expressions} & \tcode{201603L} \\ \rowsep +\defnxname{cpp_generic_lambdas} & \tcode{201304L} \\ \rowsep +\defnxname{cpp_guaranteed_copy_elision} & \tcode{201606L} \\ \rowsep +\defnxname{cpp_hex_float} & \tcode{201603L} \\ \rowsep +\defnxname{cpp_if_constexpr} & \tcode{201606L} \\ \rowsep +\defnxname{cpp_inheriting_constructors} & \tcode{201511L} \\ \rowsep +\defnxname{cpp_init_captures} & \tcode{201304L} \\ \rowsep +\defnxname{cpp_initializer_lists} & \tcode{200806L} \\ \rowsep +\defnxname{cpp_inline_variables} & \tcode{201606L} \\ \rowsep +\defnxname{cpp_lambdas} & \tcode{200907L} \\ \rowsep +\defnxname{cpp_namespace_attributes} & \tcode{201411L} \\ \rowsep +\defnxname{cpp_noexcept_function_type} & \tcode{201510L} \\ \rowsep +\defnxname{cpp_nontype_template_args} & \tcode{201411L} \\ \rowsep +\defnxname{cpp_nontype_template_parameter_auto} & \tcode{201606L} \\ \rowsep +\defnxname{cpp_nontype_template_parameter_class} & \tcode{201806L} \\ \rowsep +\defnxname{cpp_nsdmi} & \tcode{200809L} \\ \rowsep +\defnxname{cpp_range_based_for} & \tcode{201603L} \\ \rowsep +\defnxname{cpp_raw_strings} & \tcode{200710L} \\ \rowsep +\defnxname{cpp_ref_qualifiers} & \tcode{200710L} \\ \rowsep +\defnxname{cpp_return_type_deduction} & \tcode{201304L} \\ \rowsep +\defnxname{cpp_rvalue_references} & \tcode{200610L} \\ \rowsep +\defnxname{cpp_sized_deallocation} & \tcode{201309L} \\ \rowsep +\defnxname{cpp_static_assert} & \tcode{201411L} \\ \rowsep +\defnxname{cpp_structured_bindings} & \tcode{201606L} \\ \rowsep +\defnxname{cpp_template_template_args} & \tcode{201611L} \\ \rowsep +\defnxname{cpp_threadsafe_static_init} & \tcode{200806L} \\ \rowsep +\defnxname{cpp_unicode_characters} & \tcode{200704L} \\ \rowsep +\defnxname{cpp_unicode_literals} & \tcode{200710L} \\ \rowsep +\defnxname{cpp_user_defined_literals} & \tcode{200809L} \\ \rowsep +\defnxname{cpp_variable_templates} & \tcode{201304L} \\ \rowsep +\defnxname{cpp_variadic_templates} & \tcode{200704L} \\ \rowsep +\defnxname{cpp_variadic_using} & \tcode{201611L} \\ \rowsep +\end{LongTable} + \pnum The following macro names are conditionally defined by the implementation: diff --git a/source/regex.tex b/source/regex.tex index 148733da5f..677dc2e1ec 100644 --- a/source/regex.tex +++ b/source/regex.tex @@ -18,7 +18,7 @@ result of a regular expression match, a series of algorithms that allow a character sequence to be operated upon by a regular expression, and two iterator types for -enumerating regular expression matches, as described in \tref{re.lib.summary}. +enumerating regular expression matches, as summarized in \tref{re.lib.summary}. \begin{libsumtab}{Regular expressions library summary}{tab:re.lib.summary} \ref{re.def} & Definitions & \\ @@ -1695,8 +1695,9 @@ \begin{itemdescr} \pnum -\requires The type \tcode{InputIterator} shall satisfy the requirements for an Input -Iterator\iref{input.iterators}. +\requires +\tcode{InputIterator} shall satisfy the +\oldconcept{InputIterator} requirements\iref{input.iterators}. \pnum \returns \tcode{assign(string_type(first, last), f)}. @@ -2477,7 +2478,8 @@ using string_type = basic_string; // \ref{re.results.const}, construct/copy/destroy - explicit match_results(const Allocator& a = Allocator()); + match_results() : match_results(Allocator()) {} + explicit match_results(const Allocator&); match_results(const match_results& m); match_results(match_results&& m) noexcept; match_results& operator=(const match_results& m); @@ -2542,7 +2544,7 @@ \indexlibrary{\idxcode{match_results}!constructor}% \begin{itemdecl} -match_results(const Allocator& a = Allocator()); +explicit match_results(const Allocator& a); \end{itemdecl} \begin{itemdescr} @@ -2642,7 +2644,7 @@ result of a successful match. Otherwise returns \tcode{0}. \begin{note} The state of a \tcode{match_results} object can be modified only by passing that object to \tcode{regex_match} or \tcode{regex_search}. -Sections~\ref{re.alg.match} and~\ref{re.alg.search} specify the +Subclauses~\ref{re.alg.match} and~\ref{re.alg.search} specify the effects of those algorithms on their \tcode{match_results} arguments. \end{note} \end{itemdescr} @@ -2791,8 +2793,8 @@ \begin{itemdescr} \pnum -\requires \tcode{ready() == true} and \tcode{OutputIter} shall satisfy the requirements for an -Output Iterator\iref{output.iterators}. +\requires \tcode{ready() == true} and \tcode{OutputIter} shall satisfy the requirements for a +\oldconcept{OutputIterator}\iref{output.iterators}. \pnum \effects Copies the character sequence \range{fmt_first}{fmt_last} to @@ -2979,8 +2981,9 @@ \begin{itemdescr} \pnum -\requires The type \tcode{BidirectionalIterator} shall satisfy the requirements -of a bidirectional iterator\iref{bidirectional.iterators}. +\requires +The type \tcode{BidirectionalIterator} shall satisfy the +\oldconcept{BidirectionalIterator} requirements\iref{bidirectional.iterators}. \pnum \effects Determines whether there is a match between the @@ -3162,8 +3165,9 @@ \begin{itemdescr} \pnum -\requires Type \tcode{BidirectionalIterator} shall satisfy the requirements of a bidirectional -iterator\iref{bidirectional.iterators}. +\requires +Type \tcode{BidirectionalIterator} shall satisfy the +\oldconcept{BidirectionalIterator} requirements\iref{bidirectional.iterators}. \pnum \effects Determines whether there is some sub-sequence within \range{first}{last} that matches @@ -3651,7 +3655,7 @@ \pnum \begin{note} This means that a compiler may call an -implementation-specific search function, in which case a user-defined +implementation-specific search function, in which case a program-defined specialization of \tcode{regex_search} will not be called. \end{note} \end{itemdescr} diff --git a/source/special.tex b/source/special.tex deleted file mode 100644 index 9a6546c603..0000000000 --- a/source/special.tex +++ /dev/null @@ -1,3468 +0,0 @@ -%!TEX root = std.tex -\rSec0[special]{Special member functions} - -\gramSec[gram.special]{Special member functions} - -\indextext{\idxcode{X(X\&)}|see{constructor, copy}}% -\indextext{~@\tcode{\~}|see{destructor}}% -\indextext{assignment!copy|see{assignment operator, copy}}% -\indextext{assignment!move|see{assignment operator, move}}% -\indextext{implicitly-declared default constructor|see{constructor, default}} - -\pnum -\indextext{constructor!default}% -\indextext{constructor!copy}% -\indextext{constructor!move}% -\indextext{assignment operator!copy}% -\indextext{assignment operator!move}% -The default constructor\iref{class.ctor}, -copy constructor and copy assignment operator\iref{class.copy}, -move constructor and move assignment operator\iref{class.copy}, -and destructor\iref{class.dtor} are -\term{special member functions}. -\begin{note} The implementation will implicitly declare these member functions for some class -types when the program does not explicitly declare them. -The implementation will implicitly define them -if they are odr-used\iref{basic.def.odr} or -needed for constant evaluation\iref{expr.const}. -See~\ref{class.ctor}, \ref{class.dtor} and~\ref{class.copy}. \end{note} -An implicitly-declared special member function is declared at the closing -\tcode{\}} of the \grammarterm{class-specifier}. -Programs shall not define implicitly-declared special member functions. - -\pnum -Programs may explicitly refer to implicitly-declared special member functions. -\begin{example} -A program may explicitly call or form a pointer to member -to an implicitly-declared special member function. - -\begin{codeblock} -struct A { }; // implicitly declared \tcode{A::operator=} -struct B : A { - B& operator=(const B &); -}; -B& B::operator=(const B& s) { - this->A::operator=(s); // well-formed - return *this; -} -\end{codeblock} -\end{example} - -\pnum -\begin{note} -The special member functions affect the way objects of class type are created, -copied, moved, and destroyed, and how values can be converted to values of other types. -Often such special member functions are called implicitly. -\end{note} - -\pnum -\indextext{access control!member function and}% -Special member functions obey the usual access rules\iref{class.access}. -\begin{example} -Declaring a constructor protected -ensures that only derived classes and friends can create objects using it. -\end{example} - -\pnum -For a class, its non-static data members, its non-virtual direct base classes, -and, if the class is not abstract\iref{class.abstract}, its virtual base -classes are called its \term{potentially constructed subobjects}. - -\rSec1[class.ctor]{Constructors}% -\indextext{constructor}% -\indextext{special member function|see{constructor}}% - -\pnum -Constructors do not have names. -In a declaration of a constructor, the \grammarterm{declarator} is a -function declarator\iref{dcl.fct} of the form - -\begin{ncbnf} -ptr-declarator \terminal{(} parameter-declaration-clause \terminal{)} \opt{noexcept-specifier} \opt{attribute-specifier-seq} -\end{ncbnf} - -where the \grammarterm{ptr-declarator} consists solely of an -\grammarterm{id-expression}, an optional \grammarterm{attribute-specifier-seq}, -and optional surrounding parentheses, and the \grammarterm{id-expression} has -one of the following forms: - -\begin{itemize} -\item -in a \grammarterm{member-declaration} that belongs to the -\grammarterm{member-specification} of a class or class template -but is not a friend -declaration\iref{class.friend}, the \grammarterm{id-expression} is the -injected-class-name\iref{class} of the immediately-enclosing entity or - -\item -in a declaration at namespace scope or in a friend declaration, the -\grammarterm{id-expression} is a \grammarterm{qualified-id} that names a -constructor\iref{class.qual}. -\end{itemize} - -The \grammarterm{class-name} shall not be a \grammarterm{typedef-name}. In a constructor -declaration, each \grammarterm{decl-specifier} in the optional -\grammarterm{decl-specifier-seq} shall be \tcode{friend}, \tcode{inline}, -\tcode{explicit}, or \tcode{constexpr}. -\begin{example} - -\begin{codeblock} -struct S { - S(); // declares the constructor -}; - -S::S() { } // defines the constructor -\end{codeblock} -\end{example} - -\pnum -A constructor is used to initialize objects of its class type. -Because constructors do not have names, they are never found during -name lookup; however an explicit type conversion using the functional -notation\iref{expr.type.conv} will cause a constructor to be called to -initialize an object. -\begin{note} -For initialization of objects of class type see~\ref{class.init}. -\end{note} - -\pnum -\indextext{\idxcode{const}!constructor and}% -\indextext{\idxcode{volatile}!constructor and}% -A constructor can be invoked for a -\tcode{const}, -\tcode{volatile} -or -\tcode{const} -\tcode{volatile} -object. -\indextext{restriction!constructor}% -\tcode{const} -and -\tcode{volatile} -semantics\iref{dcl.type.cv} are not applied on an object under construction. -They come into effect when the constructor for the -most derived object\iref{intro.object} ends. - -\pnum -\indextext{constructor!inheritance of}% -\indextext{constructor!non-trivial}% -A -\defnx{default}{constructor!default} -constructor for a class -\tcode{X} -is a constructor of class -\tcode{X} -for which -each parameter -that is not a function parameter pack -has a default argument -(including the case of a constructor with no parameters). -\indextext{implicitly-declared default constructor}% -If there is no user-declared constructor for class -\tcode{X}, -a non-explicit constructor having no parameters is implicitly declared -as defaulted\iref{dcl.fct.def}. -An implicitly-declared default constructor is an -inline public member of its class. - -\pnum -A defaulted default constructor for class \tcode{X} is defined as deleted if: - -\begin{itemize} -\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} -has a default member initializer, - -\item any non-static data member with no default member initializer\iref{class.mem} is -of reference type, - -\item any non-variant non-static data member of const-qualified type (or array -thereof) with no \grammarterm{brace-or-equal-initializer} does not have a user-provided default constructor, - -\item \tcode{X} is a union and all of its variant members are of const-qualified -type (or array thereof), - -\item \tcode{X} is a non-union class and all members of any anonymous union member are -of const-qualified type (or array thereof), - -\item any potentially constructed subobject, except for a non-static data member -with a \grammarterm{brace-or-equal-initializer}, has -class type \tcode{M} (or array thereof) and either \tcode{M} -has no default constructor or overload resolution\iref{over.match} -as applied to find \tcode{M}'s corresponding -constructor results in an ambiguity or in a function that is deleted or -inaccessible from the defaulted default constructor, or - -\item any potentially constructed subobject has a type -with a destructor that is deleted or inaccessible from the defaulted default -constructor. -\end{itemize} - -\pnum -A default constructor is -\defnx{trivial}{constructor!default!trivial} -if it is not user-provided and if: - -\begin{itemize} -\item -its class has no virtual functions\iref{class.virtual} and no virtual base -classes\iref{class.mi}, and - -\item no non-static data member of its class has -a default member initializer\iref{class.mem}, and - -\item -all the direct base classes of its class have trivial default constructors, and - -\item -for all the non-static data members of its class that are of class -type (or array thereof), each such class has a trivial default constructor. -\end{itemize} - -Otherwise, the default constructor is -\defnx{non-trivial}{constructor!default!non-trivial}. - -\pnum -A default constructor -that is defaulted and not defined as deleted -is -\defnx{implicitly defined}{constructor!implicitly defined} -when it is odr-used\iref{basic.def.odr} -to create an object of its class type\iref{intro.object}, -when it is needed for constant evaluation\iref{expr.const}, or -when it is explicitly defaulted after its first declaration. -The implicitly-defined default constructor performs the set of -initializations of the class that would be performed by a user-written default -constructor for that class with no -\grammarterm{ctor-initializer}\iref{class.base.init} and an empty -\grammarterm{compound-statement}. -If that user-written default constructor would be ill-formed, -the program is ill-formed. -If that user-written default constructor would satisfy the requirements -of a constexpr constructor\iref{dcl.constexpr}, the implicitly-defined -default constructor is \tcode{constexpr}. -Before the defaulted default constructor for a class is -implicitly defined, -all the non-user-provided default constructors for its base classes and -its non-static data members shall have been implicitly defined. -\begin{note} -An implicitly-declared default constructor has an -exception specification\iref{except.spec}. -An explicitly-defaulted definition might have an -implicit exception specification, see~\ref{dcl.fct.def}. -\end{note} - -\pnum -\indextext{constructor!implicitly called}% -Default constructors are called implicitly to create class objects of static, thread, -or automatic storage duration~(\ref{basic.stc.static}, \ref{basic.stc.thread}, \ref{basic.stc.auto}) defined -without an initializer\iref{dcl.init}, -are called to create class objects of dynamic storage duration\iref{basic.stc.dynamic} created by a -\grammarterm{new-expression} -in which the -\grammarterm{new-initializer} -is omitted\iref{expr.new}, or -are called when the explicit type conversion syntax\iref{expr.type.conv} is -used. -A program is ill-formed if the default constructor for an object -is implicitly used and the constructor is not accessible\iref{class.access}. - -\pnum -\begin{note} -\indextext{order of execution!base class constructor}% -\indextext{order of execution!member constructor}% -\ref{class.base.init} describes the order in which constructors for base -classes and non-static data members are called and -describes how arguments can be specified for the calls to these constructors. -\end{note} - -\pnum -\indextext{restriction!constructor}% -A -\tcode{return} -statement in the body of a constructor shall not specify a return value. -\indextext{constructor!address of}% -The address of a constructor shall not be taken. - -\pnum -\indextext{object!unnamed}% -\indextext{constructor!explicit call}% -A functional notation type conversion\iref{expr.type.conv} can be used -to create new objects of its type. -\begin{note} -The syntax looks like an explicit call of the constructor. -\end{note} -\begin{example} -\begin{codeblock} -complex zz = complex(1,2.3); -cprint( complex(7.8,1.2) ); -\end{codeblock} -\end{example} - -\pnum -An object created in this way is unnamed. -\begin{note} -\ref{class.temporary} describes the lifetime of temporary objects. -\end{note} -\begin{note} -Explicit constructor calls do not yield lvalues, see~\ref{basic.lval}. -\end{note} - -\pnum -\begin{note} -\indextext{member function!constructor and}% -Some language constructs have special semantics when used during construction; -see~\ref{class.base.init} and~\ref{class.cdtor}. -\end{note} - -\pnum -During the construction of an object, -if the value of the object or any of its subobjects is -accessed through a glvalue that is not obtained, directly or indirectly, from -the constructor's -\tcode{this} -pointer, the value of the object or subobject thus obtained is unspecified. -\begin{example} - -\begin{codeblock} -struct C; -void no_opt(C*); - -struct C { - int c; - C() : c(0) { no_opt(this); } -}; - -const C cobj; - -void no_opt(C* cptr) { - int i = cobj.c * 100; // value of \tcode{cobj.c} is unspecified - cptr->c = 1; - cout << cobj.c * 100 // value of \tcode{cobj.c} is unspecified - << '\n'; -} - -extern struct D d; -struct D { - D(int a) : a(a), b(d.a) {} - int a, b; -}; -D d = D(1); // value of \tcode{d.b} is unspecified -\end{codeblock} -\end{example} - -\rSec1[class.temporary]{Temporary objects} - -\pnum -\indextext{object temporary|see{temporary}}% -\indextext{temporary}% -\indextext{optimization of temporary|see{temporary, elimination of}}% -\indextext{temporary!elimination of}% -\indextext{temporary!implementation-defined generation of}% -Temporary objects are created -\begin{itemize} -\item -when a prvalue is materialized so that it can be used as a glvalue\iref{conv.rval}, -\item -when needed by the implementation to pass or return an object of trivially-copyable type (see below), -and -\item -when throwing an exception\iref{except.throw}. -\begin{note} -The lifetime of exception objects is described in~\ref{except.throw}. -\end{note} -\end{itemize} -Even when the creation of the temporary object is -unevaluated\iref{expr.prop}, -all the semantic restrictions shall be respected as if the temporary object -had been created and later destroyed. -\begin{note} -This includes accessibility\iref{class.access} and whether it is deleted, -for the constructor selected and for the destructor. However, in the special -case of the operand of a -\grammarterm{decltype-specifier}\iref{expr.call}, no temporary is introduced, -so the foregoing does not apply to such a prvalue. -\end{note} - -\pnum -The materialization of a temporary object is generally -delayed as long as possible -in order to avoid creating unnecessary temporary objects. -\begin{note} -Temporary objects are materialized: -\begin{itemize} -\item -when binding a reference to a prvalue~(\ref{dcl.init.ref}, \ref{expr.type.conv}, -\ref{expr.dynamic.cast}, \ref{expr.static.cast}, \ref{expr.const.cast}, \ref{expr.cast}), -\item -when performing member access on a class prvalue~(\ref{expr.ref}, \ref{expr.mptr.oper}), -\item -when performing an array-to-pointer conversion or subscripting on an array prvalue~(\ref{conv.array}, \ref{expr.sub}), -\item -when initializing an object of type \tcode{std::initializer_list} from a \grammarterm{braced-init-list}\iref{dcl.init.list}, -\item -for certain unevaluated operands~(\ref{expr.typeid}, \ref{expr.sizeof}), and -\item -when a prvalue appears as a discarded-value expression\iref{expr.prop}. -\end{itemize} -\end{note} -\begin{example} Consider the following code: -\begin{codeblock} -class X { -public: - X(int); - X(const X&); - X& operator=(const X&); - ~X(); -}; - -class Y { -public: - Y(int); - Y(Y&&); - ~Y(); -}; - -X f(X); -Y g(Y); - -void h() { - X a(1); - X b = f(X(2)); - Y c = g(Y(3)); - a = f(a); -} -\end{codeblock} - -\indextext{class object copy|see{constructor, copy}}% -\indextext{constructor!copy}% -\tcode{X(2)} is constructed in the space used to hold \tcode{f()}'s argument and -\tcode{Y(3)} is constructed in the space used to hold \tcode{g()}'s argument. -Likewise, -\tcode{f()}'s result is constructed directly in \tcode{b} and -\tcode{g()}'s result is constructed directly in \tcode{c}. -On the other hand, the expression -\tcode{a = f(a)} -requires a temporary for -the result of \tcode{f(a)}, -which is materialized so that the reference parameter -of \tcode{A::operator=(const A\&)} can bind to it. -\end{example} - -\pnum -When an object of class type \tcode{X} -is passed to or returned from a function, -if each copy constructor, move constructor, and destructor of \tcode{X} -is either trivial or deleted, -and \tcode{X} -has at least one non-deleted copy or move constructor, -implementations are permitted -to create a temporary object -to hold the function parameter or result object. -The temporary object is constructed -from the function argument or return value, respectively, -and the function's parameter or return object -is initialized as if by -using the non-deleted trivial constructor to copy the temporary -(even if that constructor is inaccessible -or would not be selected by overload resolution -to perform a copy or move of the object). -\begin{note} -This latitude is granted to allow objects of class type to be passed to or returned from functions in registers. -\end{note} - -\pnum -\indextext{temporary!constructor for}% -\indextext{temporary!destructor for}% -\indextext{temporary!destruction of}% -When an implementation introduces a temporary object of a class that has a -non-trivial constructor~(\ref{class.ctor}, \ref{class.copy}), it shall ensure that -a constructor is called for the temporary object. -Similarly, the destructor shall be called for a temporary with a non-trivial -destructor\iref{class.dtor}. -Temporary objects are destroyed as the last step -in evaluating -the full-expression\iref{intro.execution} -that (lexically) contains the point where -they were created. -This is true even if that evaluation ends in throwing an exception. -The -\indextext{value computation}% -value computations and -\indextext{side effects}% -side effects of destroying a temporary object -are associated only with the full-expression, not with any specific -subexpression. - -\pnum -\indextext{initializer!temporary and declarator}% -\indextext{temporary!order of destruction of}% -There are three contexts in which temporaries are destroyed at a different -point than the end of the full-expression. -The first context is when a default constructor is called to initialize -an element of an array with no corresponding initializer\iref{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.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. - -\pnum -The third context is when a reference is bound to a -temporary object.\footnote{The same rules apply to initialization of an - \tcode{initializer_list} object\iref{dcl.init.list} with its - underlying temporary array.} -The temporary object to which the reference is bound or the temporary object -that is the complete object of a subobject to which the reference is bound -persists for the lifetime of the reference if the glvalue -to which the reference is bound -was obtained through one of the following: -\begin{itemize} -\item - a temporary materialization conversion\iref{conv.rval}, -\item - \tcode{(} \grammarterm{expression} \tcode{)}, - where \grammarterm{expression} is one of these expressions, -\item - subscripting\iref{expr.sub} of an array operand, - where that operand is one of these expressions, -\item - a class member access\iref{expr.ref} using the \tcode{.} operator - where the left operand is one of these expressions and - the right operand designates a non-static data member of non-reference type, -\item - a pointer-to-member operation\iref{expr.mptr.oper} using the \tcode{.*} operator - where the left operand is one of these expressions and - the right operand is a pointer to data member of non-reference type, -\item - a - \begin{itemize} - \item \tcode{const_cast}\iref{expr.const.cast}, - \item \tcode{static_cast}\iref{expr.static.cast}, - \item \tcode{dynamic_cast}\iref{expr.dynamic.cast}, or - \item \tcode{reinterpret_cast}\iref{expr.reinterpret.cast} - \end{itemize} - converting, without a user-defined conversion, - a glvalue operand that is one of these expressions - to a glvalue that refers - to the object designated by the operand, or - to its complete object or a subobject thereof, -\item - a conditional expression\iref{expr.cond} that is a glvalue - where the second or third operand is one of these expressions, or -\item - a comma expression\iref{expr.comma} that is a glvalue - where the right operand is one of these expressions. -\end{itemize} -\begin{example} -\begin{codeblock} -template using id = T; - -int i = 1; -int&& a = id{1, 2, 3}[i]; // temporary array has same lifetime as \tcode{a} -const int& b = static_cast(0); // temporary \tcode{int} has same lifetime as \tcode{b} -int&& c = cond ? id{1, 2, 3}[i] : static_cast(0); - // exactly one of the two temporaries is lifetime-extended -\end{codeblock} -\end{example} -\begin{note} -An explicit type conversion~(\ref{expr.type.conv}, \ref{expr.cast}) -is interpreted as -a sequence of elementary casts, -covered above. -\begin{example} -\begin{codeblock} -const int& x = (const int&)1; // temporary for value 1 has same lifetime as x -\end{codeblock} -\end{example} -\end{note} -\begin{note} -If a temporary object has a reference member initialized by another temporary object, -lifetime extension applies recursively to such a member's initializer. -\begin{example} -\begin{codeblock} -struct S { - const int& m; -}; -const S& s = S{1}; // both \tcode{S} and \tcode{int} temporaries have lifetime of \tcode{s} -\end{codeblock} -\end{example} -\end{note} - -The exceptions to this lifetime rule are: -\begin{itemize} -\item A temporary object bound to a reference parameter in a function call\iref{expr.call} -persists until the completion of the full-expression containing the call. - -\item The lifetime of a temporary bound to the returned value in a function \tcode{return} statement\iref{stmt.return} is not extended; the temporary is destroyed at the end of the full-expression in the \tcode{return} statement. - -\item A temporary bound to a reference in a \grammarterm{new-initializer}\iref{expr.new} persists until the completion of the full-expression containing the \grammarterm{new-initializer}. -\begin{note} This may introduce a dangling reference. \end{note} -\begin{example} -\begin{codeblock} -struct S { int mi; const std::pair& mp; }; -S a { 1, {2,3} }; -S* p = new S{ 1, {2,3} }; // creates dangling reference -\end{codeblock} -\end{example} -\end{itemize} - -\pnum -The destruction of a temporary whose lifetime is not extended by being -bound to a reference is sequenced before the destruction of every -temporary which is constructed earlier in the same full-expression. -If the lifetime of two or more temporaries to which references are bound ends -at the same point, -these temporaries are destroyed at that point in the reverse order of the -completion of their construction. -In addition, the destruction of temporaries bound to references shall -take into account the ordering of destruction of objects with static, thread, or -automatic storage duration~(\ref{basic.stc.static}, \ref{basic.stc.thread}, \ref{basic.stc.auto}); -that is, if -\tcode{obj1} -is an object with the same storage duration as the temporary and -created before the temporary is created -the temporary shall be destroyed before -\tcode{obj1} -is destroyed; -if -\tcode{obj2} -is an object with the same storage duration as the temporary and -created after the temporary is created -the temporary shall be destroyed after -\tcode{obj2} -is destroyed. - -\pnum -\begin{example} -\begin{codeblock} -struct S { - S(); - S(int); - friend S operator+(const S&, const S&); - ~S(); -}; -S obj1; -const S& cr = S(16)+S(23); -S obj2; -\end{codeblock} - -The expression -\tcode{S(16) + S(23)} -creates three temporaries: -a first temporary -\tcode{T1} -to hold the result of the expression -\tcode{S(16)}, -a second temporary -\tcode{T2} -to hold the result of the expression -\tcode{S(23)}, -and a third temporary -\tcode{T3} -to hold the result of the addition of these two expressions. -The temporary -\tcode{T3} -is then bound to the reference -\tcode{cr}. -It is unspecified whether -\tcode{T1} -or -\tcode{T2} -is created first. -On an implementation where -\tcode{T1} -is created before -\tcode{T2}, -\tcode{T2} -shall be destroyed before -\tcode{T1}. -The temporaries -\tcode{T1} -and -\tcode{T2} -are bound to the reference parameters of -\tcode{operator+}; -these temporaries are destroyed at the end of the full-expression -containing the call to -\tcode{operator+}. -The temporary -\tcode{T3} -bound to the reference -\tcode{cr} -is destroyed at the end of -\tcode{cr}'s -lifetime, that is, at the end of the program. -In addition, the order in which -\tcode{T3} -is destroyed takes into account the destruction order of other objects with -static storage duration. -That is, because -\tcode{obj1} -is constructed before -\tcode{T3}, -and -\tcode{T3} -is constructed before -\tcode{obj2}, -\tcode{obj2} -shall be destroyed before -\tcode{T3}, -and -\tcode{T3} -shall be destroyed before -\tcode{obj1}. -\end{example} - -\rSec1[class.conv]{Conversions} - -\pnum -\indextext{conversion!class}% -\indextext{constructor, conversion by|see{conversion, user-defined}}% -\indextext{conversion function|see{conversion, user-defined}}% -\indextext{conversion!implicit}% -Type conversions of class objects can be specified by constructors and -by conversion functions. -These conversions are called -\defnx{user-defined conversions}{conversion!user-defined} -and are used for implicit type conversions\iref{conv}, -for initialization\iref{dcl.init}, -and for explicit type conversions~(\ref{expr.cast}, \ref{expr.static.cast}). - -\pnum -User-defined conversions are applied only where they are unambiguous~(\ref{class.member.lookup}, \ref{class.conv.fct}). -Conversions obey the access control rules\iref{class.access}. -Access control is applied after ambiguity resolution\iref{basic.lookup}. - -\pnum -\begin{note} -See~\ref{over.match} for a discussion of the use of conversions in function calls -as well as examples below. -\end{note} - -\pnum -\indextext{conversion!implicit user-defined}% -At most one user-defined conversion (constructor or conversion function) -is implicitly applied to a single value. -\begin{example} -\begin{codeblock} -struct X { - operator int(); -}; - -struct Y { - operator X(); -}; - -Y a; -int b = a; // error, \tcode{a.operator X().operator int()} not tried -int c = X(a); // OK: \tcode{a.operator X().operator int()} -\end{codeblock} -\end{example} - -\pnum -User-defined conversions are used implicitly only if they are unambiguous. -\indextext{name hiding!user-defined conversion and}% -A conversion function in a derived class does not hide a conversion function -in a base class unless the two functions convert to the same type. -Function overload resolution\iref{over.match.best} selects the best -conversion function to perform the conversion. -\begin{example} -\begin{codeblock} -struct X { - operator int(); -}; - -struct Y : X { - operator char(); -}; - -void f(Y& a) { - if (a) { // ill-formed: \tcode{X::operator int()} or \tcode{Y::operator char()} - } -} -\end{codeblock} -\end{example} - -\rSec2[class.conv.ctor]{Conversion by constructor}% -\indextext{conversion!user-defined}% - -\pnum -A constructor declared without the -\grammarterm{function-specifier} -\tcode{explicit} -specifies a conversion from -the types of its parameters (if any) -to the type of its class. -Such a constructor is called a -\defnx{converting constructor}{constructor!converting}. -\begin{example} - -\indextext{Jessie}% -\begin{codeblock} -struct X { - X(int); - X(const char*, int =0); - X(int, int); -}; - -void f(X arg) { - X a = 1; // \tcode{a = X(1)} - X b = "Jessie"; // \tcode{b = X("Jessie",0)} - a = 2; // \tcode{a = X(2)} - f(3); // \tcode{f(X(3))} - f({1, 2}); // \tcode{f(X(1,2))} -} -\end{codeblock} -\end{example} - -\pnum -\begin{note} -An explicit constructor constructs objects just like non-explicit -constructors, but does so only where the direct-initialization syntax\iref{dcl.init} -or where casts~(\ref{expr.static.cast}, \ref{expr.cast}) are explicitly -used; see also~\ref{over.match.copy}. -A default constructor may be an explicit constructor; such a constructor -will be used to perform default-initialization -or value-initialization\iref{dcl.init}. -\begin{example} -\begin{codeblock} -struct Z { - explicit Z(); - explicit Z(int); - explicit Z(int, int); -}; - -Z a; // OK: default-initialization performed -Z b{}; // OK: direct initialization syntax used -Z c = {}; // error: copy-list-initialization -Z a1 = 1; // error: no implicit conversion -Z a3 = Z(1); // OK: direct initialization syntax used -Z a2(1); // OK: direct initialization syntax used -Z* p = new Z(1); // OK: direct initialization syntax used -Z a4 = (Z)1; // OK: explicit cast used -Z a5 = static_cast(1); // OK: explicit cast used -Z a6 = { 3, 4 }; // error: no implicit conversion -\end{codeblock} -\end{example} -\end{note} - -\pnum -A -non-explicit -copy/move constructor\iref{class.copy} is a converting constructor. -\begin{note} -An implicitly-declared copy/move constructor is not an explicit constructor; -it may be called for implicit type conversions. -\end{note} - -\rSec2[class.conv.fct]{Conversion functions}% -\indextext{function!conversion}% -\indextext{fundamental type conversion|see{conversion, user-defined}}% -\indextext{conversion!user-defined}% - -\pnum -A member function of a class \tcode{X} having no parameters with a name of the form - -\begin{bnf} -\nontermdef{conversion-function-id}\br - \terminal{operator} conversion-type-id -\end{bnf} - -\begin{bnf} -\nontermdef{conversion-type-id}\br - type-specifier-seq \opt{conversion-declarator} -\end{bnf} - -\begin{bnf} -\nontermdef{conversion-declarator}\br - ptr-operator \opt{conversion-declarator} -\end{bnf} - -specifies a conversion from -\tcode{X} -to the type specified by the -\grammarterm{conversion-type-id}. -Such functions are called \defnx{conversion functions}{conversion function}. -A \grammarterm{decl-specifier} in the \grammarterm{decl-specifier-seq} -of a conversion function (if any) shall be neither -a \grammarterm{defining-type-specifier} nor \tcode{static}. -\indextext{conversion!type of}% -The type of the conversion function\iref{dcl.fct} is -``function taking no parameter returning -\grammarterm{conversion-type-id}''. -A conversion function is never used to convert a (possibly cv-qualified) object -to the (possibly cv-qualified) same object type (or a reference to it), -to a (possibly cv-qualified) base class of that type (or a reference to it), -or to (possibly cv-qualified) void.\footnote{These conversions are considered -as standard conversions for the purposes of overload resolution~(\ref{over.best.ics}, \ref{over.ics.ref}) and therefore initialization\iref{dcl.init} and explicit casts\iref{expr.static.cast}. A conversion to \tcode{void} does not invoke any conversion function\iref{expr.static.cast}. -Even though never directly called to perform a conversion, -such conversion functions can be declared and can potentially -be reached through a call to a virtual conversion function in a base class.} -\begin{example} -\begin{codeblock} -struct X { - operator int(); - operator auto() -> short; // error: trailing return type -}; - -void f(X a) { - int i = int(a); - i = (int)a; - i = a; -} -\end{codeblock} -In all three cases the value assigned will be converted by -\tcode{X::operator int()}. -\end{example} - -\pnum -A conversion function may be explicit\iref{dcl.fct.spec}, in which case it is only considered as a user-defined conversion for direct-initialization\iref{dcl.init}. Otherwise, user-defined conversions are not restricted to use in assignments and initializations. -\begin{example} -\begin{codeblock} -class Y { }; -struct Z { - explicit operator Y() const; -}; - -void h(Z z) { - Y y1(z); // OK: direct-initialization - Y y2 = z; // ill-formed: copy-initialization - Y y3 = (Y)z; // OK: cast notation -} - -void g(X a, X b) { - int i = (a) ? 1+a : 0; - int j = (a&&b) ? a+b : i; - if (a) { - } -} -\end{codeblock} -\end{example} - -\pnum -The -\grammarterm{conversion-type-id} -shall not represent a function type nor an array type. -The -\grammarterm{conversion-type-id} -in a -\grammarterm{conversion-function-id} -is the longest sequence of -tokens that could possibly form a \grammarterm{conversion-type-id}. -\begin{note} -This prevents ambiguities between the declarator operator \tcode{*} and its expression -counterparts. -\begin{example} -\begin{codeblock} -&ac.operator int*i; // syntax error: - // parsed as: \tcode{\&(ac.operator int *)i} - // not as: \tcode{\&(ac.operator int)*i} -\end{codeblock} -The \tcode{*} is the pointer declarator and not the multiplication operator. -\end{example} -This rule also prevents ambiguities for attributes. -\begin{example} -\begin{codeblock} -operator int [[noreturn]] (); // error: \tcode{noreturn} attribute applied to a type -\end{codeblock} -\end{example} -\end{note} - -\pnum -\indextext{conversion!inheritance of user-defined}% -Conversion functions are inherited. - -\pnum -\indextext{conversion!virtual user-defined}% -Conversion functions can be virtual. - -\pnum -\indextext{conversion!deduced return type of user-defined}% -A conversion function template shall not have a -deduced return type\iref{dcl.spec.auto}. -\begin{example} -\begin{codeblock} -struct S { - operator auto() const { return 10; } // OK - template - operator auto() const { return 1.2; } // error: conversion function template -}; -\end{codeblock} -\end{example} - -\rSec1[class.dtor]{Destructors}% -\indextext{destructor}% -\indextext{special member function|see{destructor}}% - -\pnum -In a declaration of a destructor, the \grammarterm{declarator} is a -function declarator\iref{dcl.fct} of the form - -\begin{ncbnf} -ptr-declarator \terminal{(} parameter-declaration-clause \terminal{)} \opt{noexcept-specifier} \opt{attribute-specifier-seq} -\end{ncbnf} - -where the \grammarterm{ptr-declarator} consists solely of an -\grammarterm{id-expression}, an optional \grammarterm{attribute-specifier-seq}, -and optional surrounding parentheses, and the \grammarterm{id-expression} has -one of the following forms: - -\begin{itemize} -\item -in a \grammarterm{member-declaration} that belongs to the -\grammarterm{member-specification} of a class or class template -but is not a friend -declaration\iref{class.friend}, the \grammarterm{id-expression} is -\tcode{\~}\grammarterm{class-name} and the \grammarterm{class-name} is the -injected-class-name\iref{class} of the immediately-enclosing entity or - -\item -in a declaration at namespace scope or in a friend declaration, the -\grammarterm{id-expression} is \grammarterm{nested-name-specifier} -\tcode{\~}\grammarterm{class-name} and the \grammarterm{class-name} names the -same class as the \grammarterm{nested-name-specifier}. -\end{itemize} - -The \grammarterm{class-name} shall not be a \grammarterm{typedef-name}. A -destructor shall take no arguments\iref{dcl.fct}. -Each \grammarterm{decl-specifier} of the \grammarterm{decl-specifier-seq} -of a destructor declaration (if any) shall be \tcode{friend}, \tcode{inline}, or -\tcode{virtual}. - -\pnum -A destructor is used to destroy objects of its class type. -\indextext{restriction!destructor}% -The address of a destructor shall not be taken. -\indextext{\idxcode{const}!destructor and}% -\indextext{\idxcode{volatile}!destructor and}% -A destructor can be invoked for a -\tcode{const}, -\tcode{volatile} -or -\tcode{const} -\tcode{volatile} -object. -\tcode{const} -and -\tcode{volatile} -semantics\iref{dcl.type.cv} are not applied on an object under destruction. -They stop being in effect when the destructor for the -most derived object\iref{intro.object} starts. - -\pnum -\begin{note} -A declaration of a destructor that does not have a \grammarterm{noexcept-specifier} -has the same exception specification as if it had been implicitly declared\iref{except.spec}. -\end{note} - -\pnum -\indextext{generated destructor|see{destructor, default}}% -\indextext{destructor!default}% -If a class has no user-declared -destructor, a destructor is implicitly -declared as defaulted\iref{dcl.fct.def}. -An implicitly-declared destructor is an -inline public member of its class. - -\pnum -A defaulted destructor for a class - \tcode{X} is defined as deleted if: -\begin{itemize} -\item \tcode{X} is a union-like class that has a variant - member with a non-trivial destructor, - -\item any potentially constructed subobject has class type - \tcode{M} (or array thereof) and - \tcode{M} has a deleted destructor or a destructor - that is inaccessible from the defaulted destructor, - -\item or, for a virtual destructor, lookup of the non-array deallocation - function results in an ambiguity or in a function that is deleted or - inaccessible from the defaulted destructor. -\end{itemize} - -\pnum -A destructor is trivial if it is not user-provided and if: - -\begin{itemize} -\item the destructor is not \tcode{virtual}, - -\item all of the direct base classes of its class have trivial destructors, and - -\item for all of the non-static data members of its class that are of class -type (or array thereof), each such class has a trivial destructor. -\end{itemize} - -Otherwise, the destructor is -\defnx{non-trivial}{destructor!non-trivial}. - -\pnum -A destructor -that is defaulted and not defined as deleted -is -\defnx{implicitly defined}{destructor!implicitly defined} -when it is odr-used\iref{basic.def.odr} -or when it is explicitly defaulted after its first declaration. - -\pnum -Before the -defaulted destructor for a class is implicitly defined, all the non-user-provided -destructors for its base classes and its non-static data members shall have been -implicitly defined. - -\pnum -\indextext{order of execution!destructor}% -\indextext{order of execution!base class destructor}% -\indextext{order of execution!member destructor}% -After executing the body of the destructor and destroying -any automatic objects allocated within the body, a -destructor for class -\tcode{X} -calls the destructors for -\tcode{X}'s -direct non-variant non-static data members, the destructors for -\tcode{X}'s -non-virtual direct base classes and, if -\tcode{X} -is the type of the most derived class\iref{class.base.init}, -its destructor calls the destructors for -\tcode{X}'s -virtual base classes. -All destructors are called as if they were referenced with a qualified name, -that is, ignoring any possible virtual overriding destructors in more -derived classes. -Bases and members are destroyed in the reverse order of the completion of -their constructor (see~\ref{class.base.init}). -A -\tcode{return} -statement\iref{stmt.return} in a destructor might not directly return to the -caller; before transferring control to the caller, the destructors for the -members and bases are called. -\indextext{order of execution!destructor and array}% -Destructors for elements of an array are called in reverse order of their -construction (see~\ref{class.init}). - -\pnum -\indextext{destructor!virtual}% -\indextext{destructor!pure virtual}% -A destructor can be declared -\tcode{virtual}\iref{class.virtual} -or pure -\tcode{virtual}\iref{class.abstract}; -if any objects of that class or any derived class are created in the program, -the destructor shall be defined. -If a class has a base class with a virtual destructor, its destructor -(whether user- or implicitly-declared) is virtual. - -\pnum -\begin{note} -\indextext{member function!destructor and}% -Some language constructs have special semantics when used during destruction; -see~\ref{class.cdtor}. -\end{note} - -\pnum -\indextext{destructor!implicit call}% -\indextext{destructor!program termination and}% -A destructor is invoked implicitly - -\begin{itemize} - -\item for a constructed object with static storage duration\iref{basic.stc.static} at program termination\iref{basic.start.term}, - -\item for a constructed object with thread storage duration\iref{basic.stc.thread} at thread exit, - -\item for a constructed object with automatic storage duration\iref{basic.stc.auto} when the block in which an object is created exits\iref{stmt.dcl}, - -\item for a constructed temporary object when its lifetime ends~(\ref{conv.rval}, \ref{class.temporary}). -\end{itemize} - -\indextext{\idxcode{delete}!destructor and}% -\indextext{destructor!explicit call}% -In each case, the context of the invocation is the context of the construction of -the object. A destructor is also invoked implicitly through use of a -\grammarterm{delete-expression}\iref{expr.delete} for a constructed object allocated -by a \grammarterm{new-expression}\iref{expr.new}; the context of the invocation is the -\grammarterm{delete-expression}. -\begin{note} An array of class type contains several subobjects for each of which -the destructor is invoked. \end{note} -A destructor can also be invoked explicitly. A destructor is \term{potentially invoked} -if it is invoked or as specified in~\ref{expr.new}, \ref{dcl.init.aggr}, -\ref{class.base.init}, and~\ref{except.throw}. -A program is ill-formed if a destructor that is potentially invoked is deleted -or not accessible from the context of the invocation. - -\pnum -At the point of definition of a virtual destructor (including an implicit -definition\iref{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 -a deleted definition\iref{dcl.fct.def}, the program is ill-formed. -\begin{note} -This assures that a deallocation function corresponding to the dynamic type of an -object is available for the -\grammarterm{delete-expression}\iref{class.free}. -\end{note} - -\pnum -\indextext{destructor!explicit call}% -In an explicit destructor call, the destructor is specified by a -\tcode{\~{}} -followed by a -\grammarterm{type-name} or \grammarterm{decltype-specifier} -that denotes the destructor's class type. -The invocation of a destructor is subject to the usual rules for member -functions\iref{class.mfct}; -that is, if the object is not of the destructor's class type and -not of a class derived from the destructor's class type (including when -the destructor is invoked via a null pointer value), the program has -undefined behavior. -\begin{note} Invoking \tcode{delete} on a null pointer does not call the -destructor; see \ref{expr.delete}. \end{note} -\begin{example} - -\begin{codeblock} -struct B { - virtual ~B() { } -}; -struct D : B { - ~D() { } -}; - -D D_object; -typedef B B_alias; -B* B_ptr = &D_object; - -void f() { - D_object.B::~B(); // calls \tcode{B}'s destructor - B_ptr->~B(); // calls \tcode{D}'s destructor - B_ptr->~B_alias(); // calls \tcode{D}'s destructor - B_ptr->B_alias::~B(); // calls \tcode{B}'s destructor - B_ptr->B_alias::~B_alias(); // calls \tcode{B}'s destructor -} -\end{codeblock} -\end{example} -\begin{note} -An explicit destructor call must always be written using -a member access operator\iref{expr.ref} or a \grammarterm{qualified-id}\iref{expr.prim.id.qual}; -in particular, the -\grammarterm{unary-expression} -\tcode{\~{}X()} -in a member function is not an explicit destructor call\iref{expr.unary.op}. -\end{note} - -\pnum -\begin{note} -\indextext{object!destructor and placement of}% -Explicit calls of destructors are rarely needed. -One use of such calls is for objects placed at specific -addresses using a placement -\grammarterm{new-expression}. -Such use of explicit placement and destruction of objects can be necessary -to cope with dedicated hardware resources and for writing memory management -facilities. -For example, -\begin{codeblock} -void* operator new(std::size_t, void* p) { return p; } -struct X { - X(int); - ~X(); -}; -void f(X* p); - -void g() { // rare, specialized use: - char* buf = new char[sizeof(X)]; - X* p = new(buf) X(222); // use \tcode{buf[]} and initialize - f(p); - p->X::~X(); // cleanup -} -\end{codeblock} -\end{note} - -\pnum -Once a destructor is invoked for an object, the object no longer exists; -the behavior is undefined if the destructor is invoked -for an object whose lifetime has ended\iref{basic.life}. -\begin{example} -If the destructor for an automatic object is explicitly invoked, -and the block is subsequently left in a manner that would ordinarily -invoke implicit destruction of the object, the behavior is undefined. -\end{example} - -\pnum -\begin{note} -\indextext{fundamental type!destructor and}% -The notation for explicit call of a destructor can be used for any scalar type -name\iref{expr.pseudo}. -Allowing this makes it possible to write code without having to know if a -destructor exists for a given type. -For example: -\begin{codeblock} -typedef int I; -I* p; -p->I::~I(); -\end{codeblock} -\end{note} - -\rSec1[class.free]{Free store}% -\indextext{free store}% - -\pnum -\indextext{\idxcode{new}!type of} -Any allocation function for a class -\tcode{T} -is a static member (even if not explicitly declared -\tcode{static}). - -\pnum -\begin{example} -\begin{codeblock} -class Arena; -struct B { - void* operator new(std::size_t, Arena*); -}; -struct D1 : B { -}; - -Arena* ap; -void foo(int i) { - new (ap) D1; // calls \tcode{B::operator new(std::size_t, Arena*)} - new D1[i]; // calls \tcode{::operator new[](std::size_t)} - new D1; // ill-formed: \tcode{::operator new(std::size_t)} hidden -} -\end{codeblock} -\end{example} - -\pnum -\indextext{\idxcode{delete}}% -When an object is deleted with a -\grammarterm{delete-expression}\iref{expr.delete}, -a deallocation function -\indextext{function!deallocation}% -(\tcode{operator delete()} -\indextext{\idxcode{operator delete}}% -for non-array objects or -\tcode{operator delete[]()} -\indextext{\idxcode{operator delete}}% -for arrays) is (implicitly) called to reclaim the storage occupied by -the object\iref{basic.stc.dynamic.deallocation}. - -\pnum -Class-specific deallocation function lookup is a part of general deallocation -function lookup\iref{expr.delete} and occurs as follows. -If the \grammarterm{delete-expression} -is used to deallocate a class object whose static type has a virtual -destructor, the deallocation function is the one selected at the point -of definition of the dynamic type's virtual -destructor\iref{class.dtor}.\footnote{A similar provision is not needed for -the array version of \tcode{operator} \tcode{delete} because~\ref{expr.delete} -requires that in this situation, the static type of the object to be deleted be -the same as its dynamic type. -} -Otherwise, if the -\grammarterm{delete-expression} -is used to deallocate an object of class -\tcode{T} -or array thereof, the static and dynamic types of the object shall be -identical and the deallocation function's name is looked up in the scope of -\tcode{T}. -If this lookup fails to find the name, general deallocation function -lookup\iref{expr.delete} continues. -If the result of the lookup is ambiguous or inaccessible, or if the lookup -selects a placement deallocation function, the program is ill-formed. - -\pnum -\indextext{\idxcode{delete}!type of}% -Any deallocation function for a class -\tcode{X} -is a static member (even if not explicitly declared -\tcode{static}). -\begin{example} -\begin{codeblock} -class X { - void operator delete(void*); - void operator delete[](void*, std::size_t); -}; - -class Y { - void operator delete(void*, std::size_t); - void operator delete[](void*); -}; -\end{codeblock} -\end{example} - -\pnum -Since member allocation and deallocation functions are -\tcode{static} -they cannot be virtual. -\begin{note} -However, when the -\grammarterm{cast-expression} -of a -\grammarterm{delete-expression} -refers to an object of class type, -because the deallocation function actually called is looked up in the scope of -the class that is the dynamic type of the object, -if the destructor is virtual, the effect is the same. -For example, -\begin{codeblock} -struct B { - virtual ~B(); - void operator delete(void*, std::size_t); -}; - -struct D : B { - void operator delete(void*); -}; - -void f() { - B* bp = new D; - delete bp; // 1: uses \tcode{D::operator delete(void*)} -} -\end{codeblock} -Here, storage for the non-array object of class -\tcode{D} -is deallocated by -\tcode{D::operator delete()}, -due to the virtual destructor. -\end{note} -\begin{note} -Virtual destructors have no effect on the deallocation function actually -called when the -\grammarterm{cast-expression} -of a -\grammarterm{delete-expression} -refers to an array of objects of class type. -For example, -\begin{codeblock} -struct B { - virtual ~B(); - void operator delete[](void*, std::size_t); -}; - -struct D : B { - void operator delete[](void*, std::size_t); -}; - -void f(int i) { - D* dp = new D[i]; - delete [] dp; // uses \tcode{D::operator delete[](void*, std::size_t)} - B* bp = new D[i]; - delete[] bp; // undefined behavior -} -\end{codeblock} -\end{note} - -\pnum -Access to the deallocation function is checked statically. -Hence, even though a different one might actually be executed, -the statically visible deallocation function is required to be accessible. -\begin{example} -For the call on line ``// 1'' above, -if -\tcode{B::operator delete()} -had been private, the delete expression would have been ill-formed. -\end{example} - -\pnum -\begin{note} -If a deallocation function has no explicit \grammarterm{noexcept-specifier}, it -has a non-throwing exception specification\iref{except.spec}. -\end{note} - -\rSec1[class.init]{Initialization}% -\indextext{initialization!class object|(}% -\indextext{initialization!default constructor and}% -\indextext{initialization!constructor and} - -\pnum -When no initializer is specified for an object of (possibly -cv-qualified) class type (or array thereof), or the initializer has -the form -\tcode{()}, -the object is initialized as specified in~\ref{dcl.init}. - -\pnum -An object of class type (or array thereof) can be explicitly initialized; -see~\ref{class.expl.init} and~\ref{class.base.init}. - -\pnum -\indextext{order of execution!constructor and array}% -When an array of class objects is initialized -(either explicitly or implicitly) and the elements are initialized by constructor, -the constructor shall be called for each element of the array, -following the subscript order; see~\ref{dcl.array}. -\begin{note} -Destructors for the array elements are called in reverse order of their -construction. -\end{note} - -\rSec2[class.expl.init]{Explicit initialization}% -\indextext{initialization!explicit}% -\indextext{initialization!constructor and}% - -\pnum -An object of class type can be initialized with a parenthesized -\grammarterm{expression-list}, -where the -\grammarterm{expression-list} -is construed as an argument list for a constructor -that is called to initialize the object. -Alternatively, a single -\grammarterm{assignment-expression} -can be specified as an -\grammarterm{initializer} -using the -\tcode{=} -form of initialization. -Either direct-initialization semantics or copy-initialization semantics apply; -see~\ref{dcl.init}. -\begin{example} -\begin{codeblock} -struct complex { - complex(); - complex(double); - complex(double,double); -}; - -complex sqrt(complex,complex); - -complex a(1); // initialize by a call of \tcode{complex(double)} -complex b = a; // initialize by a copy of \tcode{a} -complex c = complex(1,2); // construct \tcode{complex(1,2)} using \tcode{complex(double,double)}, - // copy/move it into \tcode{c} -complex d = sqrt(b,c); // call \tcode{sqrt(complex,complex)} and copy/move the result into \tcode{d} -complex e; // initialize by a call of \tcode{complex()} -complex f = 3; // construct \tcode{complex(3)} using \tcode{complex(double)}, copy/move it into \tcode{f} -complex g = { 1, 2 }; // initialize by a call of \tcode{complex(double, double)} -\end{codeblock} -\end{example} -\begin{note} -\indextext{initialization!overloaded assignment and}% -Overloading of the assignment operator\iref{over.ass} -has no effect on initialization. -\end{note} - -\pnum -\indextext{initialization!array of class objects}% -\indextext{constructor!array of class objects and}% -An object of class type can also be initialized by a -\grammarterm{braced-init-list}. List-initialization semantics apply; -see~\ref{dcl.init} and~\ref{dcl.init.list}. \begin{example} - -\begin{codeblock} -complex v[6] = { 1, complex(1,2), complex(), 2 }; -\end{codeblock} - -Here, -\tcode{complex::complex(double)} -is called for the initialization of -\tcode{v[0]} -and -\tcode{v[3]}, -\tcode{complex::complex(\brk{}double, double)} -is called for the initialization of -\tcode{v[1]}, -\tcode{complex::complex()} -is called for the initialization -\tcode{v[2]}, -\tcode{v[4]}, -and -\tcode{v[5]}. -For another example, - -\begin{codeblock} -struct X { - int i; - float f; - complex c; -} x = { 99, 88.8, 77.7 }; -\end{codeblock} - -Here, -\tcode{x.i} -is initialized with 99, -\tcode{x.f} -is initialized with 88.8, and -\tcode{complex::complex(double)} -is called for the initialization of -\tcode{x.c}. -\end{example} -\begin{note} -Braces can be elided in the -\grammarterm{initializer-list} -for any aggregate, even if the aggregate has members of a class type with -user-defined type conversions; see~\ref{dcl.init.aggr}. -\end{note} - -\pnum -\begin{note} -If -\tcode{T} -is a class type with no default constructor, -any declaration of an object of type -\tcode{T} -(or array thereof) is ill-formed if no -\grammarterm{initializer} -is explicitly specified (see~\ref{class.init} and~\ref{dcl.init}). -\end{note} - -\pnum -\begin{note} -\indextext{order of execution!constructor and \tcode{static} objects}% -The order in which objects with static or thread storage duration -are initialized is described in~\ref{basic.start.dynamic} and~\ref{stmt.dcl}. -\end{note} - -\rSec2[class.base.init]{Initializing bases and members}% -\indextext{initialization!base class}% -\indextext{initialization!member} - -\pnum -In the definition of a constructor for a class, -initializers for direct and virtual base class subobjects and -non-static data members can be specified by a -\grammarterm{ctor-initializer}, -which has the form - -\begin{bnf} -\nontermdef{ctor-initializer}\br - \terminal{:} mem-initializer-list -\end{bnf} - -\begin{bnf} -\nontermdef{mem-initializer-list}\br - mem-initializer \opt{\terminal{...}}\br - mem-initializer-list \terminal{,} mem-initializer \opt{\terminal{...}} -\end{bnf} - -\begin{bnf} -\nontermdef{mem-initializer}\br - mem-initializer-id \terminal{(} \opt{expression-list} \terminal{)}\br - mem-initializer-id braced-init-list -\end{bnf} - -\begin{bnf} -\nontermdef{mem-initializer-id}\br - class-or-decltype\br - identifier -\end{bnf} - -\pnum -In a \grammarterm{mem-initializer-id} an initial unqualified -\grammarterm{identifier} is looked up in the scope of the constructor's class -and, if not found in that scope, it is looked up in the scope containing the -constructor's definition. -\begin{note} -If the constructor's class contains a member with the same name as a direct -or virtual base class of the class, a -\grammarterm{mem-initializer-id} -naming the member or base class and composed of a single identifier -refers to the class member. -A -\grammarterm{mem-initializer-id} -for the hidden base class may be specified using a qualified name. -\end{note} -Unless the -\grammarterm{mem-initializer-id} -names the constructor's class, -a non-static data member of the constructor's class, or -a direct or virtual base of that class, -the -\grammarterm{mem-initializer} -is ill-formed. - -\pnum -A -\grammarterm{mem-initializer-list} -can initialize a base class using any \grammarterm{class-or-decltype} that denotes that base class type. -\begin{example} - -\begin{codeblock} -struct A { A(); }; -typedef A global_A; -struct B { }; -struct C: public A, public B { C(); }; -C::C(): global_A() { } // mem-initializer for base \tcode{A} -\end{codeblock} -\end{example} - -\pnum -If a -\grammarterm{mem-initializer-id} -is ambiguous because it designates both a direct non-virtual base class and -an inherited virtual base class, the -\grammarterm{mem-initializer} -is ill-formed. -\begin{example} - -\begin{codeblock} -struct A { A(); }; -struct B: public virtual A { }; -struct C: public A, public B { C(); }; -C::C(): A() { } // ill-formed: which \tcode{A}? -\end{codeblock} -\end{example} - -\pnum -A -\grammarterm{ctor-initializer} -may initialize a variant member of the -constructor's class. -If a -\grammarterm{ctor-initializer} -specifies more than one -\grammarterm{mem-initializer} -for the same member or for the same base class, -the -\grammarterm{ctor-initializer} -is ill-formed. - -\pnum -A \grammarterm{mem-initializer-list} can delegate to another -constructor of the constructor's class using any -\grammarterm{class-or-decltype} that denotes the constructor's class itself. If a -\grammarterm{mem-initializer-id} designates the constructor's class, -it shall be the only \grammarterm{mem-initializer}; the constructor -is a \term{delegating constructor}, and the constructor selected by the -\grammarterm{mem-initializer} is the \term{target constructor}. -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 required. \begin{example} - -\begin{codeblock} -struct C { - C( int ) { } // \#1: non-delegating constructor - C(): C(42) { } // \#2: delegates to \#1 - C( char c ) : C(42.0) { } // \#3: ill-formed due to recursion with \#4 - C( double d ) : C('a') { } // \#4: ill-formed due to recursion with \#3 -}; -\end{codeblock} -\end{example} - -\pnum -\indextext{initialization!base class}% -\indextext{initialization!member object}% -The -\grammarterm{expression-list} -or \grammarterm{braced-init-list} -in a -\grammarterm{mem-initializer} -is used to initialize the -designated subobject (or, in the case of a delegating constructor, the complete class object) -according to the initialization rules of~\ref{dcl.init} for direct-initialization. -\begin{example} -\begin{codeblock} -struct B1 { B1(int); @\commentellip@ }; -struct B2 { B2(int); @\commentellip@ }; -struct D : B1, B2 { - D(int); - B1 b; - const int c; -}; - -D::D(int a) : B2(a+1), B1(a+2), c(a+3), b(a+4) { @\commentellip@ } -D d(10); -\end{codeblock} -\end{example} -\begin{note} -The initialization -performed by each \grammarterm{mem-initializer} -constitutes a full-expres\-sion\iref{intro.execution}. -Any expression in -a -\grammarterm{mem-initializer} -is evaluated as part of the full-expression that performs the initialization. -\end{note} -A \grammarterm{mem-initializer} where the \grammarterm{mem-initializer-id} denotes -a virtual base class is ignored during execution of a constructor of any class that is -not the most derived class. - -\pnum -A temporary expression bound to a reference member in a \grammarterm{mem-initializer} -is ill-formed. -\begin{example} -\begin{codeblock} -struct A { - A() : v(42) { } // error - const int& v; -}; -\end{codeblock} -\end{example} - -\pnum -In a non-delegating constructor, if -a given potentially constructed subobject is not designated by a -\grammarterm{mem-initializer-id} -(including the case where there is no -\grammarterm{mem-initializer-list} -because the constructor has no -\grammarterm{ctor-initializer}), -then - -\begin{itemize} -\item if the entity is a non-static data member that has -a default member initializer\iref{class.mem} and either - -\begin{itemize} -\item the constructor's class is a union\iref{class.union}, and no other variant -member of that union is designated by a \grammarterm{mem-initializer-id} or - -\item the constructor's class is not a union, and, if the entity is a member of an -anonymous union, no other member of that union is designated by a -\grammarterm{mem-initializer-id}, -\end{itemize} - -the entity is initialized from its default member initializer -as specified in~\ref{dcl.init}; - -\item otherwise, if the entity is an anonymous union or a variant member\iref{class.union.anon}, no initialization is performed; - -\item otherwise, the entity is default-initialized\iref{dcl.init}. -\end{itemize} - -\begin{note} An abstract class\iref{class.abstract} is never a most derived -class, thus its constructors never initialize virtual base classes, therefore the -corresponding \grammarterm{mem-initializer}{s} may be omitted. \end{note} -An attempt to initialize more than one non-static data member of a union renders the -program ill-formed. -\indextext{initialization!const member}% -\indextext{initialization!reference member}% -\begin{note} -After the call to a constructor for class -\tcode{X} -for an object with automatic or dynamic storage duration -has completed, if -the constructor was not invoked as part of value-initialization and -a member of -\tcode{X} -is neither initialized nor -given a value -during execution of the \grammarterm{compound-statement} of the body of the constructor, -the member has an indeterminate value. -\end{note} -\begin{example} -\begin{codeblock} -struct A { - A(); -}; - -struct B { - B(int); -}; - -struct C { - C() { } // initializes members as follows: - A a; // OK: calls \tcode{A::A()} - const B b; // error: \tcode{B} has no default constructor - int i; // OK: \tcode{i} has indeterminate value - int j = 5; // OK: \tcode{j} has the value \tcode{5} -}; -\end{codeblock} -\end{example} - -\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 -default member initializer is ignored. -\begin{example} Given -% The comment below is misrendered with an overly large space before 'effects' -% if left to listings (see NB US-26 (C++17 CD)) (possibly due to the ff -% ligature), so we fix it up manually. -\begin{codeblock} -struct A { - int i = /* some integer expression with side effects */ ; - A(int arg) : i(arg) { } - // ... -}; -\end{codeblock} - -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 -will not take place. -\end{example} - -\pnum -A temporary expression bound to a reference member from a -default member initializer is ill-formed. -\begin{example} -\begin{codeblock} -struct A { - A() = default; // OK - A(int v) : v(v) { } // OK - const int& v = 42; // OK -}; -A a1; // error: ill-formed binding of temporary to reference -A a2(1); // OK, unfortunately -\end{codeblock} -\end{example} - -\pnum -In a non-delegating constructor, the destructor for each potentially constructed -subobject of class type is potentially invoked\iref{class.dtor}. -\begin{note} This provision ensures that destructors can be called for fully-constructed -subobjects in case an exception is thrown\iref{except.ctor}. \end{note} - -\pnum -In a non-delegating constructor, initialization -proceeds in the following order: -\begin{itemize} -\item -\indextext{initialization!order of virtual base class}% -First, and only for the constructor of the most derived class\iref{intro.object}, -virtual base classes are initialized in the order they appear on a -depth-first left-to-right traversal of the directed acyclic graph of -base classes, -where ``left-to-right'' is the order of appearance of the base classes -in the derived class -\grammarterm{base-specifier-list}. -\item -\indextext{initialization!order of base class}% -Then, direct base classes are initialized in declaration order -as they appear in the -\grammarterm{base-specifier-list} -(regardless of the order of the -\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-initializer}{s}). -\item -Finally, the \grammarterm{compound-statement} of the constructor -body is executed. -\end{itemize} - -\begin{note} -The declaration order is mandated to ensure that base and member -subobjects are destroyed in the reverse order of initialization. -\end{note} - -\pnum -\begin{example} -\begin{codeblock} -struct V { - V(); - V(int); -}; - -struct A : virtual V { - A(); - A(int); -}; - -struct B : virtual V { - B(); - B(int); -}; - -struct C : A, B, virtual V { - C(); - C(int); -}; - -A::A(int i) : V(i) { @\commentellip@ } -B::B(int i) { @\commentellip@ } -C::C(int i) { @\commentellip@ } - -V v(1); // use \tcode{V(int)} -A a(2); // use \tcode{V(int)} -B b(3); // use \tcode{V()} -C c(4); // use \tcode{V()} -\end{codeblock} -\end{example} - -\pnum -\indextext{initializer!scope of member}% -Names in the -\grammarterm{expression-list} -or \grammarterm{braced-init-list} -of a -\grammarterm{mem-initializer} -are evaluated in the scope of the constructor for which the -\grammarterm{mem-initializer} -is specified. -\begin{example} - -\begin{codeblock} -class X { - int a; - int b; - int i; - int j; -public: - const int& r; - X(int i): r(a), b(i), i(i), j(this->i) { } -}; -\end{codeblock} - -initializes -\tcode{X::r} -to refer to -\tcode{X::a}, -initializes -\tcode{X::b} -with the value of the constructor parameter -\tcode{i}, -initializes -\tcode{X::i} -with the value of the constructor parameter -\tcode{i}, -and initializes -\tcode{X::j} -with the value of -\tcode{X::i}; -this takes place each time an object of class -\tcode{X} -is created. -\end{example} -\begin{note} -Because the -\grammarterm{mem-initializer} -are evaluated in the scope of the constructor, the -\tcode{this} -pointer can be used in the -\grammarterm{expression-list} -of a -\grammarterm{mem-initializer} -to refer to the object being initialized. -\end{note} - -\pnum -\indextext{initialization!member function call during}% -Member functions (including virtual member functions, \ref{class.virtual}) can be -called for an object under construction. -Similarly, an object under construction can be the operand of the -\tcode{typeid} -operator\iref{expr.typeid} or of a -\tcode{dynamic_cast}\iref{expr.dynamic.cast}. -However, if these operations are performed in a -\grammarterm{ctor-initializer} -(or in a function called directly or indirectly from a -\grammarterm{ctor-initializer}) -before all the -\grammarterm{mem-initializer}{s} -for base classes have completed, the program has undefined behavior. -\begin{example} -\begin{codeblock} -class A { -public: - A(int); -}; - -class B : public A { - int j; -public: - int f(); - B() : A(f()), // undefined: calls member function but base \tcode{A} not yet initialized - j(f()) { } // well-defined: bases are all initialized -}; - -class C { -public: - C(int); -}; - -class D : public B, C { - int i; -public: - D() : C(f()), // undefined: calls member function but base \tcode{C} not yet initialized - i(f()) { } // well-defined: bases are all initialized -}; -\end{codeblock} -\end{example} - -\pnum -\begin{note} -\ref{class.cdtor} describes the result of virtual function calls, -\tcode{typeid} -and -\tcode{dynamic_cast}s -during construction for the well-defined cases; -that is, describes the -\term{polymorphic behavior} -of an object under construction. -\end{note} - -\pnum -\indextext{initializer!pack expansion}% -A \grammarterm{mem-initializer} followed by an ellipsis is -a pack expansion\iref{temp.variadic} that initializes the base -classes specified by a pack expansion in the \grammarterm{base-specifier-list} -for the class. \begin{example} - -\begin{codeblock} -template -class X : public Mixins... { -public: - X(const Mixins&... mixins) : Mixins(mixins)... { } -}; -\end{codeblock} - -\end{example} - -\rSec2[class.inhctor.init]{Initialization by inherited constructor}% -\indextext{initialization!by inherited constructor} - -\pnum -When a constructor for type \tcode{B} is invoked -to initialize an object of a different type \tcode{D} -(that is, when the constructor was inherited\iref{namespace.udecl}), -initialization proceeds as if a defaulted default constructor -were used to initialize the \tcode{D} object and -each base class subobject from which the constructor was inherited, -except that the \tcode{B} subobject is initialized -by the invocation of the inherited constructor. -The complete initialization is considered to be a single function call; -in particular, the initialization of the inherited constructor's parameters -is sequenced before the initialization of any part of the \tcode{D} object. -\begin{example} -\begin{codeblock} -struct B1 { - B1(int, ...) { } -}; - -struct B2 { - B2(double) { } -}; - -int get(); - -struct D1 : B1 { - using B1::B1; // inherits \tcode{B1(int, ...)} - int x; - int y = get(); -}; - -void test() { - D1 d(2, 3, 4); // OK: \tcode{B1} is initialized by calling \tcode{B1(2, 3, 4)}, - // then \tcode{d.x} is default-initialized (no initialization is performed), - // then \tcode{d.y} is initialized by calling \tcode{get()} - D1 e; // error: \tcode{D1} has a deleted default constructor -} - -struct D2 : B2 { - using B2::B2; - B1 b; -}; - -D2 f(1.0); // error: \tcode{B1} has a deleted default constructor - -struct W { W(int); }; -struct X : virtual W { using W::W; X() = delete; }; -struct Y : X { using X::X; }; -struct Z : Y, virtual W { using Y::Y; }; -Z z(0); // OK: initialization of \tcode{Y} does not invoke default constructor of \tcode{X} - -template struct Log : T { - using T::T; // inherits all constructors from class \tcode{T} - ~Log() { std::clog << "Destroying wrapper" << std::endl; } -}; -\end{codeblock} -Class template \tcode{Log} wraps any class and forwards all of its constructors, -while writing a message to the standard log -whenever an object of class \tcode{Log} is destroyed. -\end{example} - -\pnum -If the constructor was inherited from multiple base class subobjects -of type \tcode{B}, the program is ill-formed. -\begin{example} -\begin{codeblock} -struct A { A(int); }; -struct B : A { using A::A; }; - -struct C1 : B { using B::B; }; -struct C2 : B { using B::B; }; - -struct D1 : C1, C2 { - using C1::C1; - using C2::C2; -}; - -struct V1 : virtual B { using B::B; }; -struct V2 : virtual B { using B::B; }; - -struct D2 : V1, V2 { - using V1::V1; - using V2::V2; -}; - -D1 d1(0); // ill-formed: ambiguous -D2 d2(0); // OK: initializes virtual \tcode{B} base class, which initializes the \tcode{A} base class - // then initializes the \tcode{V1} and \tcode{V2} base classes as if by a defaulted default constructor - -struct M { M(); M(int); }; -struct N : M { using M::M; }; -struct O : M {}; -struct P : N, O { using N::N; using O::O; }; -P p(0); // OK: use \tcode{M(0)} to initialize \tcode{N}{'s} base class, - // use \tcode{M()} to initialize \tcode{O}{'s} base class -\end{codeblock} -\end{example} - -\pnum -When an object is initialized by an inherited constructor, -initialization of the object is complete -when the initialization of all subobjects is complete.% -\indextext{initialization!class object|)} - -\rSec1[class.cdtor]{Construction and destruction}% -\indextext{construction|(}% -\indextext{destruction|(}% - -\pnum -\indextext{construction!member access}% -\indextext{destruction!member access}% -For an object with a non-trivial constructor, referring to any non-static member -or base class of the object before the constructor begins execution results in -undefined behavior. For an object with a non-trivial destructor, referring to -any non-static member or base class of the object after the destructor finishes -execution results in undefined behavior. -\begin{example} -\begin{codeblock} -struct X { int i; }; -struct Y : X { Y(); }; // non-trivial -struct A { int a; }; -struct B : public A { int j; Y y; }; // non-trivial - -extern B bobj; -B* pb = &bobj; // OK -int* p1 = &bobj.a; // undefined, refers to base class member -int* p2 = &bobj.y.i; // undefined, refers to member's member - -A* pa = &bobj; // undefined, upcast to a base class type -B bobj; // definition of \tcode{bobj} - -extern X xobj; -int* p3 = &xobj.i; // OK, \tcode{X} is a trivial class -X xobj; -\end{codeblock} -For another example, -\begin{codeblock} -struct W { int j; }; -struct X : public virtual W { }; -struct Y { - int* p; - X x; - Y() : p(&x.j) { // undefined, \tcode{x} is not yet constructed - } -}; -\end{codeblock} -\end{example} - -\pnum -\indextext{construction!pointer to member or base}% -\indextext{destruction!pointer to member or base}% -To explicitly or implicitly convert a pointer (a glvalue) referring to -an object of class -\tcode{X} -to a pointer (reference) to a direct or indirect base class -\tcode{B} -of -\tcode{X}, -the construction of -\tcode{X} -and the construction of all of its direct or indirect bases that directly or -indirectly derive from -\tcode{B} -shall have started and the destruction of these classes shall not have -completed, otherwise the conversion results in undefined behavior. -To form a pointer to (or access the value of) a direct non-static member of -an object -\tcode{obj}, -the construction of -\tcode{obj} -shall have started and its destruction shall not have completed, -otherwise the computation of the pointer value (or accessing the member -value) results in undefined behavior. -\begin{example} -\begin{codeblock} -struct A { }; -struct B : virtual A { }; -struct C : B { }; -struct D : virtual A { D(A*); }; -struct X { X(A*); }; - -struct E : C, D, X { - E() : D(this), // undefined: upcast from \tcode{E*} to \tcode{A*} might use path \tcode{E*} $\rightarrow$ \tcode{D*} $\rightarrow$ \tcode{A*} - // but \tcode{D} is not constructed - - // ``\tcode{D((C*)this)}\!'' would be defined: \tcode{E*} $\rightarrow$ \tcode{C*} is defined because \tcode{E()} has started, - // and \tcode{C*} $\rightarrow$ \tcode{A*} is defined because \tcode{C} is fully constructed - - X(this) {} // defined: upon construction of \tcode{X}, \tcode{C/B/D/A} sublattice is fully constructed -}; -\end{codeblock} -\end{example} - -\pnum -\indextext{virtual function call!constructor and}% -\indextext{virtual function call!destructor and}% -\indextext{construction!virtual function call}% -\indextext{destruction!virtual function call}% -Member functions, including virtual functions\iref{class.virtual}, can be called -during construction or destruction\iref{class.base.init}. -When a virtual function is called directly or indirectly from a constructor -or from a destructor, -including during the construction or destruction of the class's non-static data -members, -and the object to which the call applies is the object (call it \tcode{x}) under construction or -destruction, -the function called is the -final overrider in the constructor's or destructor's class and not one -overriding it in a more-derived class. -If the virtual function call uses an explicit class member access\iref{expr.ref} -and the object expression refers to -the complete object of \tcode{x} or one of that object's base class subobjects -but not \tcode{x} or one of its base class subobjects, the behavior -is undefined. -\begin{example} - -\begin{codeblock} -struct V { - virtual void f(); - virtual void g(); -}; - -struct A : virtual V { - virtual void f(); -}; - -struct B : virtual V { - virtual void g(); - B(V*, A*); -}; - -struct D : A, B { - virtual void f(); - virtual void g(); - D() : B((A*)this, this) { } -}; - -B::B(V* v, A* a) { - f(); // calls \tcode{V::f}, not \tcode{A::f} - g(); // calls \tcode{B::g}, not \tcode{D::g} - v->g(); // \tcode{v} is base of \tcode{B}, the call is well-defined, calls \tcode{B::g} - a->f(); // undefined behavior, \tcode{a}'s type not a base of \tcode{B} -} -\end{codeblock} -\end{example} - -\pnum -\indextext{construction!\idxcode{typeid} operator}% -\indextext{destruction!\idxcode{typeid} operator}% -\indextext{\idxcode{typeid}!construction and}% -\indextext{\idxcode{typeid}!destruction and}% -The -\tcode{typeid} -operator\iref{expr.typeid} can be used during construction or destruction\iref{class.base.init}. -When -\tcode{typeid} -is used in a constructor (including the -\grammarterm{mem-initializer} or default member initializer\iref{class.mem} -for a non-static data member) -or in a destructor, or used in a function called (directly or indirectly) from -a constructor or destructor, if the operand of -\tcode{typeid} -refers to the object under construction or destruction, -\tcode{typeid} -yields the -\tcode{std::type_info} -object representing the constructor or destructor's class. -If the operand of -\tcode{typeid} -refers to the object under construction or destruction and the static type of -the operand is neither the constructor or destructor's class nor one of its -bases, the behavior is undefined. - -\pnum -\indextext{construction!dynamic cast and}% -\indextext{destruction!dynamic cast and}% -\indextext{cast!dynamic!construction and}% -\indextext{cast!dynamic!destruction and}% -\tcode{dynamic_cast}s\iref{expr.dynamic.cast} can be used during construction -or destruction\iref{class.base.init}. When a -\tcode{dynamic_cast} -is used in a constructor (including the -\grammarterm{mem-initializer} or default member initializer -for a non-static data member) -or in a destructor, or used in a function called (directly or indirectly) from -a constructor or destructor, if the operand of the -\tcode{dynamic_cast} -refers to the object under construction or destruction, this object is -considered to be a most derived object that has the type of the constructor or -destructor's class. -If the operand of the -\tcode{dynamic_cast} -refers to the object under construction or destruction and the static type of -the operand is not a pointer to or object of the constructor or destructor's -own class or one of its bases, the -\tcode{dynamic_cast} -results in undefined behavior. -\begin{example} -\begin{codeblock} -struct V { - virtual void f(); -}; - -struct A : virtual V { }; - -struct B : virtual V { - B(V*, A*); -}; - -struct D : A, B { - D() : B((A*)this, this) { } -}; - -B::B(V* v, A* a) { - typeid(*this); // \tcode{type_info} for \tcode{B} - typeid(*v); // well-defined: \tcode{*v} has type \tcode{V}, a base of \tcode{B} yields \tcode{type_info} for \tcode{B} - typeid(*a); // undefined behavior: type \tcode{A} not a base of \tcode{B} - dynamic_cast(v); // well-defined: \tcode{v} of type \tcode{V*}, \tcode{V} base of \tcode{B} results in \tcode{B*} - dynamic_cast(a); // undefined behavior, \tcode{a} has type \tcode{A*}, \tcode{A} not a base of \tcode{B} -} -\end{codeblock} -\end{example} -\indextext{destruction|)}% -\indextext{construction|)}% - -\rSec1[class.copy]{Copying and moving class objects}% - -\pnum -A class object can be copied or moved in two ways: -by initialization~(\ref{class.ctor}, \ref{dcl.init}), including for function argument passing\iref{expr.call} and for function value return\iref{stmt.return}; -and by assignment\iref{expr.ass}. -Conceptually, these two operations are implemented by a -copy/move constructor\iref{class.ctor} -and copy/move assignment operator\iref{over.ass}. - -\pnum -\indextext{constructor!copy!inaccessible}% -\indextext{constructor!move!inaccessible}% -\indextext{assignment operator!copy!inaccessible}% -\indextext{assignment operator!move!inaccessible}% -A program is ill-formed if the copy/move constructor or the copy/move assignment -operator for an object is implicitly odr-used and the special member function -is not accessible\iref{class.access}. -\begin{note} -Copying/moving one object into another using the copy/move constructor or -the copy/move assignment operator does not change the layout or size of either -object. -\end{note} - -\rSec2[class.copy.ctor]{Copy/move constructors}% - -\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 -a -copy -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 arguments\iref{dcl.fct.default}. -\begin{example} -\tcode{X::X(const X\&)} -and -\tcode{X::X(X\&,int=1)} -are copy constructors. - -\begin{codeblock} -struct X { - X(int); - X(const X&, int = 1); -}; -X a(1); // calls \tcode{X(int);} -X b(a, 0); // calls \tcode{X(const X\&, int);} -X c = b; // calls \tcode{X(const X\&, int);} -\end{codeblock} -\end{example} - -\pnum -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 -arguments\iref{dcl.fct.default}. -\begin{example} \tcode{Y::Y(Y\&\&)} is a move constructor. -\begin{codeblock} -struct Y { - Y(const Y&); - Y(Y&&); -}; -extern Y f(int); -Y d(f(1)); // calls \tcode{Y(Y\&\&)} -Y e = d; // calls \tcode{Y(const Y\&)} -\end{codeblock} -\end{example} - -\pnum -\begin{note} -All forms of copy/move constructor may be declared for a class. -\begin{example} - -\begin{codeblock} -struct X { - X(const X&); - X(X&); // OK - X(X&&); - X(const X&&); // OK, but possibly not sensible -}; -\end{codeblock} -\end{example} -\end{note} - -\pnum -\begin{note} -If a class -\tcode{X} -only has a copy constructor with a parameter of type -\tcode{X\&}, -an initializer of type -\tcode{const} -\tcode{X} -or -\tcode{volatile} -\tcode{X} -cannot initialize an object of type -(possibly -cv-qualified) -\tcode{X}. -\begin{example} - -\begin{codeblock} -struct X { - X(); // default constructor - X(X&); // copy constructor with a non-const parameter -}; -const X cx; -X x = cx; // error: \tcode{X::X(X\&)} cannot copy \tcode{cx} into \tcode{x} -\end{codeblock} -\end{example} -\end{note} - -\pnum -A declaration of a constructor for a class -\tcode{X} -is ill-formed if its first parameter is of type (optionally cv-qualified) -\tcode{X} -and either there are no other parameters or else all other parameters have -default arguments. -A member function template is never instantiated to -produce such a constructor signature. -\begin{example} -\begin{codeblock} -struct S { - template S(T); - S(); -}; - -S g; - -void h() { - S a(g); // does not instantiate the member template to produce \tcode{S::S(S)}; - // uses the implicitly declared copy constructor -} -\end{codeblock} -\end{example} - -\pnum -If the class definition does not explicitly declare a copy constructor, -a non-explicit one is declared \defnx{implicitly}{constructor!copy!implicitly declared}. -If the class definition declares a move -constructor or move assignment operator, the implicitly declared copy -constructor is defined as deleted; otherwise, it is defined as -defaulted\iref{dcl.fct.def}. -The latter case is deprecated if the class has a user-declared copy assignment -operator or a user-declared destructor. - -\pnum -The implicitly-declared copy constructor for a class -\tcode{X} -will have the form - -\begin{codeblock} -X::X(const X&) -\end{codeblock} - -if each potentially constructed subobject of a class type -\tcode{M} -(or array thereof) -has a copy constructor whose first parameter is of type -\tcode{const} -\tcode{M\&} -or -\tcode{const} -\tcode{volatile} -\tcode{M\&}.\footnote{This implies that the reference parameter of the -implicitly-declared copy constructor -cannot bind to a -\tcode{volatile} -lvalue; see~\ref{diff.special}.} -Otherwise, the implicitly-declared copy constructor will have the form - -\begin{codeblock} -X::X(X&) -\end{codeblock} - -\pnum -\indextext{constructor!move!implicitly declared}% -If the definition of a class \tcode{X} does not explicitly declare -a move constructor, a non-explicit one will be -implicitly declared as defaulted if and only if - -\begin{itemize} -\item -\tcode{X} does not have a user-declared copy constructor, - -\item -\tcode{X} does not have a user-declared copy assignment operator, - -\item -\tcode{X} does not have a user-declared move assignment operator, and - -\item -\tcode{X} does not have a user-declared destructor. -\end{itemize} - -\begin{note} When the move constructor is not implicitly declared or explicitly supplied, -expressions that otherwise would have invoked the move constructor may instead invoke -a copy constructor. \end{note} - -\pnum -The implicitly-declared move constructor for class \tcode{X} will have the form -\begin{codeblock} -X::X(X&&) -\end{codeblock} - -\pnum -An implicitly-declared copy/move constructor is an -inline public member of its class. -A defaulted copy/\brk{}move constructor for a class - \tcode{X} is defined as deleted\iref{dcl.fct.def.delete} if \tcode{X} has: -\begin{itemize} -\item a potentially constructed subobject type - \tcode{M} (or array thereof) that cannot be copied/moved because - overload resolution\iref{over.match}, as applied to find - \tcode{M}'s - corresponding constructor, results in an ambiguity or - a function that is deleted or inaccessible from the - defaulted constructor, - -\item a variant member whose corresponding constructor - as selected by overload resolution is non-trivial, - -\item any potentially constructed subobject of a type - with a destructor that is deleted or inaccessible from the defaulted - constructor, or, - -\item for the copy constructor, a non-static data member of rvalue reference type. -\end{itemize} - -A defaulted move constructor that is defined as deleted is ignored by overload -resolution~(\ref{over.match}, \ref{over.over}). -\begin{note} -A deleted move constructor would otherwise interfere with initialization from -an rvalue which can use the copy constructor instead. -\end{note} - -\pnum -\indextext{constructor!copy!trivial}% -\indextext{constructor!move!trivial}% -A copy/move constructor for class -\tcode{X} -is -trivial -if it is not user-provided and if: - -\begin{itemize} -\item -class -\tcode{X} -has no virtual functions\iref{class.virtual} -and no virtual base classes\iref{class.mi}, and - -\item -the constructor selected to copy/move each direct base class subobject is trivial, and - -\item -for each non-static data member of -\tcode{X} -that is of class type (or array thereof), -the constructor selected to copy/move that member is trivial; -\end{itemize} - -\indextext{constructor!move!non-trivial}% -otherwise the copy/move constructor is -\defnx{non-trivial}{constructor!copy!nontrivial}. - -\pnum -\indextext{constructor!copy!implicitly defined}% -\indextext{constructor!move!implicitly defined}% -A copy/move constructor -that is defaulted and not defined as deleted -is -\term{implicitly defined} -when it is odr-used\iref{basic.def.odr}, -when it is needed for constant evaluation\iref{expr.const}, or -when it is explicitly defaulted after its first declaration. -\begin{note} -The copy/move constructor is implicitly defined even if the implementation elided -its odr-use~(\ref{basic.def.odr}, \ref{class.temporary}). -\end{note} -If the implicitly-defined constructor would satisfy the requirements of a -constexpr constructor\iref{dcl.constexpr}, the implicitly-defined -constructor is \tcode{constexpr}. - -\pnum -Before the defaulted copy/move constructor for a class is -implicitly defined, -all non-user-provided copy/move constructors for its -potentially constructed subobjects -shall have been implicitly defined. -\begin{note} -An implicitly-declared copy/move constructor has an -implied exception specification\iref{except.spec}. -\end{note} - -\pnum -The implicitly-defined copy/move constructor for a non-union class -\tcode{X} -performs a memberwise copy/move of its bases and members. -\begin{note} Default member initializers of non-static data members are ignored. See also the example in~\ref{class.base.init}. \end{note} -The order of initialization is the same as the order of initialization of bases -and members in a user-defined constructor (see~\ref{class.base.init}). -Let \tcode{x} be either the parameter of the constructor or, for the move constructor, an -xvalue referring to the parameter. -Each base or non-static data member -is copied/moved in the manner appropriate to its type: - -\begin{itemize} -\item -if the member is an array, each element is -direct-initialized with the corresponding subobject of \tcode{x}; - -\item -if a member \tcode{m} has rvalue reference type \tcode{T\&\&}, it is direct-initialized with -\tcode{static_cast(x.m)}; - -\item -otherwise, the base or member is direct-initialized with the corresponding base or member of \tcode{x}. -\end{itemize} - -\indextext{initialization!virtual base class}% -Virtual base class subobjects shall be initialized only once by -the implicitly-defined copy/move constructor (see~\ref{class.base.init}). - -\pnum -The implicitly-defined copy/move constructor for a union -\tcode{X} copies the object representation\iref{basic.types} of \tcode{X}.% -\indextext{constructor!move|)}% -\indextext{constructor!copy|)} - - -\rSec2[class.copy.assign]{Copy/move assignment operator}% - -\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\&}, -\tcode{volatile} \tcode{X\&} or \tcode{const} \tcode{volatile} -\tcode{X\&}.\footnote{Because a template assignment operator or an assignment -operator taking an rvalue reference parameter is never a copy assignment -operator, the presence of such an assignment operator does not suppress the -implicit declaration of a copy assignment operator. Such assignment operators -participate in overload resolution with other assignment operators, including -copy assignment operators, and, if selected, will be used to assign an object.} -\begin{note} -An overloaded assignment operator must be declared to have only one parameter; -see~\ref{over.ass}. -\end{note} -\begin{note} -More than one form of copy assignment operator may be declared for a class. -\end{note} -\begin{note} -If a class -\tcode{X} -only has a copy assignment operator with a parameter of type -\tcode{X\&}, -an expression of type const -\tcode{X} -cannot be assigned to an object of type -\tcode{X}. -\begin{example} - -\begin{codeblock} -struct X { - X(); - X& operator=(X&); -}; -const X cx; -X x; -void f() { - x = cx; // error: \tcode{X::operator=(X\&)} cannot assign \tcode{cx} into \tcode{x} -} -\end{codeblock} -\end{example} -\end{note} - -\pnum -If the class definition does not explicitly declare a copy assignment operator, -one is declared \defnx{implicitly}{assignment operator!copy!implicitly declared}. -If the class definition declares a move -constructor or move assignment operator, the implicitly declared copy -assignment operator is defined as deleted; otherwise, it is defined as -defaulted\iref{dcl.fct.def}. -The latter case is deprecated if the class has a user-declared copy constructor -or a user-declared destructor. -The implicitly-declared copy assignment operator for a class -\tcode{X} -will have the form - -\begin{codeblock} -X& X::operator=(const X&) -\end{codeblock} - -if - -\begin{itemize} -\item -each direct base class -\tcode{B} -of -\tcode{X} -has a copy assignment operator whose parameter is of type -\tcode{const} -\tcode{B\&}, -\tcode{const} -\tcode{volatile} -\tcode{B\&} -or -\tcode{B}, -and -\item -for all the non-static data members of -\tcode{X} -that are of a class type -\tcode{M} -(or array thereof), -each such class type has a copy assignment operator whose parameter is of type -\tcode{const} -\tcode{M\&}, -\tcode{const} -\tcode{volatile} -\tcode{M\&} -or -\tcode{M}.\footnote{This implies that the reference parameter of the -implicitly-declared copy assignment operator cannot bind to a -\tcode{volatile} -lvalue; see~\ref{diff.special}.} -\end{itemize} - -Otherwise, the implicitly-declared copy -assignment operator -will have the form - -\begin{codeblock} -X& X::operator=(X&) -\end{codeblock} - -\pnum -A user-declared move 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{const X\&\&}, \tcode{volatile X\&\&}, or -\tcode{const volatile X\&\&}. \begin{note} An overloaded assignment operator must be -declared to have only one parameter; see~\ref{over.ass}. \end{note}{} -\begin{note} More -than one form of move assignment operator may be declared for a class. \end{note} - -\pnum -\indextext{assignment operator!move!implicitly declared}% -If the definition of a class \tcode{X} does not explicitly declare a -move assignment operator, one -will be implicitly declared as defaulted if and only if - -\begin{itemize} -\item -\tcode{X} does not have a user-declared copy constructor, - -\item -\tcode{X} does not have a user-declared move constructor, - -\item -\tcode{X} does not have a user-declared copy assignment operator, and - -\item -\tcode{X} does not have a user-declared destructor. -\end{itemize} - -\begin{example} The class definition -\begin{codeblock} -struct S { - int a; - S& operator=(const S&) = default; -}; -\end{codeblock} - -will not have a default move assignment operator implicitly declared because the -copy assignment operator has been user-declared. The move assignment operator may -be explicitly defaulted. - -\begin{codeblock} -struct S { - int a; - S& operator=(const S&) = default; - S& operator=(S&&) = default; -}; -\end{codeblock} -\end{example} - -\pnum -The implicitly-declared move assignment operator for a class \tcode{X} will have the form -\begin{codeblock} -X& X::operator=(X&&); -\end{codeblock} - -\pnum -The implicitly-declared copy/move assignment operator for class -\tcode{X} -has the return type -\tcode{X\&}; -it returns the object for which the assignment operator is invoked, that is, -the object assigned to. -An implicitly-declared copy/move assignment operator is an -inline public member of its class. - -\pnum -A defaulted copy/move assignment operator for -class \tcode{X} is defined as deleted if \tcode{X} has: -\begin{itemize} -\item a variant member with a non-trivial corresponding assignment operator and - \tcode{X} is a union-like class, or - -\item a non-static data member of \tcode{const} non-class - type (or array thereof), or - -\item a non-static data member of reference type, or - -\item a direct non-static data member of class type \tcode{M} - (or array thereof) or a direct base class \tcode{M} - that cannot be copied/moved because overload resolution - \iref{over.match}, as applied to find \tcode{M}'s corresponding - assignment operator, results in an ambiguity or - a function that is deleted or inaccessible from the - defaulted assignment operator. -\end{itemize} - -A defaulted move assignment operator that is defined as deleted is ignored by -overload resolution~(\ref{over.match}, \ref{over.over}). - -\pnum -\indextext{assignment operator!copy!hidden}% -\indextext{assignment operator!move!hidden}% -Because a copy/move assignment operator is implicitly declared for a class -if not declared by the user, -a base class copy/move assignment operator is always hidden -by the corresponding assignment operator of a derived class\iref{over.ass}. -A -\grammarterm{using-declaration}\iref{namespace.udecl} that brings in from a base class an assignment operator -with a parameter type that could be that of a -copy/move assignment operator for the -derived class is not considered an explicit declaration of such an -operator and does not suppress the implicit declaration of the derived class -operator; -the operator introduced by the -\grammarterm{using-declaration} -is hidden by the implicitly-declared operator in the derived -class. - -\pnum -\indextext{assignment operator!copy!trivial}% -\indextext{assignment operator!move!trivial}% -A copy/move assignment operator for class -\tcode{X} -is -trivial -if it is not user-provided and if: - -\begin{itemize} -\item -class -\tcode{X} -has no virtual functions\iref{class.virtual} -and no virtual base classes\iref{class.mi}, and - -\item the assignment operator selected to copy/move each direct -base class subobject is trivial, and - -\item -for each non-static data member of -\tcode{X} -that is of class type (or array thereof), -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 -\defnx{non-trivial}{assignment operator!copy!non-trivial}. - -\pnum -\indextext{assignment operator!copy!implicitly defined}% -\indextext{assignment operator!move!implicitly defined}% -A copy/move assignment operator for a class \tcode{X} -that is defaulted and not defined as deleted -is -\term{implicitly defined} -when it is odr-used\iref{basic.def.odr} -(e.g., when it is selected by overload resolution -to assign to an object of its class type), -when it is needed for constant evaluation\iref{expr.const}, or -when it is explicitly defaulted after its first declaration. -The implicitly-defined copy/move assignment operator is \tcode{constexpr} if -\begin{itemize} -\item -\tcode{X} is a literal type, and - -\item -the assignment operator selected to copy/move each direct base class subobject -is a constexpr function, and - -\item -for each non-static data member of \tcode{X} that is of class type (or array -thereof), the assignment operator selected to copy/move that member is a -constexpr function. -\end{itemize} - -\pnum -Before the defaulted copy/move assignment operator for a class is -implicitly defined, -all non-user-provided copy/move assignment operators for -its direct base classes and -its non-static data members shall have been implicitly defined. -\begin{note} -An implicitly-declared copy/move assignment operator has an -implied exception specification\iref{except.spec}. -\end{note} - -\pnum -The implicitly-defined copy/move assignment operator for a -non-union class \tcode{X} performs memberwise copy/move assignment of its subobjects. The direct -base classes of \tcode{X} are assigned first, in the order of their declaration in the -\grammarterm{base-specifier-list}, and then the immediate non-static data members of -\tcode{X} are assigned, in the order in which they were declared in the class -definition. -Let \tcode{x} be either the parameter of the function or, for the move operator, an -xvalue referring to the parameter. -Each subobject is assigned in the manner appropriate to its type: - -\begin{itemize} -\item -if the subobject is of class type, -as if by a call to \tcode{operator=} with the subobject as the object expression -and the corresponding subobject of \tcode{x} as a single function argument -(as if by explicit qualification; that is, -ignoring any possible virtual overriding functions in more derived classes); -\item -if the subobject is an array, each element is assigned, -in the manner appropriate to the element type; -\item -if the subobject is of scalar type, -the built-in assignment operator is used. -\end{itemize} - -\indextext{assignment operator!copy!virtual bases and}% -It is unspecified whether subobjects representing virtual base classes -are assigned more than once by the implicitly-defined copy/move assignment -operator. -\begin{example} - -\begin{codeblock} -struct V { }; -struct A : virtual V { }; -struct B : virtual V { }; -struct C : B, A { }; -\end{codeblock} - -It is unspecified whether the virtual base class subobject -\tcode{V} -is assigned twice by the implicitly-defined copy/move assignment operator for -\tcode{C}. -\end{example} - -\pnum -The implicitly-defined copy assignment operator for a -union \tcode{X} copies the object representation\iref{basic.types} of \tcode{X}.% -\indextext{assignment operator!move|)}% -\indextext{assignment operator!copy|)} - -\rSec2[class.copy.elision]{Copy/move elision}% - -\pnum -\indextext{temporary!elimination of}% -\indextext{elision!copy constructor|see{constructor, copy, elision}}% -\indextext{elision!move constructor|see{constructor, move, elision}}% -\indextext{constructor!copy!elision}% -\indextext{constructor!move!elision}% -When certain criteria are met, an implementation is -allowed to omit the copy/move construction of a class object, -even if the constructor selected for the copy/move operation and/or the -destructor for the object have -\indextext{side effects}% -side effects. In such cases, the -implementation treats the source and target of the -omitted copy/move operation as simply two different ways of -referring to the same object. If the first parameter of the -selected constructor is an rvalue reference to the object's type, -the destruction of that object occurs when the target would have been destroyed; -otherwise, the destruction occurs at the later of the times when the -two objects would have been destroyed without the -optimization.\footnote{Because only one object is destroyed instead of two, -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}}% -\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 -eliminate multiple copies): - -\begin{itemize} -\item in a \tcode{return} statement in a function with a class return type, -when the \grammarterm{expression} is the name of a non-volatile -automatic object (other than a function parameter or a variable -introduced by the \grammarterm{exception-declaration} of a -\grammarterm{handler}\iref{except.handle}) -with the same type (ignoring cv-qualification) as -the function return type, the copy/move operation can be -omitted by constructing the automatic object directly -into the function call's return object - -\item in a \grammarterm{throw-expression}\iref{expr.throw}, when the operand -is the name of a non-volatile automatic object -(other than a function or catch-clause parameter) -whose scope does not extend beyond the end of the innermost enclosing -\grammarterm{try-block} (if there is one), the copy/move operation from the -operand to the exception object\iref{except.throw} can be omitted by -constructing the automatic object directly into the exception object - -\item when the \grammarterm{exception-declaration} of an -exception handler\iref{except} declares an object of the same -type (except for cv-qualification) as the exception -object\iref{except.throw}, the copy operation can be omitted by treating -the \grammarterm{exception-declaration} as an alias for the exception -object if the meaning of the program will be unchanged except for the execution -of constructors and destructors for the object declared by the -\grammarterm{exception-declaration}. -\begin{note} There cannot be a move from the exception object because it is -always an lvalue. \end{note} -\end{itemize} -Copy elision is required -where an expression is evaluated in a context -requiring a constant expression\iref{expr.const} -and in constant initialization\iref{basic.start.static}. -\begin{note} -Copy elision might not be performed -if the same expression -is evaluated in another context. -\end{note} - -\pnum -\begin{example} -\begin{codeblock} -class Thing { -public: - Thing(); - ~Thing(); - Thing(const Thing&); -}; - -Thing f() { - Thing t; - return t; -} - -Thing t2 = f(); - -struct A { - void *p; - constexpr A(): p(this) {} -}; - -constexpr A g() { - A a; - return a; -} - -constexpr A a; // well-formed, \tcode{a.p} points to \tcode{a} -constexpr A b = g(); // well-formed, \tcode{b.p} points to \tcode{b} - -void g() { - A c = g(); // well-formed, \tcode{c.p} may point to \tcode{c} or to an ephemeral temporary -} -\end{codeblock} -Here the criteria for elision can -eliminate -the copying of the local automatic object -\tcode{t} -into the result object for the function call -\tcode{f()}, -which is the global object -\tcode{t2}. -Effectively, the construction of the local object -\tcode{t} -can be viewed as directly initializing the global -object -\tcode{t2}, -and that object's destruction will occur at program -exit. -Adding a move constructor to \tcode{Thing} has the same effect, but it is the -move construction from the local automatic object to \tcode{t2} that is elided. -\end{example} - -\pnum -In the following copy-initialization contexts, a move operation might be used instead of a copy operation: -\begin{itemize} -\item If the \grammarterm{expression} in a \tcode{return} statement\iref{stmt.return} -is a (possibly parenthesized) \grammarterm{id-expression} -that names an object with automatic storage duration declared in the body -or \grammarterm{parameter-declaration-clause} of the innermost enclosing -function or \grammarterm{lambda-expression}, or - -\item if the operand of a \grammarterm{throw-expression}\iref{expr.throw} -is the name of a non-volatile automatic object -(other than a function or catch-clause parameter) -whose scope does not extend beyond the end of the innermost enclosing -\grammarterm{try-block} (if there is one), -\end{itemize} -overload resolution to select the constructor -for the copy is first performed as if the object were designated by an -rvalue. -If the first overload resolution fails or was not performed, -or if the type of the first parameter of the selected -constructor is not an rvalue reference to the object's type (possibly cv-qualified), -overload resolution is performed again, considering the object as an lvalue. -\begin{note} -This two-stage overload resolution must be performed regardless -of whether copy elision will occur. It determines the constructor to be called if -elision is not performed, and the selected constructor must be accessible even if -the call is elided. -\end{note} - -\pnum -\begin{example} -\begin{codeblock} -class Thing { -public: - Thing(); - ~Thing(); - Thing(Thing&&); -private: - Thing(const Thing&); -}; - -Thing f(bool b) { - Thing t; - if (b) - throw t; // OK: \tcode{Thing(Thing\&\&)} used (or elided) to throw \tcode{t} - return t; // OK: \tcode{Thing(Thing\&\&)} used (or elided) to return \tcode{t} -} - -Thing t2 = f(false); // OK: no extra copy/move performed, \tcode{t2} constructed by call to \tcode{f} - -struct Weird { - Weird(); - Weird(Weird&); -}; - -Weird g() { - Weird w; - return w; // OK: first overload resolution fails, second overload resolution selects \tcode{Weird(Weird\&)} -} -\end{codeblock} -\end{example} - -\rSec1[class.compare]{Comparisons}% - -\rSec2[class.compare.default]{Defaulted comparison operator functions}% - -\pnum -A defaulted comparison operator function (\ref{expr.spaceship}, \ref{expr.rel}, \ref{expr.eq}) -for some class \tcode{C} -shall be a non-template function -declared in the \grammarterm{member-specification} of \tcode{C} -that is -\begin{itemize} -\item a non-static member of \tcode{C} having one parameter of type \tcode{const C\&}, or -\item a friend of \tcode{C} having two parameters of type \tcode{const C\&}. -\end{itemize} - -\rSec2[class.spaceship]{Three-way comparison} -\indextext{operator!three-way comparison!defaulted}% - -\pnum -The direct base class subobjects of \tcode{C}, -in the order of their declaration in the \grammarterm{base-specifier-list} of \tcode{C}, -followed by the non-static data members of \tcode{C}, -in the order of their declaration in the \grammarterm{member-specification} of \tcode{C}, -form a list of subobjects. -In that list, any subobject of array type is recursively expanded -to the sequence of its elements, in the order of increasing subscript. -Let $\tcode{x}_i$ be an lvalue denoting the $i^\text{th}$ element -in the expanded list of subobjects for an object \tcode{x} -(of length $n$), -where $\tcode{x}_i$ is -formed by a sequence of -derived-to-base conversions\iref{over.best.ics}, -class member access expressions\iref{expr.ref}, and -array subscript expressions\iref{expr.sub} applied to \tcode{x}. -The type of the expression $\tcode{x}_i$ \tcode{<=>} $\tcode{x}_i$ -is denoted by $\tcode{R}_i$. -It is unspecified -whether virtual base class subobjects are compared more than once. - -\pnum -If the declared return type -of a defaulted three-way comparison operator function -is \tcode{auto}, -then the return type is deduced as -the common comparison type (see below) of -$\tcode{R}_0$, $\tcode{R}_1$, $\dotsc$, $\tcode{R}_{n-1}$. -\begin{note} -Otherwise, -the program will be ill-formed -if the expression $\tcode{x}_i$ \tcode{<=>} $\tcode{x}_i$ -is not implicitly convertible to the declared return type for any $i$. -\end{note} -If the return type is deduced as \tcode{void}, -the operator function is defined as deleted. - -\pnum -The return value \tcode{V} of type \tcode{R} -of the defaulted three-way comparison operator function -with parameters \tcode{x} and \tcode{y} of the same type -is determined by comparing corresponding elements -$\tcode{x}_i$ and $\tcode{y}_i$ -in the expanded lists of subobjects for \tcode{x} and \tcode{y} -until the first index $i$ -where $\tcode{x}_i$ \tcode{<=>} $\tcode{y}_i$ -yields a result value $\tcode{v}_i$ where $\tcode{v}_i \mathrel{\tcode{!=}} 0$, -contextually converted to \tcode{bool}, yields \tcode{true}; -\tcode{V} is $\tcode{v}_i$ converted to \tcode{R}. -If no such index exists, \tcode{V} is -\tcode{std::strong_ordering::equal} converted to \tcode{R}. - -\pnum -The \defn{common comparison type} \tcode{U} -of a possibly-empty list of $n$ types -$\tcode{T}_0$, $\tcode{T}_1$, $\dotsc$, $\tcode{T}_{n-1}$ -is defined as follows: - -\begin{itemize} -\item -If any $\tcode{T}_i$ -is not a comparison category type\iref{cmp.categories}, -\tcode{U} is \tcode{void}. - -\item -Otherwise, if -at least one $\tcode{T}_i$ is \tcode{std::weak_equality}, or -at least one $\tcode{T}_i$ is \tcode{std::strong_equality} and -at least one $\tcode{T}_j$ is \tcode{std::partial_ordering} or - \tcode{std::weak_ordering}, -\tcode{U} is \tcode{std::weak_equality}\iref{cmp.weakeq}. - -\item -Otherwise, if at least one $\tcode{T}_i$ is \tcode{std::strong_equality}, -\tcode{U} is \tcode{std::strong_equality}\iref{cmp.strongeq}. - -\item -Otherwise, if at least one $\tcode{T}_i$ is \tcode{std::partial_ordering}, -\tcode{U} is \tcode{std::partial_ordering}\iref{cmp.partialord}. - -\item -Otherwise, if at least one $\tcode{T}_i$ is \tcode{std::weak_ordering}, -\tcode{U} is \tcode{std::weak_ordering}\iref{cmp.weakord}. - -\item -Otherwise, \tcode{U} is \tcode{std::strong_ordering}\iref{cmp.strongord}. -\begin{note} -In particular, this is the result when $n$ is 0. -\end{note} -\end{itemize} - -\rSec2[class.rel.eq]{Other comparison operators} -\indextext{operator!relational!defaulted}% -\indextext{operator!equality!defaulted}% -\indextext{operator!inequality!defaulted}% - -\pnum -A defaulted relational\iref{expr.rel} or equality\iref{expr.eq} operator function -for some operator \tcode{@} -shall have a declared return type \tcode{bool}. - -\pnum -The operator function with parameters \tcode{x} and \tcode{y} -is defined as deleted if - -\begin{itemize} -\item -overload resolution\iref{over.match}, -as applied to \tcode{x <=> y} -(also considering synthesized candidates with reversed order of parameters\iref{over.match.oper}), -results in an ambiguity -or a function that is deleted or inaccessible from the operator function, -or - -\item -the operator \tcode{@} -cannot be applied to the return type of \tcode{x <=> y} or \tcode{y <=> x}. -\end{itemize} - -Otherwise, the operator function yields -\tcode{x <=> y @ 0} -if an \tcode{operator<=>} -with the original order of parameters was selected, or -\tcode{0 @ y <=> x} -otherwise. - -\pnum -\begin{example} -\begin{codeblock} -struct C { - friend std::strong_equality operator<=>(const C&, const C&); - friend bool operator==(const C& x, const C& y) = default; // OK, returns \tcode{x <=> y == 0} - bool operator<(const C&) = default; // OK, function is deleted -}; -\end{codeblock} -\end{example} diff --git a/source/statements.tex b/source/statements.tex index 668fe3daf4..55f5236f8b 100644 --- a/source/statements.tex +++ b/source/statements.tex @@ -807,7 +807,7 @@ an invocation of a constructor to perform a copy or move of the operand if it is not a prvalue or if its type differs from the return type of the function. A copy operation associated with a \tcode{return} statement may be elided or -converted to a move operation if an automatic storage duration variable is returned\iref{class.copy}. +converted to a move operation if an automatic storage duration variable is returned\iref{class.copy.elision}. \end{note} \begin{example} \begin{codeblock} diff --git a/source/std.tex b/source/std.tex index 7d3c73923b..4625ee43e0 100644 --- a/source/std.tex +++ b/source/std.tex @@ -101,29 +101,26 @@ \include{intro} \include{lex} \include{basic} -\include{conversions} \include{expressions} \include{statements} \include{declarations} -\include{declarators} \include{classes} -\include{derived} -\include{access} -\include{special} \include{overloading} \include{templates} \include{exceptions} \include{preprocessor} \include{lib-intro} \include{support} +\include{concepts} \include{diagnostics} \include{utilities} \include{strings} -\include{locales} \include{containers} \include{iterators} \include{algorithms} \include{numerics} +\include{time} +\include{locales} \include{iostreams} \include{regex} \include{atomics} diff --git a/source/strings.tex b/source/strings.tex index 3b0cfd8e78..fa0b6a7fbb 100644 --- a/source/strings.tex +++ b/source/strings.tex @@ -276,9 +276,9 @@ \requires \tcode{state_type} shall satisfy the -\tcode{CopyAssignable} (\tref{copyassignable}), -\tcode{CopyConstructible} (\tref{copyconstructible}), and -\tcode{DefaultConstructible} (\tref{defaultconstructible}) requirements. +\oldconcept{CopyAssignable} (\tref{copyassignable}), +\oldconcept{CopyConstructible} (\tref{copyconstructible}), and +\oldconcept{DefaultConstructible} (\tref{defaultconstructible}) requirements. \end{itemdescr} \rSec2[char.traits.specializations]{\tcode{char_traits} specializations} @@ -1380,6 +1380,15 @@ of the array whose first element is pointed at by \tcode{s}, \tcode{size()} is equal to \tcode{traits::length(s)}, and \tcode{capacity()} is a value at least as large as \tcode{size()}. + +\pnum +\remarks +Shall not participate in overload resolution +if \tcode{Allocator} is a type +that does not qualify as an allocator\iref{container.requirements.general}. +\begin{note} +This affects class template argument deduction. +\end{note} \end{itemdescr} \indexlibrary{\idxcode{basic_string}!constructor}% @@ -1404,6 +1413,15 @@ of \tcode{n} elements, each storing the initial value \tcode{c}, \tcode{size()} is equal to \tcode{n}, and \tcode{capacity()} is a value at least as large as \tcode{size()}. + +\pnum +\remarks +Shall not participate in overload resolution +if \tcode{Allocator} is a type +that does not qualify as an allocator\iref{container.requirements.general}. +\begin{note} +This affects class template argument deduction. +\end{note} \end{itemdescr} \indexlibrary{\idxcode{basic_string}!constructor}% diff --git a/source/support.tex b/source/support.tex index dc5ddd9e83..052c097507 100644 --- a/source/support.tex +++ b/source/support.tex @@ -17,6 +17,7 @@ functions supporting start and termination of a \Cpp{} program, support for dynamic memory management, support for dynamic type identification, +support for contract violation handling, support for exception processing, support for initializer lists, and other runtime support, as summarized in \tref{lang.sup.lib.summary}. @@ -32,6 +33,7 @@ \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.contract} & Contract violation handling & \tcode{} \\ \rowsep \ref{support.exception} & Exception handling & \tcode{} \\ \rowsep \ref{support.initlist} & Initializer lists & \tcode{} \\ \rowsep \ref{cmp} & Comparisons & \tcode{} \\ \rowsep @@ -514,6 +516,176 @@ about the C++ standard library (e.g., version number and release date). +\pnum +The macros in \tref{support.ft} are defined +after inclusion of the header \tcode{} or +one of the corresponding headers specified in the table. +\begin{note} +Future versions of this International Standard might replace +the values of these macros with greater values. +\end{note} + +\begin{LongTable}{Standard library feature-test macros} +{tab:support.ft}{llx{.3\hsize}} +\\ \topline +\lhdr{Macro name} & \chdr{Value} & \rhdr{Header(s)} \\ \capsep +\endfirsthead +\continuedcaption \\ +\hline +\lhdr{Macro name} & \chdr{Value} & \rhdr{Header(s)} \\ \capsep +\endhead +\defnlibxname{cpp_lib_addressof_constexpr} & \tcode{201603L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_allocator_traits_is_always_equal} & \tcode{201411L} & + \tcode{} \tcode{} \tcode{} + \tcode{} \tcode{} \tcode{} \tcode{} + \tcode{} \tcode{} \tcode{} + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_any} & \tcode{201606L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_apply} & \tcode{201603L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_array_constexpr} & \tcode{201603L} & + \tcode{} \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_as_const} & \tcode{201510L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_atomic_is_always_lock_free} & \tcode{201603L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_atomic_ref} & \tcode{201806L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_bit_cast} & \tcode{201806L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_bool_constant} & \tcode{201505L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_boyer_moore_searcher} & \tcode{201603L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_byte} & \tcode{201603L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_chrono} & \tcode{201611L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_clamp} & \tcode{201603L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_complex_udls} & \tcode{201309L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_concepts} & \tcode{201806L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_constexpr_swap_algorithms} & \tcode{201806L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_enable_shared_from_this} & \tcode{201603L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_exchange_function} & \tcode{201304L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_execution} & \tcode{201603L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_filesystem} & \tcode{201703L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_gcd_lcm} & \tcode{201606L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_generic_associative_lookup} & \tcode{201304L} & + \tcode{} \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_hardware_interference_size} & \tcode{201703L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_has_unique_object_representations} & \tcode{201606L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_hypot} & \tcode{201603L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_incomplete_container_elements} & \tcode{201505L} & + \tcode{} \tcode{} \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_integer_sequence} & \tcode{201304L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_integral_constant_callable} & \tcode{201304L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_invoke} & \tcode{201411L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_is_aggregate} & \tcode{201703L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_is_final} & \tcode{201402L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_is_invocable} & \tcode{201703L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_is_null_pointer} & \tcode{201309L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_is_swappable} & \tcode{201603L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_launder} & \tcode{201606L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_list_remove_return_type} & \tcode{201806L} & + \tcode{} \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_logical_traits} & \tcode{201510L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_make_from_tuple} & \tcode{201606L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_make_reverse_iterator} & \tcode{201402L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_make_unique} & \tcode{201304L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_map_try_emplace} & \tcode{201411L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_math_special_functions} & \tcode{201603L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_memory_resource} & \tcode{201603L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_node_extract} & \tcode{201606L} & + \tcode{} \tcode{} \tcode{} + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_nonmember_container_access} & \tcode{201411L} & + \tcode{} \tcode{} \tcode{} \tcode{} + \tcode{} \tcode{} \tcode{} \tcode{} \tcode{} + \tcode{} \tcode{} \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_not_fn} & \tcode{201603L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_null_iterators} & \tcode{201304L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_optional} & \tcode{201606L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_parallel_algorithm} & \tcode{201603L} & + \tcode{} \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_quoted_string_io} & \tcode{201304L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_raw_memory_algorithms} & \tcode{201606L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_result_of_sfinae} & \tcode{201210L} & + \tcode{} \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_robust_nonmodifying_seq_ops} & \tcode{201304L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_sample} & \tcode{201603L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_scoped_lock} & \tcode{201703L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_shared_mutex} & \tcode{201505L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_shared_ptr_arrays} & \tcode{201611L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_shared_ptr_weak_type} & \tcode{201606L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_shared_timed_mutex} & \tcode{201402L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_string_udls} & \tcode{201304L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_string_view} & \tcode{201606L} & + \tcode{} \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_to_chars} & \tcode{201611L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_transformation_trait_aliases} & \tcode{201304L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_transparent_operators} & \tcode{201510L} & + \tcode{} \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_tuple_element_t} & \tcode{201402L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_tuples_by_type} & \tcode{201304L} & + \tcode{} \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_type_trait_variable_templates} & \tcode{201510L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_uncaught_exceptions} & \tcode{201411L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_unordered_map_try_emplace} & \tcode{201411L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_variant} & \tcode{201606L} & + \tcode{} \\ \rowsep +\defnlibxname{cpp_lib_void_t} & \tcode{201411L} & + \tcode{} \\ \rowsep +\end{LongTable} + \rSec2[limits.syn]{Header \tcode{} synopsis} \indexhdr{limits}% \indextext{\idxcode{numeric_limits}}% @@ -1713,7 +1885,7 @@ \tcode{main}.} If control leaves a registered function called by \tcode{exit} because the function does -not provide a handler for a thrown exception, \tcode{std::terminate()} shall be called\iref{except.terminate}.% +not provide a handler for a thrown exception, the function \tcode{std::terminate} shall be called\iref{except.terminate}.% \indexlibrary{\idxcode{terminate}}% \item @@ -1790,7 +1962,7 @@ previously registered functions that had already been called at the time it was registered. Objects shall not be destroyed as a result of calling \tcode{quick_exit}. If control leaves a registered function called by \tcode{quick_exit} because the -function does not provide a handler for a thrown exception, \tcode{std::terminate()} shall +function does not provide a handler for a thrown exception, the function \tcode{std::terminate} shall be called.\indexlibrary{\idxcode{terminate}} \begin{note} A function registered via \tcode{at_quick_exit} @@ -1822,6 +1994,8 @@ \rSec2[new.syn]{Header \tcode{} synopsis} \indexhdr{new}% \indexlibrary{\idxcode{align_val_t}}% +\indexlibrary{\idxcode{destroying_delete_t}}% +\indexlibrary{\idxcode{destroying_delete}}% \indexlibrary{\idxcode{nothrow_t}}% \indexlibrary{\idxcode{nothrow}}% \begin{codeblock} @@ -1829,6 +2003,11 @@ class bad_alloc; class bad_array_new_length; + struct destroying_delete_t { + explicit destroying_delete_t() = default; + }; + inline constexpr destroying_delete_t destroying_delete{}; + enum class align_val_t : size_t {}; struct nothrow_t { explicit nothrow_t() = default; }; @@ -3074,6 +3253,99 @@ \tcode{wstring}~(\ref{string.classes}, \ref{locale.codecvt}) \end{itemdescr} +\rSec1[support.contract]{Contract violation handling} + +\rSec2[contract.syn]{Header \tcode{} synopsis} + +The header \tcode{} defines a type +for reporting information about contract violations +generated by the implementation. +\begin{codeblock} +namespace std { + class contract_violation; +} +\end{codeblock} + +\rSec2[support.contract.cviol]{Class \tcode{contract_violation}} +\indexlibrary{\idxcode{contract_violation}}% + +\begin{codeblock} +namespace std { + class contract_violation { + public: + uint_least32_t line_number() const noexcept; + string_view file_name() const noexcept; + string_view function_name() const noexcept; + string_view comment() const noexcept; + string_view assertion_level() const noexcept; + }; +} +\end{codeblock} + +\pnum +The class \tcode{contract_violation} describes information about +a contract violation generated by the implementation. + +\indexlibrarymember{line_number}{contract_violation}% +\begin{itemdecl} +uint_least32_t line_number() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns The source code location +where the contract violation happened\iref{dcl.attr.contract}. +If the location is unknown, an implementation may return \tcode{0}. +\end{itemdescr} + +\indexlibrarymember{file_name}{contract_violation}% +\begin{itemdecl} +string_view file_name() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns The source file name +where the contract violation happened\iref{dcl.attr.contract}. +If the file name is unknown, +an implementation may return \tcode{string_view\{\}}. +\end{itemdescr} + +\indexlibrarymember{function_name}{contract_violation}% +\begin{itemdecl} +string_view function_name() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns The name of the function +where the contract violation happened\iref{dcl.attr.contract}. +If the function name is unknown, +an implementation may return \tcode{string_view\{\}}. +\end{itemdescr} + +\indexlibrarymember{comment}{contract_violation}% +\begin{itemdecl} +string_view comment() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns Implementation-defined text describing +the predicate of the violated contract. +\end{itemdescr} + +\indexlibrarymember{assertion_level}{contract_violation}% +\begin{itemdecl} +string_view assertion_level() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns Text describing the \grammarterm{assertion-level} +of the violated contract. +\end{itemdescr} + \rSec1[support.exception]{Exception handling} \pnum @@ -3373,8 +3645,8 @@ \pnum \remarks When \tcode{uncaught_exceptions() > 0}, -throwing an exception can result in a call of\\ -\tcode{std::terminate()}\iref{except.terminate}. +throwing an exception can result in a call of the function +\tcode{std::terminate}\iref{except.terminate}. \end{itemdescr} \rSec2[propagation]{Exception propagation} @@ -3390,7 +3662,7 @@ \pnum \tcode{exception_ptr} shall satisfy the requirements of -\tcode{NullablePointer} (\tref{nullablepointer}). +\oldconcept{NullablePointer} (\tref{nullablepointer}). \pnum Two non-null values of type \tcode{exception_ptr} are equivalent and compare equal if and @@ -3529,7 +3801,7 @@ \begin{itemdescr} \pnum -\effects If \tcode{nested_ptr()} returns a null pointer, the function calls \tcode{std::terminate()}. +\effects If \tcode{nested_ptr()} returns a null pointer, the function calls the function \tcode{std::terminate}. Otherwise, it throws the stored exception captured by \tcode{*this}. \end{itemdescr} @@ -3553,7 +3825,7 @@ Let \tcode{U} be \tcode{decay_t}. \pnum -\requires \tcode{U} shall be \tcode{CopyConstructible}. +\requires \tcode{U} shall be \oldconcept{CopyConstructible}. \pnum \throws @@ -3710,7 +3982,7 @@ \rSec1[cmp]{Comparisons} -\rSec2[cmp.syn]{Header \tcode{} synopsis} +\rSec2[compare.syn]{Header \tcode{} synopsis} \pnum The header \tcode{} specifies types, objects, and functions diff --git a/source/tables.tex b/source/tables.tex index 0c0cdf05e8..1b63834806 100644 --- a/source/tables.tex +++ b/source/tables.tex @@ -82,6 +82,32 @@ \end{floattablebase} } +% a column in a multicolfloattable (internal) +\newenvironment{mcftcol}{% + \renewcommand{\columnbreak}{% + \end{mcftcol} & + \begin{mcftcol} + }% + \setlength{\tabcolsep}{0pt}% + \begin{tabular}[t]{l} +}{ + \end{tabular} +} + +% usage: \begin{multicolfloattable}{TITLE}{XREF}{COLUMNS} +% produces floating table, location determined within limits +% by LaTeX. +\newenvironment{multicolfloattable}[3] +{ + \begin{floattable}{#1}{#2}{#3} + \topline + \begin{mcftcol} +} +{ + \end{mcftcol} \\ + \end{floattable} +} + % usage: \begin{tokentable}{TITLE}{XREF}{HDR1}{HDR2} % produces six-column table used for lists of replacement tokens; % the columns are in pairs -- left-hand column has header HDR1, diff --git a/source/templates.tex b/source/templates.tex index 983ee8d089..6437e308aa 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -365,24 +365,21 @@ \end{note} \pnum -A non-type -\grammarterm{template-parameter} -shall have one of the following (optionally -cv-qualified) -types: +A non-type \grammarterm{template-parameter} +shall have one of the following (optionally cv-qualified) types: \begin{itemize} -\item integral or enumeration type, - -\item pointer to object or pointer to function, - -\item lvalue reference to object or lvalue reference to function, +\item a type that is literal, +has strong structural equality\iref{class.compare.default}, +has no \tcode{mutable} or \tcode{volatile} subobjects, +and in which if there is a defaulted member \tcode{operator<=>}, +then it is declared public, -\item pointer to member, +\item an lvalue reference type, -\item \tcode{std::nullptr_t}, or +\item a type that contains a placeholder type\iref{dcl.spec.auto}, or -\item a type that contains a placeholder type\iref{dcl.spec.auto}. +\item a placeholder for a deduced class type\iref{dcl.type.class.deduct}. \end{itemize} \pnum @@ -398,27 +395,38 @@ are ignored when determining its type. \pnum -A non-type non-reference -\grammarterm{template-parameter} -is a prvalue. -It shall not be assigned to or in any other way have its value changed. -A non-type non-reference -\grammarterm{template-parameter} -cannot have its address taken. -When a non-type non-reference -\grammarterm{template-parameter} +When a non-type \grammarterm{template-parameter} +of non-reference and non-class type is used as an initializer for a reference, a temporary is always used. +An \grammarterm{id-expression} naming +a non-type \grammarterm{template-parameter} of class type \tcode{T} +denotes a static storage duration object of type \tcode{const T}, +known as a \defn{template parameter object}, +whose value is that of the corresponding template argument +after it has been converted +to the type of the \grammarterm{template-parameter}. +All such template parameters in the program of the same type +with the same value denote the same template parameter object. +\begin{note} +If an \grammarterm{id-expression} names +a non-type non-reference \grammarterm{template-parameter}, +then it is a prvalue if it has non-class type. +Otherwise, if it is of class type \tcode{T}, +it is an lvalue and has type \tcode{const T}\iref{expr.prim.id.unqual}. +\end{note} \begin{example} \begin{codeblock} -template void f() { +struct A { auto operator<=>(A, A) = default; }; +template void f() { i++; // error: change of template-parameter value &x; // OK &i; // error: address of non-reference template-parameter - + &a; // OK int& ri = i; // error: non-const reference bound to temporary const int& cri = i; // OK: const reference bound to temporary + const A& ra = a; // OK: const reference bound to a template parameter object } \end{codeblock} \end{example} @@ -962,6 +970,45 @@ A \grammarterm{template-id} that names an alias template specialization is a \grammarterm{type-name}. +\pnum +A \grammarterm{template-id} is \defnx{valid}{\idxgram{template-id}!valid} if +\begin{itemize} +\item + there are at most as many arguments as there are parameters + or a parameter is a template parameter pack\iref{temp.variadic}, + +\item + there is an argument for each non-deducible non-pack parameter + that does not have a default \grammarterm{template-argument}, + +\item + each \grammarterm{template-argument} matches the corresponding + \grammarterm{template-parameter}\iref{temp.arg}, + +\item + substitution of each template argument into the following + template parameters (if any) succeeds, and + +\item + if the \grammarterm{template-id} is non-dependent, + the associated constraints are satisfied as specified in the next paragraph. +\end{itemize} +A \grammarterm{simple-template-id} shall be valid unless it names a +function template specialization\iref{temp.deduct}. +\begin{example} +\begin{codeblock} +template class X; +struct S { + using type = int; +}; +using T1 = X; // error: too many arguments +using T2 = X<>; // error: no default argument for first template parameter +using T3 = X<1>; // error: value \tcode{1} does not match type-parameter +using T4 = X; // error: substitution failure for second template parameter +using T5 = X; // OK +\end{codeblock} +\end{example} + \pnum When the \grammarterm{template-name} of a \grammarterm{simple-template-id} @@ -1245,27 +1292,28 @@ \rSec2[temp.arg.nontype]{Template non-type arguments} \pnum -If the type of a \grammarterm{template-parameter} -contains a placeholder type~(\ref{dcl.spec.auto}, \ref{temp.param}), -the deduced parameter type is determined -from the type of the \grammarterm{template-argument} -by placeholder type deduction\iref{dcl.type.auto.deduct}. +If the type \tcode{T} of a \grammarterm{template-parameter}\iref{temp.param} +contains a placeholder type\iref{dcl.spec.auto} +or a placeholder for a deduced class type\iref{dcl.type.class.deduct}, +the type of the parameter is the type deduced +for the variable \tcode{x} in the invented declaration +\begin{codeblock} + T x = @\grammartermnc{template-argument}@ ; +\end{codeblock} If a deduced parameter type is not permitted for a \grammarterm{template-parameter} declaration\iref{temp.param}, the program is ill-formed. \pnum -A -\grammarterm{template-argument} -for a non-type -\grammarterm{template-parameter} -shall be -a converted -constant expression\iref{expr.const} +A \grammarterm{template-argument} +for a non-type \grammarterm{template-parameter} +shall be a converted constant expression\iref{expr.const} of the type of the \grammarterm{template-parameter}. For a non-type \grammarterm{template-parameter} of reference or pointer type, -the value of the constant expression shall not refer to -(or for a pointer type, shall not be the address of): +or for each non-static data member of reference or pointer type +in a non-type \grammarterm{template-parameter} of class type or subobject thereof, +the reference or pointer value shall not refer to +or be the address of (respectively): \begin{itemize} \item a subobject\iref{intro.object}, @@ -1314,20 +1362,27 @@ \pnum \begin{note} -A string literal\iref{lex.string} -is not an acceptable -\grammarterm{template-argument}. +A string literal\iref{lex.string} is +not an acceptable \grammarterm{template-argument} +for a \grammarterm{template-parameter} of non-class type. \begin{example} \begin{codeblock} -template class X { +template class X { @\commentellip@ }; -X x1; // error: string literal as template-argument +X x; // error: string literal as template-argument const char p[] = "Vivisectionist"; -X x2; // OK +X y; // OK + +class A { + constexpr A(const char*) {} + auto operator<=>(A, A) = default; +}; + +X z; // OK, string literal is a constructor argument to \tcode{A} \end{codeblock} \end{example} \end{note} @@ -1548,7 +1603,7 @@ \pnum In order for a constrained template to be instantiated\iref{temp.spec}, its associated constraints\iref{temp.constr.decl} -shall be satisfied as described in the following subsections. +shall be satisfied as described in the following subclauses. \begin{note} Forming the name of a specialization of a class template, @@ -1974,17 +2029,17 @@ refer to the same template and} \item {their corresponding type \grammarterm{template-argument}{s} are the same type and} -\item {their corresponding non-type -template arguments of -integral or enumeration type have identical values and} -\item {their corresponding non-type \grammarterm{template-argument}{s} of -pointer type refer to the same object or function or are both the null -pointer value and} \item {their corresponding non-type \grammarterm{template-argument}{s} of pointer-to-member type refer to the same class member or are both the null member pointer value and} \item {their corresponding non-type \grammarterm{template-argument}{s} of reference type refer to the same object or function and} +\item {their remaining corresponding +non-type \grammarterm{template-argument}{s} +have the same type and value +after conversion to the type of the \grammarterm{template-parameter}, +where they are considered to have the same value if they compare equal +with \tcode{operator<=>}, and} \item {their corresponding template \grammarterm{template-argument}{s} refer to the same template.} \end{itemize} @@ -2472,11 +2527,9 @@ \end{codeblock} \end{example} \begin{note} -Because the explicit template argument list follows the function template -name, and because conversion member function templates and constructor -member function templates are called without using a function name, -there is no way to provide an explicit template argument list for these -function templates. +There is no syntax to form a \grammarterm{template-id}\iref{temp.names} +by providing an explicit template argument list\iref{temp.arg.explicit} +for a conversion function template\iref{class.conv.fct}. \end{note} \pnum @@ -2686,7 +2739,7 @@ where $N$ is the number of elements in the pack expansion parameters. Each $\mathtt{E}_i$ is generated by instantiating the pattern and -replacing each pack expansion parameter with its $i^{\textrm{th}}$ element. +replacing each pack expansion parameter with its $i^\text{th}$ element. Such an element, in the context of the instantiation, is interpreted as follows: @@ -2694,13 +2747,13 @@ \item if the pack is a template parameter pack, the element is a template parameter\iref{temp.param} of the corresponding kind (type or -non-type) designating the $i^{\textrm{th}}$ +non-type) designating the $i^\text{th}$ corresponding type or value template argument; \item if the pack is a function parameter pack, the element is an \grammarterm{id-expression} -designating the $i^{\textrm{th}}$ function parameter +designating the $i^\text{th}$ function parameter that resulted from instantiation of the function parameter pack declaration; otherwise @@ -2709,7 +2762,7 @@ if the pack is an \grammarterm{init-capture} pack, the element is an \grammarterm{id-expression} designating the variable introduced by -the $i^{\textrm{th}}$ \grammarterm{init-capture} +the $i^\text{th}$ \grammarterm{init-capture} that resulted from instantiation of the \grammarterm{init-capture} pack. \end{itemize} @@ -2776,7 +2829,7 @@ \placeholder{op} is the \grammarterm{fold-operator}, $N$ is the number of elements in the pack expansion parameters, and each $\mathtt{E}_i$ is generated by instantiating the pattern -and replacing each pack expansion parameter with its $i$th element. +and replacing each pack expansion parameter with its $i^\text{th}$ element. For a binary fold-expression, $\mathtt{E}$ is generated by instantiating the \grammarterm{cast-expression} @@ -3933,9 +3986,10 @@ \end{example} \pnum -The type of a lambda expression appearing in an alias template declaration -is different between instantiations of that template, even when the lambda -expression is not dependent. +The type of a \grammarterm{lambda-expression} +appearing in an alias template declaration +is different between instantiations of that template, +even when the \grammarterm{lambda-expression} is not dependent. \begin{example} \begin{codeblock} template @@ -4613,7 +4667,7 @@ value of template parameters (as determined by the template arguments) and this determines the context for name lookup for certain names. -An expressions may be +An expression may be \defnx{type-dependent}{expression!type-dependent} (that is, its type may depend on a template parameter) or \defnx{value-dependent}{expression!value-dependent} @@ -5092,6 +5146,13 @@ declared with a type that contains a placeholder type\iref{dcl.spec.auto}, +\item +an +\grammarterm{identifier} +associated by name lookup with +a variable declared with a type that contains a placeholder type\iref{dcl.spec.auto} +where the initializer is type-dependent, + \item an \grammarterm{identifier} associated by name lookup with one or more declarations of member functions of the current instantiation declared @@ -6178,7 +6239,10 @@ function\iref{special}, the program is ill-formed. \pnum -The \grammarterm{declaration} in an \grammarterm{explicit-instantiation} and the \grammarterm{declaration} produced by the corresponding substitution into the templated function, variable, or class are two declarations of the same entity. +The \grammarterm{declaration} in an \grammarterm{explicit-instantiation} and +the \grammarterm{declaration} produced by the corresponding substitution +into the templated function, variable, or class +are two declarations of the same entity. \begin{note} These declarations are required to have matching types as specified in~\ref{basic.link}, except as specified in~\ref{except.spec}. \begin{example} @@ -6648,6 +6712,14 @@ \end{codeblock} \end{example} +\pnum +\begin{note} +For an explicit specialization of a function template, +the contract conditions\iref{dcl.attr.contract} +of the explicit specialization +are independent of those of the primary template. +\end{note} + \pnum An explicit specialization of a static data member of a template or an explicit specialization of a static data member template is a @@ -6978,10 +7050,10 @@ \pnum \begin{note} Because the explicit template argument list follows the function -template name, and because conversion member function templates and -constructor member function templates are called without using a -function name, there is no way to provide an explicit template -argument list for these function templates. +template name, and because +constructor templates\iref{class.ctor} are named without using a +function name\iref{class.qual}, there is no way to provide an explicit +template argument list for these function templates. \end{note} \pnum @@ -7026,30 +7098,11 @@ \end{example} \pnum -When an explicit template argument list is specified, if the template -arguments are not compatible with the template parameter list or do -not result in a valid function type as described below, type -deduction fails. Specifically, the following steps are performed when -evaluating an explicitly specified template argument list with respect -to a given function template: -\begin{itemize} -\item If the specified template arguments do not match the template -parameters in -kind (i.e., type, non-type, template), or if there -are more arguments than there are parameters -and no parameter is a template parameter pack, or if there is not -an argument for each non-pack parameter, +When an explicit template argument list is specified, if the +given \grammarterm{template-id} is not valid\iref{temp.names}, type deduction fails. - -\item If any non-type argument does not match the type of the -corresponding non-type -template parameter, and is not convertible to the type of the -corresponding non-type parameter as specified in~\ref{temp.arg.nontype}, -type deduction fails. - -\item The specified template argument values are substituted for the +Otherwise, the specified template argument values are substituted for the corresponding template parameters as specified below. -\end{itemize} \pnum After this substitution is performed, the function parameter type @@ -7146,6 +7199,9 @@ inside \tcode{sizeof}, \tcode{decltype}, and other contexts that allow non-constant expressions. The substitution proceeds in lexical order and stops when a condition that causes deduction to fail is encountered. +If substitution into different declarations of the same function template would +cause template instantiations to occur in a different order or not at all, +the program is ill-formed; no diagnostic required. \begin{note} The equivalent substitution in exception specifications is done only when the \grammarterm{noexcept-specifier} is instantiated, @@ -7159,10 +7215,14 @@ template void f(...) { } template auto g(typename A::X) -> typename T::X; template void g(...) { } +template typename T::X h(typename A::X); +template auto h(typename A::X) -> typename T::X; // redeclaration +template void h(...) { } -void h() { +void x() { f(0); // OK, substituting return type causes deduction to fail g(0); // error, substituting parameter type instantiates \tcode{A} + h(0); // ill-formed, no diagnostic required } \end{codeblock} \end{example} @@ -7177,9 +7237,11 @@ as part of the substitution process. \end{note} -Only invalid types and expressions in the immediate -context of the function type and its template parameter types can result in a deduction -failure. +Only invalid types and expressions in the immediate context of +the function type, +its template parameter types, +and its \grammarterm{explicit-specifier} +can result in a deduction failure. \begin{note} The substitution into types and expressions can result in effects such as the instantiation of class template specializations and/or @@ -7248,7 +7310,7 @@ \item Attempting to instantiate a pack expansion containing multiple packs of differing lengths. \item Attempting to create an array with an element type that is \tcode{void}, a -function type, a reference type, or an abstract class type, or attempting +function type, or a reference type, or attempting to create an array with a size that is zero or negative. \begin{example} \begin{codeblock} @@ -7342,10 +7404,6 @@ Attempting to create a function type in which a parameter has a type of \tcode{void}, or in which the return type is a function type or array type. - -\item -Attempting to create a function type in which a parameter type or the return type is an -abstract class type\iref{class.abstract}. \end{itemize} \end{note} diff --git a/source/threads.tex b/source/threads.tex index 50034e08f8..2d710a1eaa 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -133,7 +133,7 @@ \pnum Implementation-provided clocks that are used for these functions shall satisfy the -\tcode{TrivialClock} requirements\iref{time.clock.req}. +\oldconcept{TrivialClock} requirements\iref{time.clock.req}. \pnum A function that takes an argument which specifies a timeout will throw if, @@ -143,7 +143,7 @@ the implementation as specified in~\ref{time.clock} do not throw exceptions. \end{note} -\rSec2[thread.req.lockable]{Requirements for \tcode{Lockable} types} +\rSec2[thread.req.lockable]{Requirements for \oldconcept{Lockable} types} \rSec3[thread.req.lockable.general]{In general} @@ -165,16 +165,16 @@ \tcode{lock_guard}\iref{thread.lock.guard}, \tcode{lock}, \tcode{try_lock}\iref{thread.lock.algorithm}, and \tcode{condition_variable_any}\iref{thread.condition.condvarany} all operate on user-supplied -lockable objects. The \tcode{BasicLockable} requirements, the \tcode{Lockable} requirements, -and the \tcode{TimedLockable} requirements list the requirements imposed by these library types +lockable objects. The \oldconcept{BasicLockable} requirements, the \oldconcept{Lockable} requirements, +and the \oldconcept{TimedLockable} requirements list the requirements imposed by these library types in order to acquire or release ownership of a \tcode{lock} by a given execution agent. \begin{note} The nature of any lock ownership and any synchronization it may entail are not part of these requirements. \end{note} -\rSec3[thread.req.lockable.basic]{\tcode{BasicLockable} requirements} +\rSec3[thread.req.lockable.basic]{\oldconcept{BasicLockable} requirements} \pnum -A type \tcode{L} meets the \tcode{BasicLockable} requirements if the following expressions are +A type \tcode{L} meets the \oldconcept{BasicLockable} requirements if the following expressions are well-formed and have the specified semantics (\tcode{m} denotes a value of type \tcode{L}). \begin{itemdecl} @@ -202,10 +202,10 @@ \throws Nothing. \end{itemdescr} -\rSec3[thread.req.lockable.req]{\tcode{Lockable} requirements} +\rSec3[thread.req.lockable.req]{\oldconcept{Lockable} requirements} \pnum -A type \tcode{L} meets the \tcode{Lockable} requirements if it meets the \tcode{BasicLockable} +A type \tcode{L} meets the \oldconcept{Lockable} requirements if it meets the \oldconcept{BasicLockable} requirements and the following expressions are well-formed and have the specified semantics (\tcode{m} denotes a value of type \tcode{L}). @@ -225,10 +225,10 @@ \returns \tcode{true} if the lock was acquired, \tcode{false} otherwise. \end{itemdescr} -\rSec3[thread.req.lockable.timed]{\tcode{TimedLockable} requirements} +\rSec3[thread.req.lockable.timed]{\oldconcept{TimedLockable} requirements} \pnum -A type \tcode{L} meets the \tcode{TimedLockable} requirements if it meets the \tcode{Lockable} +A type \tcode{L} meets the \oldconcept{TimedLockable} requirements if it meets the \oldconcept{Lockable} requirements and the following expressions are well-formed and have the specified semantics (\tcode{m} denotes a value of type \tcode{L}, \tcode{rel_time} denotes a value of an instantiation of \tcode{duration}\iref{time.duration}, and \tcode{abs_time} denotes a value @@ -522,7 +522,7 @@ \begin{itemdescr} \pnum \requires\ \tcode{F} and each $\tcode{T}_i$ in \tcode{Args} shall satisfy the -\tcode{MoveConstructible} requirements. +\oldconcept{MoveConstructible} requirements. \tcode{% \placeholdernc{INVOKE}(\brk{}% \placeholdernc{DECAY_COPY}(\brk{}% @@ -895,10 +895,10 @@ denotes an object of a mutex type. \pnum -The mutex types shall satisfy the \tcode{Lockable} requirements\iref{thread.req.lockable.req}. +The mutex types shall satisfy the \oldconcept{Lockable} requirements\iref{thread.req.lockable.req}. \pnum -The mutex types shall be \tcode{DefaultConstructible} and \tcode{Destructible}. If +The mutex types shall be \oldconcept{DefaultConstructible} and \oldconcept{Destructible}. If initialization of an object of a mutex type fails, an exception of type \tcode{system_error} shall be thrown. The mutex types shall not be copyable or movable. @@ -1141,7 +1141,7 @@ instantiation of \tcode{time_point}\iref{time.point}. \pnum -The timed mutex types shall satisfy the \tcode{TimedLockable} +The timed mutex types shall satisfy the \oldconcept{TimedLockable} requirements\iref{thread.req.lockable.timed}. \pnum @@ -1681,7 +1681,7 @@ object throughout the \tcode{lock_guard} object's lifetime\iref{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 satisfy the \tcode{BasicLockable} +object. The supplied \tcode{Mutex} type shall satisfy the \oldconcept{BasicLockable} requirements\iref{thread.req.lockable.basic}. \indexlibrary{\idxcode{lock_guard}!constructor}% @@ -1760,9 +1760,9 @@ object. When \tcode{sizeof...(MutexTypes)} is \tcode{1}, the supplied \tcode{Mutex} type -shall satisfy the \tcode{BasicLockable} requirements\iref{thread.req.lockable.basic}. +shall satisfy the \oldconcept{BasicLockable} requirements\iref{thread.req.lockable.basic}. Otherwise, each of the mutex types -shall satisfy the \tcode{Lockable} requirements\iref{thread.req.lockable.req}. +shall satisfy the \oldconcept{Lockable} requirements\iref{thread.req.lockable.req}. \indexlibrary{\idxcode{scoped_lock}!constructor}% \begin{itemdecl} @@ -1875,16 +1875,16 @@ \tcode{pm} is not null and the lockable object pointed to by \tcode{pm} does not exist for the entire remaining lifetime\iref{basic.life} of the \tcode{unique_lock} object. The supplied -\tcode{Mutex} type shall satisfy the \tcode{BasicLockable} +\tcode{Mutex} type shall satisfy the \oldconcept{BasicLockable} requirements\iref{thread.req.lockable.basic}. \pnum -\begin{note} \tcode{unique_lock} meets the \tcode{BasicLockable} requirements. If \tcode{Mutex} -meets the \tcode{Lockable} requirements\iref{thread.req.lockable.req}, -\tcode{unique_lock} also meets the \tcode{Lockable} requirements; +\begin{note} \tcode{unique_lock} meets the \oldconcept{BasicLockable} requirements. If \tcode{Mutex} +meets the \oldconcept{Lockable} requirements\iref{thread.req.lockable.req}, +\tcode{unique_lock} also meets the \oldconcept{Lockable} requirements; if \tcode{Mutex} -meets the \tcode{TimedLockable} requirements\iref{thread.req.lockable.timed}, -\tcode{unique_lock} also meets the \tcode{TimedLockable} requirements. \end{note} +meets the \oldconcept{TimedLockable} requirements\iref{thread.req.lockable.timed}, +\tcode{unique_lock} also meets the \oldconcept{TimedLockable} requirements. \end{note} \rSec4[thread.lock.unique.cons]{\tcode{unique_lock} constructors, destructor, and assignment} @@ -1938,7 +1938,7 @@ \begin{itemdescr} \pnum \requires -The supplied \tcode{Mutex} type shall satisfy the \tcode{Lockable} +The supplied \tcode{Mutex} type shall satisfy the \oldconcept{Lockable} requirements\iref{thread.req.lockable.req}. If \tcode{mutex_type} is not a recursive mutex the calling thread does not own the mutex. @@ -1979,7 +1979,7 @@ \pnum \requires If \tcode{mutex_type} is not a recursive mutex the calling thread does not own the mutex. The supplied \tcode{Mutex} type shall satisfy the -\tcode{TimedLockable} requirements\iref{thread.req.lockable.timed}. +\oldconcept{TimedLockable} requirements\iref{thread.req.lockable.timed}. \pnum \effects Constructs an object of type \tcode{unique_lock} and calls \tcode{m.try_lock_until(abs_time)}. @@ -1999,7 +1999,7 @@ \begin{itemdescr} \pnum \requires If \tcode{mutex_type} is not a recursive mutex the calling thread does not own the mutex. -The supplied \tcode{Mutex} type shall satisfy the \tcode{TimedLockable} requirements\iref{thread.req.lockable.timed}. +The supplied \tcode{Mutex} type shall satisfy the \oldconcept{TimedLockable} requirements\iref{thread.req.lockable.timed}. \pnum \effects Constructs an object of type \tcode{unique_lock} and calls \tcode{m.try_lock_for(rel_time)}. @@ -2079,7 +2079,7 @@ \begin{itemdescr} \pnum -\requires The supplied \tcode{Mutex} shall satisfy the \tcode{Lockable} +\requires The supplied \tcode{Mutex} shall satisfy the \oldconcept{Lockable} requirements\iref{thread.req.lockable.req}. \pnum @@ -2113,7 +2113,7 @@ \begin{itemdescr} \pnum -\requires The supplied \tcode{Mutex} type shall satisfy the \tcode{TimedLockable} +\requires The supplied \tcode{Mutex} type shall satisfy the \oldconcept{TimedLockable} requirements\iref{thread.req.lockable.timed}. \pnum @@ -2147,7 +2147,7 @@ \begin{itemdescr} \pnum -\requires The supplied \tcode{Mutex} type shall satisfy the \tcode{TimedLockable} requirements\iref{thread.req.lockable.timed}. +\requires The supplied \tcode{Mutex} type shall satisfy the \oldconcept{TimedLockable} requirements\iref{thread.req.lockable.timed}. \pnum \effects As if by \tcode{pm->try_lock_for(rel_time)}. @@ -2320,7 +2320,7 @@ requirements\iref{thread.sharedtimedmutex.requirements}. \pnum -\begin{note} \tcode{shared_lock} meets the \tcode{TimedLockable} +\begin{note} \tcode{shared_lock} meets the \oldconcept{TimedLockable} requirements\iref{thread.req.lockable.timed}. \end{note} \rSec4[thread.lock.shared.cons]{\tcode{shared_lock} constructors, destructor, and assignment} @@ -2695,7 +2695,7 @@ \begin{itemdescr} \pnum -\requires Each template parameter type shall satisfy the \tcode{Lockable} requirements. \begin{note} The +\requires Each template parameter type shall satisfy the \oldconcept{Lockable} requirements. \begin{note} The \tcode{unique_lock} class template meets these requirements when suitably instantiated. \end{note} @@ -2719,7 +2719,7 @@ \begin{itemdescr} \pnum -\requires Each template parameter type shall satisfy the \tcode{Lockable} requirements, +\requires Each template parameter type shall satisfy the \oldconcept{Lockable} requirements, \begin{note} The \tcode{unique_lock} class template meets these requirements when suitably instantiated. \end{note} @@ -3325,7 +3325,7 @@ \rSec2[thread.condition.condvarany]{Class \tcode{condition_variable_any}} \pnum -A \tcode{Lock} type shall satisfy the \tcode{BasicLockable} +A \tcode{Lock} type shall satisfy the \oldconcept{BasicLockable} requirements\iref{thread.req.lockable.basic}. \begin{note} All of the standard mutex types meet this requirement. If a \tcode{Lock} type other than one of the standard mutex types or a \tcode{unique_lock} wrapper for a standard mutex type @@ -3934,7 +3934,7 @@ \begin{itemdescr} \pnum -\requires \tcode{Alloc} shall satisfy the \tcode{Allocator} +\requires \tcode{Alloc} shall satisfy the \oldconcept{Allocator} requirements (\tref{utilities.allocator.requirements}). \end{itemdescr} @@ -4787,7 +4787,7 @@ \pnum \requires \tcode{F} and each $\tcode{T}_i$ in \tcode{Args} shall satisfy the -\tcode{MoveConstructible} requirements, and +\oldconcept{MoveConstructible} requirements, and \begin{codeblock} @\placeholdernc{INVOKE}@(@\placeholdernc{DECAY_COPY}@(std::forward(f)), @\placeholdernc{DECAY_COPY}@(std::forward(args))...) // see \ref{func.require}, \ref{thread.thread.constr} diff --git a/source/time.tex b/source/time.tex new file mode 100644 index 0000000000..c2bc33d501 --- /dev/null +++ b/source/time.tex @@ -0,0 +1,11277 @@ +%!TEX root = std.tex +\rSec0[time]{Time library} + +\rSec1[time.general]{General} + +\pnum +\indexlibrary{\idxcode{chrono}}% +This Clause describes the chrono library\iref{time.syn} and various C +functions\iref{ctime.syn} that provide generally useful time +utilities, as summarized in \tref{time.lib.summary}. + +\begin{libsumtab}{Time library summary}{tab:time.lib.summary} +\ref{time.clock.req} & \oldconcept{Clock} requirements & \\ \rowsep +\ref{time.traits} & Time-related traits & \tcode{} \\ +\ref{time.duration} & Class template \tcode{duration} & \\ +\ref{time.point} & Class template \tcode{time_point} & \\ +\ref{time.clock} & Clocks & \\ +\ref{time.cal} & Civil calendar & \\ +\ref{time.tod} & Class template \tcode{time_of_day} & \\ +\ref{time.zone} & Time zones & \\ +\ref{time.format} & Formatting & \\ +\ref{time.parse} & Parsing & \\ \rowsep +\ref{ctime.syn} & C library time utilities & \tcode{} \\ \rowsep +\end{libsumtab} + +\rSec1[time.syn]{Header \tcode{} synopsis} + +\indexhdr{chrono}% +\indexlibrary{\idxcode{treat_as_floating_point_v}}% +\indexlibrary{\idxcode{is_clock_v}}% +\indexlibrary{\idxcode{nanoseconds}}% +\indexlibrary{\idxcode{microseconds}}% +\indexlibrary{\idxcode{milliseconds}}% +\indexlibrary{\idxcode{seconds}}% +\indexlibrary{\idxcode{minutes}}% +\indexlibrary{\idxcode{hours}}% +\indexlibrary{\idxcode{days}}% +\indexlibrary{\idxcode{weeks}}% +\indexlibrary{\idxcode{years}}% +\indexlibrary{\idxcode{months}}% +\indexlibrary{\idxcode{sys_time}}% +\indexlibrary{\idxcode{sys_seconds}}% +\indexlibrary{\idxcode{sys_days}}% +\indexlibrary{\idxcode{utc_time}}% +\indexlibrary{\idxcode{utc_seconds}}% +\indexlibrary{\idxcode{tai_time}}% +\indexlibrary{\idxcode{tai_seconds}}% +\indexlibrary{\idxcode{gps_time}}% +\indexlibrary{\idxcode{gps_seconds}}% +\indexlibrary{\idxcode{file_time}}% +\indexlibrary{\idxcode{local_time}}% +\indexlibrary{\idxcode{local_seconds}}% +\indexlibrary{\idxcode{local_days}}% +\indexlibrary{\idxcode{local_t}}% +\indexlibrary{\idxcode{choose}}% +\indexlibrarymember{earliest}{choose}% +\indexlibrarymember{latest}{choose}% +\begin{codeblock} +namespace std { + namespace chrono { + // \ref{time.duration}, class template \tcode{duration} + template> class duration; + + // \ref{time.point}, class template \tcode{time_point} + template class time_point; + } + + // \ref{time.traits.specializations}, \tcode{common_type} specializations + template + struct common_type, + chrono::duration>; + + template + struct common_type, + chrono::time_point>; + + namespace chrono { + // \ref{time.traits}, customization traits + template struct treat_as_floating_point; + template struct duration_values; + template + inline constexpr bool treat_as_floating_point_v = treat_as_floating_point::value; + + template struct is_clock; + template inline constexpr bool is_clock_v = is_clock::value; + + // \ref{time.duration.nonmember}, \tcode{duration} arithmetic + template + constexpr common_type_t, duration> + operator+(const duration& lhs, const duration& rhs); + template + constexpr common_type_t, duration> + operator-(const duration& lhs, const duration& rhs); + template + constexpr duration, Period> + operator*(const duration& d, const Rep2& s); + template + constexpr duration, Period> + operator*(const Rep1& s, const duration& d); + template + constexpr duration, Period> + operator/(const duration& d, const Rep2& s); + template + constexpr common_type_t + operator/(const duration& lhs, const duration& rhs); + template + constexpr duration, Period> + operator%(const duration& d, const Rep2& s); + template + constexpr common_type_t, duration> + operator%(const duration& lhs, const duration& rhs); + + // \ref{time.duration.comparisons}, \tcode{duration} comparisons + template + constexpr bool operator==(const duration& lhs, + const duration& rhs); + template + constexpr bool operator!=(const duration& lhs, + const duration& rhs); + template + constexpr bool operator< (const duration& lhs, + const duration& rhs); + template + constexpr bool operator> (const duration& lhs, + const duration& rhs); + template + constexpr bool operator<=(const duration& lhs, + const duration& rhs); + template + constexpr bool operator>=(const duration& lhs, + const duration& rhs); + + // \ref{time.duration.cast}, \tcode{duration_cast} + template + constexpr ToDuration duration_cast(const duration& d); + template + constexpr ToDuration floor(const duration& d); + template + constexpr ToDuration ceil(const duration& d); + template + constexpr ToDuration round(const duration& d); + + // \ref{time.duration.io}, \tcode{duration} I/O + template + basic_ostream& + operator<<(basic_ostream& os, + const duration& d); + template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, + const duration& d); + template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + duration& d, + basic_string* abbrev = nullptr, + minutes* offset = nullptr); + + // convenience typedefs + using nanoseconds = duration<@\term{signed integer type of at least 64 bits}@, nano>; + using microseconds = duration<@\term{signed integer type of at least 55 bits}@, micro>; + using milliseconds = duration<@\term{signed integer type of at least 45 bits}@, milli>; + using seconds = duration<@\term{signed integer type of at least 35 bits}@>; + 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>>; + using days = duration<@\term{signed integer type of at least 25 bits}@, + ratio_multiply, hours::period>>; + using weeks = duration<@\term{signed integer type of at least 22 bits}@, + ratio_multiply, days::period>>; + using years = duration<@\term{signed integer type of at least 17 bits}@, + ratio_multiply, days::period>>; + using months = duration<@\term{signed integer type of at least 20 bits}@, + ratio_divide>>; + + // \ref{time.point.nonmember}, \tcode{time_point} arithmetic + template + constexpr time_point>> + operator+(const time_point& lhs, const duration& rhs); + template + constexpr time_point, Duration2>> + operator+(const duration& lhs, const time_point& rhs); + template + constexpr time_point>> + operator-(const time_point& lhs, const duration& rhs); + template + constexpr common_type_t + operator-(const time_point& lhs, + const time_point& rhs); + + // \ref{time.point.comparisons}, \tcode{time_point} comparisons + template + constexpr bool operator==(const time_point& lhs, + const time_point& rhs); + template + constexpr bool operator!=(const time_point& lhs, + const time_point& rhs); + template + constexpr bool operator< (const time_point& lhs, + const time_point& rhs); + template + constexpr bool operator> (const time_point& lhs, + const time_point& rhs); + template + constexpr bool operator<=(const time_point& lhs, + const time_point& rhs); + template + constexpr bool operator>=(const time_point& lhs, + const time_point& rhs); + + // \ref{time.point.cast}, \tcode{time_point_cast} + template + constexpr time_point + time_point_cast(const time_point& t); + template + constexpr time_point floor(const time_point& tp); + template + constexpr time_point ceil(const time_point& tp); + template + constexpr time_point round(const time_point& tp); + + // \ref{time.duration.alg}, specialized algorithms + template + constexpr duration abs(duration d); + + // \ref{time.clock.system}, class \tcode{system_clock} + class system_clock; + + template + using sys_time = time_point; + using sys_seconds = sys_time; + using sys_days = sys_time; + + template + basic_ostream& + operator<<(basic_ostream& os, const sys_time& tp); + + template + basic_ostream& + operator<<(basic_ostream& os, const sys_days& dp); + + template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, + const sys_time& tp); + + template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + sys_time& tp, + basic_string* abbrev = nullptr, + minutes* offset = nullptr); + + // \ref{time.clock.utc}, class \tcode{utc_clock} + class utc_clock; + + template + using utc_time = time_point; + using utc_seconds = utc_time; + + template + basic_ostream& + operator<<(basic_ostream& os, const utc_time& t); + template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, + const utc_time& tp); + template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + utc_time& tp, + basic_string* abbrev = nullptr, + minutes* offset = nullptr); + + // \ref{time.clock.tai}, class \tcode{tai_clock} + class tai_clock; + + template + using tai_time = time_point; + using tai_seconds = tai_time; + + template + basic_ostream& + operator<<(basic_ostream& os, const tai_time& t); + template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, + const tai_time& tp); + template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + tai_time& tp, + basic_string* abbrev = nullptr, + minutes* offset = nullptr); + + // \ref{time.clock.gps}, class \tcode{gps_clock} + class gps_clock; + + template + using gps_time = time_point; + using gps_seconds = gps_time; + + template + basic_ostream& + operator<<(basic_ostream& os, const gps_time& t); + template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, + const gps_time& tp); + template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + gps_time& tp, + basic_string* abbrev = nullptr, + minutes* offset = nullptr); + + // \ref{time.clock.file}, class \tcode{file_clock} + class file_clock; + + template + using file_time = time_point; + + template + basic_ostream& + operator<<(basic_ostream& os, const file_time& tp); + template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, + const file_time& tp); + template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + file_time& tp, + basic_string* abbrev = nullptr, + minutes* offset = nullptr); + + // \ref{time.clock.steady}, class \tcode{steady_clock} + class steady_clock; + + // \ref{time.clock.hires}, class \tcode{high_resolution_clock} + class high_resolution_clock; + + // \ref{time.clock.local}, local time + struct local_t {}; + template + using local_time = time_point; + using local_seconds = local_time; + using local_days = local_time; + + template + basic_ostream& + operator<<(basic_ostream& os, const local_time& tp); + template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, + const local_time& tp, + const string* abbrev = nullptr, const seconds* offset_sec = nullptr); + template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + local_time& tp, + basic_string* abbrev = nullptr, + minutes* offset = nullptr); + + // \ref{time.clock.cast}, \tcode{time_point} conversions + template + struct clock_time_conversion; + + template + auto clock_cast(const time_point& t); + + // \ref{time.cal.last}, class \tcode{last_spec} + struct last_spec; + + // \ref{time.cal.day}, class \tcode{day} + class day; + + constexpr bool operator==(const day& x, const day& y) noexcept; + constexpr bool operator!=(const day& x, const day& y) noexcept; + constexpr bool operator< (const day& x, const day& y) noexcept; + constexpr bool operator> (const day& x, const day& y) noexcept; + constexpr bool operator<=(const day& x, const day& y) noexcept; + constexpr bool operator>=(const day& x, const day& y) noexcept; + + constexpr day operator+(const day& x, const days& y) noexcept; + constexpr day operator+(const days& x, const day& y) noexcept; + constexpr day operator-(const day& x, const days& y) noexcept; + constexpr days operator-(const day& x, const day& y) noexcept; + + template + basic_ostream& + operator<<(basic_ostream& os, const day& d); + template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, const day& d); + template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + day& d, basic_string* abbrev = nullptr, + minutes* offset = nullptr); + + // \ref{time.cal.month}, class \tcode{month} + class month; + + constexpr bool operator==(const month& x, const month& y) noexcept; + constexpr bool operator!=(const month& x, const month& y) noexcept; + constexpr bool operator< (const month& x, const month& y) noexcept; + constexpr bool operator> (const month& x, const month& y) noexcept; + constexpr bool operator<=(const month& x, const month& y) noexcept; + constexpr bool operator>=(const month& x, const month& y) noexcept; + + constexpr month operator+(const month& x, const months& y) noexcept; + constexpr month operator+(const months& x, const month& y) noexcept; + constexpr month operator-(const month& x, const months& y) noexcept; + constexpr months operator-(const month& x, const month& y) noexcept; + + template + basic_ostream& + operator<<(basic_ostream& os, const month& m); + template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, const month& m); + template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + month& m, basic_string* abbrev = nullptr, + minutes* offset = nullptr); + + // \ref{time.cal.year}, class \tcode{year} + class year; + + constexpr bool operator==(const year& x, const year& y) noexcept; + constexpr bool operator!=(const year& x, const year& y) noexcept; + constexpr bool operator< (const year& x, const year& y) noexcept; + constexpr bool operator> (const year& x, const year& y) noexcept; + constexpr bool operator<=(const year& x, const year& y) noexcept; + constexpr bool operator>=(const year& x, const year& y) noexcept; + + constexpr year operator+(const year& x, const years& y) noexcept; + constexpr year operator+(const years& x, const year& y) noexcept; + constexpr year operator-(const year& x, const years& y) noexcept; + constexpr years operator-(const year& x, const year& y) noexcept; + + template + basic_ostream& + operator<<(basic_ostream& os, const year& y); + + template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, const year& y); + + template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + year& y, basic_string* abbrev = nullptr, + minutes* offset = nullptr); + + // \ref{time.cal.wd}, class \tcode{weekday} + class weekday; + + constexpr bool operator==(const weekday& x, const weekday& y) noexcept; + constexpr bool operator!=(const weekday& x, const weekday& y) noexcept; + + constexpr weekday operator+(const weekday& x, const days& y) noexcept; + constexpr weekday operator+(const days& x, const weekday& y) noexcept; + constexpr weekday operator-(const weekday& x, const days& y) noexcept; + constexpr days operator-(const weekday& x, const weekday& y) noexcept; + + template + basic_ostream& + operator<<(basic_ostream& os, const weekday& wd); + + template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, const weekday& wd); + + template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + weekday& wd, basic_string* abbrev = nullptr, + minutes* offset = nullptr); + + // \ref{time.cal.wdidx}, class \tcode{weekday_indexed} + class weekday_indexed; + + constexpr bool operator==(const weekday_indexed& x, const weekday_indexed& y) noexcept; + constexpr bool operator!=(const weekday_indexed& x, const weekday_indexed& y) noexcept; + + template + basic_ostream& + operator<<(basic_ostream& os, const weekday_indexed& wdi); + + // \ref{time.cal.wdlast}, class \tcode{weekday_last} + class weekday_last; + + constexpr bool operator==(const weekday_last& x, const weekday_last& y) noexcept; + constexpr bool operator!=(const weekday_last& x, const weekday_last& y) noexcept; + + template + basic_ostream& + operator<<(basic_ostream& os, const weekday_last& wdl); + + // \ref{time.cal.md}, class \tcode{month_day} + class month_day; + + constexpr bool operator==(const month_day& x, const month_day& y) noexcept; + constexpr bool operator!=(const month_day& x, const month_day& y) noexcept; + constexpr bool operator< (const month_day& x, const month_day& y) noexcept; + constexpr bool operator> (const month_day& x, const month_day& y) noexcept; + constexpr bool operator<=(const month_day& x, const month_day& y) noexcept; + constexpr bool operator>=(const month_day& x, const month_day& y) noexcept; + + template + basic_ostream& + operator<<(basic_ostream& os, const month_day& md); + + template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, const month_day& md); + + template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + month_day& md, basic_string* abbrev = nullptr, + minutes* offset = nullptr); + + // \ref{time.cal.mdlast}, class \tcode{month_day_last} + class month_day_last; + + constexpr bool operator==(const month_day_last& x, const month_day_last& y) noexcept; + constexpr bool operator!=(const month_day_last& x, const month_day_last& y) noexcept; + constexpr bool operator< (const month_day_last& x, const month_day_last& y) noexcept; + constexpr bool operator> (const month_day_last& x, const month_day_last& y) noexcept; + constexpr bool operator<=(const month_day_last& x, const month_day_last& y) noexcept; + constexpr bool operator>=(const month_day_last& x, const month_day_last& y) noexcept; + + template + basic_ostream& + operator<<(basic_ostream& os, const month_day_last& mdl); + + // \ref{time.cal.mwd}, class \tcode{month_weekday} + class month_weekday; + + constexpr bool operator==(const month_weekday& x, const month_weekday& y) noexcept; + constexpr bool operator!=(const month_weekday& x, const month_weekday& y) noexcept; + + template + basic_ostream& + operator<<(basic_ostream& os, const month_weekday& mwd); + + // \ref{time.cal.mwdlast}, class \tcode{month_weekday_last} + class month_weekday_last; + + constexpr bool operator==(const month_weekday_last& x, const month_weekday_last& y) noexcept; + constexpr bool operator!=(const month_weekday_last& x, const month_weekday_last& y) noexcept; + + template + basic_ostream& + operator<<(basic_ostream& os, const month_weekday_last& mwdl); + + // \ref{time.cal.ym}, class \tcode{year_month} + class year_month; + + constexpr bool operator==(const year_month& x, const year_month& y) noexcept; + constexpr bool operator!=(const year_month& x, const year_month& y) noexcept; + constexpr bool operator< (const year_month& x, const year_month& y) noexcept; + constexpr bool operator> (const year_month& x, const year_month& y) noexcept; + constexpr bool operator<=(const year_month& x, const year_month& y) noexcept; + constexpr bool operator>=(const year_month& x, const year_month& y) noexcept; + + constexpr year_month operator+(const year_month& ym, const months& dm) noexcept; + constexpr year_month operator+(const months& dm, const year_month& ym) noexcept; + constexpr year_month operator-(const year_month& ym, const months& dm) noexcept; + constexpr months operator-(const year_month& x, const year_month& y) noexcept; + constexpr year_month operator+(const year_month& ym, const years& dy) noexcept; + constexpr year_month operator+(const years& dy, const year_month& ym) noexcept; + constexpr year_month operator-(const year_month& ym, const years& dy) noexcept; + + template + basic_ostream& + operator<<(basic_ostream& os, const year_month& ym); + + template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, const year_month& ym); + + template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + year_month& ym, basic_string* abbrev = nullptr, + minutes* offset = nullptr); + + // \ref{time.cal.ymd}, class \tcode{year_month_day} + class year_month_day; + + constexpr bool operator==(const year_month_day& x, const year_month_day& y) noexcept; + constexpr bool operator!=(const year_month_day& x, const year_month_day& y) noexcept; + constexpr bool operator< (const year_month_day& x, const year_month_day& y) noexcept; + constexpr bool operator> (const year_month_day& x, const year_month_day& y) noexcept; + constexpr bool operator<=(const year_month_day& x, const year_month_day& y) noexcept; + constexpr bool operator>=(const year_month_day& x, const year_month_day& y) noexcept; + + constexpr year_month_day operator+(const year_month_day& ymd, const months& dm) noexcept; + constexpr year_month_day operator+(const months& dm, const year_month_day& ymd) noexcept; + constexpr year_month_day operator+(const year_month_day& ymd, const years& dy) noexcept; + constexpr year_month_day operator+(const years& dy, const year_month_day& ymd) noexcept; + constexpr year_month_day operator-(const year_month_day& ymd, const months& dm) noexcept; + constexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept; + + template + basic_ostream& + operator<<(basic_ostream& os, const year_month_day& ymd); + + template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, + const year_month_day& ymd); + + template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + year_month_day& ymd, + basic_string* abbrev = nullptr, + minutes* offset = nullptr); + + // \ref{time.cal.ymdlast}, class \tcode{year_month_day_last} + class year_month_day_last; + + constexpr bool operator==(const year_month_day_last& x, + const year_month_day_last& y) noexcept; + constexpr bool operator!=(const year_month_day_last& x, + const year_month_day_last& y) noexcept; + constexpr bool operator< (const year_month_day_last& x, + const year_month_day_last& y) noexcept; + constexpr bool operator> (const year_month_day_last& x, + const year_month_day_last& y) noexcept; + constexpr bool operator<=(const year_month_day_last& x, + const year_month_day_last& y) noexcept; + constexpr bool operator>=(const year_month_day_last& x, + const year_month_day_last& y) noexcept; + + constexpr year_month_day_last + operator+(const year_month_day_last& ymdl, const months& dm) noexcept; + constexpr year_month_day_last + operator+(const months& dm, const year_month_day_last& ymdl) noexcept; + constexpr year_month_day_last + operator+(const year_month_day_last& ymdl, const years& dy) noexcept; + constexpr year_month_day_last + operator+(const years& dy, const year_month_day_last& ymdl) noexcept; + constexpr year_month_day_last + operator-(const year_month_day_last& ymdl, const months& dm) noexcept; + constexpr year_month_day_last + operator-(const year_month_day_last& ymdl, const years& dy) noexcept; + + template + basic_ostream& + operator<<(basic_ostream& os, const year_month_day_last& ymdl); + + // \ref{time.cal.ymwd}, class \tcode{year_month_weekday} + class year_month_weekday; + + constexpr bool operator==(const year_month_weekday& x, + const year_month_weekday& y) noexcept; + constexpr bool operator!=(const year_month_weekday& x, + const year_month_weekday& y) noexcept; + + constexpr year_month_weekday + operator+(const year_month_weekday& ymwd, const months& dm) noexcept; + constexpr year_month_weekday + operator+(const months& dm, const year_month_weekday& ymwd) noexcept; + constexpr year_month_weekday + operator+(const year_month_weekday& ymwd, const years& dy) noexcept; + constexpr year_month_weekday + operator+(const years& dy, const year_month_weekday& ymwd) noexcept; + constexpr year_month_weekday + operator-(const year_month_weekday& ymwd, const months& dm) noexcept; + constexpr year_month_weekday + operator-(const year_month_weekday& ymwd, const years& dy) noexcept; + + template + basic_ostream& + operator<<(basic_ostream& os, const year_month_weekday& ymwdi); + + // \ref{time.cal.ymwdlast}, class \tcode{year_month_weekday_last} + class year_month_weekday_last; + + constexpr bool operator==(const year_month_weekday_last& x, + const year_month_weekday_last& y) noexcept; + constexpr bool operator!=(const year_month_weekday_last& x, + const year_month_weekday_last& y) noexcept; + + constexpr year_month_weekday_last + operator+(const year_month_weekday_last& ymwdl, const months& dm) noexcept; + constexpr year_month_weekday_last + operator+(const months& dm, const year_month_weekday_last& ymwdl) noexcept; + constexpr year_month_weekday_last + operator+(const year_month_weekday_last& ymwdl, const years& dy) noexcept; + constexpr year_month_weekday_last + operator+(const years& dy, const year_month_weekday_last& ymwdl) noexcept; + constexpr year_month_weekday_last + operator-(const year_month_weekday_last& ymwdl, const months& dm) noexcept; + constexpr year_month_weekday_last + operator-(const year_month_weekday_last& ymwdl, const years& dy) noexcept; + + template + basic_ostream& + operator<<(basic_ostream& os, const year_month_weekday_last& ymwdl); + + // \ref{time.cal.operators}, civil calendar conventional syntax operators + constexpr year_month + operator/(const year& y, const month& m) noexcept; + constexpr year_month + operator/(const year& y, int m) noexcept; + constexpr month_day + operator/(const month& m, const day& d) noexcept; + constexpr month_day + operator/(const month& m, int d) noexcept; + constexpr month_day + operator/(int m, const day& d) noexcept; + constexpr month_day + operator/(const day& d, const month& m) noexcept; + constexpr month_day + operator/(const day& d, int m) noexcept; + constexpr month_day_last + operator/(const month& m, last_spec) noexcept; + constexpr month_day_last + operator/(int m, last_spec) noexcept; + constexpr month_day_last + operator/(last_spec, const month& m) noexcept; + constexpr month_day_last + operator/(last_spec, int m) noexcept; + constexpr month_weekday + operator/(const month& m, const weekday_indexed& wdi) noexcept; + constexpr month_weekday + operator/(int m, const weekday_indexed& wdi) noexcept; + constexpr month_weekday + operator/(const weekday_indexed& wdi, const month& m) noexcept; + constexpr month_weekday + operator/(const weekday_indexed& wdi, int m) noexcept; + constexpr month_weekday_last + operator/(const month& m, const weekday_last& wdl) noexcept; + constexpr month_weekday_last + operator/(int m, const weekday_last& wdl) noexcept; + constexpr month_weekday_last + operator/(const weekday_last& wdl, const month& m) noexcept; + constexpr month_weekday_last + operator/(const weekday_last& wdl, int m) noexcept; + constexpr year_month_day + operator/(const year_month& ym, const day& d) noexcept; + constexpr year_month_day + operator/(const year_month& ym, int d) noexcept; + constexpr year_month_day + operator/(const year& y, const month_day& md) noexcept; + constexpr year_month_day + operator/(int y, const month_day& md) noexcept; + constexpr year_month_day + operator/(const month_day& md, const year& y) noexcept; + constexpr year_month_day + operator/(const month_day& md, int y) noexcept; + constexpr year_month_day_last + operator/(const year_month& ym, last_spec) noexcept; + constexpr year_month_day_last + operator/(const year& y, const month_day_last& mdl) noexcept; + constexpr year_month_day_last + operator/(int y, const month_day_last& mdl) noexcept; + constexpr year_month_day_last + operator/(const month_day_last& mdl, const year& y) noexcept; + constexpr year_month_day_last + operator/(const month_day_last& mdl, int y) noexcept; + constexpr year_month_weekday + operator/(const year_month& ym, const weekday_indexed& wdi) noexcept; + constexpr year_month_weekday + operator/(const year& y, const month_weekday& mwd) noexcept; + constexpr year_month_weekday + operator/(int y, const month_weekday& mwd) noexcept; + constexpr year_month_weekday + operator/(const month_weekday& mwd, const year& y) noexcept; + constexpr year_month_weekday + operator/(const month_weekday& mwd, int y) noexcept; + constexpr year_month_weekday_last + operator/(const year_month& ym, const weekday_last& wdl) noexcept; + constexpr year_month_weekday_last + operator/(const year& y, const month_weekday_last& mwdl) noexcept; + constexpr year_month_weekday_last + operator/(int y, const month_weekday_last& mwdl) noexcept; + constexpr year_month_weekday_last + operator/(const month_weekday_last& mwdl, const year& y) noexcept; + constexpr year_month_weekday_last + operator/(const month_weekday_last& mwdl, int y) noexcept; + + // \ref{time.tod}, class template \tcode{time_of_day} + template class time_of_day; + template<> class time_of_day; + template<> class time_of_day; + template<> class time_of_day; + template class time_of_day>; + + template + basic_ostream& + operator<<(basic_ostream& os, const time_of_day& t); + + template + basic_ostream& + operator<<(basic_ostream& os, const time_of_day& t); + + template + basic_ostream& + operator<<(basic_ostream& os, const time_of_day& t); + + template + basic_ostream& + operator<<(basic_ostream& os, + const time_of_day>& t); + + // \ref{time.zone.db}, time zone database + struct tzdb; + class tzdb_list; + + // \ref{time.zone.db.access}, time zone database access + const tzdb& get_tzdb(); + tzdb_list& get_tzdb_list(); + const time_zone* locate_zone(string_view tz_name); + const time_zone* current_zone(); + + // \ref{time.zone.db.remote}, remote time zone database support + const tzdb& reload_tzdb(); + string remote_version(); + + // \ref{time.zone.exception}, exception classes + class nonexistent_local_time; + class ambiguous_local_time; + + // \ref{time.zone.info}, information classes + struct sys_info; + template + basic_ostream& + operator<<(basic_ostream& os, const sys_info& si); + + struct local_info; + template + basic_ostream& + operator<<(basic_ostream& os, const local_info& li); + + // \ref{time.zone.timezone}, class \tcode{time_zone} + enum class choose {earliest, latest}; + class time_zone; + + bool operator==(const time_zone& x, const time_zone& y) noexcept; + bool operator!=(const time_zone& x, const time_zone& y) noexcept; + + bool operator<(const time_zone& x, const time_zone& y) noexcept; + bool operator>(const time_zone& x, const time_zone& y) noexcept; + bool operator<=(const time_zone& x, const time_zone& y) noexcept; + bool operator>=(const time_zone& x, const time_zone& y) noexcept; + + // \ref{time.zone.zonedtraits}, class template \tcode{zoned_traits} + template struct zoned_traits; + + // \ref{time.zone.zonedtime}, class template \tcode{zoned_time} + template class zoned_time; + + using zoned_seconds = zoned_time; + + template + bool operator==(const zoned_time& x, + const zoned_time& y); + + template + bool operator!=(const zoned_time& x, + const zoned_time& y); + + template + basic_ostream& + operator<<(basic_ostream& os, + const zoned_time& t); + + template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, + const zoned_time& tp); + + // \ref{time.zone.leap}, leap second support + class leap; + + bool operator==(const leap& x, const leap& y); + bool operator!=(const leap& x, const leap& y); + bool operator< (const leap& x, const leap& y); + bool operator> (const leap& x, const leap& y); + bool operator<=(const leap& x, const leap& y); + bool operator>=(const leap& x, const leap& y); + + template + bool operator==(const leap& x, const sys_time& y); + template + bool operator==(const sys_time& x, const leap& y); + template + bool operator!=(const leap& x, const sys_time& y); + template + bool operator!=(const sys_time& x, const leap& y); + template + bool operator< (const leap& x, const sys_time& y); + template + bool operator< (const sys_time& x, const leap& y); + template + bool operator> (const leap& x, const sys_time& y); + template + bool operator> (const sys_time& x, const leap& y); + template + bool operator<=(const leap& x, const sys_time& y); + template + bool operator<=(const sys_time& x, const leap& y); + template + bool operator>=(const leap& x, const sys_time& y); + template + bool operator>=(const sys_time& x, const leap& y); + + // \ref{time.zone.link}, class \tcode{link} + class link; + + bool operator==(const link& x, const link& y); + bool operator!=(const link& x, const link& y); + bool operator< (const link& x, const link& y); + bool operator> (const link& x, const link& y); + bool operator<=(const link& x, const link& y); + bool operator>=(const link& x, const link& y); + + // \ref{time.format}, formatting + template + basic_string + format(const charT* fmt, const Streamable& s); + template + basic_string + format(const locale& loc, const charT* fmt, const Streamable& s); + template + basic_string + format(const basic_string& fmt, const Streamable& s); + template + basic_string + format(const locale& loc, const basic_string& fmt, + const Streamable& s); + + // \ref{time.parse}, parsing + template + @\unspec@ + parse(const basic_string& format, Parsable& tp); + + template + @\unspec@ + parse(const basic_string& format, Parsable& tp, + basic_string& abbrev); + + template + @\unspec@ + parse(const basic_string& format, Parsable& tp, + minutes& offset); + + template + @\unspec@ + parse(const basic_string& format, Parsable& tp, + basic_string& abbrev, minutes& offset); + + // calendrical constants + inline constexpr last_spec last{}; + + inline constexpr weekday Sunday{0}; + inline constexpr weekday Monday{1}; + inline constexpr weekday Tuesday{2}; + inline constexpr weekday Wednesday{3}; + inline constexpr weekday Thursday{4}; + inline constexpr weekday Friday{5}; + inline constexpr weekday Saturday{6}; + + inline constexpr month January{1}; + inline constexpr month February{2}; + inline constexpr month March{3}; + inline constexpr month April{4}; + inline constexpr month May{5}; + inline constexpr month June{6}; + inline constexpr month July{7}; + inline constexpr month August{8}; + inline constexpr month September{9}; + inline constexpr month October{10}; + inline constexpr month November{11}; + inline constexpr month December{12}; + } + + 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); + + // \ref{time.cal.day.nonmembers}, non-member functions + constexpr chrono::day operator""d(unsigned long long d) noexcept; + + // \ref{time.cal.year.nonmembers}, non-member functions + constexpr chrono::year operator""y(unsigned long long y) noexcept; + } + } + + namespace chrono { + using namespace literals::chrono_literals; + } +} +\end{codeblock} + +\rSec1[time.clock.req]{\oldconcept{Clock} requirements} + +\pnum +A clock is a bundle consisting of a \tcode{duration}, a +\tcode{time_point}, and a function \tcode{now()} to get the current \tcode{time_point}. +The origin of the clock's \tcode{time_point} is referred to as the clock's \defn{epoch}. + A clock shall satisfy the requirements in \tref{time.clock}. + +\pnum +In \tref{time.clock} \tcode{C1} and \tcode{C2} denote clock types. \tcode{t1} and +\tcode{t2} are values returned by \tcode{C1::now()} where the call returning \tcode{t1} happens +before\iref{intro.multithread} the call returning \tcode{t2} and both of these calls +occur +before \tcode{C1::time_point::max()}. +\begin{note} This means \tcode{C1} did not wrap around between \tcode{t1} and +\tcode{t2}. \end{note} + +\begin{libreqtab3a} +{\oldconcept{Clock} requirements} +{tab:time.clock} +\\ \topline +\lhdr{Expression} & \chdr{Return type} & \rhdr{Operational semantics} \\ \capsep +\endfirsthead +\continuedcaption\\ +\hline +\lhdr{Expression} & \chdr{Return type} & \rhdr{Operational semantics} \\ \capsep +\endhead + +\tcode{C1::rep} & + An arithmetic type or a class emulating an arithmetic type & + The representation type of \tcode{C1::duration}. \\ \rowsep + +\tcode{C1::period} & + a specialization of \tcode{ratio} & + The tick period of the clock in seconds. \\ \rowsep + +\tcode{C1::duration} & + \tcode{chrono::duration} & + The \tcode{duration} type of the clock. \\ \rowsep + +\tcode{C1::time_point} & + \tcode{chrono::time_point} or \tcode{chrono::time_point} & + The \tcode{time_point} type of the clock. \tcode{C1} and \tcode{C2} shall + refer to the same epoch. \\ \rowsep + +\tcode{C1::is_steady} & + \tcode{const bool} & + \tcode{true} if \tcode{t1 <= t2} is always \tcode{true} and the time between clock + ticks is constant, otherwise \tcode{false}. \\ \rowsep + +\tcode{C1::now()} & + \tcode{C1::time_point} & + Returns a \tcode{time_point} object representing the current point in time. \\ + +\end{libreqtab3a} + +\pnum +\begin{note} The relative difference in durations between those reported by a given clock and the +SI definition is a measure of the quality of implementation. \end{note} + +\pnum +A type \tcode{TC} meets the \oldconcept{TrivialClock} requirements if: + +\begin{itemize} +\item \tcode{TC} satisfies the \oldconcept{Clock} requirements\iref{time.clock.req}, + +\item the types \tcode{TC::rep}, \tcode{TC::duration}, and \tcode{TC::time_point} +satisfy the \oldconcept{EqualityComparable} (\tref{equalitycomparable}), +\oldconcept{LessThanComparable} (\tref{lessthancomparable}), +\oldconcept{DefaultConstructible} (\tref{defaultconstructible}), +\oldconcept{\-Copy\-Con\-structible} (\tref{copyconstructible}), +\oldconcept{CopyAssignable} (\tref{copyassignable}), and +\oldconcept{Destructible} (\tref{destructible}) requirements and the requirements of +numeric types\iref{numeric.requirements}. \begin{note} This means, in particular, +that operations on these types will not throw exceptions. \end{note} + +\item lvalues of the types \tcode{TC::rep}, \tcode{TC::duration}, and +\tcode{TC::time_point} are swappable\iref{swappable.requirements}, + +\item the function \tcode{TC::now()} does not throw exceptions, and + +\item the type \tcode{TC::time_point::clock} meets the \oldconcept{TrivialClock} +requirements, recursively. +\end{itemize} + +\rSec1[time.traits]{Time-related traits} + +\rSec2[time.traits.is_fp]{\tcode{treat_as_floating_point}} + +\indexlibrary{\idxcode{treat_as_floating_point}}% +\begin{itemdecl} +template struct treat_as_floating_point : is_floating_point { }; +\end{itemdecl} + +\pnum +The \tcode{duration} template uses the \tcode{treat_as_floating_point} trait to +help determine if a \tcode{duration} object can be converted to another +\tcode{duration} with a different tick \tcode{period}. If +\tcode{treat_as_floating_point_v} is \tcode{true}, then implicit conversions +are allowed among \tcode{duration}s. Otherwise, the implicit convertibility +depends on the tick \tcode{period}s of the \tcode{duration}s. +\begin{note} +The intention of this trait is to indicate whether a given class behaves like a floating-point +type, and thus allows division of one value by another with acceptable loss of precision. If +\tcode{treat_as_floating_point_v} is \tcode{false}, \tcode{Rep} will be treated as +if it behaved like an integral type for the purpose of these conversions. +\end{note} + +\rSec2[time.traits.duration_values]{\tcode{duration_values}} + +\indexlibrary{\idxcode{duration_values}}% +\begin{itemdecl} +template + struct duration_values { + public: + static constexpr Rep zero(); + static constexpr Rep min(); + static constexpr Rep max(); +}; +\end{itemdecl} + +\pnum +The \tcode{duration} template uses the \tcode{duration_values} trait to +construct special values of the duration's representation (\tcode{Rep}). This is +done because the representation might be a class type with behavior which +requires some other implementation to return these special values. In that case, +the author of that class type should specialize \tcode{duration_values} to +return the indicated values. + +\indexlibrarymember{zero}{duration_values}% +\begin{itemdecl} +static constexpr Rep zero(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{Rep(0)}. \begin{note} \tcode{Rep(0)} is specified instead of +\tcode{Rep()} because \tcode{Rep()} may have some other meaning, such as an +uninitialized value. \end{note} + +\pnum +\remarks The value returned shall be the additive identity. +\end{itemdescr} + +\indexlibrarymember{min}{duration_values}% +\begin{itemdecl} +static constexpr Rep min(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{numeric_limits::lowest()}. + +\pnum +\remarks The value returned shall compare less than or equal to \tcode{zero()}. +\end{itemdescr} + +\indexlibrarymember{max}{duration_values}% +\begin{itemdecl} +static constexpr Rep max(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{numeric_limits::max()}. + +\pnum +\remarks The value returned shall compare greater than \tcode{zero()}. +\end{itemdescr} + +\rSec2[time.traits.specializations]{Specializations of \tcode{common_type}} + +\indexlibrary{\idxcode{common_type}}% +\begin{itemdecl} +template +struct common_type, chrono::duration> { + using type = chrono::duration, @\seebelow@>; +}; +\end{itemdecl} + +\pnum +The \tcode{period} of the \tcode{duration} indicated by this specialization of +\tcode{common_type} shall be the greatest common divisor of \tcode{Period1} and +\tcode{Period2}. \begin{note} This can be computed by forming a ratio of the +greatest common divisor of \tcode{Period1::num} and \tcode{Period2::num} and the +least common multiple of \tcode{Period1::den} and \tcode{Period2::den}. +\end{note} + +\pnum +\begin{note} The \tcode{typedef} name \tcode{type} is a synonym for the +\tcode{duration} with the largest tick \tcode{period} possible where both +\tcode{duration} arguments will convert to it without requiring a division +operation. The representation of this type is intended to be able to hold any +value resulting from this conversion with no truncation error, although +floating-point durations may have round-off errors. \end{note} + +\indexlibrary{\idxcode{common_type}}% +\begin{itemdecl} +template + struct common_type, chrono::time_point> { + using type = chrono::time_point>; +}; +\end{itemdecl} + +\pnum +The common type of two \tcode{time_point} types is a \tcode{time_point} with the same +clock as the two types and the common type of their two \tcode{duration}s. + +\rSec2[time.traits.is_clock]{Class template \tcode{is_clock}} + +\indexlibrary{\idxcode{is_clock}}% +\begin{itemdecl} +template struct is_clock; +\end{itemdecl} + +\pnum +\tcode{is_clock} is a \oldconcept{UnaryTypeTrait}\iref{meta.rqmts} +with a base characteristic of \tcode{true_type} +if \tcode{T} meets the \oldconcept{Clock} requirements\iref{time.clock.req}, +otherwise \tcode{false_type}. +For the purposes of the specification of this trait, +the extent to which an implementation determines +that a type cannot meet the \oldconcept{Clock} requirements is unspecified, +except that as a minimum +a type \tcode{T} shall not qualify as a \oldconcept{Clock} +unless it satisfies all of the following conditions: + +\begin{itemize} +\item the \grammarterm{qualified-id}s +\tcode{T::rep}, +\tcode{T::period}, +\tcode{T::duration}, and +\tcode{T::time_point} +are valid and each denotes a type\iref{temp.deduct}, +\item the expression +\tcode{T::is_steady} +is well-formed when treated as an unevaluated operand, +\item the expression +\tcode{T::now()} +is well-formed when treated as an unevaluated operand. +\end{itemize} + +\pnum +The behavior of a program that adds specializations for \tcode{is_clock} is undefined. + +\rSec1[time.duration]{Class template \tcode{duration}} + +\pnum +A \tcode{duration} type measures time between two points in time (\tcode{time_point}s). +A \tcode{duration} has a representation which holds a count of ticks and a tick period. +The tick period is the amount of time which occurs from one tick to the next, in units +of seconds. It is expressed as a rational constant using the template \tcode{ratio}. + +\indexlibrary{\idxcode{duration}}% +\begin{codeblock} +namespace std::chrono { + template> + class duration { + public: + using rep = Rep; + using period = typename Period::type; + + private: + rep rep_; // \expos + + public: + // \ref{time.duration.cons}, construct/copy/destroy + constexpr duration() = default; + template + constexpr explicit duration(const Rep2& r); + template + constexpr duration(const duration& d); + ~duration() = default; + duration(const duration&) = default; + duration& operator=(const duration&) = default; + + // \ref{time.duration.observer}, observer + constexpr rep count() const; + + // \ref{time.duration.arithmetic}, arithmetic + constexpr common_type_t operator+() const; + constexpr common_type_t operator-() const; + constexpr duration& operator++(); + constexpr duration operator++(int); + constexpr duration& operator--(); + constexpr duration operator--(int); + + constexpr duration& operator+=(const duration& d); + constexpr duration& operator-=(const duration& d); + + constexpr duration& operator*=(const rep& rhs); + constexpr duration& operator/=(const rep& rhs); + constexpr duration& operator%=(const rep& rhs); + constexpr duration& operator%=(const duration& rhs); + + // \ref{time.duration.special}, special values + static constexpr duration zero(); + static constexpr duration min(); + static constexpr duration max(); + }; +} +\end{codeblock} + +\pnum +\tcode{Rep} shall be an arithmetic type or a class emulating an arithmetic type. +If \tcode{duration} is instantiated with a \tcode{duration} type as the argument for the template +parameter \tcode{Rep}, the program is ill-formed. + +\pnum +If \tcode{Period} is not a specialization of \tcode{ratio}, the program is ill-formed. +If \tcode{Period::num} is not positive, the program is ill-formed. + +\pnum +Members of \tcode{duration} shall not throw exceptions other than +those thrown by the indicated operations on their representations. + +\pnum +The defaulted copy constructor of duration shall be a +constexpr function if and only if the required initialization +of the member \tcode{rep_} for copy and move, respectively, would +satisfy the requirements for a constexpr function. + +\pnum +\begin{example} +\begin{codeblock} +duration> d0; // holds a count of minutes using a \tcode{long} +duration d1; // holds a count of milliseconds using a \tcode{long long} +duration> d2; // holds a count with a tick period of $\frac{1}{30}$ of a second + // (30 Hz) using a \tcode{double} +\end{codeblock} +\end{example} + +\rSec2[time.duration.cons]{Constructors} + +\indexlibrary{\idxcode{duration}!constructor}% +\begin{itemdecl} +template + constexpr explicit duration(const Rep2& r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks This constructor shall not participate in overload +resolution unless +\tcode{Rep2} is implicitly convertible to \tcode{rep} and +\begin{itemize} +\item \tcode{treat_as_floating_point_v} is \tcode{true} or +\item \tcode{treat_as_floating_point_v} is \tcode{false}. +\end{itemize} +\begin{example} +\begin{codeblock} +duration d(3); // OK +duration d(3.5); // error +\end{codeblock} +\end{example} + +\pnum +\effects Constructs an object of type \tcode{duration}. + +\pnum +\postconditions \tcode{count() == static_cast(r)}. +\end{itemdescr} + +\indexlibrary{\idxcode{duration}!constructor}% +\begin{itemdecl} +template + constexpr duration(const duration& d); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks This constructor shall not participate in overload resolution unless +no overflow is induced in the conversion and +\tcode{treat_as_floating_point_v} is \tcode{true} or both +\tcode{ratio_divide::den} is \tcode{1} and +\tcode{treat_as_floating_point_v} is \tcode{false}. \begin{note} This +requirement prevents implicit truncation error when converting between +integral-based \tcode{duration} types. Such a construction could easily lead to +confusion about the value of the \tcode{duration}. \end{note} +\begin{example} +\begin{codeblock} +duration ms(3); +duration us = ms; // OK +duration ms2 = us; // error +\end{codeblock} +\end{example} + +\pnum +\effects Constructs an object of type \tcode{duration}, constructing \tcode{rep_} from\\ +\tcode{duration_cast(d).count()}. +\end{itemdescr} + +\rSec2[time.duration.observer]{Observer} + +\indexlibrarymember{count}{duration}% +\begin{itemdecl} +constexpr rep count() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{rep_}. +\end{itemdescr} + +\rSec2[time.duration.arithmetic]{Arithmetic} + +\indexlibrarymember{operator+}{duration}% +\begin{itemdecl} +constexpr common_type_t operator+() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{common_type_t(*this)}. +\end{itemdescr} + +\indexlibrarymember{operator-}{duration}% +\begin{itemdecl} +constexpr common_type_t operator-() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{common_type_t(-rep_)}. +\end{itemdescr} + +\indexlibrarymember{operator++}{duration}% +\begin{itemdecl} +constexpr duration& operator++(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects As if by \tcode{++rep_}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator++}{duration}% +\begin{itemdecl} +constexpr duration operator++(int); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{duration(rep_++)}. +\end{itemdescr} + +\indexlibrarymember{operator\dcr}{duration}% +\begin{itemdecl} +constexpr duration& operator--(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects As if by \tcode{--rep_}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator\dcr}{duration}% +\begin{itemdecl} +constexpr duration operator--(int); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{duration(rep_-{}-)}. +\end{itemdescr} + +\indexlibrarymember{operator+=}{duration}% +\begin{itemdecl} +constexpr duration& operator+=(const duration& d); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects As if by: \tcode{rep_ += d.count();} + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator-=}{duration}% +\begin{itemdecl} +constexpr duration& operator-=(const duration& d); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects As if by: \tcode{rep_ -= d.count();} + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator*=}{duration}% +\begin{itemdecl} +constexpr duration& operator*=(const rep& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects As if by: \tcode{rep_ *= rhs;} + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator/=}{duration}% +\begin{itemdecl} +constexpr duration& operator/=(const rep& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects As if by: \tcode{rep_ /= rhs;} + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator\%=}{duration}% +\begin{itemdecl} +constexpr duration& operator%=(const rep& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects As if by: \tcode{rep_ \%= rhs;} + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator\%=}{duration}% +\begin{itemdecl} +constexpr duration& operator%=(const duration& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects As if by: \tcode{rep_ \%= rhs.count();} + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + + +\rSec2[time.duration.special]{Special values} + +\indexlibrarymember{zero}{duration}% +\begin{itemdecl} +static constexpr duration zero(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{duration(duration_values::zero())}. +\end{itemdescr} + +\indexlibrarymember{min}{duration}% +\begin{itemdecl} +static constexpr duration min(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{duration(duration_values::min())}. +\end{itemdescr} + +\indexlibrarymember{max}{duration}% +\begin{itemdecl} +static constexpr duration max(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{duration(duration_values::max())}. +\end{itemdescr} + +\rSec2[time.duration.nonmember]{Non-member arithmetic} + +\pnum +In the function descriptions that follow, unless stated otherwise, +let \tcode{CD} represent the return type of the function. + +\indexlibrary{\idxcode{common_type}}% +\begin{itemdecl} +template + constexpr common_type_t, duration> + operator+(const duration& lhs, const duration& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{CD(CD(lhs).count() + CD(rhs).count())}. +\end{itemdescr} + +\indexlibrary{\idxcode{common_type}}% +\begin{itemdecl} +template + constexpr common_type_t, duration> + operator-(const duration& lhs, const duration& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{CD(CD(lhs).count() - CD(rhs).count())}. +\end{itemdescr} + +\indexlibrarymember{operator*}{duration}% +\begin{itemdecl} +template + constexpr duration, Period> + operator*(const duration& d, const Rep2& s); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks This operator shall not participate in overload +resolution unless \tcode{Rep2} is implicitly convertible to \tcode{common_type_t}. + +\pnum +\returns \tcode{CD(CD(d).count() * s)}. +\end{itemdescr} + +\indexlibrarymember{operator*}{duration}% +\begin{itemdecl} +template + constexpr duration, Period> + operator*(const Rep1& s, const duration& d); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks This operator shall not participate in overload +resolution unless \tcode{Rep1} is implicitly convertible to \tcode{common_type_t}. + +\pnum +\returns \tcode{d * s}. +\end{itemdescr} + +\indexlibrarymember{operator/}{duration}% +\begin{itemdecl} +template + constexpr duration, Period> + operator/(const duration& d, const Rep2& s); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks This operator shall not participate in overload +resolution unless \tcode{Rep2} is implicitly convertible to \tcode{common_type_t} +and \tcode{Rep2} is not a specialization of \tcode{duration}. + +\pnum +\returns \tcode{CD(CD(d).count() / s)}. +\end{itemdescr} + +\indexlibrarymember{operator/}{duration}% +\begin{itemdecl} +template + constexpr common_type_t + operator/(const duration& lhs, const duration& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let \tcode{CD} be +\tcode{common_type_t, duration>}. + +\pnum +\returns \tcode{CD(lhs).count() / CD(rhs).count()}. +\end{itemdescr} + +\indexlibrarymember{operator\%}{duration}% +\begin{itemdecl} +template + constexpr duration, Period> + operator%(const duration& d, const Rep2& s); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks This operator shall not participate in overload +resolution unless \tcode{Rep2} is implicitly convertible to \tcode{common_type_t} and +\tcode{Rep2} is not a specialization of \tcode{duration}. + +\pnum +\returns \tcode{CD(CD(d).count() \% s)}. +\end{itemdescr} + +\indexlibrarymember{operator\%}{duration}% +\begin{itemdecl} +template + constexpr common_type_t, duration> + operator%(const duration& lhs, const duration& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{CD(CD(lhs).count() \% CD(rhs).count())}. +\end{itemdescr} + + +\rSec2[time.duration.comparisons]{Comparisons} + +\pnum +In the function descriptions that follow, \tcode{CT} represents +\tcode{common_type_t}, where \tcode{A} and \tcode{B} are the types of +the two arguments to the function. + +\indexlibrarymember{operator==}{duration}% +\begin{itemdecl} +template + constexpr bool operator==(const duration& lhs, + const duration& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{CT(lhs).count() == CT(rhs).count()}. +\end{itemdescr} + +\indexlibrarymember{operator"!=}{duration}% +\begin{itemdecl} +template + constexpr bool operator!=(const duration& lhs, + const duration& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{!(lhs == rhs)}. +\end{itemdescr} + +\indexlibrarymember{operator<}{duration}% +\begin{itemdecl} +template + constexpr bool operator<(const duration& lhs, + const duration& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{CT(lhs).count() < CT(rhs).count()}. +\end{itemdescr} + +\indexlibrarymember{operator>}{duration}% +\begin{itemdecl} +template + constexpr bool operator>(const duration& lhs, + const duration& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{rhs < lhs}. +\end{itemdescr} + +\indexlibrarymember{operator<=}{duration}% +\begin{itemdecl} +template + constexpr bool operator<=(const duration& lhs, + const duration& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{!(rhs < lhs)}. +\end{itemdescr} + +\indexlibrarymember{operator>=}{duration}% +\begin{itemdecl} +template + constexpr bool operator>=(const duration& lhs, + const duration& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{!(lhs < rhs)}. +\end{itemdescr} + +\rSec2[time.duration.cast]{\tcode{duration_cast}} + +\indexlibrary{\idxcode{duration}!\idxcode{duration_cast}}% +\indexlibrary{\idxcode{duration_cast}}% +\begin{itemdecl} +template + constexpr ToDuration duration_cast(const duration& d); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks This function shall not participate in overload resolution +unless \tcode{ToDuration} is a specialization of \tcode{duration}. + +\pnum +\returns Let \tcode{CF} be \tcode{ratio_divide}, and \tcode{CR} be \tcode{common_type::type}. +\begin{itemize} +\item If \tcode{CF::num == 1} and \tcode{CF::den == 1}, returns +\begin{codeblock} +ToDuration(static_cast(d.count())) +\end{codeblock} + +\item otherwise, if \tcode{CF::num != 1} and \tcode{CF::den == 1}, returns +\begin{codeblock} +ToDuration(static_cast( + static_cast(d.count()) * static_cast(CF::num))) +\end{codeblock} + +\item otherwise, if \tcode{CF::num == 1} and \tcode{CF::den != 1}, returns +\begin{codeblock} +ToDuration(static_cast( + static_cast(d.count()) / static_cast(CF::den))) +\end{codeblock} + +\item otherwise, returns +\begin{codeblock} +ToDuration(static_cast( + static_cast(d.count()) * static_cast(CF::num) / static_cast(CF::den))) +\end{codeblock} +\end{itemize} + +\pnum +\begin{note} +This function does not use any implicit conversions; all conversions +are done with \tcode{static_cast}. It avoids multiplications and divisions when +it is known at compile time that one or more arguments is 1. Intermediate +computations are carried out in the widest representation and only converted to +the destination representation at the final step. +\end{note} +\end{itemdescr} + +\indexlibrarymember{floor}{duration}% +\begin{itemdecl} +template + constexpr ToDuration floor(const duration& d); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks This function shall not participate in overload resolution +unless \tcode{ToDuration} is a specialization of \tcode{duration}. + +\pnum +\returns The greatest result \tcode{t} representable in \tcode{ToDuration} +for which \tcode{t <= d}. +\end{itemdescr} + +\indexlibrarymember{ceil}{duration}% +\begin{itemdecl} +template + constexpr ToDuration ceil(const duration& d); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks This function shall not participate in overload resolution +unless \tcode{ToDuration} is a specialization of \tcode{duration}. + +\pnum +\returns The least result \tcode{t} representable in \tcode{ToDuration} +for which \tcode{t >= d}. +\end{itemdescr} + +\indexlibrarymember{round}{duration}% +\begin{itemdecl} +template + constexpr ToDuration round(const duration& d); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks This function shall not participate in overload resolution +unless \tcode{ToDuration} is a specialization of \tcode{duration}, +and \tcode{treat_as_floating_point_v} +is \tcode{false}. + +\pnum +\returns The value of \tcode{ToDuration} that is closest to \tcode{d}. +If there are two closest values, then return the value \tcode{t} +for which \tcode{t \% 2 == 0}. +\end{itemdescr} + +\rSec2[time.duration.literals]{Suffixes for duration literals} + +\pnum +This subclause describes literal suffixes for constructing duration literals. The +suffixes \tcode{h}, \tcode{min}, \tcode{s}, \tcode{ms}, \tcode{us}, \tcode{ns} +denote duration values of the corresponding types \tcode{hours}, \tcode{minutes}, +\tcode{seconds}, \tcode{milliseconds}, \tcode{microseconds}, and \tcode{nanoseconds} +respectively if they are applied to integral literals. + +\pnum +If any of these suffixes are applied to a floating-point literal the result is a +\tcode{chrono::duration} literal with an unspecified floating-point representation. + +\pnum +If any of these suffixes are applied to an integer literal and the resulting +\tcode{chrono::duration} value cannot be represented in the result type because +of overflow, the program is ill-formed. + +\pnum +\begin{example} +The following code shows some duration literals. +\begin{codeblock} +using namespace std::chrono_literals; +auto constexpr aday=24h; +auto constexpr lesson=45min; +auto constexpr halfanhour=0.5h; +\end{codeblock} +\end{example} + +\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); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{duration} literal representing \tcode{hours} hours. +\end{itemdescr} + +\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); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{duration} literal representing \tcode{minutes} minutes. +\end{itemdescr} + +\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); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{duration} literal representing \tcode{sec} seconds. + +\pnum +\begin{note} +The same suffix \tcode{s} is used for \tcode{basic_string} but there is no +conflict, since duration suffixes apply to numbers and string literal suffixes +apply to character array literals. +\end{note} +\end{itemdescr} + +\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); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{duration} literal representing \tcode{msec} milliseconds. +\end{itemdescr} + +\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); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{duration} literal representing \tcode{usec} microseconds. +\end{itemdescr} + +\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); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{duration} literal representing \tcode{nsec} nanoseconds. +\end{itemdescr} + +\rSec2[time.duration.alg]{Algorithms} + +\indexlibrarymember{abs}{duration}% +\begin{itemdecl} +template + constexpr duration abs(duration d); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks This function shall not participate in overload resolution +unless \tcode{numeric_limits::is_signed} is \tcode{true}. + +\pnum +\returns If \tcode{d >= d.zero()}, return \tcode{d}, +otherwise return \tcode{-d}. +\end{itemdescr} + +\rSec2[time.duration.io]{I/O} + +\indexlibrarymember{operator<<}{duration}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const duration& d); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{Rep} is an integral type +whose integer conversion rank\iref{conv.rank} +is greater than or equal to that of \tcode{short}, +or a floating point type. +\tcode{charT} is \tcode{char} or \tcode{wchar_t}. + +\pnum +\effects +Forms a \tcode{basic_string} from \tcode{d.count()} +using \tcode{to_string} if \tcode{charT} is \tcode{char}, +or \tcode{to_wstring} if \tcode{charT} is \tcode{wchar_t}. +Appends the units suffix described below to the \tcode{basic_string}. +Inserts the resulting \tcode{basic_string} into \tcode{os}. +\begin{note} +This specification ensures that the result of this streaming operation +will obey the width and alignment properties of the stream. +\end{note} + +\pnum +The units suffix depends on the type \tcode{Period::type} as follows: +\begin{itemize} +\item If \tcode{Period::type} is \tcode{atto}, the suffix is \tcode{"as"}. +\item Otherwise, if \tcode{Period::type} is \tcode{femto}, the suffix is \tcode{"fs"}. +\item Otherwise, if \tcode{Period::type} is \tcode{pico}, the suffix is \tcode{"ps"}. +\item Otherwise, if \tcode{Period::type} is \tcode{nano}, the suffix is \tcode{"ns"}. +\item Otherwise, if \tcode{Period::type} is \tcode{micro}, the suffix is \tcode{"\textmu{}s"} (\tcode{"\textbackslash{}u00b5\textbackslash{}u0073"}). +\item Otherwise, if \tcode{Period::type} is \tcode{milli}, the suffix is \tcode{"ms"}. +\item Otherwise, if \tcode{Period::type} is \tcode{centi}, the suffix is \tcode{"cs"}. +\item Otherwise, if \tcode{Period::type} is \tcode{deci}, the suffix is \tcode{"ds"}. +\item Otherwise, if \tcode{Period::type} is \tcode{ratio<1>}, the suffix is \tcode{"s"}. +\item Otherwise, if \tcode{Period::type} is \tcode{deca}, the suffix is \tcode{"das"}. +\item Otherwise, if \tcode{Period::type} is \tcode{hecto}, the suffix is \tcode{"hs"}. +\item Otherwise, if \tcode{Period::type} is \tcode{kilo}, the suffix is \tcode{"ks"}. +\item Otherwise, if \tcode{Period::type} is \tcode{mega}, the suffix is \tcode{"Ms"}. +\item Otherwise, if \tcode{Period::type} is \tcode{giga}, the suffix is \tcode{"Gs"}. +\item Otherwise, if \tcode{Period::type} is \tcode{tera}, the suffix is \tcode{"Ts"}. +\item Otherwise, if \tcode{Period::type} is \tcode{peta}, the suffix is \tcode{"Ps"}. +\item Otherwise, if \tcode{Period::type} is \tcode{exa}, the suffix is \tcode{"Es"}. +\item Otherwise, if \tcode{Period::type} is \tcode{ratio<60>}, the suffix is \tcode{"min"}. +\item Otherwise, if \tcode{Period::type} is \tcode{ratio<3600>}, the suffix is \tcode{"h"}. +\item Otherwise, if \tcode{Period::type::den == 1}, the suffix is \tcode{"[\placeholder{num}]s"}. +\item Otherwise, the suffix is \tcode{"[\placeholder{num}/\placeholder{den}]s"}. +\end{itemize} +In the list above the use of \tcode{\placeholder{num}} and \tcode{\placeholder{den}} +refer to the static data members of \tcode{Period::type}, +which are converted to arrays of \tcode{charT} using a decimal conversion with no leading zeroes. + +\pnum +If \tcode{Period::type} is \tcode{micro}, +but the character U+00B5 cannot be represented in +the encoding used for \tcode{charT}, +the unit suffix \tcode{"us"} is used instead of \tcode{"\textmu{}s"}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{to_stream}{duration}% +\begin{itemdecl} +template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, + const duration& d); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Streams \tcode{d} into \tcode{os} using +the format specified by the NTCTS \tcode{fmt}. +\tcode{fmt} encoding follows the rules specified in \ref{time.format}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{from_stream}{duration}% +\begin{itemdecl} +template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + duration& d, + basic_string* abbrev = nullptr, + minutes* offset = nullptr); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Attempts to parse the input stream \tcode{is} +into the duration \tcode{d} +using the format flags given in the NTCTS \tcode{fmt} +as specified in \ref{time.parse}. +If the parse parses everything specified by the parsing format flags without error, +and yet none of the flags impacts a duration, +\tcode{d} will be assigned a zero value. +If \tcode{\%Z} is used and successfully parsed, +that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. +If \tcode{\%z} (or a modified variant) is used and successfully parsed, +that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. + +\pnum +\returns \tcode{is}. +\end{itemdescr} + +\rSec1[time.point]{Class template \tcode{time_point}} + +\indexlibrary{\idxcode{time_point}}% +\begin{codeblock} +namespace std::chrono { + template + class time_point { + public: + using clock = Clock; + using duration = Duration; + using rep = typename duration::rep; + using period = typename duration::period; + + private: + duration d_; // \expos + + public: + // \ref{time.point.cons}, construct + constexpr time_point(); // has value epoch + constexpr explicit time_point(const duration& d); // same as \tcode{time_point() + d} + template + constexpr time_point(const time_point& t); + + // \ref{time.point.observer}, observer + constexpr duration time_since_epoch() const; + + // \ref{time.point.arithmetic}, arithmetic + constexpr time_point& operator++(); + constexpr time_point operator++(int); + constexpr time_point& operator--(); + constexpr time_point operator--(int); + constexpr time_point& operator+=(const duration& d); + constexpr time_point& operator-=(const duration& d); + + // \ref{time.point.special}, special values + static constexpr time_point min(); + static constexpr time_point max(); + }; +} +\end{codeblock} + +\pnum +\tcode{Clock} shall either +satisfy the \oldconcept{Clock} requirements\iref{time.clock.req} +or be the type \tcode{local_t}. + +\pnum +If \tcode{Duration} is not an instance of \tcode{duration}, +the program is ill-formed. + +\rSec2[time.point.cons]{Constructors} + +\indexlibrary{\idxcode{time_point}!constructor}% +\begin{itemdecl} +constexpr time_point(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Constructs an object of type \tcode{time_point}, initializing +\tcode{d_} with \tcode{duration::zero()}. Such a \tcode{time_point} object +represents the epoch. +\end{itemdescr} + +\indexlibrary{\idxcode{time_point}!constructor}% +\begin{itemdecl} +constexpr explicit time_point(const duration& d); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Constructs an object of type \tcode{time_point}, initializing +\tcode{d_} with \tcode{d}. Such a \tcode{time_point} object represents the epoch +\tcode{+ d}. +\end{itemdescr} + +\indexlibrary{\idxcode{time_point}!constructor}% +\begin{itemdecl} +template + constexpr time_point(const time_point& t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks This constructor shall not participate in overload resolution unless \tcode{Duration2} +is implicitly convertible to \tcode{duration}. + +\pnum +\effects Constructs an object of type \tcode{time_point}, initializing +\tcode{d_} with \tcode{t.time_since_epoch()}. +\end{itemdescr} + +\rSec2[time.point.observer]{Observer} + +\indexlibrarymember{time_since_epoch}{time_point}% +\begin{itemdecl} +constexpr duration time_since_epoch() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{d_}. +\end{itemdescr} + +\rSec2[time.point.arithmetic]{Arithmetic} + +\indexlibrarymember{operator++}{time_point}% +\begin{itemdecl} +constexpr time_point& operator++(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{++d_}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator++}{time_point}% +\begin{itemdecl} +constexpr time_point operator++(int); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{time_point\{d_++\}}. +\end{itemdescr} + +\indexlibrarymember{operator--}{time_point}% +\begin{itemdecl} +constexpr time_point& operator--(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{--d_}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator--}{time_point}% +\begin{itemdecl} +constexpr time_point operator--(int); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{time_point\{d_--\}}. +\end{itemdescr} + +\indexlibrarymember{operator+=}{time_point}% +\begin{itemdecl} +constexpr time_point& operator+=(const duration& d); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects As if by: \tcode{d_ += d;} + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator-=}{time_point}% +\begin{itemdecl} +constexpr time_point& operator-=(const duration& d); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects As if by: \tcode{d_ -= d;} + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\rSec2[time.point.special]{Special values} + +\indexlibrarymember{min}{time_point}% +\begin{itemdecl} +static constexpr time_point min(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{time_point(duration::min())}. +\end{itemdescr} + +\indexlibrarymember{max}{time_point}% +\begin{itemdecl} +static constexpr time_point max(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{time_point(duration::max())}. +\end{itemdescr} + +\rSec2[time.point.nonmember]{Non-member arithmetic} + +\indexlibrarymember{operator+}{time_point}% +\indexlibrarymember{operator+}{duration}% +\begin{itemdecl} +template + constexpr time_point>> + operator+(const time_point& lhs, const duration& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{CT(lhs.time_since_epoch() + rhs)}, where \tcode{CT} is the type of the return value. +\end{itemdescr} + +\indexlibrarymember{operator+}{time_point}% +\indexlibrarymember{operator+}{duration}% +\begin{itemdecl} +template + constexpr time_point, Duration2>> + operator+(const duration& lhs, const time_point& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{rhs + lhs}. +\end{itemdescr} + +\indexlibrarymember{operator-}{time_point}% +\indexlibrarymember{operator-}{duration}% +\begin{itemdecl} +template + constexpr time_point>> + operator-(const time_point& lhs, const duration& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{CT(lhs.time_since_epoch() - rhs)}, +where \tcode{CT} is the type of the return value. +\end{itemdescr} + +\indexlibrarymember{operator-}{time_point}% +\begin{itemdecl} +template + constexpr common_type_t + operator-(const time_point& lhs, const time_point& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{lhs.time_since_epoch() - rhs.time_since_epoch()}. +\end{itemdescr} + +\rSec2[time.point.comparisons]{Comparisons} + +\indexlibrarymember{operator==}{time_point}% +\begin{itemdecl} +template + constexpr bool operator==(const time_point& lhs, + const time_point& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{lhs.time_since_epoch() == rhs.time_since_epoch()}. +\end{itemdescr} + +\indexlibrarymember{operator"!=}{time_point}% +\begin{itemdecl} +template + constexpr bool operator!=(const time_point& lhs, + const time_point& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{!(lhs == rhs)}. +\end{itemdescr} + +\indexlibrarymember{operator<}{time_point}% +\begin{itemdecl} +template + constexpr bool operator<(const time_point& lhs, + const time_point& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{lhs.time_since_epoch() < rhs.time_since_epoch()}. +\end{itemdescr} + +\indexlibrarymember{operator>}{time_point}% +\begin{itemdecl} +template + constexpr bool operator>(const time_point& lhs, + const time_point& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{rhs < lhs}. +\end{itemdescr} + +\indexlibrarymember{operator<=}{time_point}% +\begin{itemdecl} +template + constexpr bool operator<=(const time_point& lhs, + const time_point& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{!(rhs < lhs)}. +\end{itemdescr} + +\indexlibrarymember{operator>=}{time_point}% +\begin{itemdecl} +template + constexpr bool operator>=(const time_point& lhs, + const time_point& rhs); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{!(lhs < rhs)}. +\end{itemdescr} + +\rSec2[time.point.cast]{\tcode{time_point_cast}} + +\indexlibrary{\idxcode{time_point}!\idxcode{time_point_cast}}% +\indexlibrary{\idxcode{time_point_cast}}% +\begin{itemdecl} +template + constexpr time_point time_point_cast(const time_point& t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks This function shall not participate in overload resolution +unless \tcode{ToDuration} is a specialization of \tcode{duration}. + +\pnum +\returns +\begin{codeblock} +time_point(duration_cast(t.time_since_epoch())) +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{floor}{time_point}% +\begin{itemdecl} +template + constexpr time_point floor(const time_point& tp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks This function shall not participate in overload resolution +unless \tcode{ToDuration} is a specialization of \tcode{duration}. + +\pnum +\returns \tcode{time_point(floor(tp.time_since_epoch()))}. +\end{itemdescr} + +\indexlibrarymember{ceil}{time_point}% +\begin{itemdecl} +template + constexpr time_point ceil(const time_point& tp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks This function shall not participate in overload resolution +unless \tcode{ToDuration} is a specialization of \tcode{duration}. + +\pnum +\returns \tcode{time_point(ceil(tp.time_since_epoch()))}. +\end{itemdescr} + +\indexlibrarymember{round}{time_point}% +\begin{itemdecl} +template + constexpr time_point round(const time_point& tp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks This function shall not participate in overload resolution +unless \tcode{ToDuration} is a specialization of \tcode{duration}, and +\tcode{treat_as_floating_point_v} is \tcode{false}. + +\pnum +\returns \tcode{time_point(round(tp.time_since_epoch()))}. +\end{itemdescr} + +\rSec1[time.clock]{Clocks} + +\pnum +The types defined in this subclause shall satisfy the +\oldconcept{TrivialClock} +requirements\iref{time.clock.req} +unless otherwise specified. + +\rSec2[time.clock.system]{Class \tcode{system_clock}} + +\rSec3[time.clock.system.overview]{Overview} +\indexlibrary{\idxcode{system_clock}}% + +\begin{codeblock} +namespace std::chrono { + class system_clock { + public: + using rep = @\seebelow@; + using period = ratio<@\unspecnc@, @\unspec{}@>; + using duration = chrono::duration; + using time_point = chrono::time_point; + static constexpr bool is_steady = @\unspec;@ + + static time_point now() noexcept; + + // mapping to/from C type \tcode{time_t} + static time_t to_time_t (const time_point& t) noexcept; + static time_point from_time_t(time_t t) noexcept; + }; +} +\end{codeblock} + +\pnum +Objects of type \tcode{system_clock} represent wall clock time from the system-wide +realtime clock. +Objects of type \tcode{sys_time} measure time since (and before) +1970-01-01 00:00:00 UTC excluding leap seconds. +This measure is commonly referred to as \defn{Unix time}. +This measure facilitates an efficient mapping between +\tcode{sys_time} and calendar types\iref{time.cal}. +\begin{example} \\ +\tcode{sys_seconds\{sys_days\{1970y/January/1\}\}.time_since_epoch()} is \tcode{0s}. \\ +\tcode{sys_seconds\{sys_days\{2000y/January/1\}\}.time_since_epoch()} is \tcode{946'684'800s}, +which is \tcode{10'957 * 86'400s}. \\ +\end{example} + +\rSec3[time.clock.system.members]{Members} + +\indexlibrarymember{rep}{system_clock}% +\begin{itemdecl} +using system_clock::rep = @\unspec@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{system_clock::duration::min() < system_clock::duration::zero()} shall +be \tcode{true}.\\ +\begin{note} This implies that \tcode{rep} is a signed type. \end{note} +\end{itemdescr} + +\indexlibrarymember{to_time_t}{system_clock}% +\begin{itemdecl} +static time_t to_time_t(const time_point& t) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns A \tcode{time_t} object that represents the same point in time as \tcode{t} +when both values are restricted to the coarser of the precisions of \tcode{time_t} and +\tcode{time_point}. +It is \impldef{whether values are rounded or truncated to the +required precision when converting between \tcode{time_t} values and \tcode{time_point} objects} +whether values are rounded or truncated to the required precision. +\end{itemdescr} + +\indexlibrarymember{from_time_t}{system_clock}% +\begin{itemdecl} +static time_point from_time_t(time_t t) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns A \tcode{time_point} object that represents the same point in time as \tcode{t} +when both values are restricted to the coarser of the precisions of \tcode{time_t} and +\tcode{time_point}. +It is \impldef{whether values are rounded or truncated to the +required precision when converting between \tcode{time_t} values and \tcode{time_point} objects} +whether values are rounded or truncated to the required precision. +\end{itemdescr} + +\rSec3[time.clock.system.nonmembers]{Non-member functions} + +\indexlibrarymember{operator<<}{sys_time}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const sys_time& tp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +This operator shall not participate in overload resolution if +\tcode{treat_as_floating_point_v} is \tcode{true}, +or if \tcode{Duration\{1\} >= days\{1\}}. + +\pnum +\effects +\begin{codeblock} +auto const dp = floor(tp); +os << year_month_day{dp} << ' ' << time_of_day{tp-dp}; +\end{codeblock} + +\pnum +\returns \tcode{os}. + +\pnum +\begin{example} +\begin{codeblock} +cout << sys_seconds{0s} << '\n'; // 1970-01-01 00:00:00 +cout << sys_seconds{946'684'800s} << '\n'; // 2000-01-01 00:00:00 +cout << sys_seconds{946'688'523s} << '\n'; // 2000-01-01 01:02:03 +\end{codeblock} +\end{example} +\end{itemdescr} + +\indexlibrarymember{operator<<}{sys_days}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const sys_days& dp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{os << year_month_day\{dp\}}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{to_stream}{sys_time}% +\begin{itemdecl} +template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, const sys_time& tp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Streams \tcode{tp} into \tcode{os} using +the format specified by the NTCTS \tcode{fmt}. +\tcode{fmt} encoding follows the rules specified in \ref{time.format}. +If \tcode{\%Z} is used, it will be replaced with +\tcode{"UTC"} widened to \tcode{charT}. +If \tcode{\%z} is used (or a modified variant of \tcode{\%z}), +an offset of \tcode{0min} will be formatted. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{from_stream}{sys_time}% +\begin{itemdecl} +template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + sys_time& tp, basic_string* abbrev = nullptr, + minutes* offset = nullptr); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Attempts to parse the input stream \tcode{is} +into the \tcode{sys_time} \tcode{tp} using +the format flags given in the NTCTS \tcode{fmt} +as specified in \ref{time.parse}. +If the parse fails to decode a valid date, +\tcode{is.setstate(ios_base::failbit)} +shall be called and \tcode{tp} shall not be modified. +If \tcode{\%Z} is used and successfully parsed, +that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. +If \tcode{\%z} (or a modified variant) is used and successfully parsed, +that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. +Additionally, the parsed offset will be subtracted +from the successfully parsed timestamp +prior to assigning that difference to \tcode{tp}. + +\pnum +\returns is. +\end{itemdescr} + +\rSec2[time.clock.utc]{Class \tcode{utc_clock}} + +\rSec3[time.clock.utc.overview]{Overview} +\indexlibrary{\idxcode{utc_clock}}% + +\begin{codeblock} +namespace std::chrono { + class utc_clock { + public: + using rep = @\textit{a signed arithmetic type}@; + using period = ratio<@\unspecnc@, @\unspec@>; + using duration = chrono::duration; + using time_point = chrono::time_point; + static constexpr bool is_steady = @\unspec@; + + static time_point now(); + + template + static sys_time> + to_sys(const utc_time& t); + template + static utc_time> + from_sys(const sys_time& t); + }; +} +\end{codeblock} + +\pnum +In contrast to \tcode{sys_time}, +which does not take leap seconds into account, +\tcode{utc_clock} and its associated \tcode{time_point}, \tcode{utc_time}, +count time, including leap seconds, since 1970-01-01 00:00:00 UTC. +\begin{example} \\ +\tcode{clock_cast(sys_seconds\{sys_days\{1970y/January/1\}\}).time_since_epoch()} is \tcode{0s}. \\ +\tcode{clock_cast(sys_seconds\{sys_days\{2000y/January/1\}\}).time_since_epoch()} \\ +is \tcode{946'684'822s}, which is \tcode{10'957 * 86'400s + 22s}. \\ +\end{example} + +\pnum +\tcode{utc_clock} is not a \oldconcept{TrivialClock} +unless the implementation can guarantee that \tcode{utc_clock::now()} +does not propagate an exception. +\begin{note} \tcode{noexcept(from_sys(system_clock::now()))} is \tcode{false}. \end{note} + +\rSec3[time.clock.utc.members]{Member functions} + +\indexlibrarymember{now}{utc_clock}% +\begin{itemdecl} +static time_point now(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{from_sys(system_clock::now())}, or a more accurate value of \tcode{utc_time}. +\end{itemdescr} + +\indexlibrarymember{to_sys}{utc_clock}% +\begin{itemdecl} +template + static sys_time> + to_sys(const utc_time& u); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{sys_time} \tcode{t}, +such that \tcode{from_sys(t) == u} if such a mapping exists. +Otherwise \tcode{u} represents a \tcode{time_point} +during a leap second insertion +and the last representable value of \tcode{sys_time} +prior to the insertion of the leap second is returned. +\end{itemdescr} + +\indexlibrarymember{from_sys}{utc_clock}% +\begin{itemdecl} +template + static utc_time> + from_sys(const sys_time& t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{utc_time} \tcode{u}, such that +\tcode{u.time_since_epoch() - t.time_since_epoch()} +is equal to the number of leap seconds that were inserted +between \tcode{t} and 1970-01-01. +If \tcode{t} is exactly the date of leap second insertion, +then the conversion counts that leap second as inserted. + +\begin{example} +\begin{codeblock} +auto t = sys_days{July/1/2015} - 2ns; +auto u = utc_clock::from_sys(t); +assert(u.time_since_epoch() - t.time_since_epoch() == 25s); +t += 1ns; +u = utc_clock::from_sys(t); +assert(u.time_since_epoch() - t.time_since_epoch() == 25s); +t += 1ns; +u = utc_clock::from_sys(t); +assert(u.time_since_epoch() - t.time_since_epoch() == 26s); +t += 1ns; +u = utc_clock::from_sys(t); +assert(u.time_since_epoch() - t.time_since_epoch() == 26s); +\end{codeblock} +\end{example} +\end{itemdescr} + +\rSec3[time.clock.utc.nonmembers]{Non-member functions} + +\indexlibrarymember{operator<<}{utc_time}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const utc_time& t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Calls \tcode{to_stream(os, fmt, t)}, +where \tcode{fmt} is a string containing \tcode{"\%F \%T"} +widened to \tcode{charT}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{to_stream}{utc_time}% +\begin{itemdecl} +template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, const utc_time& tp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Streams \tcode{tp} into \tcode{os} using +the format specified by the NTCTS \tcode{fmt}. +\tcode{fmt} encoding follows the rules specified in \ref{time.format}. +If \tcode{\%Z} is used, it will be replaced with \tcode{"UTC"} widened to \tcode{charT}. +If \tcode{\%z} is used (or a modified variant of \tcode{\%z}), +an offset of \tcode{0min} will be formatted. +If \tcode{tp} represents a time during a leap second insertion, +and if a seconds field is formatted, +the integral portion of that format shall be \tcode{"60"} widened to \tcode{charT}. + +\pnum +\returns \tcode{os}. + +\pnum +\begin{example} +\begin{codeblock} +auto t = sys_days{July/1/2015} - 500ms; +auto u = clock_cast(t); +for (auto i = 0; i < 8; ++i, u += 250ms) + cout << u << " UTC\n"; +\end{codeblock} + +Produces this output: + +\begin{codeblock} +2015-06-30 23:59:59.500 UTC +2015-06-30 23:59:59.750 UTC +2015-06-30 23:59:60.000 UTC +2015-06-30 23:59:60.250 UTC +2015-06-30 23:59:60.500 UTC +2015-06-30 23:59:60.750 UTC +2015-07-01 00:00:00.000 UTC +2015-07-01 00:00:00.250 UTC +\end{codeblock} +\end{example} +\end{itemdescr} + +\indexlibrarymember{from_stream}{utc_time}% +\begin{itemdecl} +template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + utc_time& tp, basic_string* abbrev = nullptr, + minutes* offset = nullptr); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Attempts to parse the input stream \tcode{is} +into the \tcode{utc_time} \tcode{tp} using +the format flags given in the NTCTS \tcode{fmt} +as specified in \ref{time.parse}. +If the parse fails to decode a valid date, +\tcode{is.setstate(ios_base::failbit)} shall be called +and \tcode{tp} shall not be modified. +If \tcode{\%Z} is used and successfully parsed, +that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. +If \tcode{\%z} (or a modified variant) is used and successfully parsed, +that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. +Additionally, the parsed offset will be subtracted from +the successfully parsed timestamp +prior to assigning that difference to \tcode{tp}. + +\pnum +\returns \tcode{is}. +\end{itemdescr} + +\rSec2[time.clock.tai]{Class \tcode{tai_clock}} + +\rSec3[time.clock.tai.overview]{Overview} +\indexlibrary{\idxcode{tai_clock}}% + +\begin{codeblock} +namespace std::chrono { + class tai_clock { + public: + using rep = @\textit{a signed arithmetic type}@; + using period = ratio<@\unspecnc@, @\unspec@>; + using duration = chrono::duration; + using time_point = chrono::time_point; + static constexpr bool is_steady = @\unspec@; + + static time_point now(); + + template + static utc_time> + to_utc(const tai_time&) noexcept; + template + static tai_time> + from_utc(const utc_time&) noexcept; + }; +} +\end{codeblock} + +\pnum +The clock \tcode{tai_clock} measures seconds since 1958-01-01 00:00:00 +and is offset 10s ahead of UTC at this date. +That is, 1958-01-01 00:00:00 TAI is equivalent to 1957-12-31 23:59:50 UTC. +Leap seconds are not inserted into TAI. +Therefore every time a leap second is inserted into UTC, +UTC falls another second behind TAI. +For example by 2000-01-01 there had been 22 leap seconds inserted +so 2000-01-01 00:00:00 UTC is equivalent to 2000-01-01 00:00:32 TAI +(22s plus the initial 10s offset). + +\pnum +\tcode{tai_clock} is not a \oldconcept{TrivialClock} +unless the implementation can guarantee that \tcode{tai_clock::now()} +does not propagate an exception. +\begin{note} +\tcode{noexcept(from_utc(utc_clock::now()))} is \tcode{false}. +\end{note} + +\rSec3[time.clock.tai.members]{Member functions} + +\indexlibrarymember{now}{tai_clock}% +\begin{itemdecl} +static time_point now(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{from_utc(utc_clock::now())}, or a more accurate value of \tcode{tai_time}. +\end{itemdescr} + +\indexlibrarymember{to_utc}{tai_clock}% +\begin{itemdecl} +template + static utc_time> + to_utc(const tai_time& t) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +utc_time>{t.time_since_epoch()} - 378691210s +\end{codeblock} +\begin{note} +\begin{codeblock} +378691210s == sys_days{1970y/January/1} - sys_days{1958y/January/1} + 10s +\end{codeblock} +\end{note} +\end{itemdescr} + +\indexlibrarymember{from_utc}{tai_clock}% +\begin{itemdecl} +template + static tai_time> + from_utc(const utc_time& t) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +tai_time>{t.time_since_epoch()} + 378691210s +\end{codeblock} +\begin{note} +\begin{codeblock} +378691210s == sys_days{1970y/January/1} - sys_days{1958y/January/1} + 10s +\end{codeblock} +\end{note} +\end{itemdescr} + +\rSec3[time.clock.tai.nonmembers]{Non-member functions} + +\indexlibrarymember{operator<<}{tai_time}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const tai_time& t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Calls \tcode{to_stream(os, fmt, t)}, +where \tcode{fmt} is a string containing +\tcode{"\%F \%T"} widened to \tcode{charT}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{to_stream}{tai_time}% +\begin{itemdecl} +template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, const tai_time& tp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Streams \tcode{tp} into \tcode{os} using +the format specified by the NTCTS \tcode{fmt}. +\tcode{fmt} encoding follows the rules specified in \ref{time.format}. +If \tcode{\%Z} is used, it will be replaced with \tcode{"TAI"}. +If \tcode{\%z} is used (or a modified variant of \tcode{\%z}), +an offset of \tcode{0min} will be formatted. +The date and time formatted shall be equivalent to +that formatted by a \tcode{sys_time} initialized with: +\begin{codeblock} +sys_time{tp.time_since_epoch()} - + (sys_days{1970y/January/1} - sys_days{1958y/January/1}) +\end{codeblock} + +\pnum +\returns os. + +\pnum +\begin{example} +\begin{codeblock} +auto st = sys_days{2000y/January/1}; +auto tt = clock_cast(st); +cout << format("%F %T %Z == ", st) << format("%F %T %Z\n", tt); +\end{codeblock} + +Produces this output: + +\begin{codeblock} +2000-01-01 00:00:00 UTC == 2000-01-01 00:00:32 TAI +\end{codeblock} +\end{example} +\end{itemdescr} + +\indexlibrarymember{from_stream}{tai_time}% +\begin{itemdecl} +template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + tai_time& tp, basic_string* abbrev = nullptr, + minutes* offset = nullptr); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Attempts to parse the input stream \tcode{is} +into the \tcode{tai_time} \tcode{tp} using +the format flags given in the NTCTS \tcode{fmt} +as specified in \ref{time.parse}. +If the parse fails to decode a valid date, +\tcode{is.setstate(ios_base::failbit)} shall be called +and \tcode{tp} shall not be modified. +If \tcode{\%Z} is used and successfully parsed, +that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. +If \tcode{\%z} (or a modified variant) is used and successfully parsed, +that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. +Additionally, the parsed offset will be subtracted from +the successfully parsed timestamp prior to assigning that difference to \tcode{tp}. + +\pnum +\returns \tcode{is}. +\end{itemdescr} + +\rSec2[time.clock.gps]{Class \tcode{gps_clock}} + +\rSec3[time.clock.gps.overview]{Overview} +\indexlibrary{\idxcode{gps_clock}}% + +\begin{codeblock} +namespace std::chrono { + class gps_clock { + public: + using rep = @\textit{a signed arithmetic type}@; + using period = ratio<@\unspecnc@, @\unspec@>; + using duration = chrono::duration; + using time_point = chrono::time_point; + static constexpr bool is_steady = @\unspec@; + + static time_point now(); + + template + static utc_time> + to_utc(const gps_time&) noexcept; + template + static gps_time> + from_utc(const utc_time&) noexcept; + }; +} +\end{codeblock} + +\pnum +The clock \tcode{gps_clock} measures +seconds since the first Sunday of January, 1980 00:00:00 UTC. +Leap seconds are not inserted into GPS. +Therefore every time a leap second is inserted into UTC, +UTC falls another second behind GPS. +Aside from the offset from \tcode{1958y/January/1} to \tcode{1980y/January/Sunday[1]}, +GPS is behind TAI by 19s due to the 10s offset between 1958 and 1970 +and the additional 9 leap seconds inserted between 1970 and 1980. + +\pnum +\tcode{gps_clock} is not a \oldconcept{TrivialClock} +unless the implementation can guarantee that +\tcode{gps_clock::now()} does not propagate an exception. +\begin{note} +\tcode{noexcept(from_utc(utc_clock::now()))} is \tcode{false}. +\end{note} + +\rSec3[time.clock.gps.members]{Member functions} + +\indexlibrarymember{now}{gps_clock}% +\begin{itemdecl} +static time_point now(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{from_utc(utc_clock::now())}, or a more accurate value of \tcode{gps_time}. +\end{itemdescr} + +\indexlibrarymember{to_utc}{gps_clock}% +\begin{itemdecl} +template + static utc_time> + to_utc(const gps_time& t) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +gps_time>{t.time_since_epoch()} + 315964809s +\end{codeblock} +\begin{note} +\begin{codeblock} +315964809s == sys_days{1980y/January/Sunday[1]} - sys_days{1970y/January/1} + 9s +\end{codeblock} +\end{note} +\end{itemdescr} + +\indexlibrarymember{from_utc}{gps_clock}% +\begin{itemdecl} +template + static gps_time> + from_utc(const utc_time& t) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +gps_time>{t.time_since_epoch()} - 315964809s +\end{codeblock} +\begin{note} +\begin{codeblock} +315964809s == sys_days{1980y/January/Sunday[1]} - sys_days{1970y/January/1} + 9s +\end{codeblock} +\end{note} +\end{itemdescr} + +\rSec3[time.clock.gps.nonmembers]{Non-member functions} + +\indexlibrarymember{operator<<}{gps_time}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const gps_time& t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Calls \tcode{to_stream(os, fmt, t)}, +where \tcode{fmt} is a string containing +\tcode{"\%F \%T"} widened to \tcode{charT}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{to_stream}{gps_time}% +\begin{itemdecl} +template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, const gps_time& tp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Streams \tcode{tp} into \tcode{os} using +the format specified by the NTCTS \tcode{fmt}. +\tcode{fmt} encoding follows the rules specified in \ref{time.format}. +If \tcode{\%Z} is used, it will be replaced with \tcode{"GPS"}. +If \tcode{\%z} is used (or a modified variant of \tcode{\%z}), +an offset of \tcode{0min} will be formatted. +The date and time formatted +shall be equivalent to that formatted by a \tcode{sys_time} initialized with: +\begin{codeblock} +sys_time{tp.time_since_epoch()} + + (sys_days{1980y/January/Sunday[1]} - sys_days{1970y/January/1}) +\end{codeblock} + +\pnum +\returns os. + +\pnum +\begin{example} +\begin{codeblock} +auto st = sys_days{2000y/January/1}; +auto gt = clock_cast(st); +cout << format("%F %T %Z == ", st) << format("%F %T %Z\n", gt); +\end{codeblock} + +Produces this output: + +\begin{codeblock} +2000-01-01 00:00:00 UTC == 2000-01-01 00:00:13 GPS +\end{codeblock} +\end{example} +\end{itemdescr} + +\indexlibrarymember{from_stream}{gps_time}% +\begin{itemdecl} +template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + gps_time& tp, basic_string* abbrev = nullptr, + minutes* offset = nullptr); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Attempts to parse the input stream \tcode{is} +into the \tcode{gps_time} \tcode{tp} using +the format flags given in the NTCTS \tcode{fmt} +as specified in \ref{time.parse}. +If the parse fails to decode a valid date, +\tcode{is.setstate(ios_base::failbit)} shall be called +and \tcode{tp} shall not be modified. +If \tcode{\%Z} is used and successfully parsed, +that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. +If \tcode{\%z} (or a modified variant) is used and successfully parsed, +that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. +Additionally, the parsed offset will be subtracted from +the successfully parsed timestamp prior to assigning that difference to \tcode{tp}. + +\pnum +\returns \tcode{is}. +\end{itemdescr} + +\rSec2[time.clock.file]{Class \tcode{file_clock}} + +\rSec3[time.clock.file.overview]{Overview} +\indexlibrary{\idxcode{file_clock}}% + +\begin{codeblock} +namespace std::chrono { + class file_clock { + public: + using rep = @\textit{a signed arithmetic type}@; + using period = ratio<@\unspecnc@, @\unspec@>; + using duration = chrono::duration; + using time_point = chrono::time_point; + static constexpr bool is_steady = @\unspec@; + + static time_point now() noexcept; + + // Conversion functions, see below + }; +} +\end{codeblock} + +\pnum +The clock \tcode{file_clock} is used to create the \tcode{time_point} system +used for \tcode{file_time_type}\iref{filesystems}. Its epoch is unspecified. + +\rSec3[time.clock.file.members]{Member functions} + +\indexlibrarymember{now}{file_clock}% +\begin{itemdecl} +static time_point now(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns A \tcode{file_clock::time_point} indicating the current time. +\end{itemdescr} + +\pnum +The class \tcode{file_clock} shall provide +precisely one of the following two sets of static member functions: + +\begin{codeblock} +template + static sys_time<@\seebelow@> + to_sys(const file_time&); +template + static file_time<@\seebelow@> + from_sys(const sys_time&); +\end{codeblock} + +or: + +\begin{codeblock} +template + static utc_time<@\seebelow@> + to_utc(const file_time&); +template + static file_time<@\seebelow@> + from_utc(const utc_time&); +\end{codeblock} + +These member functions shall provide \tcode{time_point} conversions +consistent with those specified by +\tcode{utc_clock}, \tcode{tai_clock}, and \tcode{gps_clock}. +The \tcode{Duration} of the resultant \tcode{time_point} +is computed from the \tcode{Duration} of the input \tcode{time_point}. + +\rSec3[time.clock.file.nonmembers]{Non-member functions} + +\indexlibrarymember{operator<<}{file_time}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const file_time& t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Calls \tcode{to_stream(os, fmt, t)}, +where \tcode{fmt} is a string containing +\tcode{"\%F \%T"} widened to \tcode{charT}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{to_stream}{file_time}% +\begin{itemdecl} +template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, const file_time& tp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Streams \tcode{tp} into \tcode{os} using +the format specified by the NTCTS \tcode{fmt}. +\tcode{fmt} encoding follows the rules specified in \ref{time.format}. +If \tcode{\%Z} is used, it will be replaced with \tcode{"UTC"} widened to \tcode{charT}. +If \tcode{\%z} is used (or a modified variant of \tcode{\%z}), +an offset of \tcode{0min} will be formatted. +The date and time formatted shall be equivalent to +that formatted by a \tcode{sys_time} initialized with +\tcode{clock_cast(tp)}, +or by a \tcode{utc_time} initialized with +\tcode{clock_cast(tp)}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{from_stream}{file_time}% +\begin{itemdecl} +template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + file_time& tp, basic_string* abbrev = nullptr, + minutes* offset = nullptr); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Attempts to parse the input stream \tcode{is} +into the \tcode{file_time} \tcode{tp} using +the format flags given in the NTCTS \tcode{fmt} +as specified in \ref{time.parse}. +If the parse fails to decode a valid date, +\tcode{is.setstate(ios_base::failbit)} shall be called +and \tcode{tp} shall not be modified. +If \tcode{\%Z} is used and successfully parsed, +that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. +If \tcode{\%z} (or a modified variant) is used and successfully parsed, +that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. +Additionally, the parsed offset will be subtracted from +the successfully parsed timestamp prior to assigning that difference to \tcode{tp}. + +\pnum +\returns \tcode{is}. +\end{itemdescr} + +\rSec2[time.clock.steady]{Class \tcode{steady_clock}} +\indexlibrary{\idxcode{steady_clock}}% + +\begin{codeblock} +namespace std::chrono { + class steady_clock { + public: + using rep = @\unspec@; + using period = ratio<@\unspecnc@, @\unspec{}@>; + using duration = chrono::duration; + using time_point = chrono::time_point<@\unspecnc@, duration>; + static constexpr bool is_steady = true; + + static time_point now() noexcept; + }; +} +\end{codeblock} + +\pnum +Objects of class \tcode{steady_clock} represent clocks for which values of \tcode{time_point} +never decrease as physical time advances and for which values of \tcode{time_point} advance at +a steady rate relative to real time. That is, the clock may not be adjusted. + +\rSec2[time.clock.hires]{Class \tcode{high_resolution_clock}} +\indexlibrary{\idxcode{high_resolution_clock}}% + +\begin{codeblock} +namespace std::chrono { + class high_resolution_clock { + public: + using rep = @\unspec@; + using period = ratio<@\unspecnc@, @\unspec{}@>; + using duration = chrono::duration; + using time_point = chrono::time_point<@\unspecnc@, duration>; + static constexpr bool is_steady = @\unspec@; + + static time_point now() noexcept; + }; +} +\end{codeblock} + +\pnum +Objects of class \tcode{high_resolution_clock} represent clocks with the +shortest tick period. \tcode{high_resolution_clock} may be a synonym for +\tcode{system_clock} or \tcode{steady_clock}. + +\rSec2[time.clock.local]{Local time} +\indexlibrary{\idxcode{local_time}}% + +\pnum +The family of time points +denoted by \tcode{local_time} +are based on the pseudo clock \tcode{local_t}. +\tcode{local_t} has no member \tcode{now()} +and thus does not meet the clock requirements. +Nevertheless \tcode{local_time} serves the vital role of +representing local time with respect to a not-yet-specified time zone. +Aside from being able to get the current time, +the complete \tcode{time_point} algebra is available +for \tcode{local_time} (just as for \tcode{sys_time}). + +\indexlibrarymember{operator<<}{local_time}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const local_time& lt); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +\begin{codeblock} +os << sys_time{lt.time_since_epoch()}; +\end{codeblock} + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{to_stream}{local_time}% +\begin{itemdecl} +template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, const local_time& tp, + const string* abbrev = nullptr, const seconds* offset_sec = nullptr); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Streams \tcode{tp} into \tcode{os} using +the format specified by the NTCTS \tcode{fmt}. +\tcode{fmt} encoding follows the rules specified in \ref{time.format}. +If \tcode{\%Z} is used, +it will be replaced with \tcode{*abbrev} if \tcode{abbrev} is not equal to \tcode{nullptr}. +If \tcode{abbrev} is equal to \tcode{nullptr} (and \tcode{\%Z} is used), +\tcode{os.setstate(ios_base::failbit)} shall be called. +If \tcode{\%z} is used (or a modified variant of \tcode{\%z}), +it will be formatted with the value of \tcode{*offset_sec} +if \tcode{offset_sec} is not equal to \tcode{nullptr}. +If \tcode{\%z} (or a modified variant of \tcode{\%z}) is used, +and \tcode{offset_sec} is equal to \tcode{nullptr}, then +\tcode{os.setstate(ios_base::failbit)} shall be called. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{from_stream}{local_time}% +\begin{itemdecl} +template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + local_time& tp, basic_string* abbrev = nullptr, + minutes* offset = nullptr); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Attempts to parse the input stream \tcode{is} +into the \tcode{local_time} \tcode{tp} using +the format flags given in the NTCTS \tcode{fmt} +as specified in \ref{time.parse}. +If the parse fails to decode a valid date, +\tcode{is.setstate(ios_base::failbit)} shall be called +and \tcode{tp} shall not be modified. +If \tcode{\%Z} is used and successfully parsed, +that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. +If \tcode{\%z} (or a modified variant) is used and successfully parsed, +that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. + +\pnum +\returns \tcode{is}. +\end{itemdescr} + +\rSec2[time.clock.cast]{\tcode{time_point} conversions} + +\rSec3[time.clock.conv]{Class template \tcode{clock_time_conversion}} +\indexlibrary{\idxcode{clock_time_conversion}}% + +\begin{codeblock} +namespace std::chrono { + template + struct clock_time_conversion {}; +} +\end{codeblock} + +\pnum +\tcode{clock_time_conversion} serves as a trait +which can be used to specify how to convert +a source \tcode{time_point} of type +\tcode{time_point} +to a destination \tcode{time_point} of type +\tcode{time_point} +via a specialization: +\tcode{clock_time_conversion}. +A specialization of \tcode{clock_time_conversion} +shall provide a const-qualified \tcode{operator()} +that takes a parameter of type \tcode{time_point} +and returns a \tcode{time_point} +representing an equivalent point in time. +\tcode{OtherDuration} is a \tcode{chrono::duration} +whose specialization is computed from the input \tcode{Duration} +in a manner which can vary for each \tcode{clock_time_conversion} specialization. +A program may specialize \tcode{clock_time_conversion} +if at least one of the template parameters is a user-defined clock type. + +\pnum +Several specializations are provided by the implementation, +as described in +\ref{time.clock.cast.id}, +\ref{time.clock.cast.sys.utc}, +\ref{time.clock.cast.sys}, and +\ref{time.clock.cast.utc}. + +\rSec3[time.clock.cast.id]{Identity conversions} + +\begin{codeblock} +template +struct clock_time_conversion { + template + time_point + operator()(const time_point& t) const; +}; +\end{codeblock} + +\indexlibrarymember{operator()}{clock_time_conversion}% +\begin{itemdecl} +template + time_point + operator()(const time_point& t) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{t}. +\end{itemdescr} + +\begin{codeblock} +template<> +struct clock_time_conversion { + template + sys_time + operator()(const sys_time& t) const; +}; +\end{codeblock} + +\indexlibrarymember{operator()}{clock_time_conversion}% +\begin{itemdecl} +template + sys_time + operator()(const sys_time& t) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{t}. +\end{itemdescr} + +\begin{codeblock} +template<> +struct clock_time_conversion { + template + utc_time + operator()(const utc_time& t) const; +}; +\end{codeblock} + +\indexlibrarymember{operator()}{clock_time_conversion}% +\begin{itemdecl} +template + utc_time + operator()(const utc_time& t) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{t}. +\end{itemdescr} + +\rSec3[time.clock.cast.sys.utc]{Conversions between \tcode{system_clock} and \tcode{utc_clock}} + +\begin{codeblock} +template<> +struct clock_time_conversion { + template + utc_time> + operator()(const sys_time& t) const; +}; +\end{codeblock} + +\indexlibrarymember{operator()}{clock_time_conversion}% +\begin{itemdecl} +template + utc_time> + operator()(const sys_time& t) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{utc_clock::from_sys(t)}. +\end{itemdescr} + +\begin{codeblock} +template<> +struct clock_time_conversion { + template + sys_time> + operator()(const utc_time& t) const; +}; +\end{codeblock} + +\indexlibrarymember{operator()}{clock_time_conversion}% +\begin{itemdecl} +template + sys_time> + operator()(const utc_time& t) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{utc_clock::to_sys(t)}. +\end{itemdescr} + +\rSec3[time.clock.cast.sys]{Conversions between \tcode{system_clock} and other clocks} + +\begin{codeblock} +template +struct clock_time_conversion { + template + auto operator()(const time_point& t) const + -> decltype(SourceClock::to_sys(t)); +}; +\end{codeblock} + +\indexlibrarymember{operator()}{clock_time_conversion}% +\begin{itemdecl} +template + auto operator()(const time_point& t) const + -> decltype(SourceClock::to_sys(t)); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +This function does not participate in overload resolution unless +\tcode{SourceClock::to_sys(t)} is well-formed. +If \tcode{SourceClock::to_sys(t)} +does not return \tcode{sys_time}, +where \tcode{Duration} is a valid \tcode{chrono::duration} specialization, +the program is ill-formed. + +\pnum +\returns \tcode{SourceClock::to_sys(t)}. +\end{itemdescr} + +\begin{codeblock} +template +struct clock_time_conversion { + template + auto operator()(const sys_time& t) const + -> decltype(DestClock::from_sys(t)); +}; +\end{codeblock} + +\indexlibrarymember{operator()}{clock_time_conversion}% +\begin{itemdecl} +template + auto operator()(const sys_time& t) const + -> decltype(DestClock::from_sys(t)); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +This function does not participate in overload resolution unless +\tcode{DestClock::from_sys(t)} is well-formed. +If \tcode{DestClock::from_sys(t)} does not return +\tcode{time_point}, +where \tcode{Duration} is a valid \tcode{chrono::duration} specialization, +the program is ill-formed. + +\pnum +\returns \tcode{DestClock::from_sys(t)}. +\end{itemdescr} + +\rSec3[time.clock.cast.utc]{Conversions between \tcode{utc_clock} and other clocks} + +\begin{codeblock} +template +struct clock_time_conversion { + template + auto operator()(const time_point& t) const + -> decltype(SourceClock::to_utc(t)); +}; +\end{codeblock} + +\indexlibrarymember{operator()}{clock_time_conversion}% +\begin{itemdecl} +template + auto operator()(const time_point& t) const + -> decltype(SourceClock::to_utc(t)); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +This function does not participate in overload resolution unless +\tcode{SourceClock::to_utc(t)} is well-formed. +If \tcode{SourceClock::to_utc(t)} does not return +\tcode{utc_time}, +where \tcode{Duration} is a valid \tcode{chrono::duration} specialization, +the program is ill-formed. + +\pnum +\returns \tcode{SourceClock::to_utc(t)}. +\end{itemdescr} + +\begin{codeblock} +template +struct clock_time_conversion { + template + auto operator()(const utc_time& t) const + -> decltype(DestClock::from_utc(t)); +}; +\end{codeblock} + +\indexlibrarymember{operator()}{clock_time_conversion}% +\begin{itemdecl} +template + auto operator()(const utc_time& t) const + -> decltype(DestClock::from_utc(t)); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +This function does not participate in overload resolution unless +\tcode{DestClock::from_utc(t)} is well-formed. +If \tcode{DestClock::from_utc(t)} does not return +\tcode{time_point}, +where \tcode{Duration} is a valid \tcode{chrono::duration} specialization, +the program is ill-formed. + +\pnum +\returns \tcode{DestClock::from_utc(t)}. +\end{itemdescr} + +\rSec3[time.clock.cast.fn]{Function template \tcode{clock_cast}} + +\indexlibrary{\idxcode{clock_cast}}% +\begin{itemdecl} +template + auto clock_cast(const time_point& t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +This function does not participate in overload resolution unless +at least one of the following clock time conversion expressions +is well-formed: + +\begin{itemize} +\item +\begin{codeblock} +clock_time_conversion{}(t) +\end{codeblock} + +\item +\begin{codeblock} +clock_time_conversion{}( + clock_time_conversion{}(t)) +\end{codeblock} + +\item +\begin{codeblock} +clock_time_conversion{}( + clock_time_conversion{}(t)) +\end{codeblock} + +\item +\begin{codeblock} +clock_time_conversion{}( + clock_time_conversion{}( + clock_time_conversion{}(t))) +\end{codeblock} + +\item +\begin{codeblock} +clock_time_conversion{}( + clock_time_conversion{}( + clock_time_conversion{}(t))) +\end{codeblock} +\end{itemize} + +A clock time conversion expression is considered better than +another clock time conversion expression if it involves fewer +\tcode{operator()} calls on \tcode{clock_time_conversion} +specializations. +If, among the well-formed clock time conversion expressions +from the above list, there is not a unique best expression, +the \tcode{clock_cast} is ambiguous and the program is ill-formed. + +\pnum +\returns +The best well-formed clock time conversion expression in the above list. +\end{itemdescr} + +\rSec1[time.cal]{The civil calendar} + +\rSec2[time.cal.general]{In general} + +\pnum +The types in \ref{time.cal} describe the civil (Gregorian) calendar +and its relationship to \tcode{sys_days} and \tcode{local_days}. + +\rSec2[time.cal.last]{Class \tcode{last_spec}} +\indexlibrary{\idxcode{last_spec}}% + +\begin{codeblock} +namespace std::chrono { + struct last_spec { + explicit last_spec() = default; + }; +} +\end{codeblock} + +\pnum +The type \tcode{last_spec} is used +in conjunction with other calendar types +to specify the last in a sequence. +For example, depending on context, +it can represent the last day of a month, +or the last day of the week of a month. + +\rSec2[time.cal.day]{Class \tcode{day}} + +\rSec3[time.cal.day.overview]{Overview} +\indexlibrary{\idxcode{day}} + +\begin{codeblock} +namespace std::chrono { + class day { + unsigned char d_; // \expos + public: + day() = default; + explicit constexpr day(unsigned d) noexcept; + + constexpr day& operator++() noexcept; + constexpr day operator++(int) noexcept; + constexpr day& operator--() noexcept; + constexpr day operator--(int) noexcept; + + constexpr day& operator+=(const days& d) noexcept; + constexpr day& operator-=(const days& d) noexcept; + + explicit constexpr operator unsigned() const noexcept; + constexpr bool ok() const noexcept; + }; +} +\end{codeblock} + +\pnum +\tcode{day} represents a day of a month. +It normally holds values in the range 1 to 31, +but may hold non-negative values outside this range. +It can be constructed with any \tcode{unsigned} value, +which will be subsequently truncated to fit into \tcode{day}'s unspecified internal storage. +\tcode{day} is \oldconcept{EqualityComparable} (Table~\ref{tab:equalitycomparable}) +and \oldconcept{LessThanComparable} (Table~\ref{tab:lessthancomparable}), +and participates in basic arithmetic with \tcode{days} objects, +which represent a difference between two \tcode{day} objects. + +\pnum +\tcode{day} is a trivially copyable and standard-layout class type. + +\rSec3[time.cal.day.members]{Member functions} + +\indexlibrary{\idxcode{day}!constructor}% +\begin{itemdecl} +explicit constexpr day(unsigned d) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{day} by +initializing \tcode{d_} with \tcode{d}. +The value held is unspecified if \tcode{d} is not in the range \crange{0}{255}. +\end{itemdescr} + +\indexlibrarymember{operator++}{day}% +\begin{itemdecl} +constexpr day& operator++() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{++d_}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator++}{day}% +\begin{itemdecl} +constexpr day operator++(int) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{++(*this)}. + +\pnum +\returns A copy of \tcode{*this} as it existed on entry to this member function. +\end{itemdescr} + +\indexlibrarymember{operator--}{day}% +\begin{itemdecl} +constexpr day& operator--() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{--d_}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator--}{day}% +\begin{itemdecl} +constexpr day operator--(int) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{--(*this)}. + +\pnum +\returns A copy of \tcode{*this} as it existed on entry to this member function. +\end{itemdescr} + +\indexlibrarymember{operator+=}{day}% +\begin{itemdecl} +constexpr day& operator+=(const days& d) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this + d}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator-=}{day}% +\begin{itemdecl} +constexpr day& operator-=(const days& d) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this - d}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator unsigned}{day}% +\begin{itemdecl} +explicit constexpr operator unsigned() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{d_}. +\end{itemdescr} + +\indexlibrarymember{ok}{day}% +\begin{itemdecl} +constexpr bool ok() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{1 <= d_ \&\& d_ <= 31}. +\end{itemdescr} + +\rSec3[time.cal.day.nonmembers]{Non-member functions} + +\indexlibrarymember{operator==}{day}% +\begin{itemdecl} +constexpr bool operator==(const day& x, const day& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{unsigned\{x\} == unsigned\{y\}}. +\end{itemdescr} + +\indexlibrarymember{operator<}{day}% +\begin{itemdecl} +constexpr bool operator<(const day& x, const day& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{unsigned\{x\} < unsigned\{y\}}. +\end{itemdescr} + +\indexlibrarymember{operator+}{day}% +\begin{itemdecl} +constexpr day operator+(const day& x, const days& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{day(unsigned\{x\} + y.count())}. +\end{itemdescr} + +\indexlibrarymember{operator+}{day}% +\begin{itemdecl} +constexpr day operator+(const days& x, const day& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y + x}. +\end{itemdescr} + +\indexlibrarymember{operator-}{day}% +\begin{itemdecl} +constexpr day operator-(const day& x, const days& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x + -y}. +\end{itemdescr} + +\indexlibrarymember{operator-}{day}% +\begin{itemdecl} +constexpr days operator-(const day& x, const day& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{days\{int(unsigned\{x\}) - int(unsigned\{y\})}. +\end{itemdescr} + +\indexlibrarymember{operator<<}{day}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const day& d); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Inserts \tcode{format(fmt, d)} +where \tcode{fmt} is \tcode{"\%d"} widened to \tcode{charT}. +If \tcode{!d.ok()}, appends with \tcode{" is not a valid day"}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{to_stream}{day}% +\begin{itemdecl} +template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, const day& d); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Streams \tcode{d} into \tcode{os} using +the format specified by the NTCTS \tcode{fmt}. +\tcode{fmt} encoding follows the rules specified in \ref{time.format}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{from_stream}{day}% +\begin{itemdecl} +template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + day& d, basic_string* abbrev = nullptr, + minutes* offset = nullptr); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Attempts to parse the input stream \tcode{is} +into the \tcode{day} \tcode{d} using +the format flags given in the NTCTS \tcode{fmt} +as specified in \ref{time.parse}. +If the parse fails to decode a valid day, +\tcode{is.setstate(ios_base::failbit)} shall be called +and \tcode{d} shall not be modified. +If \tcode{\%Z} is used and successfully parsed, +that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. +If \tcode{\%z} (or a modified variant) is used and successfully parsed, +that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. + +\pnum +\returns \tcode{is}. +\end{itemdescr} + +\indexlibrarymember{operator""""d}{day}% +\begin{itemdecl} +constexpr day operator""d(unsigned long long d) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{day\{static_cast(d)\}}. +\end{itemdescr} + +\rSec2[time.cal.month]{Class \tcode{month}} + +\rSec3[time.cal.month.overview]{Overview} +\indexlibrary{\idxcode{month}} + +\begin{codeblock} +namespace std::chrono { + class month { + unsigned char m_; // \expos + public: + month() = default; + explicit constexpr month(unsigned m) noexcept; + + constexpr month& operator++() noexcept; + constexpr month operator++(int) noexcept; + constexpr month& operator--() noexcept; + constexpr month operator--(int) noexcept; + + constexpr month& operator+=(const months& m) noexcept; + constexpr month& operator-=(const months& m) noexcept; + + explicit constexpr operator unsigned() const noexcept; + constexpr bool ok() const noexcept; + }; +} +\end{codeblock} + +\pnum +\tcode{month} represents a month of a year. +It normally holds values in the range 1 to 12, +but may hold non-negative values outside this range. +It can be constructed with any \tcode{unsigned} value, +which will be subsequently truncated to fit into \tcode{month}'s unspecified internal storage. +\tcode{month} is \oldconcept{EqualityComparable} (Table~\ref{tab:equalitycomparable}) +and \oldconcept{LessThanComparable} (Table~\ref{tab:lessthancomparable}), +and participates in basic arithmetic with \tcode{months} objects, +which represent a difference between two \tcode{month} objects. + +\pnum +\tcode{month} is a trivially copyable and standard-layout class type. + +\rSec3[time.cal.month.members]{Member functions} + +\indexlibrary{\idxcode{month}!constructor}% +\begin{itemdecl} +explicit constexpr month(unsigned m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{month} by +initializing \tcode{m_} with \tcode{m}. +The value held is unspecified if \tcode{m} is not in the range \crange{0}{255}. +\end{itemdescr} + +\indexlibrarymember{operator++}{month}% +\begin{itemdecl} +constexpr month& month::operator++() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this += months\{1\}}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator++}{month}% +\begin{itemdecl} +constexpr month operator++(int) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{++(*this)}. + +\pnum +\returns A copy of \tcode{*this} as it existed on entry to this member function. +\end{itemdescr} + +\indexlibrarymember{operator--}{month}% +\begin{itemdecl} +constexpr month& operator--() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this -= months\{1\}}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator--}{month}% +\begin{itemdecl} +constexpr month operator--(int) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{--(*this)}. + +\pnum +\returns A copy of \tcode{*this} as it existed on entry to this member function. +\end{itemdescr} + +\indexlibrarymember{operator+=}{month}% +\begin{itemdecl} +constexpr month& operator+=(const months& m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this + m}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator-=}{month}% +\begin{itemdecl} +constexpr month& operator-=(const months& m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this - m}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator unsigned}{month}% +\begin{itemdecl} +explicit constexpr month::operator unsigned() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{m_}. +\end{itemdescr} + +\indexlibrarymember{ok}{month}% +\begin{itemdecl} +constexpr bool month::ok() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{1 <= m_ \&\& m_ <= 12}. +\end{itemdescr} + +\rSec3[time.cal.month.nonmembers]{Non-member functions} + +\indexlibrarymember{operator==}{month}% +\begin{itemdecl} +constexpr bool operator==(const month& x, const month& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{unsigned\{x\} == unsigned\{y\}}. +\end{itemdescr} + +\indexlibrarymember{operator<}{month}% +\begin{itemdecl} +constexpr bool operator<(const month& x, const month& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{unsigned\{x\} < unsigned\{y\}}. +\end{itemdescr} + +\indexlibrarymember{operator+}{month}% +\begin{itemdecl} +constexpr month operator+(const month& x, const months& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +month{modulo(static_cast(unsigned{x}) + (y.count() - 1), 12) + 1} +\end{codeblock} +where \tcode{modulo(n, 12)} computes the remainder of \tcode{n} divided by 12 using Euclidean division. +\begin{note} +Given a divisor of 12, Euclidean division truncates towards negative infinity and +always produces a remainder in the range of \crange{0}{11}. +Assuming no overflow in the signed summation, +this operation results in a \tcode{month} holding a value in the range \crange{1}{12} even if \tcode{!x.ok()}. +\end{note} +\begin{example} +\tcode{February + months\{11\} == January}. +\end{example} +\end{itemdescr} + +\indexlibrarymember{operator+}{month}% +\begin{itemdecl} +constexpr month operator+(const months& x, const month& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y + x}. +\end{itemdescr} + +\indexlibrarymember{operator-}{month}% +\begin{itemdecl} +constexpr month operator-(const month& x, const months& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x + -y}. +\end{itemdescr} + +\indexlibrarymember{operator-}{month}% +\begin{itemdecl} +constexpr months operator-(const month& x, const month& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If \tcode{x.ok() == true} +and \tcode{y.ok() == true}, +returns a value \tcode{m} +in the range \crange{months\{0\}}{months\{11\}} +satisfying \tcode{y + m == x}. +Otherwise the value returned is unspecified. +\begin{example} +\tcode{January - February == months\{11\}}. +\end{example} +\end{itemdescr} + +\indexlibrarymember{operator<<}{month}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const month& m); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \tcode{m.ok() == true} +inserts \tcode{format(os.getloc(), fmt, m)} +where fmt is \tcode{"\%b"} widened to \tcode{charT}. +Otherwise inserts \tcode{unsigned\{m\} << " is not a valid month"}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{to_stream}{month}% +\begin{itemdecl} +template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, const month& m); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Streams \tcode{m} into \tcode{os} using +the format specified by the NTCTS \tcode{fmt}. +\tcode{fmt} encoding follows the rules specified in \ref{time.format}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{from_stream}{month}% +\begin{itemdecl} +template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + month& m, basic_string* abbrev = nullptr, + minutes* offset = nullptr); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Attempts to parse the input stream \tcode{is} +into the \tcode{month} \tcode{m} using +the format flags given in the NTCTS \tcode{fmt} +as specified in \ref{time.parse}. +If the parse fails to decode a valid month, +\tcode{is.setstate(ios_base::failbit)} shall be called +and \tcode{m} shall not be modified. +If \tcode{\%Z} is used and successfully parsed, +that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. +If \tcode{\%z} (or a modified variant) is used and successfully parsed, +that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. + +\pnum +\returns \tcode{is}. +\end{itemdescr} + +\rSec2[time.cal.year]{Class \tcode{year}} + +\rSec3[time.cal.year.overview]{Overview} +\indexlibrary{\idxcode{year}} + +\begin{codeblock} +namespace std::chrono { + class year { + short y_; // \expos + public: + year() = default; + explicit constexpr year(int y) noexcept; + + constexpr year& operator++() noexcept; + constexpr year operator++(int) noexcept; + constexpr year& operator--() noexcept; + constexpr year operator--(int) noexcept; + + constexpr year& operator+=(const years& y) noexcept; + constexpr year& operator-=(const years& y) noexcept; + + constexpr year operator+() const noexcept; + constexpr year operator-() const noexcept; + + constexpr bool is_leap() const noexcept; + + explicit constexpr operator int() const noexcept; + constexpr bool ok() const noexcept; + + static constexpr year min() noexcept; + static constexpr year max() noexcept; + }; +} +\end{codeblock} + +\pnum +\tcode{year} represents a year in the civil calendar. +It can represent values in the range \crange{min()}{max()}. +It can be constructed with any \tcode{int} value, +which will be subsequently truncated to fit into \tcode{year}'s unspecified internal storage. +\tcode{year} is \oldconcept{EqualityComparable} (Table~\ref{tab:equalitycomparable}) +and \oldconcept{LessThanComparable} (Table~\ref{tab:lessthancomparable}), +and participates in basic arithmetic with \tcode{years} objects, +which represent a difference between two \tcode{year} objects. + +\pnum +\tcode{year} is a trivially copyable and standard-layout class type. + +\rSec3[time.cal.year.members]{Member functions} + +\indexlibrary{\idxcode{year}!constructor}% +\begin{itemdecl} +explicit constexpr year(int y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{year} by +initializing \tcode{y_} with \tcode{y}. +The value held is unspecified if \tcode{y} is not in the range \crange{-32767}{32767}. +\end{itemdescr} + +\indexlibrarymember{operator++}{year}% +\begin{itemdecl} +constexpr year& operator++() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{++y_}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator++}{year}% +\begin{itemdecl} +constexpr year operator++(int) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{++(*this)}. + +\pnum +\returns A copy of \tcode{*this} as it existed on entry to this member function. +\end{itemdescr} + +\indexlibrarymember{operator--}{year}% +\begin{itemdecl} +constexpr year& operator--() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{--y_}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator--}{year}% +\begin{itemdecl} +constexpr year operator--(int) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{--(*this)}. + +\pnum +\returns A copy of \tcode{*this} as it existed on entry to this member function. +\end{itemdescr} + +\indexlibrarymember{operator+=}{year}% +\begin{itemdecl} +constexpr year& operator+=(const years& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this + y}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator-=}{year}% +\begin{itemdecl} +constexpr year& operator-=(const years& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this - y}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator+}{year}% +\begin{itemdecl} +constexpr year operator+() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator-}{year}% +\begin{itemdecl} +constexpr year year::operator-() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{year\{-y_\}}. +\end{itemdescr} + +\indexlibrarymember{is_leap}{year}% +\begin{itemdecl} +constexpr bool is_leap() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y_ \% 4 == 0 \&\& (y_ \% 100 != 0 || y_ \% 400 == 0)}. +\end{itemdescr} + +\indexlibrarymember{operator int}{year}% +\begin{itemdecl} +explicit constexpr operator int() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y_}. +\end{itemdescr} + +\indexlibrarymember{ok}{year}% +\begin{itemdecl} +constexpr bool ok() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{min() <= y_ \&\& y_ <= max()}. +\end{itemdescr} + +\indexlibrarymember{min}{year}% +\begin{itemdecl} +static constexpr year min() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{year\{-32767\}}. +\end{itemdescr} + +\indexlibrarymember{max}{year}% +\begin{itemdecl} +static constexpr year max() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{year\{32767\}}. +\end{itemdescr} + +\rSec3[time.cal.year.nonmembers]{Non-member functions} + +\indexlibrarymember{operator==}{year}% +\begin{itemdecl} +constexpr bool operator==(const year& x, const year& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{int\{x\} == int\{y\}}. +\end{itemdescr} + +\indexlibrarymember{operator<}{year}% +\begin{itemdecl} +constexpr bool operator<(const year& x, const year& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{int\{x\} < int\{y\}}. +\end{itemdescr} + +\indexlibrarymember{operator+}{year}% +\begin{itemdecl} +constexpr year operator+(const year& x, const years& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{year\{int\{x\} + y.count()\}}. +\end{itemdescr} + +\indexlibrarymember{operator+}{year}% +\begin{itemdecl} +constexpr year operator+(const years& x, const year& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y + x}. +\end{itemdescr} + +\indexlibrarymember{operator-}{year}% +\begin{itemdecl} +constexpr year operator-(const year& x, const years& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x + -y}. +\end{itemdescr} + +\indexlibrarymember{operator-}{year}% +\begin{itemdecl} +constexpr years operator-(const year& x, const year& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{years\{int\{x\} - int\{y\}\}}. +\end{itemdescr} + +\indexlibrarymember{operator<<}{year}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const year& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Inserts \tcode{format(fmt, y)} where \tcode{fmt} is +\tcode{"\%Y"} widened to \tcode{charT}. +If \tcode{!y.ok()}, appends with \tcode{" is not a valid year"}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{to_stream}{year}% +\begin{itemdecl} +template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, const year& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Streams \tcode{y} into \tcode{os} using +the format specified by the NTCTS \tcode{fmt}. +\tcode{fmt} encoding follows the rules specified in \ref{time.format}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{from_stream}{year}% +\begin{itemdecl} +template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + year& y, basic_string* abbrev = nullptr, + minutes* offset = nullptr); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Attempts to parse the input stream \tcode{is} +into the \tcode{year} \tcode{y} using +the format flags given in the NTCTS \tcode{fmt} +as specified in \ref{time.parse}. +If the parse fails to decode a valid year, +\tcode{is.setstate(ios_base::failbit)} shall be called +and \tcode{y} shall not be modified. +If \tcode{\%Z} is used and successfully parsed, +that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. +If \tcode{\%z} (or a modified variant) is used and successfully parsed, +that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. + +\pnum +\returns \tcode{is}. +\end{itemdescr} + +\indexlibrarymember{operator""""y}{year}% +\begin{itemdecl} +constexpr year operator""y(unsigned long long y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{year\{static_cast(y)\}}. +\end{itemdescr} + +\rSec2[time.cal.wd]{Class \tcode{weekday}} + +\rSec3[time.cal.wd.overview]{Overview} +\indexlibrary{\idxcode{weekday}} + +\begin{codeblock} +namespace std::chrono { + class weekday { + unsigned char wd_; // \expos + public: + weekday() = default; + explicit constexpr weekday(unsigned wd) noexcept; + constexpr weekday(const sys_days& dp) noexcept; + explicit constexpr weekday(const local_days& dp) noexcept; + + constexpr weekday& operator++() noexcept; + constexpr weekday operator++(int) noexcept; + constexpr weekday& operator--() noexcept; + constexpr weekday operator--(int) noexcept; + + constexpr weekday& operator+=(const days& d) noexcept; + constexpr weekday& operator-=(const days& d) noexcept; + + explicit constexpr operator unsigned() const noexcept; + constexpr bool ok() const noexcept; + + constexpr weekday_indexed operator[](unsigned index) const noexcept; + constexpr weekday_last operator[](last_spec) const noexcept; + }; +} +\end{codeblock} + +\pnum +\tcode{weekday} represents a day of the week in the civil calendar. +It normally holds values in the range \tcode{0} to \tcode{6}, +corresponding to Sunday through Saturday, but +it may hold non-negative values outside this range. +It can be constructed with any \tcode{unsigned} value, +which will be subsequently truncated to fit into \tcode{weekday}'s unspecified internal storage. +\tcode{weekday} is \oldconcept{EqualityComparable} (Table~\ref{tab:equalitycomparable}). +\begin{note} +\tcode{weekday} is not +\oldconcept{LessThanComparable} +because there is no universal consensus on which day is the first day of the week. +\tcode{weekday}'s arithmetic operations treat the days of the week as a circular range, +with no beginning and no end. +\end{note} + +\pnum +\tcode{weekday} is a trivially copyable and standard-layout class type. + +\rSec3[time.cal.wd.members]{Member functions} + +\indexlibrary{\idxcode{weekday}!constructor}% +\begin{itemdecl} +explicit constexpr weekday(unsigned wd) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{weekday} by +initializing \tcode{wd_} with \tcode{wd}. +The value held is unspecified if \tcode{wd} is not in the range \crange{0}{255}. +\end{itemdescr} + +\indexlibrary{\idxcode{weekday}!constructor}% +\begin{itemdecl} +constexpr weekday(const sys_days& dp) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{weekday} by +computing what day of the week corresponds to the \tcode{sys_days} \tcode{dp}, +and representing that day of the week in \tcode{wd_}. + +\pnum +\begin{example} +If \tcode{dp} represents 1970-01-01, +the constructed \tcode{weekday} represents Thursday +by storing \tcode{4} in \tcode{wd_}. +\end{example} +\end{itemdescr} + +\indexlibrary{\idxcode{weekday}!constructor}% +\begin{itemdecl} +explicit constexpr weekday(const local_days& dp) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{weekday} by +computing what day of the week corresponds to the \tcode{local_days} \tcode{dp}, +and representing that day of the week in \tcode{wd_}. + +\pnum +\remarks +The value after construction is identical to that constructed from +\tcode{sys_days\{dp.time_since_epoch()\}}. +\end{itemdescr} + +\indexlibrarymember{operator++}{weekday}% +\begin{itemdecl} +constexpr weekday& operator++() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this += days\{1\}}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator++}{weekday}% +\begin{itemdecl} +constexpr weekday operator++(int) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{++(*this)}. + +\pnum +\returns A copy of \tcode{*this} as it existed on entry to this member function. +\end{itemdescr} + +\indexlibrarymember{operator--}{weekday}% +\begin{itemdecl} +constexpr weekday& operator--() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this -= days\{1\}}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator--}{weekday}% +\begin{itemdecl} +constexpr weekday operator--(int) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{--(*this)}. + +\pnum +\returns A copy of \tcode{*this} as it existed on entry to this member function. +\end{itemdescr} + +\indexlibrarymember{operator+=}{weekday}% +\begin{itemdecl} +constexpr weekday& operator+=(const days& d) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this + d}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator-=}{weekday}% +\begin{itemdecl} +constexpr weekday& operator-=(const days& d) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this - d}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator unsigned}{weekday}% +\begin{itemdecl} +explicit constexpr operator unsigned() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{wd_}. +\end{itemdescr} + +\indexlibrarymember{ok}{weekday}% +\begin{itemdecl} +constexpr bool ok() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{wd_ <= 6}. +\end{itemdescr} + +\indexlibrarymember{operator[]}{weekday}% +\begin{itemdecl} +constexpr weekday_indexed operator[](unsigned index) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{\{*this, index\}}. +\end{itemdescr} + +\indexlibrarymember{operator[]}{weekday}% +\begin{itemdecl} +constexpr weekday_last operator[](last_spec) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{weekday_last\{*this\}}. +\end{itemdescr} + +\rSec3[time.cal.wd.nonmembers]{Non-member functions} + +\indexlibrarymember{operator==}{weekday}% +\begin{itemdecl} +constexpr bool operator==(const weekday& x, const weekday& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{unsigned\{x\} == unsigned\{y\}}. +\end{itemdescr} + +\indexlibrarymember{operator+}{weekday}% +\begin{itemdecl} +constexpr weekday operator+(const weekday& x, const days& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +weekday{modulo(static_cast(unsigned{x}) + y.count(), 7)} +\end{codeblock} +where \tcode{modulo(n, 7)} computes the remainder of \tcode{n} divided by 7 using Euclidean division. +\begin{note} +Given a divisor of 7, Euclidean division truncates towards negative infinity and +always produces a remainder in the range of \crange{0}{6}. +Assuming no overflow in the signed summation, +this operation results in a \tcode{weekday} holding a value in the range \crange{0}{6} even if \tcode{!x.ok()}. +\end{note} +\begin{example} +\tcode{Monday + days\{6\} == Sunday}. +\end{example} +\end{itemdescr} + +\indexlibrarymember{operator+}{weekday}% +\begin{itemdecl} +constexpr weekday operator+(const days& x, const weekday& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y + x}. +\end{itemdescr} + +\indexlibrarymember{operator-}{weekday}% +\begin{itemdecl} +constexpr weekday operator-(const weekday& x, const days& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x + -y}. +\end{itemdescr} + +\indexlibrarymember{operator-}{weekday}% +\begin{itemdecl} +constexpr days operator-(const weekday& x, const weekday& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If \tcode{x.ok() == true} +and \tcode{y.ok() == true}, +returns a value \tcode{d} +in the range \crange{days\{0\}}{days\{6\}} +satisfying \tcode{y + d == x}. +Otherwise the value returned is unspecified. +\begin{example} +\tcode{Sunday - Monday == days\{6\}}. +\end{example} +\end{itemdescr} + +\indexlibrarymember{operator<<}{weekday}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const weekday& wd); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \tcode{wd.ok() == true} +inserts \tcode{format(os.getloc(), fmt, wd)} +where \tcode{fmt} is \tcode{"\%a"} widened to \tcode{charT}. +Otherwise inserts \tcode{unsigned\{wd\} << " is not a valid weekday"}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{to_stream}{weekday}% +\begin{itemdecl} +template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, const weekday& wd); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Streams \tcode{wd} into \tcode{os} using +the format specified by the NTCTS \tcode{fmt}. +\tcode{fmt} encoding follows the rules specified in \ref{time.format}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{from_stream}{weekday}% +\begin{itemdecl} +template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + weekday& wd, basic_string* abbrev = nullptr, + minutes* offset = nullptr); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Attempts to parse the input stream \tcode{is} +into the \tcode{weekday} \tcode{wd} using +the format flags given in the NTCTS \tcode{fmt} +as specified in \ref{time.parse}. +If the parse fails to decode a valid weekday, +\tcode{is.setstate(ios_base::failbit)} shall be called +and \tcode{wd} shall not be modified. +If \tcode{\%Z} is used and successfully parsed, +that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. +If \tcode{\%z} (or a modified variant) is used and successfully parsed, +that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. + +\pnum +\returns \tcode{is}. +\end{itemdescr} + +\rSec2[time.cal.wdidx]{Class \tcode{weekday_indexed}} + +\rSec3[time.cal.wdidx.overview]{Overview} +\indexlibrary{\idxcode{weekday_indexed}} + +\begin{codeblock} +namespace std::chrono { + class weekday_indexed { + chrono::weekday wd_; // \expos + unsigned char index_; // \expos + + public: + weekday_indexed() = default; + constexpr weekday_indexed(const chrono::weekday& wd, unsigned index) noexcept; + + constexpr chrono::weekday weekday() const noexcept; + constexpr unsigned index() const noexcept; + constexpr bool ok() const noexcept; + }; +} +\end{codeblock} + +\pnum +\tcode{weekday_indexed} represents a \tcode{weekday} +and a small index in the range 1 to 5. +This class is used to represent the +first, second, third, fourth, or fifth weekday of a month. + +\pnum +\begin{note} +A \tcode{weekday_indexed} object +can be constructed by indexing a \tcode{weekday} +with an \tcode{unsigned}. +\end{note} +\begin{example} +\begin{codeblock} +constexpr auto wdi = Sunday[2]; // \tcode{wdi} is the second Sunday of an as yet unspecified month +static_assert(wdi.weekday() == Sunday); +static_assert(wdi.index() == 2); +\end{codeblock} +\end{example} + +\pnum +\tcode{weekday_indexed} is a trivially copyable and standard-layout class type. + +\rSec3[time.cal.wdidx.members]{Member functions} + +\indexlibrary{\idxcode{weekday_indexed}!constructor}% +\begin{itemdecl} +constexpr weekday_indexed(const chrono::weekday& wd, unsigned index) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{weekday_indexed} by +initializing \tcode{wd_} with \tcode{wd} and \tcode{index_} with \tcode{index}. +The values held are unspecified if \tcode{!wd.ok()} or \tcode{index} is not in the range \crange{1}{5}. +\end{itemdescr} + +\indexlibrarymember{weekday}{weekday_indexed}% +\begin{itemdecl} +constexpr chrono::weekday weekday() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{wd_}. +\end{itemdescr} + +\indexlibrarymember{index}{weekday_indexed}% +\begin{itemdecl} +constexpr unsigned index() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{index_}. +\end{itemdescr} + +\indexlibrarymember{ok}{weekday_indexed}% +\begin{itemdecl} +constexpr bool ok() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{wd_.ok() \&\& 1 <= index_ \&\& index_ <= 5}. +\end{itemdescr} + +\rSec3[time.cal.wdidx.nonmembers]{Non-member functions} + +\indexlibrarymember{operator==}{weekday_indexed}% +\begin{itemdecl} +constexpr bool operator==(const weekday_indexed& x, const weekday_indexed& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x.weekday() == y.weekday() \&\& x.index() == y.index()}. +\end{itemdescr} + +\indexlibrarymember{operator<<}{weekday_indexed}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const weekday_indexed& wdi); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +\tcode{os << wdi.weekday() << '[' << wdi.index()}. +If \tcode{wdi.index()} is in the range \crange{1}{5}, +appends with \tcode{']'}, +otherwise +appends with \tcode{" is not a valid index]"}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\rSec2[time.cal.wdlast]{Class \tcode{weekday_last}} + +\rSec3[time.cal.wdlast.overview]{Overview} +\indexlibrary{\idxcode{weekday_last}} + +\begin{codeblock} +namespace std::chrono { + class weekday_last { + chrono::weekday wd_; // \expos + + public: + explicit constexpr weekday_last(const chrono::weekday& wd) noexcept; + + constexpr chrono::weekday weekday() const noexcept; + constexpr bool ok() const noexcept; + }; +} +\end{codeblock} + +\pnum +\tcode{weekday_last} represents the last weekday of a month. + +\pnum +\begin{note} +A \tcode{weekday_last} object +can be constructed by indexing a \tcode{weekday} with \tcode{last}. +\end{note} +\begin{example} +\begin{codeblock} +constexpr auto wdl = Sunday[last]; // \tcode{wdl} is the last Sunday of an as yet unspecified month +static_assert(wdl.weekday() == Sunday); +\end{codeblock} +\end{example} + +\pnum +\tcode{weekday_last} is a trivially copyable and standard-layout class type. + +\rSec3[time.cal.wdlast.members]{Member functions} + +\indexlibrary{\idxcode{weekday_last}!constructor}% +\begin{itemdecl} +explicit constexpr weekday_last(const chrono::weekday& wd) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{weekday_last} by +initializing \tcode{wd_} with \tcode{wd}. +\end{itemdescr} + +\indexlibrarymember{weekday_last}{weekday}% +\begin{itemdecl} +constexpr chrono::weekday weekday() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{wd_}. +\end{itemdescr} + +\indexlibrarymember{ok}{weekday_last}% +\begin{itemdecl} +constexpr bool ok() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{wd_.ok()}. +\end{itemdescr} + +\rSec3[time.cal.wdlast.nonmembers]{Non-member functions} + +\indexlibrarymember{operator==}{weekday_last}% +\begin{itemdecl} +constexpr bool operator==(const weekday_last& x, const weekday_last& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x.weekday() == y.weekday()}. +\end{itemdescr} + +\indexlibrarymember{operator<<}{weekday_last}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const weekday_last& wdl); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{os << wdl.weekday() << "[last]"}. +\end{itemdescr} + +\rSec2[time.cal.md]{Class \tcode{month_day}} + +\rSec3[time.cal.md.overview]{Overview} +\indexlibrary{\idxcode{month_day}} + +\begin{codeblock} +namespace std::chrono { + class month_day { + chrono::month m_; // \expos + chrono::day d_; // \expos + + public: + month_day() = default; + constexpr month_day(const chrono::month& m, const chrono::day& d) noexcept; + + constexpr chrono::month month() const noexcept; + constexpr chrono::day day() const noexcept; + constexpr bool ok() const noexcept; + }; +} +\end{codeblock} + +\pnum +\tcode{month_day} represents a specific day of a specific month, +but with an unspecified year. +\tcode{month_day} is \oldconcept{EqualityComparable} (Table~\ref{tab:equalitycomparable}) +and \oldconcept{LessThanComparable} (Table~\ref{tab:lessthancomparable}). + +\pnum +\tcode{month_day} is a trivially copyable and standard-layout class type. + +\rSec3[time.cal.md.members]{Member functions} + +\indexlibrary{\idxcode{month_day}!constructor}% +\begin{itemdecl} +constexpr month_day(const chrono::month& m, const chrono::day& d) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{month_day} by +initializing \tcode{m_} with \tcode{m}, and \tcode{d_} with \tcode{d}. +\end{itemdescr} + +\indexlibrarymember{month}{month_day}% +\begin{itemdecl} +constexpr chrono::month month() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{m_}. +\end{itemdescr} + +\indexlibrarymember{day}{month_day}% +\begin{itemdecl} +constexpr chrono::day day() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{d_}. +\end{itemdescr} + +\indexlibrarymember{ok}{month_day}% +\begin{itemdecl} +constexpr bool ok() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\tcode{true} if +\tcode{m_.ok()} is \tcode{true}, +\tcode{1d <= d_}, and +\tcode{d_} is less than or equal to the number of days in month \tcode{m_}; +otherwise returns \tcode{false}. +When \tcode{m_ == February}, +the number of days is considered to be 29. +\end{itemdescr} + +\rSec3[time.cal.md.nonmembers]{Non-member functions} + +\indexlibrarymember{operator==}{month_day}% +\begin{itemdecl} +constexpr bool operator==(const month_day& x, const month_day& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x.month() == y.month() \&\& x.day() == y.day()}. +\end{itemdescr} + +\indexlibrarymember{operator<}{month_day}% +\begin{itemdecl} +constexpr bool operator<(const month_day& x, const month_day& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If \tcode{x.month() < y.month()} returns \tcode{true}. +Otherwise, if \tcode{x.month() > y.month()} returns \tcode{false}. +Otherwise, returns \tcode{x.day() < y.day()}. +\end{itemdescr} + +\indexlibrarymember{operator<<}{month_day}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const month_day& md); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{os << md.month() << '/' << md.day()}. +\end{itemdescr} + +\indexlibrarymember{to_stream}{month_day}% +\begin{itemdecl} +template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, const month_day& md); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Streams \tcode{md} into \tcode{os} using +the format specified by the NTCTS \tcode{fmt}. +\tcode{fmt} encoding follows the rules specified in \ref{time.format}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{from_stream}{month_day}% +\begin{itemdecl} +template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + month_day& md, basic_string* abbrev = nullptr, + minutes* offset = nullptr); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Attempts to parse the input stream \tcode{is} +into the \tcode{month_day} \tcode{md} using +the format flags given in the NTCTS \tcode{fmt} +as specified in \ref{time.parse}. +If the parse fails to decode a valid \tcode{month_day}, +\tcode{is.setstate(ios_base::failbit)} shall be called +and \tcode{md} shall not be modified. +If \tcode{\%Z} is used and successfully parsed, +that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. +If \tcode{\%z} (or a modified variant) is used and successfully parsed, +that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. + +\pnum +\returns \tcode{is}. +\end{itemdescr} + +\rSec2[time.cal.mdlast]{Class \tcode{month_day_last}} +\indexlibrary{\idxcode{month_day_last}} + +\begin{codeblock} +namespace std::chrono { + class month_day_last { + chrono::month m_; // \expos + + public: + explicit constexpr month_day_last(const chrono::month& m) noexcept; + + constexpr chrono::month month() const noexcept; + constexpr bool ok() const noexcept; + }; +} +\end{codeblock} + +\pnum +\tcode{month_day_last} represents the last day of a month. + +\pnum +\begin{note} +A \tcode{month_day_last} object +can be constructed using the expression \tcode{m/last} or \tcode{last/m}, +where \tcode{m} is an expression of type \tcode{month}. +\end{note} +\begin{example} +\begin{codeblock} +constexpr auto mdl = February/last; // \tcode{mdl} is the last day of February of an as yet unspecified year +static_assert(mdl.month() == February); +\end{codeblock} +\end{example} + +\pnum +\tcode{month_day_last} is a trivially copyable and standard-layout class type. + +\indexlibrary{\idxcode{month_day_last}!constructor}% +\begin{itemdecl} +explicit constexpr month_day_last(const chrono::month& m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{month_day_last} by +initializing \tcode{m_} with \tcode{m}. +\end{itemdescr} + +\indexlibrarymember{month}{month_day_last}% +\begin{itemdecl} +constexpr month month() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{m_}. +\end{itemdescr} + +\indexlibrarymember{ok}{month_day_last}% +\begin{itemdecl} +constexpr bool ok() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{m_.ok()}. +\end{itemdescr} + +\indexlibrarymember{operator==}{month_day_last}% +\begin{itemdecl} +constexpr bool operator==(const month_day_last& x, const month_day_last& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x.month() == y.month()}. +\end{itemdescr} + +\indexlibrarymember{operator<}{month_day_last}% +\begin{itemdecl} +constexpr bool operator<(const month_day_last& x, const month_day_last& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x.month() < y.month()}. +\end{itemdescr} + +\indexlibrarymember{operator<<}{month_day_last}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const month_day_last& mdl); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{os << mdl.month() << "/last"}. +\end{itemdescr} + +\rSec2[time.cal.mwd]{Class \tcode{month_weekday}} + +\rSec3[time.cal.mwd.overview]{Overview} +\indexlibrary{\idxcode{month_weekday}} + +\begin{codeblock} +namespace std::chrono { + class month_weekday { + chrono::month m_; // \expos + chrono::weekday_indexed wdi_; // \expos + public: + constexpr month_weekday(const chrono::month& m, const chrono::weekday_indexed& wdi) noexcept; + + constexpr chrono::month month() const noexcept; + constexpr chrono::weekday_indexed weekday_indexed() const noexcept; + constexpr bool ok() const noexcept; + }; +} +\end{codeblock} + +\pnum +\tcode{month_weekday} represents the $n^\text{th}$ weekday of a month, +of an as yet unspecified year. +To do this the \tcode{month_weekday} stores a \tcode{month} and a \tcode{weekday_indexed}. + +\pnum +\begin{example} +\begin{codeblock} +constexpr auto mwd + = February/Tueday[3]; // \tcode{mwd} is the third Tuesday of February of an as yet unspecified year +static_assert(mwd.month() == February); +static_assert(mwd.weekday_indexed() == Tueday[3]); +\end{codeblock} +\end{example} + +\pnum +\tcode{month_weekday} is a trivially copyable and standard-layout class type. + +\rSec3[time.cal.mwd.members]{Member functions} + +\indexlibrary{\idxcode{month_weekday}!constructor}% +\begin{itemdecl} +constexpr month_weekday(const chrono::month& m, const chrono::weekday_indexed& wdi) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{month_weekday} by +initializing \tcode{m_} with \tcode{m}, and \tcode{wdi_} with \tcode{wdi}. +\end{itemdescr} + +\indexlibrarymember{month}{month_weekday}% +\begin{itemdecl} +constexpr chrono::month month() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{m_}. +\end{itemdescr} + +\indexlibrarymember{weekday_indexed}{month_weekday}% +\begin{itemdecl} +constexpr chrono::weekday_indexed weekday_indexed() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{wdi_}. +\end{itemdescr} + +\indexlibrarymember{ok}{month_weekday}% +\begin{itemdecl} +constexpr bool ok() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{m_.ok() \&\& wdi_.ok()}. +\end{itemdescr} + +\rSec3[time.cal.mwd.nonmembers]{Non-member functions} + +\indexlibrarymember{operator==}{month_weekday}% +\begin{itemdecl} +constexpr bool operator==(const month_weekday& x, const month_weekday& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x.month() == y.month() \&\& x.weekday_indexed() == y.weekday_indexed()}. +\end{itemdescr} + +\indexlibrarymember{operator<<}{month_weekday}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const month_weekday& mwd); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{os << mwd.month() << '/' << mwd.weekday_indexed()}. +\end{itemdescr} + +\rSec2[time.cal.mwdlast]{Class \tcode{month_weekday_last}} + +\rSec3[time.cal.mwdlast.overview]{Overview} +\indexlibrary{\idxcode{month_weekday_last}} + +\begin{codeblock} +namespace std::chrono { + class month_weekday_last { + chrono::month m_; // \expos + chrono::weekday_last wdl_; // \expos + public: + constexpr month_weekday_last(const chrono::month& m, + const chrono::weekday_last& wdl) noexcept; + + constexpr chrono::month month() const noexcept; + constexpr chrono::weekday_last weekday_last() const noexcept; + constexpr bool ok() const noexcept; + }; +} +\end{codeblock} + +\pnum +\tcode{month_weekday_last} represents the last weekday of a month, +of an as yet unspecified year. +To do this the \tcode{month_weekday_last} stores a \tcode{month} and a \tcode{weekday_last}. + +\pnum +\begin{example} +\begin{codeblock} +constexpr auto mwd + = February/Tueday[last]; // \tcode{mwd} is the last Tuesday of February of an as yet unspecified year +static_assert(mwd.month() == February); +static_assert(mwd.weekday_last() == Tueday[last]); +\end{codeblock} +\end{example} + +\pnum +\tcode{month_weekday_last} is a trivially copyable and standard-layout class type. + +\rSec3[time.cal.mwdlast.members]{Member functions} + +\indexlibrary{\idxcode{month_weekday_last}!constructor}% +\begin{itemdecl} +constexpr month_weekday_last(const chrono::month& m, + const chrono::weekday_last& wdl) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{month_weekday_last} by +initializing \tcode{m_} with \tcode{m}, and \tcode{wdl_} with \tcode{wdl}. +\end{itemdescr} + +\indexlibrarymember{month}{month_weekday_last}% +\begin{itemdecl} +constexpr chrono::month month() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{m_}. +\end{itemdescr} + +\indexlibrarymember{weekday_last}{month_weekday_last}% +\begin{itemdecl} +constexpr chrono::weekday_last weekday_last() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{wdl_}. +\end{itemdescr} + +\indexlibrarymember{ok}{month_weekday_last}% +\begin{itemdecl} +constexpr bool ok() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{m_.ok() \&\& wdl_.ok()}. +\end{itemdescr} + +\rSec3[time.cal.mwdlast.nonmembers]{Non-member functions} + +\indexlibrarymember{operator==}{month_weekday_last}% +\begin{itemdecl} +constexpr bool operator==(const month_weekday_last& x, const month_weekday_last& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x.month() == y.month() \&\& x.weekday_last() == y.weekday_last()}. +\end{itemdescr} + +\indexlibrarymember{operator<<}{month_weekday_last}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const month_weekday_last& mwdl); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{os << mwdl.month() << '/' << mwdl.weekday_last()}. +\end{itemdescr} + +\rSec2[time.cal.ym]{Class \tcode{year_month}} + +\rSec3[time.cal.ym.overview]{Overview} +\indexlibrary{\idxcode{year_month}} + +\begin{codeblock} +namespace std::chrono { + class year_month { + chrono::year y_; // \expos + chrono::month m_; // \expos + + public: + year_month() = default; + constexpr year_month(const chrono::year& y, const chrono::month& m) noexcept; + + constexpr chrono::year year() const noexcept; + constexpr chrono::month month() const noexcept; + + constexpr year_month& operator+=(const months& dm) noexcept; + constexpr year_month& operator-=(const months& dm) noexcept; + constexpr year_month& operator+=(const years& dy) noexcept; + constexpr year_month& operator-=(const years& dy) noexcept; + + constexpr bool ok() const noexcept; + }; +} +\end{codeblock} + +\pnum +\tcode{year_month} represents a specific month of a specific year, +but with an unspecified day. +\tcode{year_month} is a field-based time point with a resolution of \tcode{months}. +\tcode{year_month} is \oldconcept{EqualityComparable} (Table~\ref{tab:equalitycomparable}) +and \oldconcept{LessThanComparable} (Table~\ref{tab:lessthancomparable}). + +\pnum +\tcode{year_month} is a trivially copyable and standard-layout class type. + +\rSec3[time.cal.ym.members]{Member functions} + +\indexlibrary{\idxcode{year_month}!constructor}% +\begin{itemdecl} +constexpr year_month(const chrono::year& y, const chrono::month& m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{year_month} by +initializing \tcode{y_} with \tcode{y}, and \tcode{m_} with \tcode{m}. +\end{itemdescr} + +\indexlibrarymember{year}{year_month}% +\begin{itemdecl} +constexpr chrono::year year() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y_}. +\end{itemdescr} + +\indexlibrarymember{month}{year_month}% +\begin{itemdecl} +constexpr chrono::month month() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{m_}. +\end{itemdescr} + +\indexlibrarymember{operator+=}{year_month}% +\begin{itemdecl} +constexpr year_month& operator+=(const months& dm) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this + dm}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator-=}{year_month}% +\begin{itemdecl} +constexpr year_month& operator-=(const months& dm) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this - dm}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator+=}{year_month}% +\begin{itemdecl} +constexpr year_month& operator+=(const years& dy) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this + dy}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator-=}{year_month}% +\begin{itemdecl} +constexpr year_month& operator-=(const years& dy) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this - dy}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{ok}{year_month}% +\begin{itemdecl} +constexpr bool ok() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y_.ok() \&\& m_.ok()}. +\end{itemdescr} + +\rSec3[time.cal.ym.nonmembers]{Non-member functions} + +\indexlibrarymember{operator==}{year_month}% +\begin{itemdecl} +constexpr bool operator==(const year_month& x, const year_month& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x.year() == y.year() \&\& x.month() == y.month()}. +\end{itemdescr} + +\indexlibrarymember{operator<}{year_month}% +\begin{itemdecl} +constexpr bool operator<(const year_month& x, const year_month& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If \tcode{x.year() < y.year()} returns \tcode{true}. +Otherwise, if \tcode{x.year() > y.year()} returns \tcode{false}. +Otherwise, returns \tcode{x.month() < y.month()}. +\end{itemdescr} + +\indexlibrarymember{operator+}{year_month}% +\begin{itemdecl} +constexpr year_month operator+(const year_month& ym, const months& dm) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns A \tcode{year_month} value \tcode{z} such that \tcode{z - ym == dm}. + +\complexity +\bigoh{1} with respect to the value of \tcode{dm}. +\end{itemdescr} + +\indexlibrarymember{operator+}{year_month}% +\begin{itemdecl} +constexpr year_month operator+(const months& dm, const year_month& ym) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{ym + dm}. +\end{itemdescr} + +\indexlibrarymember{operator-}{year_month}% +\begin{itemdecl} +constexpr year_month operator-(const year_month& ym, const months& dm) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{ym + -dm}. +\end{itemdescr} + +\indexlibrarymember{operator-}{year_month}% +\begin{itemdecl} +constexpr months operator-(const year_month& x, const year_month& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +x.year() - y.year() + months{static_cast(unsigned{x.month()}) - + static_cast(unsigned{y.month()})} +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator+}{year_month}% +\begin{itemdecl} +constexpr year_month operator+(const year_month& ym, const years& dy) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{(ym.year() + dy) / ym.month()}. +\end{itemdescr} + +\indexlibrarymember{operator+}{year_month}% +\begin{itemdecl} +constexpr year_month operator+(const years& dy, const year_month& ym) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{ym + dy}. +\end{itemdescr} + +\indexlibrarymember{operator-}{year_month}% +\begin{itemdecl} +constexpr year_month operator-(const year_month& ym, const years& dy) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{ym + -dy}. +\end{itemdescr} + +\indexlibrarymember{operator<<}{year_month}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const year_month& ym); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{os << ym.year() << '/' << ym.month()}. +\end{itemdescr} + +\indexlibrarymember{to_stream}{year_month}% +\begin{itemdecl} +template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, const year_month& ym); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Streams \tcode{ym} into \tcode{os} using +the format specified by the NTCTS \tcode{fmt}. +\tcode{fmt} encoding follows the rules specified in \ref{time.format}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{from_stream}{year_month}% +\begin{itemdecl} +template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + year_month& ym, basic_string* abbrev = nullptr, + minutes* offset = nullptr); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Attempts to parse the input stream \tcode{is} +into the \tcode{year_month} \tcode{ym} using +the format flags given in the NTCTS \tcode{fmt} +as specified in \ref{time.parse}. +If the parse fails to decode a valid \tcode{year_month}, +\tcode{is.setstate(ios_base::failbit)} shall be called +and \tcode{ym} shall not be modified. +If \tcode{\%Z} is used and successfully parsed, +that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. +If \tcode{\%z} (or a modified variant) is used and successfully parsed, +that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. + +\pnum +\returns \tcode{is}. +\end{itemdescr} + +\rSec2[time.cal.ymd]{Class \tcode{year_month_day}} + +\rSec3[time.cal.ymd.overview]{Overview} +\indexlibrary{\idxcode{year_month_day}} + +\begin{codeblock} +namespace std::chrono { + class year_month_day { + chrono::year y_; // \expos + chrono::month m_; // \expos + chrono::day d_; // \expos + + public: + year_month_day() = default; + constexpr year_month_day(const chrono::year& y, const chrono::month& m, + const chrono::day& d) noexcept; + constexpr year_month_day(const year_month_day_last& ymdl) noexcept; + constexpr year_month_day(const sys_days& dp) noexcept; + explicit constexpr year_month_day(const local_days& dp) noexcept; + + constexpr year_month_day& operator+=(const months& m) noexcept; + constexpr year_month_day& operator-=(const months& m) noexcept; + constexpr year_month_day& operator+=(const years& y) noexcept; + constexpr year_month_day& operator-=(const years& y) noexcept; + + constexpr chrono::year year() const noexcept; + constexpr chrono::month month() const noexcept; + constexpr chrono::day day() const noexcept; + + constexpr operator sys_days() const noexcept; + explicit constexpr operator local_days() const noexcept; + constexpr bool ok() const noexcept; + }; +} +\end{codeblock} + +\pnum +\tcode{year_month_day} represents a specific year, month, and day. +\tcode{year_month_day} is a field-based time point with a resolution of \tcode{days}. +\begin{note} +\tcode{year_month_day} supports \tcode{years}- and \tcode{months}-oriented arithmetic, +but not \tcode{days}-oriented arithmetic. +For the latter, there is a conversion to \tcode{sys_days}, +which efficiently supports \tcode{days}-oriented arithmetic. +\end{note} +\tcode{year_month_day} is \oldconcept{EqualityComparable} (Table~\ref{tab:equalitycomparable}) +and \oldconcept{LessThanComparable} (Table~\ref{tab:lessthancomparable}), + +\pnum +\tcode{year_month_day} is a trivially copyable and standard-layout class type. + +\rSec3[time.cal.ymd.members]{Member functions} + +\indexlibrary{\idxcode{year_month_day}!constructor}% +\begin{itemdecl} +constexpr year_month_day(const chrono::year& y, const chrono::month& m, + const chrono::day& d) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{year_month_day} by +initializing +\tcode{y_} with \tcode{y}, +\tcode{m_} with \tcode{m}, and +\tcode{d_} with \tcode{d}. +\end{itemdescr} + +\indexlibrary{\idxcode{year_month_day}!constructor}% +\begin{itemdecl} +constexpr year_month_day(const year_month_day_last& ymdl) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{year_month_day} by +initializing +\tcode{y_} with \tcode{ymdl.year()}, +\tcode{m_} with \tcode{ymdl.month()}, and +\tcode{d_} with \tcode{ymdl.day()}. +\begin{note} +This conversion from \tcode{year_month_day_last} to \tcode{year_month_day} +may be more efficient than converting a \tcode{year_month_day_last} to a \tcode{sys_days}, +and then converting that \tcode{sys_days} to a \tcode{year_month_day}. +\end{note} +\end{itemdescr} + +\indexlibrary{\idxcode{year_month_day}!constructor}% +\begin{itemdecl} +constexpr year_month_day(const sys_days& dp) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{year_month_day} +that corresponds to the date represented by \tcode{dp}. + +\pnum +\remarks +For any value \tcode{ymd} of type \tcode{year_month_day} +for which \tcode{ymd.ok()} is \tcode{true}, +\tcode{ymd == year_month_day\{sys_days\{ymd\}\}} +is \tcode{true}. +\end{itemdescr} + +\indexlibrary{\idxcode{year_month_day}!constructor}% +\begin{itemdecl} +explicit constexpr year_month_day(const local_days& dp) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{year_month_day} +that corresponds to the date represented by \tcode{dp}. + +\pnum +\remarks +Equivalent to constructing with \tcode{sys_days\{dp.time_since_epoch()\}}. +\end{itemdescr} + +\indexlibrarymember{operator+=}{year_month_day}% +\begin{itemdecl} +constexpr year_month_day& operator+=(const months& m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this + m}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator-=}{year_month_day}% +\begin{itemdecl} +constexpr year_month_day& operator-=(const months& m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this - m}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator+=}{year_month_day}% +\begin{itemdecl} +constexpr year_month_day& year_month_day::operator+=(const years& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this + y}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator-=}{year_month_day}% +\begin{itemdecl} +constexpr year_month_day& year_month_day::operator-=(const years& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this - y}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{year}{year_month_day}% +\begin{itemdecl} +constexpr chrono::year year() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y_}. +\end{itemdescr} + +\indexlibrarymember{month}{year_month_day}% +\begin{itemdecl} +constexpr chrono::month month() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{m_}. +\end{itemdescr} + +\indexlibrarymember{day}{year_month_day}% +\begin{itemdecl} +constexpr chrono::day day() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{d_}. +\end{itemdescr} + +\indexlibrarymember{operator sys_days}{year_month_day}% +\begin{itemdecl} +constexpr operator sys_days() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If \tcode{ok()}, +returns a \tcode{sys_days} +holding a count of days from the \tcode{sys_days} epoch to \tcode{*this} +(a negative value if \tcode{*this} represents a date prior to the \tcode{sys_days} epoch). +Otherwise, if \tcode{y_.ok() \&\& m_.ok()} is \tcode{true}, +returns a \tcode{sys_days} +which is offset from \tcode{sys_days\{y_/m_/last\}} +by the number of days \tcode{d_} is offset from \tcode{sys_days\{y_/m_/last\}.day()}. +Otherwise the value returned is unspecified. + +\pnum +\remarks +A \tcode{sys_days} in the range \crange{days\{-12687428\}}{days\{11248737\}} +which is converted to a \tcode{year_month_day} +shall have the same value when converted back to a \tcode{sys_days}. + +\pnum +\begin{example} +\begin{codeblock} +static_assert(year_month_day{sys_days{2017y/January/0}} == 2016y/December/31); +static_assert(year_month_day{sys_days{2017y/January/31}} == 2017y/January/31); +static_assert(year_month_day{sys_days{2017y/January/32}} == 2017y/February/1); +\end{codeblock} +\end{example} +\end{itemdescr} + +\indexlibrarymember{operator local_days}{year_month_day}% +\begin{itemdecl} +explicit constexpr operator local_days() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{local_days\{sys_days\{*this\}.time_since_epoch()\}}. +\end{itemdescr} + +\indexlibrarymember{ok}{year_month_day}% +\begin{itemdecl} +constexpr bool ok() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If \tcode{y_.ok()} is \tcode{true}, +and \tcode{m_.ok()} is \tcode{true}, +and \tcode{d_} is in the range \crange{1d}{(y_/m_/last).day()}, +then returns \tcode{true}; otherwise returns \tcode{false}. +\end{itemdescr} + +\rSec3[time.cal.ymd.nonmembers]{Non-member functions} + +\indexlibrarymember{operator==}{year_month_day}% +\begin{itemdecl} +constexpr bool operator==(const year_month_day& x, const year_month_day& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x.year() == y.year() \&\& x.month() == y.month() \&\& x.day() == y.day()}. +\end{itemdescr} + +\indexlibrarymember{operator<}{year_month_day}% +\begin{itemdecl} +constexpr bool operator<(const year_month_day& x, const year_month_day& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If \tcode{x.year() < y.year()}, returns \tcode{true}. +Otherwise, if \tcode{x.year() > y.year()}, returns \tcode{false}. +Otherwise, if \tcode{x.month() < y.month()}, returns \tcode{true}. +Otherwise, if \tcode{x.month() > y.month()}, returns \tcode{false}. +Otherwise, returns \tcode{x.day() < y.day()}. +\end{itemdescr} + +\indexlibrarymember{operator+}{year_month_day}% +\begin{itemdecl} +constexpr year_month_day operator+(const year_month_day& ymd, const months& dm) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{(ymd.year() / ymd.month() + dm) / ymd.day()}. + +\pnum +\begin{note} +If \tcode{ymd.day()} is in the range \crange{1d}{28d}, +\tcode{ok()} will return \tcode{true} for +the resultant \tcode{year_month_day}. +\end{note} +\end{itemdescr} + +\indexlibrarymember{operator+}{year_month_day}% +\begin{itemdecl} +constexpr year_month_day operator+(const months& dm, const year_month_day& ymd) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{ymd + dm}. +\end{itemdescr} + +\indexlibrarymember{operator-}{year_month_day}% +\begin{itemdecl} +constexpr year_month_day operator-(const year_month_day& ymd, const months& dm) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{ymd + (-dm)}. +\end{itemdescr} + +\indexlibrarymember{operator+}{year_month_day}% +\begin{itemdecl} +constexpr year_month_day operator+(const year_month_day& ymd, const years& dy) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{(ymd.year() + dy) / ymd.month() / ymd.day()}. + +\pnum +\begin{note} +If \tcode{ymd.month()} is February +and \tcode{ymd.day()} is not in the range \crange{1d}{28d}, +\tcode{ok()} may return \tcode{false} for +the resultant \tcode{year_month_day}. +\end{note} +\end{itemdescr} + +\indexlibrarymember{operator+}{year_month_day}% +\begin{itemdecl} +constexpr year_month_day operator+(const years& dy, const year_month_day& ymd) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{ymd + dy}. +\end{itemdescr} + +\indexlibrarymember{operator-}{year_month_day}% +\begin{itemdecl} +constexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{ymd + (-dy)}. +\end{itemdescr} + +\indexlibrarymember{operator<<}{year_month_day}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const year_month_day& ymd); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Inserts \tcode{format(fmt, ymd)} +where \tcode{fmt} is \tcode{"\%F"} widened to \tcode{charT}. +If \tcode{!ymd.ok()}, appends with \tcode{" is not a valid date"}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{to_stream}{year_month_day}% +\begin{itemdecl} +template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, const year_month_day& ymd); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Streams \tcode{ymd} into \tcode{os} using +the format specified by the NTCTS \tcode{fmt}. +\tcode{fmt} encoding follows the rules specified in \ref{time.format}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{from_stream}{year_month_day}% +\begin{itemdecl} +template> + basic_istream& + from_stream(basic_istream& is, const charT* fmt, + year_month_day& ymd, basic_string* abbrev = nullptr, + minutes* offset = nullptr); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Attempts to parse the input stream \tcode{is} +into the \tcode{year_month_day} \tcode{ymd} using +the format flags given in the NTCTS \tcode{fmt} +as specified in \ref{time.parse}. +If the parse fails to decode a valid \tcode{year_month_day}, +\tcode{is.setstate(ios_base::failbit)} shall be called +and \tcode{ymd} shall not be modified. +If \tcode{\%Z} is used and successfully parsed, +that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. +If \tcode{\%z} (or a modified variant) is used and successfully parsed, +that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. + +\pnum +\returns \tcode{is}. +\end{itemdescr} + +\rSec2[time.cal.ymdlast]{Class \tcode{year_month_day_last}} + +\rSec3[time.cal.ymdlast.overview]{Overview} +\indexlibrary{\idxcode{year_month_day_last}} + +\begin{codeblock} +namespace std::chrono { + class year_month_day_last { + chrono::year y_; // \expos + chrono::month_day_last mdl_; // \expos + + public: + constexpr year_month_day_last(const chrono::year& y, + const chrono::month_day_last& mdl) noexcept; + + constexpr year_month_day_last& operator+=(const months& m) noexcept; + constexpr year_month_day_last& operator-=(const months& m) noexcept; + constexpr year_month_day_last& operator+=(const years& y) noexcept; + constexpr year_month_day_last& operator-=(const years& y) noexcept; + + constexpr chrono::year year() const noexcept; + constexpr chrono::month month() const noexcept; + constexpr chrono::month_day_last month_day_last() const noexcept; + constexpr chrono::day day() const noexcept; + + constexpr operator sys_days() const noexcept; + explicit constexpr operator local_days() const noexcept; + constexpr bool ok() const noexcept; + }; +} +\end{codeblock} + +\pnum +\tcode{year_month_day_last} represents the last day of a specific year and month. +\tcode{year_month_day_last} is a field-based time point with a resolution of \tcode{days}, +except that it is restricted to pointing to the last day of a year and month. +\begin{note} +\tcode{year_month_day_last} supports \tcode{years}- and \tcode{months}-oriented arithmetic, +but not \tcode{days}-oriented arithmetic. +For the latter, there is a conversion to \tcode{sys_days}, +which efficiently supports \tcode{days}-oriented arithmetic. +\end{note} +\tcode{year_month_day_last} is \oldconcept{EqualityComparable} (Table~\ref{tab:equalitycomparable}) +and \oldconcept{LessThanComparable} (Table~\ref{tab:lessthancomparable}), + +\pnum +\tcode{year_month_day_last} is a trivially copyable and standard-layout class type. + +\rSec3[time.cal.ymdlast.members]{Member functions} + +\indexlibrary{\idxcode{year_month_day_last}!constructor}% +\begin{itemdecl} +constexpr year_month_day_last(const chrono::year& y, + const chrono::month_day_last& mdl) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{year_month_day_last} by +initializing \tcode{y_} with \tcode{y} and \tcode{mdl_} with \tcode{mdl}. +\end{itemdescr} + +\indexlibrarymember{operator+=}{year_month_day_last}% +\begin{itemdecl} +constexpr year_month_day_last& operator+=(const months& m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this + m}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator-=}{year_month_day_last}% +\begin{itemdecl} +constexpr year_month_day_last& operator-=(const months& m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this - m}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator+=}{year_month_day_last}% +\begin{itemdecl} +constexpr year_month_day_last& operator+=(const years& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this + y}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator-=}{year_month_day_last}% +\begin{itemdecl} +constexpr year_month_day_last& operator-=(const years& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this - y}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{year}{year_month_day_last}% +\begin{itemdecl} +constexpr chrono::year year() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y_}. +\end{itemdescr} + +\indexlibrarymember{month}{year_month_day_last}% +\begin{itemdecl} +constexpr chrono::month month() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{mdl_.month()}. +\end{itemdescr} + +\indexlibrarymember{month_day_last}{year_month_day_last}% +\begin{itemdecl} +constexpr chrono::month_day_last month_day_last() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{mdl_}. +\end{itemdescr} + +\indexlibrarymember{day}{year_month_day_last}% +\begin{itemdecl} +constexpr chrono::day day() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{day} representing the last day of the (\tcode{year}, \tcode{month}) pair +represented by \tcode{*this}. + +\pnum +\begin{note} +This value may be computed on demand. +\end{note} +\end{itemdescr} + +\indexlibrarymember{operator sys_days}{year_month_day_last}% +\begin{itemdecl} +constexpr operator sys_days() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{sys_days\{year()/month()/day()\}}. +\end{itemdescr} + +\indexlibrarymember{operator local_days}{year_month_day_last}% +\begin{itemdecl} +explicit constexpr operator local_days() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{local_days\{sys_days\{*this\}.time_since_epoch()\}}. +\end{itemdescr} + +\indexlibrarymember{ok}{year_month_day_last}% +\begin{itemdecl} +constexpr bool ok() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y_.ok() \&\& mdl_.ok()}. +\end{itemdescr} + +\rSec3[time.cal.ymdlast.nonmembers]{Non-member functions} + +\indexlibrarymember{operator==}{year_month_day_last}% +\begin{itemdecl} +constexpr bool operator==(const year_month_day_last& x, const year_month_day_last& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x.year() == y.year() \&\& x.month_day_last() == y.month_day_last()}. +\end{itemdescr} + +\indexlibrarymember{operator<}{year_month_day_last}% +\begin{itemdecl} +constexpr bool operator<(const year_month_day_last& x, const year_month_day_last& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If \tcode{x.year() < y.year()}, returns \tcode{true}. +Otherwise, if \tcode{x.year() > y.year()}, returns \tcode{false}. +Otherwise, returns \tcode{x.month_day_last() < y.month_day_last()}. +\end{itemdescr} + +\indexlibrarymember{operator+}{year_month_day_last}% +\begin{itemdecl} +constexpr year_month_day_last + operator+(const year_month_day_last& ymdl, const months& dm) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{(ymdl.year() / ymdl.month() + dm) / last}. +\end{itemdescr} + +\indexlibrarymember{operator+}{year_month_day_last}% +\begin{itemdecl} +constexpr year_month_day_last + operator+(const months& dm, const year_month_day_last& ymdl) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{ymdl + dm}. +\end{itemdescr} + +\indexlibrarymember{operator-}{year_month_day_last}% +\begin{itemdecl} +constexpr year_month_day_last + operator-(const year_month_day_last& ymdl, const months& dm) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{ymdl + (-dm)}. +\end{itemdescr} + +\indexlibrarymember{operator+}{year_month_day_last}% +\begin{itemdecl} +constexpr year_month_day_last + operator+(const year_month_day_last& ymdl, const years& dy) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{\{ymdl.year()+dy, ymdl.month_day_last()\}}. +\end{itemdescr} + +\indexlibrarymember{operator+}{year_month_day_last}% +\begin{itemdecl} +constexpr year_month_day_last + operator+(const years& dy, const year_month_day_last& ymdl) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{ymdl + dy}. +\end{itemdescr} + +\indexlibrarymember{operator-}{year_month_day_last}% +\begin{itemdecl} +constexpr year_month_day_last + operator-(const year_month_day_last& ymdl, const years& dy) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{ymdl + (-dy)}. +\end{itemdescr} + +\indexlibrarymember{operator<<}{year_month_day_last}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const year_month_day_last& ymdl); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{os << ymdl.year() << '/' << ymdl.month_day_last()}. +\end{itemdescr} + +\rSec2[time.cal.ymwd]{Class \tcode{year_month_weekday}} + +\rSec3[time.cal.ymwd.overview]{Overview} +\indexlibrary{\idxcode{year_month_weekday}} + +\begin{codeblock} +namespace std::chrono { + class year_month_weekday { + chrono::year y_; // \expos + chrono::month m_; // \expos + chrono::weekday_indexed wdi_; // \expos + + public: + year_month_weekday() = default; + constexpr year_month_weekday(const chrono::year& y, const chrono::month& m, + const chrono::weekday_indexed& wdi) noexcept; + constexpr year_month_weekday(const sys_days& dp) noexcept; + explicit constexpr year_month_weekday(const local_days& dp) noexcept; + + constexpr year_month_weekday& operator+=(const months& m) noexcept; + constexpr year_month_weekday& operator-=(const months& m) noexcept; + constexpr year_month_weekday& operator+=(const years& y) noexcept; + constexpr year_month_weekday& operator-=(const years& y) noexcept; + + constexpr chrono::year year() const noexcept; + constexpr chrono::month month() const noexcept; + constexpr chrono::weekday weekday() const noexcept; + constexpr unsigned index() const noexcept; + constexpr chrono::weekday_indexed weekday_indexed() const noexcept; + + constexpr operator sys_days() const noexcept; + explicit constexpr operator local_days() const noexcept; + constexpr bool ok() const noexcept; + }; +} +\end{codeblock} + +\pnum +\tcode{year_month_weekday} represents a specific year, month, +and $n^\text{th}$ weekday of the month. +\tcode{year_month_weekday} is a field-based time point with a resolution of \tcode{days}. +\begin{note} +\tcode{year_month_weekday} supports \tcode{years}- and \tcode{months}-oriented arithmetic, +but not \tcode{days}-oriented arithmetic. +For the latter, there is a conversion to \tcode{sys_days}, +which efficiently supports \tcode{days}-oriented arithmetic. +\end{note} +\tcode{year_month_weekday} is \oldconcept{EqualityComparable} (Table~\ref{tab:equalitycomparable}). + +\pnum +\tcode{year_month_weekday} is a trivially copyable and standard-layout class type. + +\rSec3[time.cal.ymwd.members]{Member functions} + +\indexlibrary{\idxcode{year_month_weekday}!constructor}% +\begin{itemdecl} +constexpr year_month_weekday(const chrono::year& y, const chrono::month& m, + const chrono::weekday_indexed& wdi) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{year_month_weekday} by +initializing \tcode{y_} with \tcode{y}, \tcode{m_} with \tcode{m}, and \tcode{wdi_} with \tcode{wdi}. +\end{itemdescr} + +\indexlibrary{\idxcode{year_month_weekday}!constructor}% +\begin{itemdecl} +constexpr year_month_weekday(const sys_days& dp) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{year_month_weekday} +which corresponds to the date represented by \tcode{dp}. + +\pnum +\remarks +For any value \tcode{ymdl} of type \tcode{year_month_weekday} +for which \tcode{ymdl.ok()} is \tcode{true}, +\tcode{ymdl == year_month_weekday\{sys_days\{ymdl\}\}} is \tcode{true}. +\end{itemdescr} + +\indexlibrary{\idxcode{year_month_weekday}!constructor}% +\begin{itemdecl} +explicit constexpr year_month_weekday(const local_days& dp) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{year_month_weekday} +that corresponds to the date represented by \tcode{dp}. + +\pnum +\remarks +Equivalent to constructing with \tcode{sys_days\{dp.time_since_epoch()\}}. +\end{itemdescr} + +\indexlibrarymember{operator+=}{year_month_weekday}% +\begin{itemdecl} +constexpr year_month_weekday& operator+=(const months& m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this + m}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator-=}{year_month_weekday}% +\begin{itemdecl} +constexpr year_month_weekday& operator-=(const months& m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this - m}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator+=}{year_month_weekday}% +\begin{itemdecl} +constexpr year_month_weekday& operator+=(const years& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this + y}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator-=}{year_month_weekday}% +\begin{itemdecl} +constexpr year_month_weekday& operator-=(const years& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this - y}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{year}{year_month_weekday}% +\begin{itemdecl} +constexpr chrono::year year() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y_}. +\end{itemdescr} + +\indexlibrarymember{month}{year_month_weekday}% +\begin{itemdecl} +constexpr chrono::month month() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{m_}. +\end{itemdescr} + +\indexlibrarymember{weekday}{year_month_weekday}% +\begin{itemdecl} +constexpr chrono::weekday weekday() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{wdi_.weekday()}. +\end{itemdescr} + +\indexlibrarymember{index}{year_month_weekday}% +\begin{itemdecl} +constexpr unsigned index() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{wdi_.index()}. +\end{itemdescr} + +\indexlibrarymember{weekday_indexed}{year_month_weekday}% +\begin{itemdecl} +constexpr chrono::weekday_indexed weekday_indexed() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{wdi_}. +\end{itemdescr} + +\indexlibrarymember{operator sys_days}{year_month_weekday}% +\begin{itemdecl} +constexpr operator sys_days() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If \tcode{y_.ok() \&\& m_.ok() \&\& wdi_.weekday().ok()}, +returns a \tcode{sys_days} that +represents the date \tcode{(index() - 1) * 7} days after +the first \tcode{weekday()} of \tcode{year()/month()}. +If \tcode{index()} is 0 +the returned \tcode{sys_days} +represents the date 7 days prior to +the first \tcode{weekday()} of \tcode{year()/month()}. +Otherwise the returned value is unspecified. +\end{itemdescr} + +\indexlibrarymember{operator local_days}{year_month_weekday}% +\begin{itemdecl} +explicit constexpr operator local_days() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{local_days\{sys_days\{*this\}.time_since_epoch()\}}. +\end{itemdescr} + +\indexlibrarymember{ok}{year_month_weekday}% +\begin{itemdecl} +constexpr bool ok() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If any of +\tcode{y_.ok()}, +\tcode{m_.ok()}, or +\tcode{wdi_.ok()} +is \tcode{false}, returns \tcode{false}. +Otherwise, if \tcode{*this} represents a valid date, +returns \tcode{true}. +Otherwise, returns \tcode{false}. +\end{itemdescr} + +\rSec3[time.cal.ymwd.nonmembers]{Non-member functions} + +\indexlibrarymember{operator==}{year_month_weekday}% +\begin{itemdecl} +constexpr bool operator==(const year_month_weekday& x, const year_month_weekday& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +x.year() == y.year() && x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed() +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator+}{year_month_weekday}% +\begin{itemdecl} +constexpr year_month_weekday operator+(const year_month_weekday& ymwd, const months& dm) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{(ymwd.year() / ymwd.month() + dm) / ymwd.weekday_indexed()}. +\end{itemdescr} + +\indexlibrarymember{operator+}{year_month_weekday}% +\begin{itemdecl} +constexpr year_month_weekday operator+(const months& dm, const year_month_weekday& ymwd) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{ymwd + dm}. +\end{itemdescr} + +\indexlibrarymember{operator-}{year_month_weekday}% +\begin{itemdecl} +constexpr year_month_weekday operator-(const year_month_weekday& ymwd, const months& dm) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{ymwd + (-dm)}. +\end{itemdescr} + +\indexlibrarymember{operator+}{year_month_weekday}% +\begin{itemdecl} +constexpr year_month_weekday operator+(const year_month_weekday& ymwd, const years& dy) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{\{ymwd.year()+dy, ymwd.month(), ymwd.weekday_indexed()\}}. +\end{itemdescr} + +\indexlibrarymember{operator+}{year_month_weekday}% +\begin{itemdecl} +constexpr year_month_weekday operator+(const years& dy, const year_month_weekday& ymwd) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{ymwd + dm}. +\end{itemdescr} + +\indexlibrarymember{operator-}{year_month_weekday}% +\begin{itemdecl} +constexpr year_month_weekday operator-(const year_month_weekday& ymwd, const years& dy) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{ymwd + (-dm)}. +\end{itemdescr} + +\indexlibrarymember{operator<<}{year_month_weekday}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const year_month_weekday& ymwd); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{os << ymwdi.year() << '/' << ymwdi.month() << '/' << ymwdi.weekday_indexed()}. +\end{itemdescr} + +\rSec2[time.cal.ymwdlast]{Class \tcode{year_month_weekday_last}} + +\rSec3[time.cal.ymwdlast.overview]{Overview} +\indexlibrary{\idxcode{year_month_weekday_last}} + +\begin{codeblock} +namespace std::chrono { + class year_month_weekday_last { + chrono::year y_; // \expos + chrono::month m_; // \expos + chrono::weekday_last wdl_; // \expos + + public: + constexpr year_month_weekday_last(const chrono::year& y, const chrono::month& m, + const chrono::weekday_last& wdl) noexcept; + + constexpr year_month_weekday_last& operator+=(const months& m) noexcept; + constexpr year_month_weekday_last& operator-=(const months& m) noexcept; + constexpr year_month_weekday_last& operator+=(const years& y) noexcept; + constexpr year_month_weekday_last& operator-=(const years& y) noexcept; + + constexpr chrono::year year() const noexcept; + constexpr chrono::month month() const noexcept; + constexpr chrono::weekday weekday() const noexcept; + constexpr chrono::weekday_last weekday_last() const noexcept; + + constexpr operator sys_days() const noexcept; + explicit constexpr operator local_days() const noexcept; + constexpr bool ok() const noexcept; + }; +} +\end{codeblock} + +\pnum +\tcode{year_month_weekday_last} represents a specific year, month, +and last weekday of the month. +\tcode{year_month_weekday_last} is a field-based time point with a resolution of \tcode{days}, +except that it is restricted to pointing to the last weekday of a year and month. +\begin{note} +\tcode{year_month_weekday_last} supports \tcode{years}- and \tcode{months}-oriented arithmetic, +but not \tcode{days}-oriented arithmetic. +For the latter, there is a conversion to \tcode{sys_days}, +which efficiently supports \tcode{days}-oriented arithmetic. +\end{note} +\tcode{year_month_weekday_last} is \oldconcept{EqualityComparable} (Table~\ref{tab:equalitycomparable}). + +\rSec3[time.cal.ymwdlast.members]{Member functions} + +\pnum +\tcode{year_month_weekday_last} is a trivially copyable and standard-layout class type. + +\indexlibrary{\idxcode{year_month_weekday_last}!constructor}% +\begin{itemdecl} +constexpr year_month_weekday_last(const chrono::year& y, const chrono::month& m, + const chrono::weekday_last& wdl) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{year_month_weekday_last} by +initializing \tcode{y_} with \tcode{y}, \tcode{m_} with \tcode{m}, and \tcode{wdl_} with \tcode{wdl}. +\end{itemdescr} + +\indexlibrarymember{operator+=}{year_month_weekday_last}% +\begin{itemdecl} +constexpr year_month_weekday_last& operator+=(const months& m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this + m}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator-=}{year_month_weekday_last}% +\begin{itemdecl} +constexpr year_month_weekday_last& operator-=(const months& m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this - m}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator+=}{year_month_weekday_last}% +\begin{itemdecl} +constexpr year_month_weekday_last& operator+=(const years& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this + y}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator-=}{year_month_weekday_last}% +\begin{itemdecl} +constexpr year_month_weekday_last& operator-=(const years& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects \tcode{*this = *this - y}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{year}{year_month_weekday_last}% +\begin{itemdecl} +constexpr chrono::year year() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y_}. +\end{itemdescr} + +\indexlibrarymember{month}{year_month_weekday_last}% +\begin{itemdecl} +constexpr chrono::month month() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{m_}. +\end{itemdescr} + +\indexlibrarymember{weekday}{year_month_weekday_last}% +\begin{itemdecl} +constexpr chrono::weekday weekday() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{wdl_.weekday()}. +\end{itemdescr} + +\indexlibrarymember{weekday_last}{year_month_weekday_last}% +\begin{itemdecl} +constexpr chrono::weekday_last weekday_last() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{wdl_}. +\end{itemdescr} + +\indexlibrarymember{operator sys_days}{year_month_weekday_last}% +\begin{itemdecl} +constexpr operator sys_days() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If \tcode{ok() == true}, +returns a \tcode{sys_days} that represents +the last \tcode{weekday()} of \tcode{year()/month()}. +Otherwise the returned value is unspecified. +\end{itemdescr} + +\indexlibrarymember{operator local_days}{year_month_weekday_last}% +\begin{itemdecl} +explicit constexpr operator local_days() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{local_days\{sys_days\{*this\}.time_since_epoch()\}}. +\end{itemdescr} + +\indexlibrarymember{ok}{year_month_weekday_last}% +\begin{itemdecl} +constexpr bool ok() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y_.ok() \&\& m_.ok() \&\& wdl_.ok()}. +\end{itemdescr} + +\rSec3[time.cal.ymwdlast.nonmembers]{Non-member functions} + +\indexlibrarymember{operator==}{year_month_weekday_last}% +\begin{itemdecl} +constexpr bool operator==(const year_month_weekday_last& x, + const year_month_weekday_last& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +x.year() == y.year() && x.month() == y.month() && x.weekday_last() == y.weekday_last() +\end{codeblock} +\end{itemdescr} + +\indexlibrarymember{operator+}{year_month_weekday_last}% +\begin{itemdecl} +constexpr year_month_weekday_last + operator+(const year_month_weekday_last& ymwdl, const months& dm) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{(ymwdl.year() / ymwdl.month() + dm) / ymwdl.weekday_last()}. +\end{itemdescr} + +\indexlibrarymember{operator+}{year_month_weekday_last}% +\begin{itemdecl} +constexpr year_month_weekday_last + operator+(const months& dm, const year_month_weekday_last& ymwdl) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{ymwdl + dm}. +\end{itemdescr} + +\indexlibrarymember{operator-}{year_month_weekday_last}% +\begin{itemdecl} +constexpr year_month_weekday_last + operator-(const year_month_weekday_last& ymwdl, const months& dm) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{ymwdl + (-dm)}. +\end{itemdescr} + +\indexlibrarymember{operator+}{year_month_weekday_last}% +\begin{itemdecl} +constexpr year_month_weekday_last + operator+(const year_month_weekday_last& ymwdl, const years& dy) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{\{ymwdl.year()+dy, ymwdl.month(), ymwdl.weekday_last()\}}. +\end{itemdescr} + +\indexlibrarymember{operator+}{year_month_weekday_last}% +\begin{itemdecl} +constexpr year_month_weekday_last + operator+(const years& dy, const year_month_weekday_last& ymwdl) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{ymwdl + dy}. +\end{itemdescr} + +\indexlibrarymember{operator-}{year_month_weekday_last}% +\begin{itemdecl} +constexpr year_month_weekday_last + operator-(const year_month_weekday_last& ymwdl, const years& dy) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{ymwdl + (-dy)}. +\end{itemdescr} + +\indexlibrarymember{operator<<}{year_month_weekday_last}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const year_month_weekday_last& ymwdl); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{os << ymwdl.year() << '/' << ymwdl.month() << '/' << ymwdl.weekday_last()}. +\end{itemdescr} + +\rSec2[time.cal.operators]{Conventional syntax operators} +\indexlibrary{\idxcode{operator/}!calendar types|(} + +\pnum +A set of overloaded \tcode{operator/} functions provides +a conventional syntax for the creation of civil calendar dates. + +\pnum +\begin{note} +The year, month, and day are accepted in any of the following 3 orders: + +\begin{codeblock} +@\tcode{\placeholder{year}}@/@\tcode{\placeholder{month}}@/@\tcode{\placeholder{day}}@ +@\tcode{\placeholder{month}}@/@\tcode{\placeholder{day}}@/@\tcode{\placeholder{year}}@ +@\tcode{\placeholder{day}}@/@\tcode{\placeholder{month}}@/@\tcode{\placeholder{year}}@ +\end{codeblock} + +Anywhere a \tcode{\placeholder{day}} is required, any of the following can also be specified: + +\begin{codeblock} +last +@\tcode{\placeholder{weekday}}@[@\tcode{\placeholder{i}}@] +@\tcode{\placeholder{weekday}}@[last] +\end{codeblock} +\end{note} + +\pnum +\begin{note} +Partial-date types such as \tcode{year_month} and \tcode{month_day} +can be created by not applying the second division operator +for any of the three orders. For example: + +\begin{codeblock} +year_month ym = 2015y/April; +month_day md1 = April/4; +month_day md2 = 4d/April; +\end{codeblock} +\end{note} + +\pnum +\begin{example} +\begin{codeblock} +auto a = 2015/4/4; // \tcode{a == int(125)} +auto b = 2015y/4/4; // \tcode{b == year_month_day\{year(2015), month(4), day(4)\}} +auto c = 2015y/4d/April; // error: no viable \tcode{operator/} for first \tcode{/} +auto d = 2015/April/4; // error: no viable \tcode{operator/} for first \tcode{/} +\end{codeblock} +\end{example} + +\begin{itemdecl} +constexpr year_month + operator/(const year& y, const month& m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{\{y, m\}}. +\end{itemdescr} + +\begin{itemdecl} +constexpr year_month + operator/(const year& y, int m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y / month(m)}. +\end{itemdescr} + +\begin{itemdecl} +constexpr month_day + operator/(const month& m, const day& d) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{\{m, d\}}. +\end{itemdescr} + +\begin{itemdecl} +constexpr month_day + operator/(const month& m, int d) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{m / day(d)}. +\end{itemdescr} + +\begin{itemdecl} +constexpr month_day + operator/(int m, const day& d) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{month(m) / d}. +\end{itemdescr} + +\begin{itemdecl} +constexpr month_day + operator/(const day& d, const month& m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{m / d}. +\end{itemdescr} + +\begin{itemdecl} +constexpr month_day + operator/(const day& d, int m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{month(m) / d}. +\end{itemdescr} + +\begin{itemdecl} +constexpr month_day_last + operator/(const month& m, last_spec) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{month_day_last\{m\}}. +\end{itemdescr} + +\begin{itemdecl} +constexpr month_day_last + operator/(int m, last_spec) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{month(m) / last}. +\end{itemdescr} + +\begin{itemdecl} +constexpr month_day_last + operator/(last_spec, const month& m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{m / last}. +\end{itemdescr} + +\begin{itemdecl} +constexpr month_day_last + operator/(last_spec, int m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{month(m) / last}. +\end{itemdescr} + +\begin{itemdecl} +constexpr month_weekday + operator/(const month& m, const weekday_indexed& wdi) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{\{m, wdi\}}. +\end{itemdescr} + +\begin{itemdecl} +constexpr month_weekday + operator/(int m, const weekday_indexed& wdi) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{month(m) / wdi}. +\end{itemdescr} + +\begin{itemdecl} +constexpr month_weekday + operator/(const weekday_indexed& wdi, const month& m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{m / wdi}. +\end{itemdescr} + +\begin{itemdecl} +constexpr month_weekday + operator/(const weekday_indexed& wdi, int m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{month(m) / wdi}. +\end{itemdescr} + +\begin{itemdecl} +constexpr month_weekday_last + operator/(const month& m, const weekday_last& wdl) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{\{m, wdl\}}. +\end{itemdescr} + +\begin{itemdecl} +constexpr month_weekday_last + operator/(int m, const weekday_last& wdl) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{month(m) / wdl}. +\end{itemdescr} + +\begin{itemdecl} +constexpr month_weekday_last + operator/(const weekday_last& wdl, const month& m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{m / wdl}. +\end{itemdescr} + +\begin{itemdecl} +constexpr month_weekday_last + operator/(const weekday_last& wdl, int m) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{month(m) / wdl}. +\end{itemdescr} + +\begin{itemdecl} +constexpr year_month_day + operator/(const year_month& ym, const day& d) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{\{ym.year(), ym.month(), d\}}. +\end{itemdescr} + +\begin{itemdecl} +constexpr year_month_day + operator/(const year_month& ym, int d) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{ym / day(d)}. +\end{itemdescr} + +\begin{itemdecl} +constexpr year_month_day + operator/(const year& y, const month_day& md) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y / md.month() / md.day()}. +\end{itemdescr} + +\begin{itemdecl} +constexpr year_month_day + operator/(int y, const month_day& md) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{year(y) / md}. +\end{itemdescr} + +\begin{itemdecl} +constexpr year_month_day + operator/(const month_day& md, const year& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y / md}. +\end{itemdescr} + +\begin{itemdecl} +constexpr year_month_day + operator/(const month_day& md, int y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{year(y) / md}. +\end{itemdescr} + +\begin{itemdecl} +constexpr year_month_day_last + operator/(const year_month& ym, last_spec) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{\{ym.year(), month_day_last\{ym.month()\}\}}. +\end{itemdescr} + +\begin{itemdecl} +constexpr year_month_day_last + operator/(const year& y, const month_day_last& mdl) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{\{y, mdl\}}. +\end{itemdescr} + +\begin{itemdecl} +constexpr year_month_day_last + operator/(int y, const month_day_last& mdl) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{year(y) / mdl}. +\end{itemdescr} + +\begin{itemdecl} +constexpr year_month_day_last + operator/(const month_day_last& mdl, const year& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y / mdl}. +\end{itemdescr} + +\begin{itemdecl} +constexpr year_month_day_last + operator/(const month_day_last& mdl, int y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{year(y) / mdl}. +\end{itemdescr} + +\begin{itemdecl} +constexpr year_month_weekday + operator/(const year_month& ym, const weekday_indexed& wdi) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{\{ym.year(), ym.month(), wdi\}}. +\end{itemdescr} + +\begin{itemdecl} +constexpr year_month_weekday + operator/(const year& y, const month_weekday& mwd) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{\{y, mwd.month(), mwd.weekday_indexed()\}}. +\end{itemdescr} + +\begin{itemdecl} +constexpr year_month_weekday + operator/(int y, const month_weekday& mwd) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{year(y) / mwd}. +\end{itemdescr} + +\begin{itemdecl} +constexpr year_month_weekday + operator/(const month_weekday& mwd, const year& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y / mwd}. +\end{itemdescr} + +\begin{itemdecl} +constexpr year_month_weekday + operator/(const month_weekday& mwd, int y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{year(y) / mwd}. +\end{itemdescr} + +\begin{itemdecl} +constexpr year_month_weekday_last + operator/(const year_month& ym, const weekday_last& wdl) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{\{ym.year(), ym.month(), wdl\}}. +\end{itemdescr} + +\begin{itemdecl} +constexpr year_month_weekday_last + operator/(const year& y, const month_weekday_last& mwdl) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{\{y, mwdl.month(), mwdl.weekday_last()\}}. +\end{itemdescr} + +\begin{itemdecl} +constexpr year_month_weekday_last + operator/(int y, const month_weekday_last& mwdl) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{year(y) / mwdl}. +\end{itemdescr} + +\begin{itemdecl} +constexpr year_month_weekday_last + operator/(const month_weekday_last& mwdl, const year& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y / mwdl}. +\end{itemdescr} + +\begin{itemdecl} +constexpr year_month_weekday_last + operator/(const month_weekday_last& mwdl, int y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{year(y) / mwdl}. +\end{itemdescr} + +\indexlibrary{\idxcode{operator/}!calendar types|)} + +\rSec1[time.tod]{Class template \tcode{time_of_day}} + +\rSec2[time.tod.overview]{Overview} +\indexlibrary{\idxcode{time_of_day}} + +\begin{codeblock} +namespace std::chrono { + template class time_of_day; + + template<> class time_of_day; + template<> class time_of_day; + template<> class time_of_day; + template class time_of_day>; +} +\end{codeblock} + +\pnum +The \tcode{time_of_day} class template +splits a \tcode{duration} representing the time elapsed since midnight +into a ``broken down'' time of day such as +$hours$:$minutes$:$seconds$. +The \tcode{Duration} template parameter dictates +the precision to which the time is broken down. +\begin{note} +This can vary from a coarse precision of hours +to a very fine precision of nanoseconds. +\end{note} +A \tcode{time_of_day} object also tracks +whether it should be output +as a 12-hour time format or a 24-hour time format. + +\pnum +The primary \tcode{time_of_day} template is not defined. +Four specializations are provided to handle four different +levels of precision. + +\pnum +Each specialization of \tcode{time_of_day} is a trivially copyable +and standard-layout class type. + +\rSec2[time.tod.hours]{Hours precision} +\indexlibrary{\idxcode{time_of_day}} + +\begin{codeblock} +namespace std::chrono { + template<> + class time_of_day { + public: + using precision = chrono::hours; + + time_of_day() = default; + explicit constexpr time_of_day(chrono::hours since_midnight) noexcept; + + constexpr chrono::hours hours() const noexcept; + + explicit constexpr operator precision() const noexcept; + constexpr precision to_duration() const noexcept; + + constexpr void make24() noexcept; + constexpr void make12() noexcept; + }; +} +\end{codeblock} + +\pnum +\begin{note} +This specialization handles hours since midnight. +\end{note} + +\indexlibrary{\idxcode{time_of_day}!constructor}% +\begin{itemdecl} +explicit constexpr time_of_day(chrono::hours since_midnight) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{time_of_day} in 24-hour format +corresponding to \tcode{since_midnight} hours after 00:00:00. + +\pnum +\postconditions +\tcode{hours()} returns the integral number of hours \tcode{since_midnight} is after 00:00:00. +\end{itemdescr} + +\indexlibrarymember{hours}{time_of_day}% +\begin{itemdecl} +constexpr chrono::hours hours() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns The stored hour of \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator precision}{time_of_day}% +\begin{itemdecl} +explicit constexpr operator precision() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns The number of hours since midnight. +\end{itemdescr} + +\indexlibrarymember{to_duration}{time_of_day}% +\begin{itemdecl} +constexpr precision to_duration() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{precision\{*this\}}. +\end{itemdescr} + +\indexlibrarymember{make24}{time_of_day}% +\begin{itemdecl} +constexpr void make24() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \tcode{*this} is a 12-hour time, +converts to a 24-hour time. +Otherwise, no effects. +\end{itemdescr} + +\indexlibrarymember{make12}{time_of_day}% +\begin{itemdecl} +constexpr void make12() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \tcode{*this} is a 24-hour time, +converts to a 12-hour time. +Otherwise, no effects. +\end{itemdescr} + +\rSec2[time.tod.minutes]{Minutes precision} +\indexlibrary{\idxcode{time_of_day}} + +\begin{codeblock} +namespace std::chrono { + template<> + class time_of_day { + public: + using precision = chrono::minutes; + + time_of_day() = default; + explicit constexpr time_of_day(chrono::minutes since_midnight) noexcept; + + constexpr chrono::hours hours() const noexcept; + constexpr chrono::minutes minutes() const noexcept; + + explicit constexpr operator precision() const noexcept; + constexpr precision to_duration() const noexcept; + + constexpr void make24() noexcept; + constexpr void make12() noexcept; + }; +} +\end{codeblock} + +\pnum +\begin{note} +This specialization handles hours and minutes since midnight. +\end{note} + +\indexlibrary{\idxcode{time_of_day}!constructor}% +\begin{itemdecl} +explicit constexpr time_of_day(minutes since_midnight) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{time_of_day} +in 24-hour format +corresponding to \tcode{since_midnight} minutes after 00:00:00. + +\pnum +\postconditions +\tcode{hours()} returns the integral number of hours +\tcode{since_midnight} is after 00:00:00. +\tcode{minutes()} returns the integral number of minutes +\tcode{since_midnight} is after \tcode{(\textrm{00:00:00} + hours())}. +\end{itemdescr} + +\indexlibrarymember{hours}{time_of_day}% +\begin{itemdecl} +constexpr chrono::hours hours() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns The stored hour of \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{minutes}{time_of_day}% +\begin{itemdecl} +constexpr chrono::minutes minutes() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns The stored minute of \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator precision}{time_of_day}% +\begin{itemdecl} +explicit constexpr operator precision() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns The number of minutes since midnight. +\end{itemdescr} + +\indexlibrarymember{to_duration}{time_of_day}% +\begin{itemdecl} +constexpr precision to_duration() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{precision\{*this\}}. +\end{itemdescr} + +\indexlibrarymember{make24}{time_of_day}% +\begin{itemdecl} +constexpr void make24() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \tcode{*this} is a 12-hour time, +converts to a 24-hour time. +Otherwise, no effects. +\end{itemdescr} + +\indexlibrarymember{make12}{time_of_day}% +\begin{itemdecl} +constexpr void make12() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \tcode{*this} is a 24-hour time, +converts to a 12-hour time. +Otherwise, no effects. +\end{itemdescr} + +\rSec2[time.tod.seconds]{Seconds precision} +\indexlibrary{\idxcode{time_of_day}} + +\begin{codeblock} +namespace std::chrono { + template<> + class time_of_day { + public: + using precision = chrono::seconds; + + time_of_day() = default; + explicit constexpr time_of_day(chrono::seconds since_midnight) noexcept; + + constexpr chrono::hours hours() const noexcept; + constexpr chrono::minutes minutes() const noexcept; + constexpr chrono::seconds seconds() const noexcept; + + explicit constexpr operator precision() const noexcept; + constexpr precision to_duration() const noexcept; + + constexpr void make24() noexcept; + constexpr void make12() noexcept; + }; +} +\end{codeblock} + +\pnum +\begin{note} +This specialization handles hours, minutes, and seconds since midnight. +\end{note} + +\indexlibrary{\idxcode{time_of_day}!constructor}% +\begin{itemdecl} +explicit constexpr time_of_day(seconds since_midnight) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{time_of_day} +in 24-hour format +corresponding to \tcode{since_midnight} seconds after 00:00:00. + +\pnum +\postconditions +\tcode{hours()} returns the integral number of hours +\tcode{since_midnight} is after 00:00:00. +\tcode{minutes()} returns the integral number of minutes +\tcode{since_midnight} is after \tcode{(\textrm{00:00:00} + hours())}. +\tcode{seconds()} returns the integral number of seconds +\tcode{since_midnight} is after \tcode{(\textrm{00:00:00} + hours() + minutes())}. +\end{itemdescr} + +\indexlibrarymember{hours}{time_of_day}% +\begin{itemdecl} +constexpr chrono::hours hours() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The stored hour of \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{minutes}{time_of_day}% +\begin{itemdecl} +constexpr chrono::minutes minutes() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The stored minute of \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{seconds}{time_of_day}% +\begin{itemdecl} +constexpr chrono::seconds seconds() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The stored second of \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator precision}{time_of_day}% +\begin{itemdecl} +explicit constexpr operator precision() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The number of seconds since midnight. +\end{itemdescr} + +\indexlibrarymember{to_duration}{time_of_day}% +\begin{itemdecl} +constexpr precision to_duration() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{precision\{*this\}}. +\end{itemdescr} + +\indexlibrarymember{make24}{time_of_day}% +\begin{itemdecl} +constexpr void make24() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \tcode{*this} is a 12-hour time, +converts to a 24-hour time. +Otherwise, no effects. +\end{itemdescr} + +\indexlibrarymember{make12}{time_of_day}% +\begin{itemdecl} +constexpr void make12() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \tcode{*this} is a 24-hour time, +converts to a 12-hour time. +Otherwise, no effects. +\end{itemdescr} + +\rSec2[time.tod.subsecond]{Sub-second precision} +\indexlibrary{\idxcode{time_of_day<\placeholder{sub-second duration}>}} + +\begin{codeblock} +namespace std::chrono { + template + class time_of_day> { + public: + using precision = duration; + + time_of_day() = default; + explicit constexpr time_of_day(precision since_midnight) noexcept; + + constexpr chrono::hours hours() const noexcept; + constexpr chrono::minutes minutes() const noexcept; + constexpr chrono::seconds seconds() const noexcept; + constexpr precision subseconds() const noexcept; + + explicit constexpr operator precision() const noexcept; + constexpr precision to_duration() const noexcept; + + constexpr void make24() noexcept; + constexpr void make12() noexcept; + }; +} +\end{codeblock} + +\pnum +This specialization shall not exist unless +\tcode{treat_as_floating_point_v} is \tcode{false} +and +\tcode{duration} is not convertible to \tcode{seconds}. +\begin{note} +This specialization handles hours, minutes, seconds, and fractional seconds since midnight. +Typical uses are with \tcode{milliseconds}, \tcode{microseconds} and \tcode{nanoseconds}. +\end{note} + +\indexlibrary{\idxcode{time_of_day<\placeholder{sub-second duration}>}!constructor}% +\begin{itemdecl} +explicit constexpr time_of_day(precision since_midnight) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Constructs an object of type \tcode{time_of_day} +in 24-hour format +corresponding to \tcode{since_midnight} fractional seconds after 00:00:00. + +\pnum +\postconditions +\tcode{hours()} returns the integral number of hours +\tcode{since_midnight} is after 00:00:00. +\tcode{minutes()} returns the integral number of minutes +\tcode{since_midnight }is after \tcode{(\textrm{00:00:00} + hours())}. +\tcode{seconds()} returns the integral number of seconds +\tcode{since_midnight }is after \tcode{(\textrm{00:00:00} + hours() + minutes())}. +\tcode{subseconds()} returns the integral number of fractional seconds +\tcode{since_midnight} is after \tcode{(\textrm{00:00:00} + hours() + minutes() + seconds())}. +\end{itemdescr} + +\indexlibrarymember{hours}{time_of_day<\placeholder{sub-second duration}>}% +\begin{itemdecl} +constexpr chrono::hours hours() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The stored hour of \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{minutes}{time_of_day<\placeholder{sub-second duration}>}% +\begin{itemdecl} +constexpr chrono::minutes minutes() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The stored minute of \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{seconds}{time_of_day<\placeholder{sub-second duration}>}% +\begin{itemdecl} +constexpr chrono::seconds seconds() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The stored second of \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{subseconds}{time_of_day<\placeholder{sub-second duration}>}% +\begin{itemdecl} +constexpr duration subseconds() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The stored subsecond of \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator precision}{time_of_day<\placeholder{sub-second duration}>}% +\begin{itemdecl} +explicit constexpr operator precision() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The number of subseconds since midnight. +\end{itemdescr} + +\indexlibrarymember{to_duration}{time_of_day<\placeholder{sub-second duration}>}% +\begin{itemdecl} +constexpr precision to_duration() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{precision\{*this\}}. +\end{itemdescr} + +\indexlibrarymember{make24}{time_of_day<\placeholder{sub-second duration}>}% +\begin{itemdecl} +constexpr void make24() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \tcode{*this} is a 12-hour time, +converts to a 24-hour time. +Otherwise, no effects. +\end{itemdescr} + +\indexlibrarymember{make12}{time_of_day<\placeholder{sub-second duration}>}% +\begin{itemdecl} +constexpr void make12() noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \tcode{*this} is a 24-hour time, +converts to a 12-hour time. +Otherwise, no effects. +\end{itemdescr} + +\rSec2[time.tod.io]{Formatted output} + +\indexlibrarymember{operator<<}{time_of_day}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const time_of_day& t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \tcode{t} is a 24-hour time, +outputs to \tcode{os} according to the format +\tcode{"\%H00"}\iref{time.format}. +Otherwise +outputs to \tcode{os} according to the format +\tcode{"\%I\%p"}\iref{time.format}. + +\pnum +\returns \tcode{os}. + +\pnum +\begin{example} +\begin{codeblock} +for (hours h : {1h, 18h}) { + time_of_day tod(h); + os << tod << '\n'; + tod.make12(); + os << tod << '\n'; +} +\end{codeblock} + +Produces the output: + +\begin{codeblock} +0100 +1am +1800 +6pm +\end{codeblock} +\end{example} +\end{itemdescr} + +\indexlibrarymember{operator<<}{time_of_day}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const time_of_day& t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \tcode{t} is a 24-hour time, +outputs to \tcode{os} according to the format +\tcode{"\%H:\%M"}\iref{time.format}. +Otherwise +outputs to \tcode{os} according to the format +\tcode{"\%I:\%M\%p"}\iref{time.format}. + +\pnum +\returns \tcode{os}. + +\begin{example} +\begin{codeblock} +for (minutes m : {68min, 1095min}) { + time_of_day tod(m); + os << tod << '\n'; + tod.make12(); + os << tod << '\n'; +} +\end{codeblock} + +Produces the output: + +\begin{codeblock} +01:08 +1:08am +18:15 +6:15pm +\end{codeblock} +\end{example} +\end{itemdescr} + +\indexlibrarymember{operator<<}{time_of_day}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const time_of_day& t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \tcode{t} is a 24-hour time, +outputs to \tcode{os} according to the format +\tcode{"\%T"}\iref{time.format}. +Otherwise +outputs to \tcode{os} according to the format +\tcode{"\%I:\%M:\%S\%p"}\iref{time.format}. + +\pnum +\returns \tcode{os}. + +\begin{example} +\begin{codeblock} +for (seconds s : {4083s, 65745s}) { + time_of_day tod(s); + os << tod << '\n'; + tod.make12(); + os << tod << '\n'; +} +\end{codeblock} + +Produces the output: + +\begin{codeblock} +01:08:03 +1:08:03am +18:15:45 +6:15:45pm +\end{codeblock} +\end{example} +\end{itemdescr} + +\indexlibrarymember{operator<<}{time_of_day<\placeholder{sub-second duration}>}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const time_of_day>& t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If \tcode{t} is a 24-hour time, +outputs to \tcode{os} according to the format +\tcode{"\%T"}\iref{time.format}. +Otherwise +outputs to \tcode{os} according to the format +\tcode{"\%I:\%M:\%S\%p"}\iref{time.format}. + +\pnum +\returns \tcode{os}. + +\begin{example} +\begin{codeblock} +for (milliseconds ms : {4083007ms, 65745123ms}) { + time_of_day tod(ms); + os << tod << '\n'; + tod.make12(); + os << tod << '\n'; +} +\end{codeblock} + +Produces the output: + +\begin{codeblock} +01:08:03.007 +1:08:03.007am +18:15:45.123 +6:15:45.123pm +\end{codeblock} +\end{example} +\end{itemdescr} + +\rSec1[time.zone]{Time zones} + +\rSec2[time.zone.general]{In general} + +\pnum +\ref{time.zone} describes an interface for accessing +the IANA Time Zone database described in RFC 6557, +that interoperates with \tcode{sys_time} and \tcode{local_time}. +This interface provides time zone support to +both the civil calendar types\iref{time.cal} +and to user-defined calendars. + +\rSec2[time.zone.db]{Time zone database} + +\rSec3[time.zone.db.tzdb]{Class \tcode{tzdb}} +\indexlibrary{\idxcode{tzdb}} + +\begin{codeblock} +namespace std::chrono { + struct tzdb { + string version; + vector zones; + vector links; + vector leaps; + + const time_zone* locate_zone(string_view tz_name) const; + const time_zone* current_zone() const; + }; +} +\end{codeblock} + +\pnum +Each \tcode{vector} in a \tcode{tzdb} object +is sorted to enable fast lookup. + +\indexlibrarymember{locate_zone}{tzdb}% +\begin{itemdecl} +const time_zone* locate_zone(string_view tz_name) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +If a \tcode{time_zone} is found +for which \tcode{name() == tz_name}, +returns a pointer to that \tcode{time_zone}. +Otherwise +if a \tcode{link} is found +for which \tcode{tz_name == link.name()}, +then a pointer is returned +to the \tcode{time_zone} for which \tcode{zone.name() == link.target()}. +\begin{note} +A \tcode{link} specifies an alternative name for a \tcode{time_zone}. +\end{note} + +\throws +If a \tcode{const time_zone*} cannot be found +as described in the \returns clause, +throws a \tcode{runtime_error}. +\begin{note} +On non-exceptional return, the return value is always a pointer to a valid \tcode{time_zone}. +\end{note} +\end{itemdescr} + +\indexlibrarymember{current_zone}{tzdb}% +\begin{itemdecl} +const time_zone* current_zone() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A pointer to the time zone which the computer has set as its local time zone. +\end{itemdescr} + +\rSec3[time.zone.db.list]{Class \tcode{tzdb_list}} +\indexlibrary{\idxcode{tzdb_list}} + +\begin{codeblock} +namespace std::chrono { + class tzdb_list { + public: + tzdb_list(const tzdb_list&) = delete; + tzdb_list& operator=(const tzdb_list&) = delete; + + // unspecified additional constructors + + class const_iterator; + + const tzdb& front() const noexcept; + + const_iterator erase_after(const_iterator p); + + const_iterator begin() const noexcept; + const_iterator end() const noexcept; + + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; + }; +} +\end{codeblock} + +\pnum +The \tcode{tzdb_list} database is a singleton; +the unique object of type \tcode{tzdb_list} can be +accessed via the \tcode{get_tzdb_list()} function. +\begin{note} +This access is only needed for those applications +that need to have long uptimes and +have a need to update the time zone database while running. +Other applications can implicitly access the \tcode{front()} of this list +via the read-only namespace scope functions +\tcode{get_tzdb()}, +\tcode{locate_zone()}, and +\tcode{current_zone()}. +\end{note} +The \tcode{tzdb_list} object contains a list of \tcode{tzdb} objects. + +\pnum +\tcode{tzdb_list::const_iterator} is a constant iterator +which meets the \oldconcept{ForwardIterator} requirements +and has a value type of \tcode{tzdb}. + +\indexlibrarymember{front}{tzdb_list}% +\begin{itemdecl} +const tzdb& front() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A reference to the first \tcode{tzdb} in the container. + +\pnum +\remarks +This operation is thread-safe with respect to \tcode{reload_tzdb()}. +\begin{note} +\tcode{reload_tzdb()} pushes a new \tcode{tzdb} +onto the front of this container. +\end{note} +\end{itemdescr} + +\indexlibrarymember{erase_after}{tzdb_list}% +\begin{itemdecl} +const_iterator erase_after(const_iterator p); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires +The iterator following \tcode{p} is dereferenceable. + +\pnum +\effects +Erases the \tcode{tzdb} referred to by the iterator following \tcode{p}. + +\pnum +\returns +An iterator pointing to the element following the one that was erased, +or \tcode{end()} if no such element exists. + +\pnum +\remarks +No pointers, references, or iterators are invalidated +except those referring to the erased \tcode{tzdb}. +\begin{note} +It is not possible to erase the \tcode{tzdb} +referred to by \tcode{begin()}. +\end{note} + +\pnum +\throws Nothing. +\end{itemdescr} + +\indexlibrarymember{begin}{tzdb_list}% +\begin{itemdecl} +const_iterator begin() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +An iterator referring to the first \tcode{tzdb} in the container. +\end{itemdescr} + +\indexlibrarymember{end}{tzdb_list}% +\begin{itemdecl} +const_iterator end() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +An iterator referring to the position one past the last \tcode{tzdb} in the container. +\end{itemdescr} + +\indexlibrarymember{cbegin}{tzdb_list}% +\begin{itemdecl} +const_iterator cbegin() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{begin()}. +\end{itemdescr} + +\indexlibrarymember{cend}{tzdb_list}% +\begin{itemdecl} +const_iterator cend() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{end()}. +\end{itemdescr} + +\rSec3[time.zone.db.access]{Time zone database access} + +\indexlibrary{\idxcode{get_tzdb_list}}% +\begin{itemdecl} +tzdb_list& get_tzdb_list(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If this is the first access to the time zone database, +initializes the database. +If this call initializes the database, +the resulting database will be a \tcode{tzdb_list} +holding a single initialized \tcode{tzdb}. + +\pnum +\returns +A reference to the database. + +\pnum +\remarks +It is safe to call this function from multiple threads at one time. + +\pnum +\throws +\tcode{runtime_error} if for any reason +a reference cannot be returned to a valid \tcode{tzdb_list} +containing one or more valid \tcode{tzdb}s. +\end{itemdescr} + +\indexlibrary{\idxcode{get_tzdb}}% +\begin{itemdecl} +const tzdb& get_tzdb(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{get_tzdb_list().front()}. +\end{itemdescr} + +\indexlibrary{\idxcode{locate_zone}}% +\begin{itemdecl} +const time_zone* locate_zone(string_view tz_name); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{get_tzdb().locate_zone(tz_name)}. + +\pnum +\begin{note} +The time zone database will be initialized +if this is the first reference to the database. +\end{note} +\end{itemdescr} + +\indexlibrary{\idxcode{current_zone}}% +\begin{itemdecl} +const time_zone* current_zone(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{get_tzdb().current_zone()}. +\end{itemdescr} + +\rSec3[time.zone.db.remote]{Remote time zone database support} + +\pnum +The local time zone database +is that supplied by the implementation +when the program first accesses the database, +for example via \tcode{current_zone()}. +While the program is running, +the implementation may choose to update the time zone database. +This update shall not impact the program in any way +unless the program calls the functions in this subclause. +This potentially updated time zone database +is referred to as the \defn{remote time zone database}. + +\indexlibrary{\idxcode{reload_tzdb}}% +\begin{itemdecl} +const tzdb& reload_tzdb(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +This function first checks +the version of the remote time zone database. +If the versions of the local and remote databases are the same, +there are no effects. +Otherwise the remote database is pushed +to the front of the \tcode{tzdb_list} +accessed by \tcode{get_tzdb_list()}. + +\pnum +\returns \tcode{get_tzdb_list().front()}. + +\pnum +\remarks +No pointers, references, or iterators are invalidated. + +\pnum +\remarks +This function is thread-safe with respect to +\tcode{get_tzdb_list().front()} and \tcode{get_tzdb_list().erase_after()}. + +\pnum +\throws +\tcode{runtime_error} if for any reason +a reference cannot be returned to a valid \tcode{tzdb}. +\end{itemdescr} + +\indexlibrary{\idxcode{remote_version}}% +\begin{itemdecl} +string remote_version(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns The latest remote database version. + +\begin{note} +This can be compared with \tcode{get_tzdb().version} +to discover if the local and remote databases are equivalent. +\end{note} +\end{itemdescr} + +\rSec2[time.zone.exception]{Exception classes} + +\rSec3[time.zone.exception.nonexist]{Class \tcode{nonexistent_local_time}} +\indexlibrary{\idxcode{nonexistent_local_time}} + +\begin{codeblock} +namespace std::chrono { + class nonexistent_local_time : public runtime_error { + public: + template + nonexistent_local_time(const local_time& tp, const local_info& i); + }; +} +\end{codeblock} + +\pnum +\tcode{nonexistent_local_time} is thrown when +an attempt is made +to convert a non-existent \tcode{local_time} to a \tcode{sys_time} +without specifying \tcode{choose::earliest} or \tcode{choose::latest}. + +\indexlibrary{\idxcode{nonexistent_local_time}!constructor}% +\begin{itemdecl} +template + nonexistent_local_time(const local_time& tp, const local_info& i); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{i.result == local_info::nonexistent}. + +\pnum +\effects +Constructs a \tcode{nonexistent_local_time} +by initializing the base class with a sequence of \tcode{char} +equivalent to that produced by \tcode{os.str()} +initialized as shown below: + +\begin{codeblock} +ostringstream os; +os << tp << " is in a gap between\n" + << local_seconds{i.first.end.time_since_epoch()} + i.first.offset << ' ' + << i.first.abbrev << " and\n" + << local_seconds{i.second.begin.time_since_epoch()} + i.second.offset << ' ' + << i.second.abbrev + << " which are both equivalent to\n" + << i.first.end << " UTC"; +\end{codeblock} + +\pnum +\begin{example} +\begin{codeblock} +#include +#include + +int main() { + using namespace std::chrono; + try { + auto zt = zoned_time{"America/New_York", + local_days{Sunday[2]/March/2016} + 2h + 30min}; + } catch (const nonexistent_local_time& e) { + std::cout << e.what() << '\n'; + } +} +\end{codeblock} + +Produces the output: + +\begin{codeblock} +2016-03-13 02:30:00 is in a gap between +2016-03-13 02:00:00 EST and +2016-03-13 03:00:00 EDT which are both equivalent to +2016-03-13 07:00:00 UTC +\end{codeblock} +\end{example} +\end{itemdescr} + +\rSec3[time.zone.exception.ambig]{Class \tcode{ambiguous_local_time}} +\indexlibrary{\idxcode{ambiguous_local_time}} + +\begin{codeblock} +namespace std::chrono { + class ambiguous_local_time : public runtime_error { + public: + template + ambiguous_local_time(const local_time& tp, const local_info& i); + }; +} +\end{codeblock} + +\pnum +\tcode{ambiguous_local_time} is thrown when +an attempt is made +to convert an ambiguous \tcode{local_time} to a \tcode{sys_time} +without specifying \tcode{choose::earliest} or \tcode{choose::latest}. + +\indexlibrary{\idxcode{ambiguous_local_time}!constructor}% +\begin{itemdecl} +template + ambiguous_local_time(const local_time& tp, const local_info& i); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{i.result == local_info::ambiguous}. + +\pnum +\effects +Constructs an \tcode{ambiguous_local_time} +by initializing the base class with a sequence of \tcode{char} +equivalent to that produced by \tcode{os.str()} +initialized as shown below: + +\begin{codeblock} +ostringstream os; +os << tp << " is ambiguous. It could be\n" + << tp << ' ' << i.first.abbrev << " == " + << tp - i.first.offset << " UTC or\n" + << tp << ' ' << i.second.abbrev << " == " + << tp - i.second.offset << " UTC"; +\end{codeblock} + +\pnum +\begin{example} +\begin{codeblock} +#include +#include + +int main() { + using namespace std::chrono; + try { + auto zt = zoned_time{"America/New_York", + local_days{Sunday[1]/November/2016} + 1h + 30min}; + } catch (const ambiguous_local_time& e) { + std::cout << e.what() << '\n'; + } +} +\end{codeblock} + +Produces the output: + +\begin{codeblock} +2016-11-06 01:30:00 is ambiguous. It could be +2016-11-06 01:30:00 EDT == 2016-11-06 05:30:00 UTC or +2016-11-06 01:30:00 EST == 2016-11-06 06:30:00 UTC +\end{codeblock} +\end{example} +\end{itemdescr} + +\rSec2[time.zone.info]{Information classes} + +\rSec3[time.zone.info.sys]{Class \tcode{sys_info}} +\indexlibrary{\idxcode{sys_info}} + +\begin{codeblock} +namespace std::chrono { + struct sys_info { + sys_seconds begin; + sys_seconds end; + seconds offset; + minutes save; + string abbrev; + }; +} +\end{codeblock} + +\pnum +A \tcode{sys_info} structure can be obtained +from the combination of a \tcode{time_zone} and +either a \tcode{sys_time} or \tcode{local_time}. +It can also be obtained from a \tcode{zoned_time}, +which is effectively a pair of a \tcode{time_zone} and \tcode{sys_time}. + +\pnum +\begin{note} +This type provides a low-level interface to time zone information. +Typical conversions from \tcode{sys_time} to \tcode{local_time} +will use this structure implicitly, not explicitly. +\end{note} + +\pnum +\indexlibrarymember{begin}{sys_info}% +\indexlibrarymember{end}{sys_info}% +The \tcode{begin} and \tcode{end} data members indicate that, +for the associated \tcode{time_zone} and \tcode{time_point}, +the \tcode{offset} and \tcode{abbrev} are in effect in the range \range{begin}{end}. +This information can be used to efficiently iterate the transitions of a \tcode{time_zone}. + +\pnum +\indexlibrarymember{offset}{sys_info}% +The \tcode{offset} data member indicates +the UTC offset in effect +for the associated \tcode{time_zone} and \tcode{time_point}. +The relationship between \tcode{local_time} and \tcode{sys_time} is: + +\begin{codeblock} +offset = local_time - sys_time +\end{codeblock} + +\pnum +\indexlibrarymember{save}{sys_info}% +The \tcode{save} data member is extra information not normally needed +for conversion between \tcode{local_time} and \tcode{sys_time}. +If \tcode{save != 0min}, this \tcode{sys_info} is said to be on ``daylight saving'' time, +and \tcode{offset - save} suggests what offset this \tcode{time_zone} might use +if it were off daylight saving time. +However, this information should not be taken as authoritative. +The only sure way to get such information +is to query the \tcode{time_zone} with a \tcode{time_point} +that returns a \tcode{sys_info} where \tcode{save == 0min}. +There is no guarantee what \tcode{time_point} might return such a \tcode{sys_info} +except that it is guaranteed not to be in the range \range{begin}{end} +(if \tcode{save != 0min} for this \tcode{sys_info}). + +\pnum +\indexlibrarymember{abbrev}{sys_info}% +The \tcode{abbrev} data member indicates +the current abbreviation used for the associated \tcode{time_zone} and \tcode{time_point}. +Abbreviations are not unique among the \tcode{time_zones}, +and so one cannot reliably map abbreviations back to a \tcode{time_zone} and UTC offset. + +\indexlibrarymember{operator<<}{sys_info} +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const sys_info& r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Streams out the \tcode{sys_info} object \tcode{r} in an unspecified format. +\end{itemdescr} + +\rSec3[time.zone.info.local]{Class \tcode{local_info}} +\indexlibrary{\idxcode{local_info}} + +\indexlibrarymember{unique}{local_info}% +\indexlibrarymember{nonexistent}{local_info}% +\indexlibrarymember{ambiguous}{local_info}% +\indexlibrarymember{result}{local_info}% +\indexlibrarymember{first}{local_info}% +\indexlibrarymember{second}{local_info}% +\begin{codeblock} +namespace std::chrono { + struct local_info { + static constexpr int unique = 0; + static constexpr int nonexistent = 1; + static constexpr int ambiguous = 2; + + int result; + sys_info first; + sys_info second; + }; +} +\end{codeblock} + +\pnum +\begin{note} +This type provides a low-level interface to time zone information. +Typical conversions from \tcode{local_time} to \tcode{sys_time} +will use this structure implicitly, not explicitly. +\end{note} + +\pnum +Describes the result of converting a \tcode{local_time} to a \tcode{sys_time} +as follows: +\begin{itemize} +\item +When a \tcode{local_time} to \tcode{sys_time} conversion is unique, +\tcode{result == unique}, +\tcode{first} will be filled out with the correct \tcode{sys_info}, +and +\tcode{second} will be zero-initialized. + +\item +If the conversion stems from a nonexistent \tcode{local_time} +then \tcode{result == nonexistent}, +\tcode{first} will be filled out with the \tcode{sys_info} +that ends just prior to the \tcode{local_time}, +and +\tcode{second} will be filled out with the \tcode{sys_info} +that begins just after the \tcode{local_time}. + +\item +If the conversion stems from an ambiguous \tcode{local_time}, +then \tcode{result == ambiguous}, +\tcode{first} will be filled out with the \tcode{sys_info} +that ends just after the \tcode{local_time}, +and +\tcode{second} will be filled out with the \tcode{sys_info} +that starts just before the \tcode{local_time}. +\end{itemize} + +\indexlibrarymember{operator<<}{local_info}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, const local_info& r); +\end{itemdecl} + +\begin{itemdescr} +\pnum +Streams out the \tcode{local_info} object \tcode{r} in an unspecified format. +\end{itemdescr} + +\rSec2[time.zone.timezone]{Class \tcode{time_zone}} + +\rSec3[time.zone.overview]{Overview} +\indexlibrary{\idxcode{time_zone}} + +\begin{codeblock} +namespace std::chrono { + class time_zone { + public: + time_zone(time_zone&&) = default; + time_zone& operator=(time_zone&&) = default; + + // unspecified additional constructors + + string_view name() const noexcept; + + template sys_info get_info(const sys_time& st) const; + template local_info get_info(const local_time& tp) const; + + template + sys_time> + to_sys(const local_time& tp) const; + + template + sys_time> + to_sys(const local_time& tp, choose z) const; + + template + local_time> + to_local(const sys_time& tp) const; + }; +} +\end{codeblock} + +\pnum +A \tcode{time_zone} represents all time zone transitions +for a specific geographic area. +\tcode{time_zone} construction is unspecified, +and performed as part of database initialization. +\begin{note} +\tcode{const time_zone} objects can be accessed +via functions such as \tcode{locate_zone}. +\end{note} + +\rSec3[time.zone.members]{Member functions} + +\indexlibrarymember{name}{time_zone}% +\begin{itemdecl} +string_view name() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns The name of the \tcode{time_zone}. + +\pnum +\begin{example} +\tcode{"America/New_York"}. +\end{example} +\end{itemdescr} + +\indexlibrarymember{get_info}{time_zone}% +\begin{itemdecl} +template + sys_info get_info(const sys_time& st) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{sys_info} \tcode{i} for which +\tcode{st} is in the range \range{i.begin}{i.end}. +\end{itemdescr} + +\indexlibrarymember{get_info}{time_zone}% +\begin{itemdecl} +template + local_info get_info(const local_time& tp) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{local_info} for \tcode{tp}. +\end{itemdescr} + +\indexlibrarymember{to_sys}{time_zone}% +\begin{itemdecl} +template + sys_time> + to_sys(const local_time& tp) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{sys_time} that is at least as fine as \tcode{seconds}, +and will be finer if the argument \tcode{tp} has finer precision. +This \tcode{sys_time} is the UTC equivalent of \tcode{tp} +according to the rules of this \tcode{time_zone}. + +\pnum +\throws +If the conversion from \tcode{tp} to a \tcode{sys_time} is ambiguous, +throws \tcode{ambiguous_local_time}. +If the \tcode{tp} represents a non-existent time between two UTC \tcode{time_points}, +throws \tcode{nonexistent_local_time}. +\end{itemdescr} + +\indexlibrarymember{to_sys}{time_zone}% +\begin{itemdecl} +template + sys_time> + to_sys(const local_time& tp, choose z) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{sys_time} that is at least as fine as \tcode{seconds}, +and will be finer if the argument \tcode{tp} has finer precision. +This \tcode{sys_time} is the UTC equivalent of \tcode{tp} +according to the rules of this \tcode{time_zone}. +If the conversion from \tcode{tp} to a \tcode{sys_time} is ambiguous, +returns the earlier \tcode{sys_time} if \tcode{z == choose::earliest}, and +returns the later \tcode{sys_time} if \tcode{z == choose::latest}. +If the \tcode{tp} represents a non-existent time between two UTC \tcode{time_points}, +then the two UTC \tcode{time_points} will be the same, +and that UTC \tcode{time_point} will be returned. +\end{itemdescr} + +\indexlibrarymember{to_local}{time_zone}% +\begin{itemdecl} +template + local_time> + to_local(const sys_time& tp) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The \tcode{local_time} associated with \tcode{tp} and this \tcode{time_zone}. +\end{itemdescr} + +\rSec3[time.zone.nonmembers]{Non-member functions} + +\indexlibrarymember{operator==}{time_zone}% +\begin{itemdecl} +bool operator==(const time_zone& x, const time_zone& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x.name() == y.name()}. +\end{itemdescr} + +\indexlibrarymember{operator<}{time_zone}% +\begin{itemdecl} +bool operator<(const time_zone& x, const time_zone& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x.name() < y.name()}. +\end{itemdescr} + +\rSec2[time.zone.zonedtraits]{Class template \tcode{zoned_traits}} +\indexlibrary{\idxcode{zoned_traits}} + +\begin{codeblock} +namespace std::chrono { + template struct zoned_traits {}; +} +\end{codeblock} + +\pnum +\tcode{zoned_traits} provides a means for customizing +the behavior of \tcode{zoned_time} +for the \tcode{zoned_time} default constructor, +and constructors taking \tcode{string_view}. +A specialization for \tcode{const time_zone*} is provided by the implementation: + +\begin{codeblock} +namespace std::chrono { + template<> struct zoned_traits { + static const time_zone* default_zone(); + static const time_zone* locate_zone(string_view name); + }; +} +\end{codeblock} + +\indexlibrarymember{default_zone}{zoned_traits}% +\begin{itemdecl} +static const time_zone* default_zone(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{std::chrono::locate_zone("UTC")}. +\end{itemdescr} + +\indexlibrarymember{locate_zone}{zoned_traits}% +\begin{itemdecl} +static const time_zone* locate_zone(string_view name); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{std::chrono::locate_zone(name)}. +\end{itemdescr} + +\rSec2[time.zone.zonedtime]{Class template \tcode{zoned_time}} + +\rSec3[time.zone.zonedtime.overview]{Overview} +\indexlibrary{\idxcode{zoned_time}} + +\begin{codeblock} +namespace std::chrono { + template + class zoned_time { + public: + using duration = common_type_t; + + private: + TimeZonePtr zone_; // \expos + sys_time tp_; // \expos + + using traits = zoned_traits; // \expos + + public: + zoned_time(); + zoned_time(const zoned_time&) = default; + zoned_time& operator=(const zoned_time&) = default; + + zoned_time(const sys_time& st); + explicit zoned_time(TimeZonePtr z); + explicit zoned_time(string_view name); + + template + zoned_time(const zoned_time& zt) noexcept; + + zoned_time(TimeZonePtr z, const sys_time& st); + zoned_time(string_view name, const sys_time& st); + + zoned_time(TimeZonePtr z, const local_time& tp); + zoned_time(string_view name, const local_time& tp); + zoned_time(TimeZonePtr z, const local_time& tp, choose c); + zoned_time(string_view name, const local_time& tp, choose c); + + template + zoned_time(TimeZonePtr z, const zoned_time& zt); + template + zoned_time(TimeZonePtr z, const zoned_time& zt, choose); + + zoned_time(string_view name, const zoned_time& zt); + zoned_time(string_view name, const zoned_time& zt, choose); + + zoned_time& operator=(const sys_time& st); + zoned_time& operator=(const local_time& ut); + + operator sys_time() const; + explicit operator local_time() const; + + TimeZonePtr get_time_zone() const; + local_time get_local_time() const; + sys_time get_sys_time() const; + sys_info get_info() const; + }; + + zoned_time() -> zoned_time; + + template + zoned_time(sys_time) + -> zoned_time>; + + template + zoned_time(TimeZonePtr, sys_time) + -> zoned_time, TimeZonePtr>; + + template + zoned_time(TimeZonePtr, local_time, choose = choose::earliest) + -> zoned_time, TimeZonePtr>; + + template + zoned_time(TimeZonePtr, zoned_time, choose = choose::earliest) + -> zoned_time, TimeZonePtr>; + + zoned_time(string_view) -> zoned_time; + + template + zoned_time(string_view, sys_time) + -> zoned_time>; + + template + zoned_time(string_view, local_time, choose = choose::earliest) + -> zoned_time>; + + template + zoned_time(TimeZonePtr, zoned_time, choose = choose::earliest) + -> zoned_time; +} +\end{codeblock} + +\pnum +\tcode{zoned_time} represents a logical pairing of +a \tcode{time_zone} and a \tcode{time_point} with precision \tcode{Duration}. +\tcode{zoned_time} maintains the invariant that +it always refers to a valid time zone and +represents a point in time that exists and is not ambiguous +in that time zone. + +\pnum +If \tcode{Duration} is not a specialization of \tcode{chrono::duration}, +the program is ill-formed. + +\rSec3[time.zone.zonedtime.ctor]{Constructors} + +\indexlibrary{\idxcode{zoned_time}!constructor|(}% +\begin{itemdecl} +zoned_time(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +This constructor does not participate in overload resolution unless +\tcode{traits::default_zone()} is a well-formed expression. + +\pnum +\effects +Constructs a \tcode{zoned_time} by +initializing \tcode{zone_} with \tcode{traits::default_zone()} and +default constructing \tcode{tp_}. +\end{itemdescr} + +\begin{itemdecl} +zoned_time(const sys_time& st); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +This constructor does not participate in overload resolution unless +\tcode{traits::default_zone()} is a well-formed expression. + +\pnum +\effects +Constructs a \tcode{zoned_time} by +initializing \tcode{zone_} with \tcode{traits::default_zone()} and \tcode{tp_} with \tcode{st}. +\end{itemdescr} + +\begin{itemdecl} +explicit zoned_time(TimeZonePtr z); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{z} refers to a time zone. + +\pnum +\effects Constructs a \tcode{zoned_time} by +initializing \tcode{zone_} with \tcode{std::move(z)}. +% FIXME: What about tp_? +\end{itemdescr} + +\begin{itemdecl} +explicit zoned_time(string_view name); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +This constructor does not participate in overload resolution unless +\tcode{traits::locate_zone(string_view\{\})} is a well-formed expression and +\tcode{zoned_time} is constructible from the return type of \tcode{traits::locate_zone(string_view\{\})}. + +\pnum +\effects +Constructs a \tcode{zoned_time} by +initializing \tcode{zone_} with \tcode{traits::locate_zone(name)} and +default constructing \tcode{tp_}. +\end{itemdescr} + +\begin{itemdecl} +template + zoned_time(const zoned_time& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +Does not participate in overload resolution unless +\tcode{sys_time} is implicitly convertible to \tcode{sys_time}. + +\pnum +\effects +Constructs a \tcode{zoned_time} by +initializing \tcode{zone_} with \tcode{y.zone_} and \tcode{tp_} with \tcode{y.tp_}. +\end{itemdescr} + +\begin{itemdecl} +zoned_time(TimeZonePtr z, const sys_time& st); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{z} refers to a time zone. + +\pnum +\effects +Constructs a \tcode{zoned_time} by +initializing \tcode{zone_} with \tcode{std::move(z)} and \tcode{tp_} with \tcode{st}. +\end{itemdescr} + +\begin{itemdecl} +zoned_time(string_view name, const sys_time& st); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +This constructor does not participate in overload resolution unless +\tcode{zoned_time} is constructible from the return type of \tcode{traits::locate_zone(name)} and \tcode{st}. + +\pnum +\effects +Equivalent to construction with \tcode{\{traits::locate_zone(name), st\}}. +\end{itemdescr} + +\begin{itemdecl} +zoned_time(TimeZonePtr z, const local_time& tp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{z} refers to a time zone. + +\pnum +\remarks +This constructor does not participate in overload resolution unless +\begin{codeblock} +decltype(declval()->to_sys(local_time{})) +\end{codeblock} +is convertible to \tcode{sys_time}. + +\pnum +\effects +Constructs a \tcode{zoned_time} by +initializing \tcode{zone_} with \tcode{std::move(z)} and \tcode{tp_} with \tcode{zone_->to_sys(tp)}. +\end{itemdescr} + +\begin{itemdecl} +zoned_time(string_view name, const local_time& tp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +This constructor does not participate in overload resolution unless +\tcode{zoned_time} is constructible from the return type of \tcode{traits::locate_zone(name)} and \tcode{tp}. + +\pnum +\effects +Equivalent to construction with \tcode{\{traits::locate_zone(name), tp\}}. +\end{itemdescr} + +\begin{itemdecl} +zoned_time(TimeZonePtr z, const local_time& tp, choose c); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\requires \tcode{z} refers to a time zone. + +\pnum +\remarks +This constructor does not participate in overload resolution unless +\begin{codeblock} +decltype(declval()->to_sys(local_time{}, choose::earliest)) +\end{codeblock} +is convertible to \tcode{sys_time}. + +\pnum +\effects +Constructs a \tcode{zoned_time} by +initializing \tcode{zone_} with \tcode{std::move(z)} and \tcode{tp_} with \tcode{zone_->to_sys(tp, c)}. +\end{itemdescr} + +\begin{itemdecl} +zoned_time(string_view name, const local_time& tp, choose c); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +This constructor does not participate in overload resolution unless +\tcode{zoned_time} is constructible from +the return type of \tcode{traits::locate_zone(name)}, \tcode{local_time}, and \tcode{choose}. + +\pnum +\effects +Equivalent to construction with \tcode{\{traits::locate_zone(name), tp, c\}}. +\end{itemdescr} + +\begin{itemdecl} +template + zoned_time(TimeZonePtr z, const zoned_time& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +Does not participate in overload resolution unless +\tcode{sys_time} is implicitly convertible to \tcode{sys_time}. + +\pnum +\requires \tcode{z} refers to a valid time zone. + +\pnum +\effects Constructs a \tcode{zoned_time} by +initializing \tcode{zone_} with \tcode{std::move(z)} and \tcode{tp_} with \tcode{y.tp_}. +\end{itemdescr} + +\begin{itemdecl} +template + zoned_time(TimeZonePtr z, const zoned_time& y, choose); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +Does not participate in overload resolution unless +\tcode{sys_time} is implicitly convertible to \tcode{sys_time}. + +\pnum +\requires \tcode{z} refers to a valid time zone. + +\pnum +\effects +Equivalent to construction with \tcode{\{z, y\}}. + +\pnum +\begin{note} +The \tcode{choose} parameter has no effect. +\end{note} +\end{itemdescr} + +\begin{itemdecl} +zoned_time(string_view name, const zoned_time& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +This constructor does not participate in overload resolution unless +\tcode{zoned_time} is constructible from the return type of \tcode{traits::locate_zone(name)} and \tcode{zoned_time}. + +\pnum +\effects +Equivalent to construction with \tcode{\{traits::locate_zone(name), y\}}. +\end{itemdescr} + +\begin{itemdecl} +zoned_time(string_view name, const zoned_time& y, choose c); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +This constructor does not participate in overload resolution unless +\tcode{zoned_time} is constructible from +the return type of \tcode{traits::locate_zone(name)}, \tcode{zoned_time}, and \tcode{choose}. + +\pnum +\effects +Equivalent to construction with \tcode{\{traits::locate_zone(name), y, c\}}. + +\pnum +\begin{note} +The \tcode{choose} parameter has no effect. +\end{note} +\end{itemdescr} +\indexlibrary{\idxcode{zoned_time}!constructor|)}% + +\rSec3[time.zone.zonedtime.members]{Member functions} + +\indexlibrarymember{operator=}{zoned_time}% +\begin{itemdecl} +zoned_time& operator=(const sys_time& st); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +After assignment, \tcode{get_sys_time() == st}. +This assignment has no effect on the return value of \tcode{get_time_zone()}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator=}{zoned_time}% +\begin{itemdecl} +zoned_time& operator=(const local_time& lt); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +After assignment, \tcode{get_local_time() == lt}. +This assignment has no effect on the return value of \tcode{get_time_zone()}. + +\pnum +\returns \tcode{*this}. +\end{itemdescr} + +\indexlibrarymember{operator sys_time}{zoned_time}% +\begin{itemdecl} +operator sys_time() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{get_sys_time()}. +\end{itemdescr} + +\indexlibrarymember{operator local_time}{zoned_time}% +\begin{itemdecl} +explicit operator local_time() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{get_local_time()}. +\end{itemdescr} + +\indexlibrarymember{get_time_zone}{zoned_time}% +\begin{itemdecl} +TimeZonePtr get_time_zone() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{zone_}. +\end{itemdescr} + +\indexlibrarymember{get_local_time}{zoned_time}% +\begin{itemdecl} +local_time get_local_time() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{zone_->to_local(tp_)}. +\end{itemdescr} + +\indexlibrarymember{get_sys_time}{zoned_time}% +\begin{itemdecl} +sys_time get_sys_time() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{tp_}. +\end{itemdescr} + +\indexlibrarymember{get_info}{zoned_time}% +\begin{itemdecl} +sys_info get_info() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{zone_->get_info(tp_)}. +\end{itemdescr} + +\rSec3[time.zone.zonedtime.nonmembers]{Non-member functions} + +\indexlibrarymember{operator==}{zoned_time}% +\begin{itemdecl} +template + bool operator==(const zoned_time& x, + const zoned_time& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x.zone_ == y.zone_ \&\& x.tp_ == y.tp_}. +\end{itemdescr} + +\indexlibrarymember{operator"!=}{zoned_time}% +\begin{itemdecl} +template + bool operator!=(const zoned_time& x, + const zoned_time& y); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{!(x == y)}. +\end{itemdescr} + +\indexlibrarymember{operator<<}{zoned_time}% +\begin{itemdecl} +template + basic_ostream& + operator<<(basic_ostream& os, + const zoned_time& t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Streams +the value returned from \tcode{t.get_local_time()} +to \tcode{os} +using the format \tcode{"\%F \%T \%Z"}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\indexlibrarymember{to_stream}{zoned_time}% +\begin{itemdecl} +template + basic_ostream& + to_stream(basic_ostream& os, const charT* fmt, + const zoned_time& tp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +First obtains a \tcode{sys_info} via \tcode{tp.get_info()} +which for exposition purposes will be referred to as \tcode{info}. +Then calls \tcode{to_stream(os, fmt, tp.get_local_time(), \&info.abbrev, \&info.offset)}. + +\pnum +\returns \tcode{os}. +\end{itemdescr} + +\rSec2[time.zone.leap]{Class \tcode{leap}} + +\rSec3[time.zone.leap.overview]{Overview} +\indexlibrary{\idxcode{leap}} + +\begin{codeblock} +namespace std::chrono { + class leap { + public: + leap(const leap&) = default; + leap& operator=(const leap&) = default; + + // unspecified additional constructors + + constexpr sys_seconds date() const noexcept; + }; +} +\end{codeblock} + +\pnum +Objects of type \tcode{leap} representing +the date of the leap second insertions +are constructed and stored in the time zone database when initialized. + +\pnum +\begin{example} +\begin{codeblock} +for (auto& l : get_tzdb().leaps) + if (l <= 2018y/March/17d) + cout << l.date() << '\n'; +\end{codeblock} + +Produces the output: + +\begin{codeblock} +1972-07-01 00:00:00 +1973-01-01 00:00:00 +1974-01-01 00:00:00 +1975-01-01 00:00:00 +1976-01-01 00:00:00 +1977-01-01 00:00:00 +1978-01-01 00:00:00 +1979-01-01 00:00:00 +1980-01-01 00:00:00 +1981-07-01 00:00:00 +1982-07-01 00:00:00 +1983-07-01 00:00:00 +1985-07-01 00:00:00 +1988-01-01 00:00:00 +1990-01-01 00:00:00 +1991-01-01 00:00:00 +1992-07-01 00:00:00 +1993-07-01 00:00:00 +1994-07-01 00:00:00 +1996-01-01 00:00:00 +1997-07-01 00:00:00 +1999-01-01 00:00:00 +2006-01-01 00:00:00 +2009-01-01 00:00:00 +2012-07-01 00:00:00 +2015-07-01 00:00:00 +2017-01-01 00:00:00 +\end{codeblock} +\end{example} + +\rSec3[time.zone.leap.members]{Member functions} + +\indexlibrarymember{date}{leap}% +\begin{itemdecl} +constexpr sys_seconds date() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns The date and time at which the leap second was inserted. +\end{itemdescr} + +\rSec3[time.zone.leap.nonmembers]{Non-member functions} + +\indexlibrarymember{operator==}{leap}% +\begin{itemdecl} +constexpr bool operator==(const leap& x, const leap& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x.date() == y.date()}. +\end{itemdescr} + +\indexlibrarymember{operator<}{leap}% +\begin{itemdecl} +constexpr bool operator<(const leap& x, const leap& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x.date() < y.date()}. +\end{itemdescr} + +\indexlibrarymember{operator==}{leap}% +\indexlibrarymember{operator==}{sys_time}% +\begin{itemdecl} +template + constexpr bool operator==(const leap& x, const sys_time& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x.date() == y}. +\end{itemdescr} + +\indexlibrarymember{operator==}{leap}% +\indexlibrarymember{operator==}{sys_time}% +\begin{itemdecl} +template + constexpr bool operator==(const sys_time& x, const leap& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y == x}. +\end{itemdescr} + +\indexlibrarymember{operator"!=}{leap}% +\indexlibrarymember{operator"!=}{sys_time}% +\begin{itemdecl} +template + constexpr bool operator!=(const leap& x, const sys_time& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{!(x == y)}. +\end{itemdescr} + +\indexlibrarymember{operator"!=}{leap}% +\indexlibrarymember{operator"!=}{sys_time}% +\begin{itemdecl} +template + constexpr bool operator!=(const sys_time& x, const leap& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{!(x == y)}. +\end{itemdescr} + +\indexlibrarymember{operator<}{leap}% +\indexlibrarymember{operator<}{sys_time}% +\begin{itemdecl} +template + constexpr bool operator<(const leap& x, const sys_time& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x.date() < y}. +\end{itemdescr} + +\indexlibrarymember{operator<}{leap}% +\indexlibrarymember{operator<}{sys_time}% +\begin{itemdecl} +template + constexpr bool operator<(const sys_time& x, const leap& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x < y.date()}. +\end{itemdescr} + +\indexlibrarymember{operator>}{leap}% +\indexlibrarymember{operator>}{sys_time}% +\begin{itemdecl} +template + constexpr bool operator>(const leap& x, const sys_time& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y < x}. +\end{itemdescr} + +\indexlibrarymember{operator>}{leap}% +\indexlibrarymember{operator>}{sys_time}% +\begin{itemdecl} +template + constexpr bool operator>(const sys_time& x, const leap& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{y < x}. +\end{itemdescr} + +\indexlibrarymember{operator<=}{leap}% +\indexlibrarymember{operator<=}{sys_time}% +\begin{itemdecl} +template + constexpr bool operator<=(const leap& x, const sys_time& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{!(y < x)}. +\end{itemdescr} + +\indexlibrarymember{operator<=}{leap}% +\indexlibrarymember{operator<=}{sys_time}% +\begin{itemdecl} +template + constexpr bool operator<=(const sys_time& x, const leap& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{!(y < x)}. +\end{itemdescr} + +\indexlibrarymember{operator>=}{leap}% +\indexlibrarymember{operator>=}{sys_time}% +\begin{itemdecl} +template + constexpr bool operator>=(const leap& x, const sys_time& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{!(x < y)}. +\end{itemdescr} + +\indexlibrarymember{operator>=}{leap}% +\indexlibrarymember{operator>=}{sys_time}% +\begin{itemdecl} +template + constexpr bool operator>=(const sys_time& x, const leap& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{!(x < y)}. +\end{itemdescr} + +\rSec2[time.zone.link]{Class \tcode{link}} + +\rSec3[time.zone.link.overview]{Overview} +\indexlibrary{\idxcode{link}} + +\begin{codeblock} +namespace std::chrono { + class link { + public: + link(link&&) = default; + link& operator=(link&&) = default; + + // unspecified additional constructors + + string_view name() const noexcept; + string_view target() const noexcept; + }; +} +\end{codeblock} + +\pnum +A \tcode{link} specifies an alternative name for a \tcode{time_zone}. +\tcode{link}s are constructed when the time zone database is initialized. + +\rSec3[time.zone.link.members]{Member functions} + +\indexlibrarymember{name}{link}% +\begin{itemdecl} +string_view name() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The alternative name for the time zone. +\end{itemdescr} + +\indexlibrarymember{target}{link}% +\begin{itemdecl} +string_view target() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +The name of the \tcode{time_zone} for which +this \tcode{link} provides an alternative name. +\end{itemdescr} + +\rSec3[time.zone.link.nonmembers]{Non-member functions} + +\indexlibrarymember{operator==}{link}% +\begin{itemdecl} +bool operator==(const link& x, const link& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x.name() == y.name()}. +\end{itemdescr} + +\indexlibrarymember{operator<}{link}% +\begin{itemdecl} +bool operator<(const link& x, const link& y) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{x.name() < y.name()}. +\end{itemdescr} + +\rSec1[time.format]{Formatting} + +\pnum +Each \tcode{format} overload specified in this subclause +calls \tcode{to_stream} unqualified, +so as to enable argument dependent lookup\iref{basic.lookup.argdep}. + +\indexlibrary{\idxcode{format}|(}% +\begin{itemdecl} +template + basic_string + format(const charT* fmt, const Streamable& s); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +This function shall not participate in overload resolution unless +\begin{codeblock} +to_stream(declval&>(), fmt, s) +\end{codeblock} +is a valid expression. + +\pnum +\effects +Constructs a local variable of type +\tcode{basic_ostringstream} +(named \tcode{os} for exposition purposes). +Executes \tcode{os.exceptions(ios::failbit | ios::badbit)}. +Then calls \tcode{to_stream(os, fmt, s)}. + +\pnum +\returns \tcode{os.str()}. +\end{itemdescr} + +\begin{itemdecl} +template + basic_string + format(const locale& loc, const charT* fmt, const Streamable& s); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +This function shall not participate in overload resolution unless +\begin{codeblock} +to_stream(declval&>(), fmt, s) +\end{codeblock} +is a valid expression. + +\pnum +\effects +Constructs a local variable of type +\tcode{basic_ostringstream} +(named \tcode{os} for exposition purposes). +Executes \tcode{os.exceptions(ios::failbit | ios::badbit)}. +Then calls \tcode{os.imbue(loc)}. +Then calls \tcode{to_stream(os, fmt, s)}. + +\pnum +\returns \tcode{os.str()}. +\end{itemdescr} + +\begin{itemdecl} +template + basic_string + format(const basic_string& fmt, const Streamable& s); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +This function shall not participate in overload resolution unless +\begin{codeblock} +to_stream(declval&>(), fmt.c_str(), s) +\end{codeblock} +is a valid expression. + +\pnum +\effects +Constructs a local variable of type +\tcode{basic_ostringstream} +(named \tcode{os} for exposition purposes). +Executes \tcode{os.exceptions(ios::failbit | ios::badbit)}. +Then calls \tcode{to_stream(os, fmt.c_str(), s)}. + +\pnum +\returns \tcode{os.str()}. +\end{itemdescr} + +\begin{itemdecl} +template + basic_string + format(const locale& loc, const basic_string& fmt, const Streamable& s); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +This function shall not participate in overload resolution unless +\begin{codeblock} +to_stream(declval&>(), fmt.c_str(), s) +\end{codeblock} +is a valid expression. + +\pnum +\effects +Constructs a local variable of type +\tcode{basic_ostringstream} +(named \tcode{os} for exposition purposes). +Then calls \tcode{os.imbue(loc)}. +Executes \tcode{os.exceptions(ios::failbit | ios::badbit)}. +Then calls \tcode{to_stream(os, fmt.c_str(), s)}. + +\pnum +\returns \tcode{os.str()}. +\end{itemdescr} + +\pnum +The \tcode{format} functions call a \tcode{to_stream} function with +a \tcode{basic_ostream}, +a formatting string specifier, +and a \tcode{Streamable} argument. +Each \tcode{to_stream} overload is customized for each \tcode{Streamable} type. +However all \tcode{to_stream} overloads +treat the formatting string specifier +according to the following specification: + +\pnum +The \tcode{fmt} string consists of zero or more conversion specifiers +and ordinary multibyte characters. +A conversion specifier consists of +a \tcode{\%} character, +possibly followed by an \tcode{E} or \tcode{O} modifier character (described below), +followed by a character that determines the behavior of the conversion specifier. +All ordinary multibyte characters (excluding the terminating null character) +are streamed unchanged into the \tcode{basic_ostream}. + +\pnum +Each conversion specifier is replaced by appropriate characters +as described in Table~\ref{tab:time.format.spec}. +Some of the conversion specifiers +depend on the locale which is imbued to the \tcode{basic_ostream}. +If the \tcode{Streamable} object does not contain +the information the conversion specifier refers to, +the value streamed to the \tcode{basic_ostream} is unspecified. + +\pnum +Unless explicitly specified, +\tcode{Streamable} types will not contain time zone abbreviation +and time zone offset information. +If available, +the conversion specifiers \tcode{\%Z} and \tcode{\%z} +will format this information (respectively). +If the information is not available, +and \tcode{\%Z} or \tcode{\%z} are contained in \tcode{fmt}, +\tcode{os.setstate(ios_base::failbit)} shall be called. + +\begin{LongTable}{Meaning of \tcode{format} conversion specifiers}{tab:time.format.spec}{lx{.8\hsize}} +\\ \topline +\lhdr{Specifier} & \rhdr{Replacement} \\ \capsep +\endfirsthead +\continuedcaption\\ +\hline +\lhdr{Specifier} & \rhdr{Replacement} \\ \capsep +\endhead +\tcode{\%a} & +The locale's abbreviated weekday name. +If the value does not contain a valid weekday, +\tcode{setstate(ios::failbit)} is called. +\\ \rowsep +\tcode{\%A} & +The locale's full weekday name. +If the value does not contain a valid weekday, +\tcode{setstate(ios::failbit)} is called. +\\ \rowsep +\tcode{\%b} & +The locale's abbreviated month name. +If the value does not contain a valid month, +\tcode{setstate(ios::failbit)} is called. +\\ \rowsep +\tcode{\%B} & +The locale's full month name. +If the value does not contain a valid month, +\tcode{setstate(ios::failbit)} is called. +\\ \rowsep +\tcode{\%c} & +The locale's date and time representation. +The modified command \tcode{\%Ec} produces +the locale's alternate date and time representation. +\\ \rowsep +\tcode{\%C} & +The year divided by 100 using floored division. +If the result is a single decimal digit, +it is prefixed with \tcode{0}. +The modified command \tcode{\%EC} produces +the locale's alternative representation of the century. +\\ \rowsep +\tcode{\%d} & +The day of month as a decimal number. +If the result is a single decimal digit, +it is prefixed with \tcode{0}. +The modified command \tcode{\%Od} produces +the locale's alternative representation. +\\ \rowsep +\tcode{\%D} & +Equivalent to \tcode{\%m/\%d/\%y}. +\\ \rowsep +\tcode{\%e} & +The day of month as a decimal number. +If the result is a single decimal digit, +it is prefixed with a space. +The modified command \tcode{\%Oe} produces +the locale's alternative representation. +\\ \rowsep +\tcode{\%F} & +Equivalent to \tcode{\%Y-\%m-\%d}. +\\ \rowsep +\tcode{\%g} & +The last two decimal digits of the ISO week-based year. +If the result is a single digit it is prefixed by \tcode{0}. +\\ \rowsep +\tcode{\%G} & +The ISO week-based year as a decimal number. +If the result is less than four digits +it is left-padded with \tcode{0} to four digits. +\\ \rowsep +\tcode{\%h} & +Equivalent to \tcode{\%b}. +\\ \rowsep +\tcode{\%H} & +The hour (24-hour clock) as a decimal number. +If the result is a single digit, +it is prefixed with \tcode{0}. +The modified command \tcode{\%OH} produces +the locale's alternative representation. +\\ \rowsep +\tcode{\%I} & +The hour (12-hour clock) as a decimal number. +If the result is a single digit, +it is prefixed with \tcode{0}. +The modified command \tcode{\%OI} produces +the locale's alternative representation. +\\ \rowsep +\tcode{\%j} & +The day of the year as a decimal number. +Jan 1 is \tcode{001}. +If the result is less than three digits, +it is left-padded with \tcode{0} to three digits. +\\ \rowsep +\tcode{\%m} & +The month as a decimal number. +Jan is \tcode{01}. +If the result is a single digit, it is prefixed with \tcode{0}. +The modified command \tcode{\%Om} produces +the locale's alternative representation. +\\ \rowsep +\tcode{\%M} & +The minute as a decimal number. +If the result is a single digit, it is prefixed with \tcode{0}. +The modified command \tcode{\%OM} produces +the locale's alternative representation. +\\ \rowsep +\tcode{\%n} & +A new-line character. +\\ \rowsep +\tcode{\%p} & +The locale's equivalent of the AM/PM designations associated with a 12-hour clock. +\\ \rowsep +\tcode{\%r} & +The locale's 12-hour clock time. +\\ \rowsep +\tcode{\%R} & +Equivalent to \tcode{\%H:\%M}. +\\ \rowsep +\tcode{\%S} & +Seconds as a decimal number. +If the number of seconds is less than \tcode{10}, the result is prefixed with \tcode{0}. +If the precision of the input cannot be exactly represented with seconds, +then the format is a decimal floating point number with a fixed format +and a precision matching that of the precision of the input +(or to a microseconds precision if the conversion to floating point decimal seconds +cannot be made within 18 fractional digits). +The character for the decimal point is localized according to the locale. +The modified command \tcode{\%OS} produces +the locale's alternative representation. +\\ \rowsep +\tcode{\%t} & +A horizontal-tab character. +\\ \rowsep +\tcode{\%T} & +Equivalent to \tcode{\%H:\%M:\%S}. +\\ \rowsep +\tcode{\%u} & +The ISO weekday as a decimal number (\tcode{1}-\tcode{7}), +where Monday is \tcode{1}. +The modified command \tcode{\%Ou} produces +the locale's alternative representation. +\\ \rowsep +\tcode{\%U} & +The week number of the year as a decimal number. +The first Sunday of the year is the first day of week \tcode{01}. +Days of the same year prior to that are in week \tcode{00}. +If the result is a single digit, it is prefixed with \tcode{0}. +The modified command \tcode{\%OU} produces +the locale's alternative representation. +\\ \rowsep +\tcode{\%V} & +The ISO week-based week number as a decimal number. +If the result is a single digit, it is prefixed with \tcode{0}. +The modified command \tcode{\%OV} produces +the locale's alternative representation. +\\ \rowsep +\tcode{\%w} & +The weekday as a decimal number (\tcode{0}-\tcode{6}), where Sunday is \tcode{0}. +The modified command \tcode{\%Ow} produces +the locale's alternative representation. +\\ \rowsep +\tcode{\%W} & +The week number of the year as a decimal number. +The first Monday of the year is the first day of week \tcode{01}. +Days of the same year prior to that are in week \tcode{00}. +If the result is a single digit, it is prefixed with \tcode{0}. +The modified command \tcode{\%OW} produces +the locale's alternative representation. +\\ \rowsep +\tcode{\%x} & +The locale's date representation. +The modified command \tcode{\%Ex} produces +the locale's alternate date representation. +\\ \rowsep +\tcode{\%X} & +The locale's time representation. +The modified command \tcode{\%EX} produces +the locale's alternate time representation. +\\ \rowsep +\tcode{\%y} & +The last two decimal digits of the year. +If the result is a single digit it is prefixed by \tcode{0}. +\\ \rowsep +\tcode{\%Y} & +The year as a decimal number. +If the result is less than four digits +it is left-padded with \tcode{0} to four digits. +\\ \rowsep +\tcode{\%z} & +The offset from UTC in the ISO 8601 format. +For example \tcode{-0430} refers to 4 hours 30 minutes behind UTC. +If the offset is zero, \tcode{+0000} is used. +The modified commands \tcode{\%Ez} and \tcode{\%Oz} +insert a \tcode{:} between the hours and minutes: \tcode{-04:30}. +If the offset information is not available, +\tcode{setstate(ios_base::failbit)} shall be called. +\\ \rowsep +\tcode{\%Z} & +The time zone abbreviation. +If the time zone abbreviation is not available, +\tcode{setstate(ios_base::failbit)} shall be called. +\\ \rowsep +\tcode{\%\%} & +A \tcode{\%} character. +\\ +\end{LongTable} + +\indexlibrary{\idxcode{format}|)}% + +\rSec1[time.parse]{Parsing} + +\indexlibrary{\idxcode{parse}|(}% + +\pnum +Each \tcode{parse} overload specified in this subclause +calls \tcode{from_stream} unqualified, +so as to enable argument dependent lookup\iref{basic.lookup.argdep}. + +\begin{itemdecl} +template + @\unspec@ + parse(const basic_string& fmt, Parsable& tp); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +This function shall not participate in overload resolution unless +\begin{codeblock} +from_stream(declval&>(), fmt.c_str(), tp) +\end{codeblock} +is a valid expression. + +\pnum +\returns +A manipulator that, when extracted from a +\tcode{basic_istream} \tcode{is}, +calls \tcode{from_stream(is, fmt.c_str(), tp)}. +\end{itemdescr} + +\begin{itemdecl} +template + @\unspec@ + parse(const basic_string& fmt, Parsable& tp, + basic_string& abbrev); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +This function shall not participate in overload resolution unless +\begin{codeblock} +from_stream(declval&>(), fmt.c_str(), tp, &abbrev) +\end{codeblock} +is a valid expression. + +\pnum +\returns +A manipulator that, when extracted from a +\tcode{basic_istream} \tcode{is}, +calls \tcode{from_stream(is, fmt.c_str(), tp, \&abbrev)}. +\end{itemdescr} + +\begin{itemdecl} +template + @\unspec@ + parse(const basic_string& fmt, Parsable& tp, + minutes& offset); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +This function shall not participate in overload resolution unless +\begin{codeblock} +from_stream(declval&>(), fmt.c_str(), tp, nullptr, &offset) +\end{codeblock} +is a valid expression. + +\pnum +\returns +A manipulator that, when extracted from a +\tcode{basic_istream} \tcode{is}, +calls \tcode{from_stream(is, fmt.c_str(), tp, nullptr, \&offset)}. +\end{itemdescr} + +\begin{itemdecl} +template + @\unspec@ + parse(const basic_string& fmt, Parsable& tp, + basic_string& abbrev, minutes& offset); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +This function shall not participate in overload resolution unless +\begin{codeblock} +from_stream(declval&>(), fmt.c_str(), tp, &abbrev, &offset) +\end{codeblock} +is a valid expression. + +\pnum +\returns +A manipulator that, when extracted from a +\tcode{basic_istream} \tcode{is}, +calls \tcode{from_stream(is, fmt.c_str(), tp, \&abbrev, \&offset)}. +\end{itemdescr} + +\pnum +All \tcode{from_stream} overloads behave as unformatted input functions, +except that they have an unspecified effect +on the value returned by subsequent calls to \tcode{basic_istream<>::gcount()}. +Each overload takes a format string containing ordinary characters +and flags which have special meaning. +Each flag begins with a \tcode{\%}. +Some flags can be modified by \tcode{E} or \tcode{O}. +During parsing each flag interprets characters as parts of date and time types +according to the table below. +Some flags can be modified by a width parameter +given as a positive decimal integer called out as \tcode{\placeholder{N}} below +which governs how many characters are parsed from the stream in interpreting the flag. +All characters in the format string that are not represented in the table below, +except for white space, are parsed unchanged from the stream. +A white space character matches zero or more white space characters in the input stream. + +\pnum +If the \tcode{from_stream} overload fails to parse +everything specified by the format string, +or if insufficient information is parsed to specify a complete +duration, time point, or calendrical data structure, +\tcode{setstate(ios_base::failbit)} +is called on the \tcode{basic_istream}. + +\begin{LongTable}{Meaning of \tcode{parse} flags}{tab:time.parse.spec}{lx{.8\hsize}} +\\ \topline +\lhdr{Flag} & \rhdr{Parsed value} \\ \capsep +\endfirsthead +\continuedcaption\\ +\hline +\lhdr{Flag} & \rhdr{Parsed value} \\ \capsep +\endhead +\tcode{\%a} & +The locale's full or abbreviated case-insensitive weekday name. +\\ \rowsep +\tcode{\%A} & +Equivalent to \tcode{\%a}. +\\ \rowsep +\tcode{\%b} & +The locale's full or abbreviated case-insensitive month name. +\\ \rowsep +\tcode{\%B} & +Equivalent to \tcode{\%b}. +\\ \rowsep +\tcode{\%c} & +The locale's date and time representation. +The modified command \tcode{\%Ec} interprets +the locale's alternate date and time representation. +\\ \rowsep +\tcode{\%C} & +The century as a decimal number. +The modified command \tcode{\%\placeholder{N}C} specifies +the maximum number of characters to read. +If \tcode{\placeholder{N}} is not specified, the default is 2. +Leading zeroes are permitted but not required. +The modified commands \tcode{\%EC} and \tcode{\%OC} interpret +the locale's alternative representation of the century. +\\ \rowsep +\tcode{\%d} & +The day of the month as a decimal number. +The modified command \tcode{\%\placeholder{N}d} specifies +the maximum number of characters to read. +If \tcode{\placeholder{N}} is not specified, the default is 2. +Leading zeroes are permitted but not required. +The modified command \tcode{\%Ed} interprets +the locale's alternative representation of the day of the month. +\\ \rowsep +\tcode{\%D} & +Equivalent to \tcode{\%m/\%d/\%y}. +\\ \rowsep +\tcode{\%e} & +Equivalent to \tcode{\%d} and can be modified like \tcode{\%d}. +\\ \rowsep +\tcode{\%F} & +Equivalent to \tcode{\%Y-\%m-\%d}. +If modified with a width \tcode{\placeholder{N}}, +the width is applied to only \tcode{\%Y}. +\\ \rowsep +\tcode{\%g} & +The last two decimal digits of the ISO week-based year. +The modified command \tcode{\%\placeholder{N}g} specifies +the maximum number of characters to read. +If \tcode{\placeholder{N}} is not specified, the default is 2. +Leading zeroes are permitted but not required. +\\ \rowsep +\tcode{\%G} & +The ISO week-based year as a decimal number. +The modified command \tcode{\%\placeholder{N}G} specifies +the maximum number of characters to read. +If \tcode{\placeholder{N}} is not specified, the default is 4. +Leading zeroes are permitted but not required. +\\ \rowsep +\tcode{\%h} & +Equivalent to \tcode{\%b}. +\\ \rowsep +\tcode{\%H} & +The hour (24-hour clock) as a decimal number. +The modified command \tcode{\%\placeholder{N}H} specifies +the maximum number of characters to read. +If \tcode{\placeholder{N}} is not specified, the default is 2. +Leading zeroes are permitted but not required. +The modified command \tcode{\%OH} interprets +the locale's alternative representation. +\\ \rowsep +\tcode{\%I} & +The hour (12-hour clock) as a decimal number. +The modified command \tcode{\%\placeholder{N}I} specifies +the maximum number of characters to read. +If \tcode{\placeholder{N}} is not specified, the default is 2. +Leading zeroes are permitted but not required. +\\ \rowsep +\tcode{\%j} & +The day of the year as a decimal number. +Jan 1 is \tcode{1}. +The modified command \tcode{\%\placeholder{N}j} specifies +the maximum number of characters to read. +If \tcode{\placeholder{N}} is not specified, the default is 3. +Leading zeroes are permitted but not required. +\\ \rowsep +\tcode{\%m} & +The month as a decimal number. +Jan is \tcode{1}. +The modified command \tcode{\%\placeholder{N}m} specifies +the maximum number of characters to read. +If \tcode{\placeholder{N}} is not specified, the default is 2. +Leading zeroes are permitted but not required. +The modified command \tcode{\%Om} interprets +the locale's alternative representation. +\\ \rowsep +\tcode{\%M} & +The minutes as a decimal number. +The modified command \tcode{\%\placeholder{N}M} specifies +the maximum number of characters to read. +If \tcode{\placeholder{N}} is not specified, the default is 2. +Leading zeroes are permitted but not required. +The modified command \tcode{\%OM} interprets +the locale's alternative representation. +\\ \rowsep +\tcode{\%n} & +Matches one white space character. +\begin{note} +\tcode{\%n}, \tcode{\%t}, and a space +can be combined to match a wide range of white-space patterns. +For example, +\tcode{"\%n "} matches one or more white space characters, and +\tcode{"\%n\%t\%t"} matches one to three white space characters. +\end{note} +\\ \rowsep +\tcode{\%p} & +The locale's equivalent of the AM/PM designations associated with a 12-hour clock. +The command \tcode{\%I} must precede \tcode{\%p} in the format string. +\\ \rowsep +\tcode{\%r} & +The locale's 12-hour clock time. +\\ \rowsep +\tcode{\%R} & +Equivalent to \tcode{\%H:\%M}. +\\ \rowsep +\tcode{\%S} & +The seconds as a decimal number. +The modified command \tcode{\%\placeholder{N}S} specifies +the maximum number of characters to read. +If \tcode{\placeholder{N}} is not specified, +the default is 2 if the input time has a precision convertible to seconds. +Otherwise the default width is determined by +the decimal precision of the input +and the field is interpreted as a \tcode{long double} in a fixed format. +If encountered, the locale determines the decimal point character. +Leading zeroes are permitted but not required. +The modified command \tcode{\%OS} interprets +the locale's alternative representation. +\\ \rowsep +\tcode{\%t} & +Matches zero or one white space characters. +\\ \rowsep +\tcode{\%T} & +Equivalent to \tcode{\%H:\%M:\%S}. +\\ \rowsep +\tcode{\%u} & +The ISO weekday as a decimal number (\tcode{1}-\tcode{7}), where Monday is \tcode{1}. +The modified command \tcode{\%\placeholder{N}u} specifies +the maximum number of characters to read. +If \tcode{\placeholder{N}} is not specified, the default is \tcode{1}. +Leading zeroes are permitted but not required. +The modified command \tcode{\%Ou} interprets +the locale's alternative representation. +\\ \rowsep +\tcode{\%U} & +The week number of the year as a decimal number. +The first Sunday of the year is the first day of week \tcode{01}. +Days of the same year prior to that are in week \tcode{00}. +The modified command \tcode{\%\placeholder{N}U} specifies +the maximum number of characters to read. +If \tcode{\placeholder{N}} is not specified, the default is 2. +Leading zeroes are permitted but not required. +\\ \rowsep +\tcode{\%V} & +The ISO week-based week number as a decimal number. +The modified command \tcode{\%\placeholder{N}V} specifies +the maximum number of characters to read. +If \tcode{\placeholder{N}} is not specified, the default is 2. +Leading zeroes are permitted but not required. +\\ \rowsep +\tcode{\%w} & +The weekday as a decimal number (\tcode{0}-\tcode{6}), where Sunday is \tcode{0}. +The modified command \tcode{\%\placeholder{N}w} specifies +the maximum number of characters to read. +If \tcode{\placeholder{N}} is not specified, the default is \tcode{1}. +Leading zeroes are permitted but not required. +The modified command \tcode{\%Ow} interprets +the locale's alternative representation. +\\ \rowsep +\tcode{\%W} & +The week number of the year as a decimal number. +The first Monday of the year is the first day of week \tcode{01}. +Days of the same year prior to that are in week \tcode{00}. +The modified command \tcode{\%\placeholder{N}W} specifies +the maximum number of characters to read. +If \tcode{\placeholder{N}} is not specified, the default is 2. +Leading zeroes are permitted but not required. +\\ \rowsep +\tcode{\%x} & +The locale's date representation. +The modified command \tcode{\%Ex} produces the locale's alternate date representation. +\\ \rowsep +\tcode{\%X} & +The locale's time representation. +The modified command \tcode{\%EX} produces the locale's alternate time representation. +\\ \rowsep +\tcode{\%y} & +The last two decimal digits of the year. +If the century is not otherwise specified +(e.g. with \tcode{\%C}), +values in the range \crange{69}{99} +are presumed to refer to the years 1969 to 1999, +and values in the range \crange{00}{68} +are presumed to refer to the years 2000 to 2068. +The modified command \tcode{\%\placeholder{N}y} specifies +the maximum number of characters to read. +If \tcode{\placeholder{N}} is not specified, the default is 2. +Leading zeroes are permitted but not required. +The modified commands \tcode{\%Ey} and \tcode{\%Oy} interpret +the locale's alternative representation. +\\ \rowsep +\tcode{\%Y} & +The year as a decimal number. +The modified command \tcode{\%\placeholder{N}Y} specifies +the maximum number of characters to read. +If \tcode{\placeholder{N}} is not specified, the default is 4. +Leading zeroes are permitted but not required. +The modified command \tcode{\%EY} interprets +the locale's alternative representation. +\\ \rowsep +\tcode{\%z} & +The offset from UTC in the format \tcode{[+|-]hh[mm]}. +For example \tcode{-0430} refers to 4 hours 30 minutes behind UTC, +and \tcode{04} refers to 4 hours ahead of UTC. +The modified commands \tcode{\%Ez} and \tcode{\%Oz} +parse a \tcode{:} between the hours and minutes +and render leading zeroes on the hour field optional: +\tcode{[+|-]h[h][:mm]}. +For example \tcode{-04:30} refers to 4 hours 30 minutes behind UTC, +and \tcode{4} refers to 4 hours ahead of UTC. +\\ \rowsep +\tcode{\%Z} & +The time zone abbreviation or name. +A single word is parsed. +This word can only contain characters +from the basic source character set\iref{lex.charset} +that are alphanumeric, or one of +\tcode{'_'}, \tcode{'/'}, \tcode{'-'}, or \tcode{'+'}. +\\ \rowsep +\tcode{\%\%} & +A \tcode{\%} character is extracted. +\\ +\end{LongTable} + +\indexlibrary{\idxcode{parse}|)} + +\rSec1[ctime.syn]{Header \tcode{} synopsis} + +\indexhdr{ctime}% +\indexlibrary{\idxcode{CLOCKS_PER_SEC}}% +\indexlibrary{\idxcode{NULL}}% +\indexlibrary{\idxcode{TIME_UTC}}% +\indexlibrary{\idxcode{asctime}}% +\indexlibrary{\idxcode{clock_t}}% +\indexlibrary{\idxcode{clock}}% +\indexlibrary{\idxcode{ctime}}% +\indexlibrary{\idxcode{difftime}}% +\indexlibrary{\idxcode{gmtime}}% +\indexlibrary{\idxcode{localtime}}% +\indexlibrary{\idxcode{mktime}}% +\indexlibrary{\idxcode{size_t}}% +\indexlibrary{\idxcode{strftime}}% +\indexlibrary{\idxcode{time_t}}% +\indexlibrary{\idxcode{timespec_get}}% +\indexlibrary{\idxcode{timespec}}% +\indexlibrary{\idxcode{time}}% +\indexlibrary{\idxcode{tm}}% +\begin{codeblock} +#define NULL @\textit{see \ref{support.types.nullptr}}@ +#define CLOCKS_PER_SEC @\seebelow@ +#define TIME_UTC @\seebelow@ + +namespace std { + using size_t = @\textit{see \ref{support.types.layout}}@; + using clock_t = @\seebelow@; + using time_t = @\seebelow@; + + struct timespec; + struct tm; + + clock_t clock(); + double difftime(time_t time1, time_t time0); + time_t mktime(struct tm* timeptr); + time_t time(time_t* timer); + int timespec_get(timespec* ts, int base); + char* asctime(const struct tm* timeptr); + char* ctime(const time_t* timer); + struct tm* gmtime(const time_t* timer); + struct tm* localtime(const time_t* timer); + size_t strftime(char* s, size_t maxsize, const char* format, const struct tm* timeptr); +} +\end{codeblock} + +\pnum +\indexhdr{time.h}% +\indexhdr{ctime}% +The contents of the header \tcode{} are the same as the C standard library header \tcode{}.% +\footnote{\tcode{strftime} supports the C conversion specifiers +\tcode{C}, \tcode{D}, \tcode{e}, \tcode{F}, \tcode{g}, \tcode{G}, \tcode{h}, +\tcode{r}, \tcode{R}, \tcode{t}, \tcode{T}, \tcode{u}, \tcode{V}, and +\tcode{z}, and the modifiers \tcode{E} and \tcode{O}.} + +\pnum +The functions \tcode{asctime}, \tcode{ctime}, \tcode{gmtime}, and +\tcode{localtime} are not required to avoid data +races\iref{res.on.data.races}. + +\xrefc{7.27} diff --git a/source/utilities.tex b/source/utilities.tex index 9edf5073a7..f94a9f7a11 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -25,8 +25,6 @@ \ref{function.objects} & Function objects & \tcode{} \\ \rowsep \ref{meta} & Type traits & \tcode{} \\ \rowsep \ref{ratio} & Compile-time rational arithmetic & \tcode{} \\ \rowsep -\ref{time} & Time utilities & \tcode{} \\ - & & \tcode{} \\ \rowsep \ref{type.index} & Type indexes & \tcode{} \\ \rowsep \ref{execpol} & Execution policies & \tcode{} \\ \rowsep \ref{charconv} & Primitive numeric conversions & \tcode{} \\ @@ -49,9 +47,9 @@ namespace std { // \ref{utility.swap}, swap template - void swap(T& a, T& b) noexcept(@\seebelow@); + constexpr void swap(T& a, T& b) noexcept(@\seebelow@); template - void swap(T (&a)[N], T (&b)[N]) noexcept(is_nothrow_swappable_v); + constexpr void swap(T (&a)[N], T (&b)[N]) noexcept(is_nothrow_swappable_v); // \ref{utility.exchange}, exchange template @@ -183,7 +181,7 @@ \indexlibrary{\idxcode{swap}}% \begin{itemdecl} template - void swap(T& a, T& b) noexcept(@\seebelow@); + constexpr void swap(T& a, T& b) noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} @@ -204,9 +202,9 @@ Type \tcode{T} shall be -\tcode{MoveConstructible} (\tref{moveconstructible}) +\oldconcept{MoveConstructible} (\tref{moveconstructible}) and -\tcode{MoveAssignable} (\tref{moveassignable}). +\oldconcept{MoveAssignable} (\tref{moveassignable}). \pnum \effects @@ -216,7 +214,7 @@ \indexlibrary{\idxcode{swap}}% \begin{itemdecl} template - void swap(T (&a)[N], T (&b)[N]) noexcept(is_nothrow_swappable_v); + constexpr void swap(T (&a)[N], T (&b)[N]) noexcept(is_nothrow_swappable_v); \end{itemdecl} \begin{itemdescr} @@ -481,14 +479,14 @@ pair(const pair&) = default; pair(pair&&) = default; - @\EXPLICIT@ constexpr pair(); - @\EXPLICIT@ constexpr pair(const T1& x, const T2& y); + explicit(@\seebelow@) constexpr pair(); + explicit(@\seebelow@) constexpr pair(const T1& x, const T2& y); template - @\EXPLICIT@ constexpr pair(U1&& x, U2&& y); + explicit(@\seebelow@) constexpr pair(U1&& x, U2&& y); template - @\EXPLICIT@ constexpr pair(const pair& p); + explicit(@\seebelow@) constexpr pair(const pair& p); template - @\EXPLICIT@ constexpr pair(pair&& p); + explicit(@\seebelow@) constexpr pair(pair&& p); template pair(piecewise_construct_t, tuple first_args, tuple second_args); @@ -517,13 +515,14 @@ 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}. + +\pnum +If \tcode{(is_trivially_destructible_v \&\& is_trivially_destructible_v)} +is \tcode{true}, then the destructor of \tcode{pair} is trivial. \indexlibrary{\idxcode{pair}!constructor}% \begin{itemdecl} -@\EXPLICIT@ constexpr pair(); +explicit(@\seebelow@) constexpr pair(); \end{itemdecl} \begin{itemdescr} @@ -538,7 +537,8 @@ \tcode{is_default_constructible_v} is \tcode{true}. \begin{note} This behavior can be implemented by a constructor template with default template arguments. \end{note} -The constructor is explicit if and only if either \tcode{first_type} or +The expression inside \tcode{explicit} evaluates to \tcode{true} +if and only if either \tcode{first_type} or \tcode{second_type} is not implicitly default-constructible. \begin{note} This behavior can be implemented with a trait that checks whether a \tcode{const first_type\&} or a \tcode{const second_type\&} @@ -547,7 +547,7 @@ \indexlibrary{\idxcode{pair}!constructor}% \begin{itemdecl} -@\EXPLICIT@ constexpr pair(const T1& x, const T2& y); +explicit(@\seebelow@) constexpr pair(const T1& x, const T2& y); \end{itemdecl} \begin{itemdescr} @@ -559,14 +559,16 @@ \remarks This constructor shall not participate in overload resolution unless \tcode{is_copy_construct\-ible_v} is \tcode{true} and \tcode{is_copy_constructible_v} is \tcode{true}. -The constructor is explicit if and only if -\tcode{is_convertible_v} is \tcode{false} or -\tcode{is_convertible_v} is \tcode{false}. +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!is_convertible_v || + !is_convertible_v +\end{codeblock} \end{itemdescr} \indexlibrary{\idxcode{pair}!constructor}% \begin{itemdecl} -template @\EXPLICIT@ constexpr pair(U1&& x, U2&& y); +template explicit(@\seebelow@) constexpr pair(U1&& x, U2&& y); \end{itemdecl} \begin{itemdescr} @@ -581,14 +583,15 @@ This constructor shall not participate in overload resolution unless \tcode{is_constructible_v} is \tcode{true} and \tcode{is_constructible_v} is \tcode{true}. -The constructor is explicit if and only if -\tcode{is_convertible_v} is \tcode{false} or -\tcode{is_convertible_v} is \tcode{false}. +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!is_convertible_v || !is_convertible_v +\end{codeblock} \end{itemdescr} \indexlibrary{\idxcode{pair}!constructor}% \begin{itemdecl} -template @\EXPLICIT@ constexpr pair(const pair& p); +template explicit(@\seebelow@) constexpr pair(const pair& p); \end{itemdecl} \begin{itemdescr} @@ -600,14 +603,15 @@ \remarks This constructor shall not participate in overload resolution unless \tcode{is_constructible_v} is \tcode{true} and \tcode{is_constructible_v} is \tcode{true}. -The constructor is explicit if and only if -\tcode{is_convertible_v} is \tcode{false} or -\tcode{is_convertible_v} is \tcode{false}. +The expression inside explicit is equivalent to: +\begin{codeblock} +!is_convertible_v || !is_convertible_v +\end{codeblock} \end{itemdescr} \indexlibrary{\idxcode{pair}!constructor}% \begin{itemdecl} -template @\EXPLICIT@ constexpr pair(pair&& p); +template explicit(@\seebelow@) constexpr pair(pair&& p); \end{itemdecl} \begin{itemdescr} @@ -622,9 +626,10 @@ \remarks This constructor shall not participate in overload resolution unless \tcode{is_constructible_v} is \tcode{true} and \tcode{is_constructible_v} is \tcode{true}. -The constructor is explicit if and only if -\tcode{is_convertible_v} is \tcode{false} or -\tcode{is_convertible_v} is \tcode{false}. +The expression inside explicit is equivalent to: +\begin{codeblock} +!is_convertible_v || !is_convertible_v +\end{codeblock} \end{itemdescr} \indexlibrary{\idxcode{pair}!constructor}% @@ -1084,43 +1089,43 @@ class tuple { public: // \ref{tuple.cnstr}, \tcode{tuple} construction - @\EXPLICIT@ constexpr tuple(); - @\EXPLICIT@ constexpr tuple(const Types&...); // only if \tcode{sizeof...(Types) >= 1} + explicit(@\seebelow@) constexpr tuple(); + explicit(@\seebelow@) constexpr tuple(const Types&...); // only if \tcode{sizeof...(Types) >= 1} template - @\EXPLICIT@ constexpr tuple(UTypes&&...); // only if \tcode{sizeof...(Types) >= 1} + explicit(@\seebelow@) constexpr tuple(UTypes&&...); // only if \tcode{sizeof...(Types) >= 1} tuple(const tuple&) = default; tuple(tuple&&) = default; template - @\EXPLICIT@ constexpr tuple(const tuple&); + explicit(@\seebelow@) constexpr tuple(const tuple&); template - @\EXPLICIT@ constexpr tuple(tuple&&); + explicit(@\seebelow@) constexpr tuple(tuple&&); template - @\EXPLICIT@ constexpr tuple(const pair&); // only if \tcode{sizeof...(Types) == 2} + explicit(@\seebelow@) constexpr tuple(const pair&); // only if \tcode{sizeof...(Types) == 2} template - @\EXPLICIT@ constexpr tuple(pair&&); // only if \tcode{sizeof...(Types) == 2} + explicit(@\seebelow@) constexpr tuple(pair&&); // only if \tcode{sizeof...(Types) == 2} // allocator-extended constructors template tuple(allocator_arg_t, const Alloc& a); template - @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, const Types&...); + explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, const Types&...); template - @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, UTypes&&...); + explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, UTypes&&...); template tuple(allocator_arg_t, const Alloc& a, const tuple&); template tuple(allocator_arg_t, const Alloc& a, tuple&&); template - @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, const tuple&); + explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, const tuple&); template - @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, tuple&&); + explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, tuple&&); template - @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, const pair&); + explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, const pair&); template - @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, pair&&); + explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, pair&&); // \ref{tuple.assign}, \tcode{tuple} assignment tuple& operator=(const tuple&); @@ -1155,6 +1160,13 @@ \rSec3[tuple.cnstr]{Construction} +\pnum +In the descriptions that follow, let $i$ be in the range +\range{0}{sizeof...(Types)} in order, $\tcode{T}_i$ +be the $i^\text{th}$ type in \tcode{Types}, and +$\tcode{U}_i$ be the $i^\text{th}$ type in a template parameter pack named \tcode{UTypes}, where indexing +is zero-based. + \pnum For each \tcode{tuple} constructor, an exception is thrown only if the construction of one of the types in \tcode{Types} throws an exception. @@ -1168,20 +1180,12 @@ constexpr functions. \pnum -The destructor of \tcode{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$ -be the $i^\text{th}$ type in \tcode{Types}, and -$\tcode{U}_i$ be the $i^\text{th}$ type in a template parameter pack named \tcode{UTypes}, where indexing -is zero-based. +If \tcode{is_trivially_destructible_v<$\tcode{T}_i$>} is \tcode{true} for all $\tcode{T}_i$, +then the destructor of \tcode{tuple} is trivial. \indexlibrary{\idxcode{tuple}!constructor}% \begin{itemdecl} -@\EXPLICIT@ constexpr tuple(); +explicit(@\seebelow@) constexpr tuple(); \end{itemdecl} \begin{itemdescr} @@ -1194,7 +1198,8 @@ \tcode{is_default_construct\-ible_v<$\tcode{T}_i$>} is \tcode{true} for all $i$. \begin{note} This behavior can be implemented by a constructor template with default template arguments. \end{note} -The constructor is explicit if and only if $\tcode{T}_i$ is not implicitly +The expression inside \tcode{explicit} evaluates to \tcode{true} +if and only if $\tcode{T}_i$ is not implicitly default-constructible for at least one $i$. \begin{note} This behavior can be implemented with a trait that checks whether a \tcode{const $\tcode{T}_i$\&} can be initialized with \tcode{\{\}}. \end{note} @@ -1202,7 +1207,7 @@ \indexlibrary{\idxcode{tuple}!constructor}% \begin{itemdecl} -@\EXPLICIT@ constexpr tuple(const Types&...); +explicit(@\seebelow@) constexpr tuple(const Types&...); \end{itemdecl} \begin{itemdescr} @@ -1213,14 +1218,16 @@ \pnum \remarks This constructor shall not participate in overload resolution unless \tcode{sizeof...(Types) >= 1} and \tcode{is_copy_constructible_v<$\tcode{T}_i$>} -is \tcode{true} for all $i$. The constructor is explicit if and only if -\tcode{is_convertible_v} is \tcode{false} -for at least one $i$. +is \tcode{true} for all $i$. +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!conjunction_v...> +\end{codeblock} \end{itemdescr} \indexlibrary{\idxcode{tuple}!constructor}% \begin{itemdecl} -template @\EXPLICIT@ constexpr tuple(UTypes&&... u); +template explicit(@\seebelow@) constexpr tuple(UTypes&&... u); \end{itemdecl} \begin{itemdescr} @@ -1232,9 +1239,11 @@ \remarks This constructor shall not participate in overload resolution unless \tcode{sizeof...(Types)} \tcode{==} \tcode{sizeof...(UTypes)} and \tcode{sizeof...(Types) >= 1} and \tcode{is_constructible_v<$\tcode{T}_i$, $\tcode{U}_i$\&\&>} -is \tcode{true} for all $i$. The constructor is explicit if and only if -\tcode{is_convertible_v<$\tcode{U}_i$\&\&, $\tcode{T}_i$>} is \tcode{false} -for at least one $i$. +is \tcode{true} for all $i$. +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!conjunction_v...> +\end{codeblock} \end{itemdescr} \indexlibrary{\idxcode{tuple}!constructor}% @@ -1267,7 +1276,7 @@ \indexlibrary{\idxcode{tuple}!constructor}% \begin{itemdecl} -template @\EXPLICIT@ constexpr tuple(const tuple& u); +template explicit(@\seebelow@) constexpr tuple(const tuple& u); \end{itemdecl} \begin{itemdescr} @@ -1288,14 +1297,15 @@ (when \tcode{Types...} expands to \tcode{T} and \tcode{UTypes...} expands to \tcode{U}) \tcode{is_convertible_v\&, T>}, \tcode{is_constructible_v\&>}, and \tcode{is_same_v} are all \tcode{false}. \end{itemize} -The constructor is explicit if and only if -\tcode{is_convertible_v} is \tcode{false} -for at least one $i$. +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!conjunction_v...> +\end{codeblock} \end{itemdescr} \indexlibrary{\idxcode{tuple}!constructor}% \begin{itemdecl} -template @\EXPLICIT@ constexpr tuple(tuple&& u); +template explicit(@\seebelow@) constexpr tuple(tuple&& u); \end{itemdecl} \begin{itemdescr} @@ -1319,15 +1329,16 @@ \tcode{is_convertible_v, T>}, \tcode{is_constructible_v>}, and \tcode{is_same_v} are all \tcode{false}. \end{itemize} -The constructor is explicit if and only if -\tcode{is_convertible_v<$\tcode{U}_i$\&\&, $\tcode{T}_i$>} is \tcode{false} -for at least one $i$. +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!conjunction_v...> +\end{codeblock} \end{itemdescr} \indexlibrary{\idxcode{tuple}!constructor}% \indexlibrary{\idxcode{pair}}% \begin{itemdecl} -template @\EXPLICIT@ constexpr tuple(const pair& u); +template explicit(@\seebelow@) constexpr tuple(const pair& u); \end{itemdecl} \begin{itemdescr} @@ -1342,15 +1353,16 @@ \tcode{is_constructible_v<$\tcode{T}_1$, const U2\&>} is \tcode{true}. \pnum -The constructor is explicit if and only if -\tcode{is_convertible_v} is \tcode{false} or -\tcode{is_convert\-ible_v} is \tcode{false}. +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!is_convertible_v || !is_convertible_v +\end{codeblock} \end{itemdescr} \indexlibrary{\idxcode{tuple}!constructor}% \indexlibrary{\idxcode{pair}}% \begin{itemdecl} -template @\EXPLICIT@ constexpr tuple(pair&& u); +template explicit(@\seebelow@) constexpr tuple(pair&& u); \end{itemdecl} \begin{itemdescr} @@ -1366,9 +1378,10 @@ \tcode{is_constructible_v<$\tcode{T}_1$, U2\&\&>} is \tcode{true}. \pnum -The constructor is explicit if and only if -\tcode{is_convertible_v} is \tcode{false} or -\tcode{is_convertible_v} is \tcode{false}. +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!is_convertible_v || !is_convertible_v +\end{codeblock} \end{itemdescr} \indexlibrary{\idxcode{tuple}!constructor}% @@ -1376,27 +1389,27 @@ template tuple(allocator_arg_t, const Alloc& a); template - @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, const Types&...); + explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, const Types&...); template - @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, UTypes&&...); + explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, UTypes&&...); template tuple(allocator_arg_t, const Alloc& a, const tuple&); template tuple(allocator_arg_t, const Alloc& a, tuple&&); template - @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, const tuple&); + explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, const tuple&); template - @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, tuple&&); + explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, tuple&&); template - @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, const pair&); + explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, const pair&); template - @\EXPLICIT@ tuple(allocator_arg_t, const Alloc& a, pair&&); + explicit(@\seebelow@) tuple(allocator_arg_t, const Alloc& a, pair&&); \end{itemdecl} \begin{itemdescr} \pnum \requires \tcode{Alloc} shall satisfy the -\tcode{Allocator} requirements (\tref{utilities.allocator.requirements}). +\oldconcept{Allocator} requirements (\tref{utilities.allocator.requirements}). \pnum \effects Equivalent to the preceding constructors except that each element is constructed with @@ -1765,7 +1778,7 @@ \begin{itemdescr} \pnum \remarks All specializations of \tcode{tuple_size} shall satisfy the -\tcode{UnaryTypeTrait} requirements\iref{meta.rqmts} with a +\oldconcept{UnaryTypeTrait} requirements\iref{meta.rqmts} with a base characteristic of \tcode{integral_constant} for some \tcode{N}. \end{itemdescr} @@ -1808,7 +1821,7 @@ Let \tcode{TS} denote \tcode{tuple_size} of the \cv-unqualified type \tcode{T}. If the expression \tcode{TS::value} is well-formed when treated as an unevaluated operand, then each -of the three templates shall satisfy the \tcode{UnaryTypeTrait} requirements\iref{meta.rqmts} +of the three templates shall satisfy the \oldconcept{UnaryTypeTrait} requirements\iref{meta.rqmts} with a base characteristic of \begin{codeblock} integral_constant @@ -1843,7 +1856,7 @@ \begin{itemdescr} \pnum Let \tcode{TE} denote \tcode{tuple_element_t} of the \cv-unqualified type \tcode{T}. Then -each of the three templates shall satisfy the \tcode{TransformationTrait} +each of the three templates shall satisfy the \oldconcept{TransformationTrait} requirements\iref{meta.rqmts} with a member typedef \tcode{type} that names the following type: @@ -2058,7 +2071,7 @@ \begin{itemdescr} \pnum -\requires \tcode{Alloc} shall satisfy the \tcode{Allocator} +\requires \tcode{Alloc} shall satisfy the \oldconcept{Allocator} requirements (\tref{utilities.allocator.requirements}). \pnum @@ -2179,11 +2192,6 @@ } \end{codeblock} -\pnum -A program that necessitates the instantiation of template \tcode{optional} for -a reference type, or for possibly cv-qualified types \tcode{in_place_t} or -\tcode{nullopt_t} is ill-formed. - \rSec2[optional.optional]{Class template \tcode{optional}} \indexlibrary{\idxcode{optional}}% @@ -2205,11 +2213,11 @@ template constexpr explicit optional(in_place_t, initializer_list, Args&&...); template - @\EXPLICIT@ constexpr optional(U&&); + explicit(@\seebelow@) constexpr optional(U&&); template - @\EXPLICIT@ optional(const optional&); + explicit(@\seebelow@) optional(const optional&); template - @\EXPLICIT@ optional(optional&&); + explicit(@\seebelow@) optional(optional&&); // \ref{optional.dtor}, destructor ~optional(); @@ -2270,7 +2278,9 @@ Member \tcode{val} is provided for exposition only. When an \tcode{optional} object contains a value, \tcode{val} points to the contained value. \pnum -\tcode{T} shall be an object type and shall satisfy the \tcode{Destructible} requirements (\tref{destructible}). +\tcode{T} shall be an object type +other than \cv{} \tcode{in_place_t} or \cv{} \tcode{nullopt_t} +and shall satisfy the \oldconcept{Destructible} requirements (\tref{destructible}). \rSec3[optional.ctor]{Constructors} @@ -2398,16 +2408,9 @@ If \tcode{T}'s constructor selected for the initialization is a constexpr constructor, this constructor shall be a constexpr constructor. \end{itemdescr} -\pnum -\begin{note} -The following constructors are conditionally specified as explicit. -This is typically implemented by declaring two such constructors, -of which at most one participates in overload resolution. -\end{note} - \indexlibrary{\idxcode{optional}!constructor}% \begin{itemdecl} -template @\EXPLICIT@ constexpr optional(U&& v); +template explicit(@\seebelow@) constexpr optional(U&& v); \end{itemdecl} \begin{itemdescr} @@ -2432,13 +2435,15 @@ \tcode{is_constructible_v} is \tcode{true}, \tcode{is_same_v, in_place_t>} is \tcode{false}, and \tcode{is_same_v, optional>} is \tcode{false}. -The constructor is explicit if and only if -\tcode{is_convertible_v} is \tcode{false}. +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!is_convertible_v +\end{codeblock} \end{itemdescr} \indexlibrary{\idxcode{optional}!constructor}% \begin{itemdecl} -template @\EXPLICIT@ optional(const optional& rhs); +template explicit(@\seebelow@) optional(const optional& rhs); \end{itemdecl} \begin{itemdescr} @@ -2470,13 +2475,15 @@ \item \tcode{is_convertible_v\&, T>} is \tcode{false}, and \item \tcode{is_convertible_v\&\&, T>} is \tcode{false}. \end{itemize} -The constructor is explicit if and only if -\tcode{is_convertible_v} is \tcode{false}. +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!is_convertible_v +\end{codeblock} \end{itemdescr} \indexlibrary{\idxcode{optional}!constructor}% \begin{itemdecl} -template @\EXPLICIT@ optional(optional&& rhs); +template explicit(@\seebelow@) optional(optional&& rhs); \end{itemdecl} \begin{itemdescr} @@ -2509,8 +2516,10 @@ \item \tcode{is_convertible_v\&, T>} is \tcode{false}, and \item \tcode{is_convertible_v\&\&, T>} is \tcode{false}. \end{itemize} -The constructor is explicit if and only if -\tcode{is_convertible_v} is \tcode{false}. +The expression inside \tcode{explicit} is equivalent to: +\begin{codeblock} +!is_convertible_v +\end{codeblock} \end{itemdescr} \rSec3[optional.dtor]{Destructor} @@ -2530,7 +2539,7 @@ \pnum \remarks -If \tcode{is_trivially_destructible_v == true} then this destructor shall be a trivial destructor. +If \tcode{is_trivially_destructible_v} is \tcode{true}, then this destructor is trivial. \end{itemdescr} \rSec3[optional.assign]{Assignment} @@ -3148,7 +3157,7 @@ \requires The expression \tcode{*x == *y} shall be well-formed and its result shall be convertible to \tcode{bool}. -\begin{note} \tcode{T} need not be \tcode{EqualityComparable}. \end{note} +\begin{note} \tcode{T} need not be \oldconcept{EqualityComparable}. \end{note} \pnum \returns @@ -3408,7 +3417,7 @@ 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}. +\tcode{T} need not be \oldconcept{EqualityComparable}. \end{note} \pnum @@ -4148,8 +4157,8 @@ \pnum \remarks -If \tcode{is_trivially_destructible_v<$\tcode{T}_i$> == true} for all $\tcode{T}_i$ -then this destructor shall be a trivial destructor. +If \tcode{is_trivially_destructible_v<$\tcode{T}_i$>} is \tcode{true} for all $\tcode{T}_i$, +then this destructor is trivial. \end{itemdescr} \rSec3[variant.assign]{Assignment} @@ -4531,7 +4540,7 @@ \pnum \remarks All specializations of \tcode{variant_size} shall satisfy the -\tcode{UnaryTypeTrait} requirements\iref{meta.rqmts} +\oldconcept{UnaryTypeTrait} requirements\iref{meta.rqmts} with a base characteristic of \tcode{integral_constant} for some \tcode{N}. \end{itemdescr} @@ -4546,7 +4555,7 @@ \pnum Let \tcode{VS} denote \tcode{variant_size} of the cv-unqualified type \tcode{T}. Then each of the three templates shall satisfy the -\tcode{UnaryTypeTrait} requirements\iref{meta.rqmts} with a +\oldconcept{UnaryTypeTrait} requirements\iref{meta.rqmts} with a base characteristic of \tcode{integral_constant}. \end{itemdescr} @@ -4568,7 +4577,7 @@ \pnum Let \tcode{VA} denote \tcode{variant_alternative} of the cv-unqualified type \tcode{T}. Then each of the three templates shall -meet the \tcode{TransformationTrait} requirements\iref{meta.rqmts} with a +meet the \oldconcept{TransformationTrait} requirements\iref{meta.rqmts} with a member typedef \tcode{type} that names the following type: \begin{itemize} \item for the first specialization, \tcode{add_const_t}, @@ -4627,7 +4636,7 @@ \pnum \requires \tcode{I < sizeof...(Types)}. -Otherwise the program is ill-formed. +Otherwise, the program is ill-formed. \pnum \effects @@ -4670,7 +4679,7 @@ \pnum \requires \tcode{I < sizeof...(Types)}. -Otherwise the program is ill-formed. +Otherwise, the program is ill-formed. \pnum \returns @@ -4854,7 +4863,7 @@ \pnum \returns $e(\tcode{m})$, where \tcode{m} is the pack for which $\tcode{m}_i$ is \tcode{vars$_i$.index()} for -all $0 \leq i < n$. The return type is the type of $e(\tcode{m})$. +all $0 \leq i < n$. The return type is $\tcode{decltype(}e(\tcode{m})\tcode{)}$. \pnum \throws @@ -5182,7 +5191,7 @@ \pnum \requires -\tcode{VT} shall satisfy the \tcode{CopyConstructible} requirements. +\tcode{VT} shall satisfy the \oldconcept{CopyConstructible} requirements. \pnum \effects @@ -5211,7 +5220,7 @@ Let \tcode{VT} be \tcode{decay_t}. \pnum -\requires \tcode{VT} shall satisfy the \tcode{CopyConstructible} requirements. +\requires \tcode{VT} shall satisfy the \oldconcept{CopyConstructible} requirements. \pnum \effects Initializes the contained value as if direct-non-list-initializing an object of @@ -5241,7 +5250,7 @@ Let \tcode{VT} be \tcode{decay_t}. \pnum -\requires \tcode{VT} shall satisfy the \tcode{CopyConstructible} requirements. +\requires \tcode{VT} shall satisfy the \oldconcept{CopyConstructible} requirements. \pnum \effects Initializes the contained value as if direct-non-list-initializing an object of @@ -5325,7 +5334,7 @@ \pnum \requires -\tcode{VT} shall satisfy the \tcode{CopyConstructible} requirements. +\tcode{VT} shall satisfy the \oldconcept{CopyConstructible} requirements. \pnum \effects @@ -5361,7 +5370,7 @@ \pnum \requires -\tcode{VT} shall satisfy the \tcode{CopyConstructible} requirements. +\tcode{VT} shall satisfy the \oldconcept{CopyConstructible} requirements. \pnum \effects Calls \tcode{reset()}. @@ -5399,7 +5408,7 @@ \pnum \requires -\tcode{VT} shall satisfy the \tcode{CopyConstructible} requirements. +\tcode{VT} shall satisfy the \oldconcept{CopyConstructible} requirements. \pnum \effects Calls \tcode{reset()}. Then initializes the contained value @@ -5654,7 +5663,8 @@ reference() noexcept; public: - ~reference() noexcept; + reference(const reference&) = default; + ~reference(); 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 @@ -6943,7 +6953,7 @@ \rSec2[util.dynamic.safety]{Pointer safety} \pnum -A complete object is \techterm{declared reachable} while the number of calls to +A complete object is \term{declared reachable} while the number of calls to \tcode{declare_reachable} with an argument referencing the object exceeds the number of calls to \tcode{undeclare_reachable} with an argument referencing the object. @@ -7116,7 +7126,7 @@ disambiguate constructor and function overloading. Specifically, several types (see \tcode{tuple}~\ref{tuple}) have constructors with \tcode{allocator_arg_t} as the first argument, immediately followed by an argument of a type that satisfies the -\tcode{Allocator} requirements (\tref{utilities.allocator.requirements}). +\oldconcept{Allocator} requirements (\tref{utilities.allocator.requirements}). \rSec2[allocator.uses]{\tcode{uses_allocator}} @@ -7130,13 +7140,13 @@ \begin{itemdescr} \pnum \remarks Automatically detects whether \tcode{T} has a nested \tcode{allocator_type} that -is convertible from \tcode{Alloc}. Meets the \tcode{BinaryTypeTrait} +is convertible from \tcode{Alloc}. Meets the \oldconcept{BinaryTypeTrait} requirements\iref{meta.rqmts}. The implementation shall provide a definition that is derived from \tcode{true_type} if the \grammarterm{qualified-id} \tcode{T::allocator_type} is valid and denotes a type\iref{temp.deduct} and \tcode{is_convertible_v != false}, otherwise it shall be derived from \tcode{false_type}. A program may specialize this template to derive from -\tcode{true_type} for a user-defined type \tcode{T} that does not have a nested +\tcode{true_type} for a program-defined type \tcode{T} that does not have a nested \tcode{allocator_type} but nonetheless can be constructed with an allocator where either: @@ -7463,13 +7473,18 @@ \indexlibrary{\idxcode{allocator}}% \indexlibrarymember{value_type}{allocator}% +\indexlibrarymember{size_type}{allocator}% +\indexlibrarymember{difference_type}{allocator}% \indexlibrarymember{propagate_on_container_move_assignment}{allocator}% \indexlibrarymember{is_always_equal}{allocator}% +\indexlibrarymember{operator=}{allocator}% \begin{codeblock} namespace std { template class allocator { public: using value_type = T; + using size_type = size_t; + using difference_type = ptrdiff_t; using propagate_on_container_move_assignment = true_type; using is_always_equal = true_type; @@ -7477,6 +7492,7 @@ constexpr allocator(const allocator&) noexcept; template constexpr allocator(const allocator&) noexcept; ~allocator(); + allocator& operator=(const allocator&) = default; [[nodiscard]] T* allocate(size_t n); void deallocate(T* p, size_t n); @@ -7573,12 +7589,12 @@ \begin{itemize} \item If an algorithm's template parameter is named \tcode{InputIterator}, -the template argument shall satisfy the requirements -of an input iterator\iref{input.iterators}. +the template argument shall satisfy the +\oldconcept{InputIterator} requirements\iref{input.iterators}. \item If an algorithm's template parameter is named \tcode{ForwardIterator}, -the template argument shall satisfy the requirements -of a forward iterator\iref{forward.iterators}, and +the template argument shall satisfy the +\oldconcept{ForwardIterator} requirements\iref{forward.iterators}, and is required to have the property that no exceptions are thrown from increment, assignment, comparison, or indirection through valid iterators. \end{itemize} @@ -7954,8 +7970,8 @@ Each object of a type \tcode{U} instantiated from the \tcode{unique_ptr} template specified in this subclause has the strict ownership semantics, specified above, of a unique pointer. In partial satisfaction of these semantics, each such \tcode{U} -is \tcode{MoveConstructible} and \tcode{MoveAssignable}, but is not -\tcode{CopyConstructible} nor \tcode{CopyAssignable}. +is \oldconcept{MoveConstructible} and \oldconcept{MoveAssignable}, but is not +\oldconcept{CopyConstructible} nor \oldconcept{CopyAssignable}. The template parameter \tcode{T} of \tcode{unique_ptr} may be an incomplete type. \pnum @@ -8125,7 +8141,7 @@ \pnum If the deleter's type \tcode{D} is not a reference type, \tcode{D} shall satisfy -the \tcode{Destructible} requirements (\tref{destructible}). +the \oldconcept{Destructible} requirements (\tref{destructible}). \pnum If the \grammarterm{qualified-id} \tcode{remove_reference_t::pointer} is valid and denotes a @@ -8133,7 +8149,7 @@ D>::pointer} shall be a synonym for \tcode{remove_reference_t::pointer}. Otherwise \tcode{unique_ptr::pointer} shall be a synonym for \tcode{element_type*}. The type \tcode{unique_ptr::pointer} shall -satisfy the \tcode{NullablePointer} requirements (\tref{nullablepointer}). +satisfy the \oldconcept{NullablePointer} requirements (\tref{nullablepointer}). \pnum \begin{example} Given an allocator type \tcode{X} (\tref{utilities.allocator.requirements}) and @@ -8141,7 +8157,7 @@ \tcode{A::const_pointer}, \tcode{A::void_pointer}, and \tcode{A::const_void_pointer} may be used as \tcode{unique_ptr::pointer}. \end{example} -\rSec4[unique.ptr.single.ctor]{\tcode{unique_ptr} constructors} +\rSec4[unique.ptr.single.ctor]{Constructors} \indexlibrary{\idxcode{unique_ptr}!constructor}% \begin{itemdecl} @@ -8152,7 +8168,7 @@ \begin{itemdescr} \pnum \requires \tcode{D} shall -satisfy the \tcode{DefaultConstructible} requirements (\tref{defaultconstructible}), +satisfy the \oldconcept{DefaultConstructible} requirements (\tref{defaultconstructible}), and that construction shall not throw an exception. \pnum @@ -8177,7 +8193,7 @@ \begin{itemdescr} \pnum \requires \tcode{D} shall -satisfy the \tcode{DefaultConstructible} requirements (\tref{defaultconstructible}), +satisfy the \oldconcept{DefaultConstructible} requirements (\tref{defaultconstructible}), and that construction shall not throw an exception. \pnum @@ -8235,10 +8251,10 @@ \pnum \requires For the first constructor, if \tcode{D} is not a reference type, -\tcode{D} shall satisfy the \tcode{CopyConstructible} requirements and +\tcode{D} shall satisfy the \oldconcept{CopyConstructible} requirements and such construction shall not exit via an exception. For the second constructor, if \tcode{D} is not a reference type, -\tcode{D} shall satisfy the \tcode{MoveConstructible} requirements and +\tcode{D} shall satisfy the \oldconcept{MoveConstructible} requirements and such construction shall not exit via an exception. \pnum @@ -8265,8 +8281,8 @@ \begin{example} \begin{codeblock} D d; -unique_ptr p1(new int, D()); // \tcode{D} must be \tcode{MoveConstructible} -unique_ptr p2(new int, d); // \tcode{D} must be \tcode{CopyConstructible} +unique_ptr p1(new int, D()); // \tcode{D} must be \oldconcept{MoveConstructible} +unique_ptr p2(new int, d); // \tcode{D} must be \oldconcept{CopyConstructible} unique_ptr p3(new int, d); // \tcode{p3} holds a reference to \tcode{d} unique_ptr p4(new int, D()); // error: rvalue deleter object combined // with reference deleter type @@ -8282,7 +8298,7 @@ \begin{itemdescr} \pnum \requires If \tcode{D} is not a reference type, -\tcode{D} shall satisfy the \tcode{MoveConstructible} +\tcode{D} shall satisfy the \oldconcept{MoveConstructible} requirements (\tref{moveconstructible}). Construction of the deleter from an rvalue of type \tcode{D} shall not @@ -8343,7 +8359,7 @@ \tcode{u.get_deleter()}. \end{itemdescr} -\rSec4[unique.ptr.single.dtor]{\tcode{unique_ptr} destructor} +\rSec4[unique.ptr.single.dtor]{Destructor} \indexlibrary{\idxcode{unique_ptr}!destructor}% \begin{itemdecl} @@ -8362,7 +8378,7 @@ Otherwise \tcode{get_deleter()(get())}. \end{itemdescr} -\rSec4[unique.ptr.single.asgn]{\tcode{unique_ptr} assignment} +\rSec4[unique.ptr.single.asgn]{Assignment} \indexlibrarymember{operator=}{unique_ptr}% \begin{itemdecl} @@ -8372,10 +8388,10 @@ \begin{itemdescr} \pnum \requires If \tcode{D} is not a reference type, \tcode{D} shall satisfy the -\tcode{MoveAssignable} requirements (\tref{moveassignable}) and assignment +\oldconcept{MoveAssignable} requirements (\tref{moveassignable}) and assignment of the deleter from an rvalue of type \tcode{D} shall not throw an exception. Otherwise, \tcode{D} is a reference type; -\tcode{remove_reference_t} shall satisfy the \tcode{CopyAssignable} +\tcode{remove_reference_t} shall satisfy the \oldconcept{CopyAssignable} requirements and assignment of the deleter from an lvalue of type \tcode{D} shall not throw an exception. @@ -8438,7 +8454,7 @@ \returns \tcode{*this}. \end{itemdescr} -\rSec4[unique.ptr.single.observers]{\tcode{unique_ptr} observers} +\rSec4[unique.ptr.single.observers]{Observers} \indexlibrarymember{operator*}{unique_ptr}% \begin{itemdecl} @@ -8503,7 +8519,7 @@ \returns \tcode{get() != nullptr}. \end{itemdescr} -\rSec4[unique.ptr.single.modifiers]{\tcode{unique_ptr} modifiers} +\rSec4[unique.ptr.single.modifiers]{Modifiers} \indexlibrarymember{release}{unique_ptr}% \begin{itemdecl} @@ -8638,7 +8654,7 @@ \pnum The template argument \tcode{T} shall be a complete type. -\rSec4[unique.ptr.runtime.ctor]{\tcode{unique_ptr} constructors} +\rSec4[unique.ptr.runtime.ctor]{Constructors} \indexlibrary{\idxcode{unique_ptr}!constructor}% \begin{itemdecl} @@ -8710,7 +8726,7 @@ \end{note} \end{itemdescr} -\rSec4[unique.ptr.runtime.asgn]{\tcode{unique_ptr} assignment} +\rSec4[unique.ptr.runtime.asgn]{Assignment} \indexlibrarymember{operator=}{unique_ptr}% \begin{itemdecl} @@ -8737,7 +8753,7 @@ \end{note} \end{itemdescr} -\rSec4[unique.ptr.runtime.observers]{\tcode{unique_ptr} observers} +\rSec4[unique.ptr.runtime.observers]{Observers} \indexlibrarymember{operator[]}{unique_ptr}% \begin{itemdecl} @@ -8754,7 +8770,7 @@ \returns \tcode{get()[i]}. \end{itemdescr} -\rSec4[unique.ptr.runtime.modifiers]{\tcode{unique_ptr} modifiers} +\rSec4[unique.ptr.runtime.modifiers]{Modifiers} \indexlibrarymember{reset}{unique_ptr}% \begin{itemdecl} @@ -8786,7 +8802,7 @@ \end{itemize} \end{itemdescr} -\rSec3[unique.ptr.create]{\tcode{unique_ptr} creation} +\rSec3[unique.ptr.create]{Creation} \indexlibrary{\idxcode{make_unique}}% \begin{itemdecl} @@ -8827,7 +8843,7 @@ \end{itemdescr} -\rSec3[unique.ptr.special]{\tcode{unique_ptr} specialized algorithms} +\rSec3[unique.ptr.special]{Specialized algorithms} \indexlibrary{\idxcode{swap(unique_ptr\&, unique_ptr\&)}}% \begin{itemdecl} @@ -9021,7 +9037,7 @@ The second function template returns \tcode{!(nullptr < x)}. \end{itemdescr} -\rSec3[unique.ptr.io]{\tcode{unique_ptr} I/O} +\rSec3[unique.ptr.io]{I/O} \indexlibrarymember{operator<<}{unique_ptr}% \begin{itemdecl} @@ -9156,8 +9172,8 @@ \end{codeblock} \pnum -Specializations of \tcode{shared_ptr} shall be \tcode{CopyConstructible}, -\tcode{CopyAssignable}, and \tcode{LessThanComparable}, allowing their use in standard +Specializations of \tcode{shared_ptr} shall be \oldconcept{CopyConstructible}, +\oldconcept{CopyAssignable}, and \oldconcept{\-Less\-Than\-Comparable}, allowing their use in standard containers. Specializations of \tcode{shared_ptr} shall be contextually convertible to \tcode{bool}, allowing their use in boolean expressions and declarations in conditions. The template @@ -9186,7 +9202,7 @@ \tcode{Y*} is convertible to \tcode{T*} or \tcode{Y} is \tcode{U[N]} and \tcode{T} is \cv{}~\tcode{U[]}. -\rSec3[util.smartptr.shared.const]{\tcode{shared_ptr} constructors} +\rSec3[util.smartptr.shared.const]{Constructors} \pnum In the constructor definitions below, @@ -9266,7 +9282,7 @@ 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 satisfy the \tcode{Allocator} requirements +\tcode{A} shall satisfy the \oldconcept{Allocator} requirements (\tref{utilities.allocator.requirements}). \pnum\effects Constructs a \tcode{shared_ptr} object that owns the @@ -9395,7 +9411,7 @@ If an exception is thrown, the constructor has no effect. \end{itemdescr} -\rSec3[util.smartptr.shared.dest]{\tcode{shared_ptr} destructor} +\rSec3[util.smartptr.shared.dest]{Destructor} \indexlibrary{\idxcode{shared_ptr}!destructor}% \begin{itemdecl} @@ -9426,7 +9442,7 @@ \tcode{*this} will report a \tcode{use_count()} that is one less than its previous value. \end{note} -\rSec3[util.smartptr.shared.assign]{\tcode{shared_ptr} assignment} +\rSec3[util.smartptr.shared.assign]{Assignment} \indexlibrarymember{operator=}{shared_ptr}% \begin{itemdecl} @@ -9481,7 +9497,7 @@ \returns \tcode{*this}. \end{itemdescr} -\rSec3[util.smartptr.shared.mod]{\tcode{shared_ptr} modifiers} +\rSec3[util.smartptr.shared.mod]{Modifiers} \indexlibrarymember{swap}{shared_ptr}% \begin{itemdecl} @@ -9530,7 +9546,7 @@ \effects Equivalent to \tcode{shared_ptr(p, d, a).swap(*this)}. \end{itemdescr} -\rSec3[util.smartptr.shared.obs]{\tcode{shared_ptr} observers} +\rSec3[util.smartptr.shared.obs]{Observers} \indexlibrarymember{get}{shared_ptr}% \begin{itemdecl} element_type* get() const noexcept; @@ -9649,7 +9665,7 @@ \end{itemdescr} -\rSec3[util.smartptr.shared.create]{\tcode{shared_ptr} creation} +\rSec3[util.smartptr.shared.create]{Creation} \pnum The common requirements that apply to @@ -9667,7 +9683,7 @@ \begin{itemdescr} \pnum -\requires \tcode{A} shall satisfy the \tcode{Allocator} +\requires \tcode{A} shall satisfy the \oldconcept{Allocator} requirements (\tref{utilities.allocator.requirements}). \pnum @@ -9922,7 +9938,7 @@ \end{example} \end{itemdescr} -\rSec3[util.smartptr.shared.cmp]{\tcode{shared_ptr} comparison} +\rSec3[util.smartptr.shared.cmp]{Comparison} \indexlibrarymember{operator==}{shared_ptr}% \begin{itemdecl} @@ -10044,7 +10060,7 @@ The second function template returns \tcode{!(nullptr < a)}. \end{itemdescr} -\rSec3[util.smartptr.shared.spec]{\tcode{shared_ptr} specialized algorithms} +\rSec3[util.smartptr.shared.spec]{Specialized algorithms} \indexlibrarymember{swap}{shared_ptr}% \begin{itemdecl} @@ -10056,7 +10072,7 @@ \pnum\effects Equivalent to \tcode{a.swap(b)}. \end{itemdescr} -\rSec3[util.smartptr.shared.cast]{\tcode{shared_ptr} casts} +\rSec3[util.smartptr.shared.cast]{Casts} \indexlibrarymember{static_pointer_cast}{shared_ptr}% \begin{itemdecl} @@ -10181,7 +10197,7 @@ \tcode{p} have been destroyed. \end{note} \end{itemdescr} -\rSec3[util.smartptr.shared.io]{\tcode{shared_ptr} I/O} +\rSec3[util.smartptr.shared.io]{I/O} \indexlibrarymember{operator<<}{shared_ptr}% \begin{itemdecl} @@ -10258,12 +10274,12 @@ \end{codeblock} \pnum -Specializations of \tcode{weak_ptr} shall be \tcode{CopyConstructible} and -\tcode{CopyAssignable}, allowing their use in standard +Specializations of \tcode{weak_ptr} shall be \oldconcept{CopyConstructible} and +\oldconcept{CopyAssignable}, allowing their use in standard containers. The template parameter \tcode{T} of \tcode{weak_ptr} may be an incomplete type. -\rSec3[util.smartptr.weak.const]{\tcode{weak_ptr} constructors} +\rSec3[util.smartptr.weak.const]{Constructors} \indexlibrary{\idxcode{weak_ptr}!constructor}% \begin{itemdecl} @@ -10311,7 +10327,7 @@ \tcode{r} shall be empty. \tcode{r.use_count() == 0}. \end{itemdescr} -\rSec3[util.smartptr.weak.dest]{\tcode{weak_ptr} destructor} +\rSec3[util.smartptr.weak.dest]{Destructor} \indexlibrary{\idxcode{weak_ptr}!destructor}% \begin{itemdecl} @@ -10323,7 +10339,7 @@ effect on the object its stored pointer points to. \end{itemdescr} -\rSec3[util.smartptr.weak.assign]{\tcode{weak_ptr} assignment} +\rSec3[util.smartptr.weak.assign]{Assignment} \indexlibrarymember{operator=}{weak_ptr}% \begin{itemdecl} @@ -10353,7 +10369,7 @@ \pnum\returns \tcode{*this}. \end{itemdescr} -\rSec3[util.smartptr.weak.mod]{\tcode{weak_ptr} modifiers} +\rSec3[util.smartptr.weak.mod]{Modifiers} \indexlibrarymember{swap}{weak_ptr}% \begin{itemdecl} void swap(weak_ptr& r) noexcept; @@ -10372,7 +10388,7 @@ \pnum\effects Equivalent to \tcode{weak_ptr().swap(*this)}. \end{itemdescr} -\rSec3[util.smartptr.weak.obs]{\tcode{weak_ptr} observers} +\rSec3[util.smartptr.weak.obs]{Observers} \indexlibrarymember{use_count}{weak_ptr}% \begin{itemdecl} long use_count() const noexcept; @@ -10424,7 +10440,7 @@ \end{itemdescr} -\rSec3[util.smartptr.weak.spec]{\tcode{weak_ptr} specialized algorithms} +\rSec3[util.smartptr.weak.spec]{Specialized algorithms} \indexlibrarymember{swap}{weak_ptr}% \begin{itemdecl} @@ -11160,14 +11176,18 @@ The \tcode{memory_resource} class is an abstract interface to an unbounded set of classes encapsulating memory resources. \indexlibrary{\idxcode{memory_resource}}% +\indexlibrarymember{operator=}{memory_resource}% \begin{codeblock} namespace std::pmr { class memory_resource { static constexpr size_t max_align = alignof(max_align_t); // \expos public: + memory_resource(const memory_resource&) = default; virtual ~memory_resource(); + memory_resource& operator=(const memory_resource&) = default; + [[nodiscard]] void* allocate(size_t bytes, size_t alignment = max_align); void deallocate(void* p, size_t bytes, size_t alignment = max_align); @@ -11319,7 +11339,7 @@ \pnum A specialization of class template \tcode{pmr::polymorphic_allocator} -satisfies the \tcode{Allocator} requirements (\tref{utilities.allocator.requirements}). +satisfies the \oldconcept{Allocator} requirements (\tref{utilities.allocator.requirements}). Constructed with different memory resources, different instances of the same specialization of \tcode{pmr::polymorphic_allocator} can exhibit entirely different allocation behavior. @@ -12748,17 +12768,13 @@ \end{itemdecl} \begin{itemdescr} -\pnum -\requires All of the types in \tcode{Args1} and \tcode{Args2} shall be -\tcode{CopyConstructible} (\tref{copyconstructible}). - \pnum \effects Constructs a \tcode{tuple} object \tcode{xprime} from \tcode{x} by the following rules: \begin{itemize} \item If \tcode{uses_allocator_v} is \tcode{false} and \tcode{is_constructible_v} is \tcode{true}, -then \tcode{xprime} is \tcode{x}. +then \tcode{xprime} is \tcode{tuple(std::move(x))}. \item Otherwise, if \tcode{uses_allocator_v} is \tcode{true} and @@ -12768,7 +12784,7 @@ \begin{codeblock} tuple_cat( tuple(allocator_arg, inner_allocator()), - std::move(x)) + tuple(std::move(x))) \end{codeblock} \item Otherwise, if \tcode{uses_allocator_v} is @@ -12776,7 +12792,8 @@ \tcode{is_construct\-ible_v} is \tcode{true}, then \tcode{xprime} is: \begin{codeblock} -tuple_cat(std::move(x), tuple(inner_allocator())) +tuple_cat(tuple(std::move(x)), + tuple(inner_allocator())) \end{codeblock} \item Otherwise, the program is ill-formed. @@ -12784,7 +12801,7 @@ and constructs a \tcode{tuple} object \tcode{yprime} from \tcode{y} by the following rules: \begin{itemize} \item If \tcode{uses_allocator_v} is \tcode{false} and -\tcode{is_constructible_v} is \tcode{true}, then \tcode{yprime} is \tcode{y}. +\tcode{is_constructible_v} is \tcode{true}, then \tcode{yprime} is \tcode{tuple(std::move(y)}. \item Otherwise, if \tcode{uses_allocator_v} is \tcode{true} and @@ -12794,7 +12811,7 @@ \begin{codeblock} tuple_cat( tuple(allocator_arg, inner_allocator()), - std::move(y)) + tuple(std::move(y))) \end{codeblock} \item Otherwise, if \tcode{uses_allocator_v} is @@ -12802,7 +12819,8 @@ \tcode{is_constructible_v} is \tcode{true}, then \tcode{yprime} is: \begin{codeblock} -tuple_cat(std::move(y), tuple(inner_allocator())) +tuple_cat(tuple(std::move(y)), + tuple(inner_allocator())) \end{codeblock} \item Otherwise, the program is ill-formed. @@ -13015,6 +13033,9 @@ template<> struct bit_xor; template<> struct bit_not; + // \ref{func.identity}, identity + struct identity; + // \ref{func.not_fn}, function template \tcode{not_fn} template @\unspec@ not_fn(F&& f); @@ -13178,14 +13199,14 @@ \indextext{call wrapper!simple}% \indextext{call wrapper!forwarding}% Every call wrapper\iref{func.def} shall be -\tcode{MoveConstructible}. +\oldconcept{MoveConstructible}. A \defn{forwarding call wrapper} is a call wrapper that can be called with an arbitrary argument list and delivers the arguments to the wrapped callable object as references. This forwarding step shall ensure that rvalue arguments are delivered as rvalue references and lvalue arguments are delivered as lvalue references. A \defn{simple call wrapper} is a forwarding call wrapper that is -\tcode{CopyConstructible} and \tcode{CopyAssignable} and +\oldconcept{CopyConstructible} and \oldconcept{CopyAssignable} and whose copy constructor, move constructor, copy assignment operator, and move assignment operator do not throw exceptions. \begin{note} @@ -13247,7 +13268,7 @@ \end{codeblock} \pnum -\tcode{reference_wrapper} is a \tcode{CopyConstructible} and \tcode{CopyAssignable} wrapper +\tcode{reference_wrapper} is a \oldconcept{CopyConstructible} and \oldconcept{CopyAssignable} wrapper around a reference to an object or function of type \tcode{T}. \pnum @@ -13624,8 +13645,8 @@ the built-in operators \tcode{<}, \tcode{>}, \tcode{<=}, \tcode{>=}. \begin{note} When \tcode{a < b} is well-defined for pointers \tcode{a} and \tcode{b} of type \tcode{P}, -this implies \tcode{(a < b) == less

(a, b)}, -\tcode{(a > b) == greater

(a, b)}, and so forth. \end{note} +this implies \tcode{(a < b) == less

()(a, b)}, +\tcode{(a > b) == greater

()(a, b)}, and so forth. \end{note} For template specializations \tcode{less}, \tcode{greater}, \tcode{less_equal}, and \tcode{greater_equal}, if the call operator calls a built-in operator comparing pointers, @@ -14142,6 +14163,28 @@ \end{itemdescr} +\rSec2[func.identity]{Class \tcode{identity}} + +\indexlibrary{\idxcode{identity}}% +\begin{itemdecl} +struct identity { + template + constexpr T&& operator()(T&& t) const noexcept; + + using is_transparent = @\unspec@; +}; + +template + constexpr T&& operator()(T&& t) const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: \tcode{return std::forward(t);} +\end{itemdescr} + + \rSec2[func.not_fn]{Function template \tcode{not_fn}} \indexlibrary{\idxcode{not_fn}}% @@ -14191,7 +14234,7 @@ \begin{itemdescr} \pnum \requires -\tcode{FD} shall satisfy the \tcode{MoveConstructible} requirements. +\tcode{FD} shall satisfy the \oldconcept{MoveConstructible} requirements. \tcode{is_constructible_v} shall be \tcode{true}. \tcode{fd} shall be a callable object\iref{func.def}. @@ -14263,11 +14306,11 @@ \pnum Instantiations of the \tcode{is_bind_expression} template shall satisfy -the \tcode{UnaryTypeTrait} requirements\iref{meta.rqmts}. The implementation +the \oldconcept{UnaryTypeTrait} requirements\iref{meta.rqmts}. The implementation shall provide a definition that has a base characteristic of \tcode{true_type} if \tcode{T} is a type returned from \tcode{bind}, otherwise it shall have a base characteristic of \tcode{false_type}. -A program may specialize this template for a user-defined type \tcode{T} +A program may specialize this template for a program-defined type \tcode{T} to have a base characteristic of \tcode{true_type} to indicate that \tcode{T} should be treated as a subexpression in a \tcode{bind} call. @@ -14287,12 +14330,12 @@ \pnum Instantiations of the \tcode{is_placeholder} template shall satisfy -the \tcode{UnaryTypeTrait} requirements\iref{meta.rqmts}. The implementation +the \oldconcept{UnaryTypeTrait} requirements\iref{meta.rqmts}. The implementation shall provide a definition that has the base characteristic of \tcode{integral_constant} if \tcode{T} is the type of \tcode{std::placeholders::_\placeholder{J}}, otherwise it shall have a base characteristic of \tcode{integral_constant}. A program -may specialize this template for a user-defined type \tcode{T} to +may specialize this template for a program-defined type \tcode{T} to have a base characteristic of \tcode{integral_constant} with \tcode{N > 0} to indicate that \tcode{T} should be treated as a placeholder type. @@ -14351,10 +14394,10 @@ \tcode{fd} or of one of the values $\tcode{td}_i$ throws an exception. \pnum -\remarks The return type shall satisfy the \tcode{MoveConstructible} requirements. If all -of \tcode{FD} and $\tcode{TD}_i$ satisfy the \tcode{CopyConstructible} requirements, then the -return type shall satisfy the \tcode{CopyConstructible} requirements. \begin{note} This implies -that all of \tcode{FD} and $\tcode{TD}_i$ are \tcode{MoveConstructible}. \end{note} +\remarks The return type shall satisfy the \oldconcept{MoveConstructible} requirements. If all +of \tcode{FD} and $\tcode{TD}_i$ satisfy the \oldconcept{CopyConstructible} requirements, then the +return type shall satisfy the \oldconcept{CopyConstructible} requirements. \begin{note} This implies +that all of \tcode{FD} and $\tcode{TD}_i$ are \oldconcept{MoveConst\-ruct\-ible}. \end{note} \end{itemdescr} \indexlibrary{\idxcode{bind}}% @@ -14394,15 +14437,15 @@ \tcode{fd} or of one of the values $\tcode{td}_i$ throws an exception. \pnum -\remarks The return type shall satisfy the \tcode{MoveConstructible} requirements. If all -of \tcode{FD} and $\tcode{TD}_i$ satisfy the \tcode{CopyConstructible} requirements, then the -return type shall satisfy the \tcode{CopyConstructible} requirements. \begin{note} This implies -that all of \tcode{FD} and $\tcode{TD}_i$ are \tcode{MoveConstructible}. \end{note} +\remarks The return type shall satisfy the \oldconcept{MoveConstructible} requirements. If all +of \tcode{FD} and $\tcode{TD}_i$ satisfy the \oldconcept{CopyConstructible} requirements, then the +return type shall satisfy the \oldconcept{CopyConstructible} requirements. \begin{note} This implies +that all of \tcode{FD} and $\tcode{TD}_i$ are \oldconcept{MoveConst\-ruct\-ible}. \end{note} \end{itemdescr} \pnum \indextext{bound arguments}% -The values of the \techterm{bound arguments} $\tcode{v}_1$, $\tcode{v}_2$, $\dotsc$, $\tcode{v}_N$ and their +The values of the \term{bound arguments} $\tcode{v}_1$, $\tcode{v}_2$, $\dotsc$, $\tcode{v}_N$ and their corresponding types $\tcode{V}_1$, $\tcode{V}_2$, $\dotsc$, $\tcode{V}_N$ depend on the types $\tcode{TD}_i$ derived from the call to \tcode{bind} and the @@ -14444,11 +14487,11 @@ \end{codeblock} \pnum -All placeholder types shall be \tcode{DefaultConstructible} and -\tcode{CopyConstructible}, and their default constructors and copy/move +All placeholder types shall be \oldconcept{DefaultConstructible} and +\oldconcept{CopyConstructible}, and their default constructors and copy/move constructors shall not throw exceptions. It is \impldef{assignability of placeholder objects} whether -placeholder types are \tcode{CopyAssignable}. \tcode{CopyAssignable} placeholders' copy +placeholder types are \oldconcept{CopyAssignable}. \oldconcept{CopyAssignable} placeholders' copy assignment operators shall not throw exceptions. \pnum @@ -14687,7 +14730,7 @@ \begin{itemdescr} \pnum -\requires \tcode{F} shall be \tcode{CopyConstructible}. +\requires \tcode{F} shall be \oldconcept{CopyConstructible}. \pnum \remarks This constructor template shall not participate in overload resolution unless @@ -14933,7 +14976,8 @@ provided to the function call operator. \pnum -Each specialization of a class template specified in this subclause \ref{func.search} shall satisfy the \tcode{CopyConstructible} and \tcode{CopyAssignable} requirements. +Each specialization of a class template specified in this subclause \ref{func.search} +shall satisfy the \oldconcept{CopyConst\-ruct\-ible} and \oldconcept{CopyAssignable} requirements. Template parameters named \begin{itemize} \item \tcode{ForwardIterator}, @@ -14947,7 +14991,7 @@ of templates specified in this subclause \ref{func.search} shall satisfy the same requirements and semantics as specified in \ref{algorithms.general}. -Template parameters named \tcode{Hash} shall satisfy the \tcode{Hash} +Template parameters named \tcode{Hash} shall satisfy the \oldconcept{Hash} requirements (\tref{hash}). \pnum @@ -15051,8 +15095,8 @@ \begin{itemdescr} \pnum \requires -The value type of \tcode{RandomAccessIterator1} shall satisfy the \tcode{DefaultConstructible} requirements, -the \tcode{CopyConstructible} requirements, and the \tcode{CopyAssignable} requirements. +The value type of \tcode{RandomAccessIterator1} shall satisfy the \oldconcept{DefaultConstructible} requirements, +the \oldconcept{CopyConstructible} requirements, and the \oldconcept{CopyAssignable} requirements. \pnum \requires @@ -15144,8 +15188,8 @@ \begin{itemdescr} \pnum \requires -The value type of \tcode{RandomAccessIterator1} shall satisfy the \tcode{DefaultConstructible}, -\tcode{Copy\-Constructible}, and \tcode{CopyAssignable} requirements. +The value type of \tcode{RandomAccessIterator1} shall satisfy the \oldconcept{DefaultConstructible}, +\oldconcept{Copy\-Constructible}, and \oldconcept{CopyAssignable} requirements. \pnum \requires @@ -15213,7 +15257,7 @@ Each specialization of \tcode{hash} is either enabled or disabled, as described below. \begin{note} -Enabled specializations meet the \tcode{Hash} requirements, and +Enabled specializations meet the \oldconcept{Hash} requirements, and disabled specializations do not. \end{note} Each header that declares the template \tcode{hash} @@ -15240,16 +15284,16 @@ are not function object types\iref{function.objects}. \begin{note} This means that the specialization of \tcode{hash} exists, but -any attempts to use it as a \tcode{Hash} will be ill-formed. +any attempts to use it as a \oldconcept{Hash} will be ill-formed. \end{note} \pnum An enabled specialization \tcode{hash} will: \begin{itemize} -\item satisfy the \tcode{Hash} requirements (\tref{hash}), +\item satisfy the \oldconcept{Hash} requirements (\tref{hash}), with \tcode{Key} as the function -call argument type, the \tcode{Default\-Constructible} requirements (\tref{defaultconstructible}), -the \tcode{CopyAssignable} requirements (\tref{copyassignable}), +call argument type, the \oldconcept{Default\-Constructible} requirements (\tref{defaultconstructible}), +the \oldconcept{CopyAssignable} requirements (\tref{copyassignable}), \item be swappable\iref{swappable.requirements} for lvalues, \item satisfy the requirement that if \tcode{k1 == k2} is \tcode{true}, \tcode{h(k1) == h(k2)} is also \tcode{true}, where \tcode{h} is an object of type \tcode{hash} and \tcode{k1} and \tcode{k2} @@ -15257,7 +15301,7 @@ \item satisfy the requirement that the expression \tcode{h(k)}, where \tcode{h} is an object of type \tcode{hash} and \tcode{k} is an object of type \tcode{Key}, shall not throw an exception unless \tcode{hash} is a -user-defined specialization that depends on at least one user-defined type. +program-defined specialization that depends on at least one program-defined type. \end{itemize} \rSec1[meta]{Metaprogramming and type traits} @@ -15281,11 +15325,11 @@ \rSec2[meta.rqmts]{Requirements} \pnum -A \defn{UnaryTypeTrait} describes a property +A \oldconceptdefn{UnaryTypeTrait} describes a property of a type. It shall be a class template that takes one template type argument and, optionally, additional arguments that help define the -property being described. It shall be \tcode{DefaultConstructible}, -\tcode{CopyConstructible}, +property being described. It shall be \oldconcept{DefaultConstructible}, +\oldconcept{CopyConstructible}, and publicly and unambiguously derived, directly or indirectly, from its \defn{base characteristic}, which is a specialization of the template @@ -15293,14 +15337,14 @@ the arguments to the template \tcode{integral_constant} determined by the requirements for the particular property being described. The member names of the base characteristic shall not be hidden and shall be -unambiguously available in the \tcode{UnaryTypeTrait}. +unambiguously available in the \oldconcept{UnaryTypeTrait}. \pnum -A \defn{BinaryTypeTrait} describes a +A \oldconceptdefn{BinaryTypeTrait} describes a relationship between two types. It shall be a class template that takes two template type arguments and, optionally, additional arguments that help define the relationship being described. It shall -be \tcode{DefaultConstructible}, \tcode{CopyConstructible}, +be \oldconcept{DefaultConstructible}, \oldconcept{CopyConstructible}, and publicly and unambiguously derived, directly or indirectly, from its \term{base characteristic}, which is a specialization @@ -15309,10 +15353,10 @@ the arguments to the template \tcode{integral_constant} determined by the requirements for the particular relationship being described. The member names of the base characteristic shall not be hidden and shall be -unambiguously available in the \tcode{BinaryTypeTrait}. +unambiguously available in the \oldconcept{BinaryTypeTrait}. \pnum -A \defn{TransformationTrait} +A \oldconceptdefn{TransformationTrait} modifies a property of a type. It shall be a class template that takes one template type argument and, optionally, additional arguments that help @@ -15322,6 +15366,10 @@ \rSec2[meta.type.synop]{Header \tcode{} synopsis} \indexhdr{type_traits}% +\indexlibrary{\idxcode{is_nothrow_convertible_v}}% +\indexlibrary{\idxcode{type_identity_t}}% +\indexlibrary{\idxcode{common_reference_t}}% +% FIXME: Many index entries missing. \begin{codeblock} namespace std { // \ref{meta.help}, helper class @@ -15423,6 +15471,7 @@ template struct is_same; template struct is_base_of; template struct is_convertible; + template struct is_nothrow_convertible; template struct is_invocable; template struct is_invocable_r; @@ -15491,6 +15540,7 @@ using add_pointer_t = typename add_pointer::type; // \ref{meta.trans.other}, other transformations + template struct type_identity; template // see \ref{meta.trans.other} struct aligned_storage; template struct aligned_union; @@ -15499,29 +15549,36 @@ template struct enable_if; template struct conditional; template struct common_type; + template class TQual, template class UQual> + struct basic_common_reference { }; + template struct common_reference; template struct underlying_type; template struct invoke_result; + template + using type_identity_t = typename type_identity::type; template // see \ref{meta.trans.other} - using aligned_storage_t = typename aligned_storage::type; + using aligned_storage_t = typename aligned_storage::type; template - using aligned_union_t = typename aligned_union::type; + using aligned_union_t = typename aligned_union::type; template - using remove_cvref_t = typename remove_cvref::type; + using remove_cvref_t = typename remove_cvref::type; template - using decay_t = typename decay::type; + using decay_t = typename decay::type; template - using enable_if_t = typename enable_if::type; + using enable_if_t = typename enable_if::type; template - using conditional_t = typename conditional::type; + using conditional_t = typename conditional::type; + template + using common_type_t = typename common_type::type; template - using common_type_t = typename common_type::type; + using common_reference_t = typename common_reference::type; template - using underlying_type_t = typename underlying_type::type; + using underlying_type_t = typename underlying_type::type; template - using invoke_result_t = typename invoke_result::type; + using invoke_result_t = typename invoke_result::type; template - using void_t = void; + using void_t = void; // \ref{meta.logical}, logical operator traits template struct conjunction; @@ -15693,6 +15750,8 @@ inline constexpr bool is_base_of_v = is_base_of::value; template inline constexpr bool is_convertible_v = is_convertible::value; + template + inline constexpr bool is_nothrow_convertible_v = is_nothrow_convertible::value; template inline constexpr bool is_invocable_v = is_invocable::value; template @@ -15758,7 +15817,7 @@ \pnum Each of these templates shall be a -\tcode{UnaryTypeTrait}\iref{meta.rqmts} +\oldconcept{UnaryTypeTrait}\iref{meta.rqmts} with a base characteristic of \tcode{true_type} if the corresponding condition is \tcode{true}, otherwise \tcode{false_type}. @@ -16418,12 +16477,12 @@ If \tcode{T} is not an array type, or if it has rank less than or equal to \tcode{I}, or if \tcode{I} is 0 and \tcode{T} has type ``array of unknown bound of \tcode{U}'', then - 0; otherwise, the bound\iref{dcl.array} of the \tcode{I}'th dimension of + 0; otherwise, the bound\iref{dcl.array} of the $\tcode{I}^\text{th}$ dimension of \tcode{T}, where indexing of \tcode{I} is zero-based \\ \end{libreqtab2a} \pnum -Each of these templates shall be a \tcode{UnaryTypeTrait}\iref{meta.rqmts} with a +Each of these templates shall be a \oldconcept{UnaryTypeTrait}\iref{meta.rqmts} with a base characteristic of \tcode{integral_constant}. \pnum @@ -16459,7 +16518,7 @@ \pnum Each of these templates shall be a -\tcode{BinaryTypeTrait}\iref{meta.rqmts} +\oldconcept{BinaryTypeTrait}\iref{meta.rqmts} with a base characteristic of \tcode{true_type} if the corresponding condition is true, otherwise \tcode{false_type}. @@ -16500,6 +16559,16 @@ types, arrays of unknown bound, or \cv{}~\tcode{void} types. \\ \rowsep +\indexlibrary{\idxcode{is_nothrow_convertible}}% +\tcode{template}\br + \tcode{struct is_nothrow_convertible;} & + \tcode{is_convertible_v} is \tcode{true} and + the conversion, as defined by \tcode{is_convertible}, + is known not to throw any exceptions\iref{expr.unary.noexcept} & + \tcode{From} and \tcode{To} shall be complete + types, arrays of unknown + bound, or \cv{}~\tcode{void} types. \\ \rowsep + \indexlibrary{\idxcode{is_invocable}}% \tcode{template}\br \tcode{struct is_invocable;} & @@ -16596,7 +16665,7 @@ \pnum Each of the templates in this subclause shall be a -\tcode{TransformationTrait}\iref{meta.rqmts}. +\oldconcept{TransformationTrait}\iref{meta.rqmts}. \rSec3[meta.trans.cv]{Const-volatile modifications} @@ -16835,6 +16904,12 @@ \lhdr{Template} & \rhdr{Comments} \\ \capsep \endhead +\indexlibrary{\idxcode{type_identity}}% +\tcode{template\br + struct type_identity;} + & + The member typedef \tcode{type} names the type \tcode{T}. \\ \rowsep + \indexlibrary{\idxcode{aligned_storage}}% \tcode{template}. \begin{note} This behavior is similar to the lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, and function-to-pointer\iref{conv.func} - conversions applied when an lvalue expression is used as an rvalue, but also + conversions applied when an lvalue is used as an rvalue, but also strips \cv-qualifiers from class types in order to more closely model by-value argument passing. \end{note} \\ \rowsep @@ -16908,6 +16983,23 @@ Each type in the template parameter pack \tcode{T} shall be complete, \cv{}~\tcode{void}, or an array of unknown bound. \\ \rowsep +\indexlibrary{\idxcode{basic_common_reference}}% +\tcode{template class,} + \hspace*{2ex}\tcode{template class>} + \tcode{struct} + \hspace*{2ex}\tcode{basic_common_reference;} + & + Unless this trait is specialized (as specified in Note D, below), + there shall be no member \tcode{type}. \\ \rowsep + +\indexlibrary{\idxcode{common_reference}}% +\tcode{template} \tcode{struct common_reference;} + & + The member \grammarterm{typedef-name} \tcode{type} is defined or omitted + as specified in Note C, below. Each type in the parameter pack \tcode{T} shall + be complete or \cv{} \tcode{void}. \\ \rowsep + \indexlibrary{\idxcode{underlying_type}}% \tcode{template}\br \tcode{struct underlying_type;} @@ -16959,6 +17051,54 @@ supported\iref{basic.align}. \indexlibrary{\idxcode{common_type}}% +\pnum +Let: +\begin{itemize} +\item \tcode{\placeholdernc{CREF}(A)} be + \tcode{add_lvalue_reference_t{}>}, +\item \tcode{\placeholdernc{XREF}(A)} denote a unary class template \tcode{T} + such that \tcode{T} denotes the same type as \tcode{U} with the addition + of \tcode{A}'s cv and reference qualifiers, for a non-reference cv-unqualified + type \tcode{U}, +\item \tcode{\placeholdernc{COPYCV}(FROM, TO)} be an alias for type \tcode{TO} + with the addition of \tcode{FROM}'s top-level cv-qualifiers. + \begin{example} + \tcode{\placeholdernc{COPYCV}(const int, volatile short)} is an alias for + \tcode{const volatile short}. + \end{example} +\item \tcode{\placeholdernc{COND_RES}(X, Y)} be + \tcode{decltype(false ?\ declval()() :\ declval()())}. +\end{itemize} +Given types \tcode{A} and \tcode{B}, +let \tcode{X} be \tcode{remove_reference_t}, +let \tcode{Y} be \tcode{remove_reference_t}, and +let \tcode{\placeholdernc{COMMON_REF}(A, B)} be: +\begin{itemize} +\item If \tcode{A} and \tcode{B} are both lvalue reference types, + \tcode{\placeholdernc{COMMON_REF}(A, B)} is + \tcode{\placeholdernc{COND_RES}(\placeholdernc{COPYCV}(X, Y) \&, + \placeholdernc{COPYCV}(\brk{}Y, X) \&)} if that type exists + and is a reference type. +\item Otherwise, let \tcode{C} be + \tcode{remove_reference_t<\placeholdernc{COMMON_REF}(X\&, Y\&)>\&\&}. + If \tcode{A} and \tcode{B} are both rvalue reference types, + \tcode{C} is well-formed, and + \tcode{is_convertible_v \&\& is_convertible_v} is \tcode{true}, + then \tcode{\placeholdernc{COMMON_REF}(A, B)} is \tcode{C}. +\item Otherwise, let \tcode{D} be + \tcode{\placeholdernc{COMMON_REF}(const X\&, Y\&)}. If \tcode{A} is an rvalue + reference and \tcode{B} is an lvalue reference and \tcode{D} is + well-formed and \tcode{is_convertible_v} is + \tcode{true}, then \tcode{\placeholdernc{COMMON_REF}(A, B)} is \tcode{D}. +\item Otherwise, if \tcode{A} is an lvalue reference and \tcode{B} + is an rvalue reference, then \tcode{\placeholdernc{COMMON_REF}(A, B)} is + \tcode{\placeholdernc{COMMON_REF}(B, A)}. +\item Otherwise, \tcode{\placeholdernc{COMMON_REF}(A, B)} is ill-formed. +\end{itemize} + +If any of the types computed above is ill-formed, then +\tcode{\placeholdernc{COMMON_REF}(A, B)} is ill-formed. + \pnum Note A: For the \tcode{common_type} trait applied to a template parameter pack \tcode{T} of types, @@ -16981,14 +17121,24 @@ \begin{itemize} \item If \tcode{is_same_v} is \tcode{false} or \tcode{is_same_v} is \tcode{false}, - let \tcode{C} denote the same type, if any, as \tcode{common_type_t}. - \item Otherwise, let \tcode{C} denote the same type, if any, as + let \tcode{C} denote the same type, if any, + as \tcode{common_type_t}. + \item + \begin{note} + None of the following will apply if there is a specialization + \tcode{common_type}. + \end{note} + \item Otherwise, if \begin{codeblock} decay_t() : declval())> \end{codeblock} - \begin{note} - This will not apply if there is a specialization \tcode{common_type}. - \end{note} + denotes a valid type, let \tcode{C} denote that type. + \item Otherwise, if + \tcode{\placeholdernc{COND_RES}(\placeholdernc{CREF}(D1), + \placeholdernc{CREF}(D2))} + denotes a type, let \tcode{C} denote the type + \tcode{decay_t<\placeholdernc{COND_RES}(\placeholdernc{CREF}(D1), + \placeholdernc{CREF}(D2))>}. \end{itemize} In either case, the member \grammarterm{typedef-name} \tcode{type} shall denote the same type, if any, as \tcode{C}. @@ -17022,6 +17172,72 @@ the same type, if any, as does \tcode{common_type_t}. No diagnostic is required for a violation of this Note's rules. +\pnum +Note C: For the \tcode{common_reference} trait applied to a parameter pack +\tcode{T} of types, the member \tcode{type} shall be either defined or not +present as follows: +\begin{itemize} +\item If \tcode{sizeof...(T)} is zero, there shall be no member \tcode{type}. + +\item Otherwise, if \tcode{sizeof...(T)} is one, let \tcode{T0} denote the sole + type in the pack \tcode{T}. The member typedef \tcode{type} shall denote the + same type as \tcode{T0}. + +\item Otherwise, if \tcode{sizeof...(T)} is two, let \tcode{T1} and \tcode{T2} + denote the two types in the pack \tcode{T}. Then + \begin{itemize} + \item If \tcode{T1} and \tcode{T2} are reference types and + \tcode{\placeholdernc{COMMON_REF}(T1, T2)} is well-formed, then the member + typedef \tcode{type} denotes that type. + + \item Otherwise, if + \tcode{basic_common_reference, remove_cvref_t, + \brk{}\placeholdernc{XREF}(\brk{}T1), \placeholdernc{XREF}(T2)>::type} + is well-formed, then the member typedef \tcode{type} denotes that type. + + \item Otherwise, if \tcode{\placeholdernc{COND_RES}(T1, T2)} is well-formed, + then the member typedef \tcode{type} denotes that type. + + \item Otherwise, if \tcode{common_type_t} is well-formed, then the + member typedef \tcode{type} denotes that type. + + \item Otherwise, there shall be no member \tcode{type}. + \end{itemize} + +\item Otherwise, if \tcode{sizeof...(T)} is greater than two, let \tcode{T1}, + \tcode{T2}, and \tcode{Rest}, respectively, denote the first, second, and + (pack of) remaining types comprising \tcode{T}. Let \tcode{C} be the type + \tcode{common_reference_t}. Then: + \begin{itemize} + \item If there is such a type \tcode{C}, the member typedef \tcode{type} shall + denote the same type, if any, as \tcode{common_reference_t}. + + \item Otherwise, there shall be no member \tcode{type}. + \end{itemize} +\end{itemize} + +\pnum +Note D: Notwithstanding the provisions of \ref{meta.type.synop}, and +pursuant to \ref{namespace.std}, a program may partially specialize +\tcode{basic_common_reference} +for types \tcode{T} and \tcode{U} such that +\tcode{is_same_v{>}} and +\tcode{is_same_v{>}} are each \tcode{true}. +\begin{note} +Such specializations +can be used to influence the result of \tcode{common_reference}, and +are needed when only explicit conversions are desired +between the template arguments. +\end{note} +Such a specialization need not have a member named \tcode{type}, but if it does, +that member shall be a \grammarterm{typedef-name} for an accessible and +unambiguous type \tcode{C} to which each of the types \tcode{TQual} and +\tcode{UQual} is convertible. +Moreover, \tcode{basic_common_reference::type} shall denote +the same type, if any, as does +\tcode{basic_common_reference::type}. +No diagnostic is required for a violation of these rules. + \pnum \begin{example} Given these definitions: @@ -17164,7 +17380,7 @@ The class template \tcode{negation} forms the logical negation of its template type argument. The type \tcode{negation} -is a \tcode{UnaryTypeTrait} with a base characteristic of \tcode{bool_constant}. +is a \oldconcept{UnaryTypeTrait} with a base characteristic of \tcode{bool_constant}. \end{itemdescr} \rSec2[meta.endian]{Endian} @@ -17437,11264 +17653,6 @@ defined; if either of the constants is not representable by \tcode{intmax_t}, the typedef shall not be defined. -\rSec1[time]{Time utilities} - -\rSec2[time.general]{In general} - -\pnum -\indexlibrary{\idxcode{chrono}}% -This subclause describes the chrono library\iref{time.syn} and various C -functions\iref{ctime.syn} that provide generally useful time -utilities. - -\rSec2[time.syn]{Header \tcode{} synopsis} - -\indexhdr{chrono}% -\indexlibrary{\idxcode{treat_as_floating_point_v}}% -\indexlibrary{\idxcode{is_clock_v}}% -\indexlibrary{\idxcode{nanoseconds}}% -\indexlibrary{\idxcode{microseconds}}% -\indexlibrary{\idxcode{milliseconds}}% -\indexlibrary{\idxcode{seconds}}% -\indexlibrary{\idxcode{minutes}}% -\indexlibrary{\idxcode{hours}}% -\indexlibrary{\idxcode{days}}% -\indexlibrary{\idxcode{weeks}}% -\indexlibrary{\idxcode{years}}% -\indexlibrary{\idxcode{months}}% -\indexlibrary{\idxcode{sys_time}}% -\indexlibrary{\idxcode{sys_seconds}}% -\indexlibrary{\idxcode{sys_days}}% -\indexlibrary{\idxcode{utc_time}}% -\indexlibrary{\idxcode{utc_seconds}}% -\indexlibrary{\idxcode{tai_time}}% -\indexlibrary{\idxcode{tai_seconds}}% -\indexlibrary{\idxcode{gps_time}}% -\indexlibrary{\idxcode{gps_seconds}}% -\indexlibrary{\idxcode{file_time}}% -\indexlibrary{\idxcode{local_time}}% -\indexlibrary{\idxcode{local_seconds}}% -\indexlibrary{\idxcode{local_days}}% -\indexlibrary{\idxcode{local_t}}% -\indexlibrary{\idxcode{choose}}% -\indexlibrarymember{earliest}{choose}% -\indexlibrarymember{latest}{choose}% -\begin{codeblock} -namespace std { - namespace chrono { - // \ref{time.duration}, class template \tcode{duration} - template> class duration; - - // \ref{time.point}, class template \tcode{time_point} - template class time_point; - } - - // \ref{time.traits.specializations}, \tcode{common_type} specializations - template - struct common_type, - chrono::duration>; - - template - struct common_type, - chrono::time_point>; - - namespace chrono { - // \ref{time.traits}, customization traits - template struct treat_as_floating_point; - template struct duration_values; - template - inline constexpr bool treat_as_floating_point_v = treat_as_floating_point::value; - - template struct is_clock; - template inline constexpr bool is_clock_v = is_clock::value; - - // \ref{time.duration.nonmember}, \tcode{duration} arithmetic - template - constexpr common_type_t, duration> - operator+(const duration& lhs, const duration& rhs); - template - constexpr common_type_t, duration> - operator-(const duration& lhs, const duration& rhs); - template - constexpr duration, Period> - operator*(const duration& d, const Rep2& s); - template - constexpr duration, Period> - operator*(const Rep1& s, const duration& d); - template - constexpr duration, Period> - operator/(const duration& d, const Rep2& s); - template - constexpr common_type_t - operator/(const duration& lhs, const duration& rhs); - template - constexpr duration, Period> - operator%(const duration& d, const Rep2& s); - template - constexpr common_type_t, duration> - operator%(const duration& lhs, const duration& rhs); - - // \ref{time.duration.comparisons}, \tcode{duration} comparisons - template - constexpr bool operator==(const duration& lhs, - const duration& rhs); - template - constexpr bool operator!=(const duration& lhs, - const duration& rhs); - template - constexpr bool operator< (const duration& lhs, - const duration& rhs); - template - constexpr bool operator> (const duration& lhs, - const duration& rhs); - template - constexpr bool operator<=(const duration& lhs, - const duration& rhs); - template - constexpr bool operator>=(const duration& lhs, - const duration& rhs); - - // \ref{time.duration.cast}, \tcode{duration_cast} - template - constexpr ToDuration duration_cast(const duration& d); - template - constexpr ToDuration floor(const duration& d); - template - constexpr ToDuration ceil(const duration& d); - template - constexpr ToDuration round(const duration& d); - - // \ref{time.duration.io}, \tcode{duration} I/O - template - basic_ostream& - operator<<(basic_ostream& os, - const duration& d); - template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, - const duration& d); - template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - duration& d, - basic_string* abbrev = nullptr, - minutes* offset = nullptr); - - // convenience typedefs - using nanoseconds = duration<@\term{signed integer type of at least 64 bits}@, nano>; - using microseconds = duration<@\term{signed integer type of at least 55 bits}@, micro>; - using milliseconds = duration<@\term{signed integer type of at least 45 bits}@, milli>; - using seconds = duration<@\term{signed integer type of at least 35 bits}@>; - 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>>; - using days = duration<@\term{signed integer type of at least 25 bits}@, - ratio_multiply, hours::period>>; - using weeks = duration<@\term{signed integer type of at least 22 bits}@, - ratio_multiply, days::period>>; - using years = duration<@\term{signed integer type of at least 17 bits}@, - ratio_multiply, days::period>>; - using months = duration<@\term{signed integer type of at least 20 bits}@, - ratio_divide>>; - - // \ref{time.point.nonmember}, \tcode{time_point} arithmetic - template - constexpr time_point>> - operator+(const time_point& lhs, const duration& rhs); - template - constexpr time_point, Duration2>> - operator+(const duration& lhs, const time_point& rhs); - template - constexpr time_point>> - operator-(const time_point& lhs, const duration& rhs); - template - constexpr common_type_t - operator-(const time_point& lhs, - const time_point& rhs); - - // \ref{time.point.comparisons}, \tcode{time_point} comparisons - template - constexpr bool operator==(const time_point& lhs, - const time_point& rhs); - template - constexpr bool operator!=(const time_point& lhs, - const time_point& rhs); - template - constexpr bool operator< (const time_point& lhs, - const time_point& rhs); - template - constexpr bool operator> (const time_point& lhs, - const time_point& rhs); - template - constexpr bool operator<=(const time_point& lhs, - const time_point& rhs); - template - constexpr bool operator>=(const time_point& lhs, - const time_point& rhs); - - // \ref{time.point.cast}, \tcode{time_point_cast} - template - constexpr time_point - time_point_cast(const time_point& t); - template - constexpr time_point floor(const time_point& tp); - template - constexpr time_point ceil(const time_point& tp); - template - constexpr time_point round(const time_point& tp); - - // \ref{time.duration.alg}, specialized algorithms - template - constexpr duration abs(duration d); - - // \ref{time.clock.system}, class \tcode{system_clock} - class system_clock; - - template - using sys_time = time_point; - using sys_seconds = sys_time; - using sys_days = sys_time; - - template - basic_ostream& - operator<<(basic_ostream& os, const sys_time& tp); - - template - basic_ostream& - operator<<(basic_ostream& os, const sys_days& dp); - - template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, - const sys_time& tp); - - template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - sys_time& tp, - basic_string* abbrev = nullptr, - minutes* offset = nullptr); - - // \ref{time.clock.utc}, class \tcode{utc_clock} - class utc_clock; - - template - using utc_time = time_point; - using utc_seconds = utc_time; - - template - basic_ostream& - operator<<(basic_ostream& os, const utc_time& t); - template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, - const utc_time& tp); - template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - utc_time& tp, - basic_string* abbrev = nullptr, - minutes* offset = nullptr); - - // \ref{time.clock.tai}, class \tcode{tai_clock} - class tai_clock; - - template - using tai_time = time_point; - using tai_seconds = tai_time; - - template - basic_ostream& - operator<<(basic_ostream& os, const tai_time& t); - template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, - const tai_time& tp); - template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - tai_time& tp, - basic_string* abbrev = nullptr, - minutes* offset = nullptr); - - // \ref{time.clock.gps}, class \tcode{gps_clock} - class gps_clock; - - template - using gps_time = time_point; - using gps_seconds = gps_time; - - template - basic_ostream& - operator<<(basic_ostream& os, const gps_time& t); - template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, - const gps_time& tp); - template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - gps_time& tp, - basic_string* abbrev = nullptr, - minutes* offset = nullptr); - - // \ref{time.clock.file}, class \tcode{file_clock} - class file_clock; - - template - using file_time = time_point; - - template - basic_ostream& - operator<<(basic_ostream& os, const file_time& tp); - template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, - const file_time& tp); - template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - file_time& tp, - basic_string* abbrev = nullptr, - minutes* offset = nullptr); - - // \ref{time.clock.steady}, class \tcode{steady_clock} - class steady_clock; - - // \ref{time.clock.hires}, class \tcode{high_resolution_clock} - class high_resolution_clock; - - // \ref{time.clock.local}, local time - struct local_t {}; - template - using local_time = time_point; - using local_seconds = local_time; - using local_days = local_time; - - template - basic_ostream& - operator<<(basic_ostream& os, const local_time& tp); - template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, - const local_time& tp, - const string* abbrev = nullptr, const seconds* offset_sec = nullptr); - template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - local_time& tp, - basic_string* abbrev = nullptr, - minutes* offset = nullptr); - - // \ref{time.clock.cast}, \tcode{time_point} conversions - template - struct clock_time_conversion; - - template - auto clock_cast(const time_point& t); - - // \ref{time.cal.last}, class \tcode{last_spec} - struct last_spec; - - // \ref{time.cal.day}, class \tcode{day} - class day; - - constexpr bool operator==(const day& x, const day& y) noexcept; - constexpr bool operator!=(const day& x, const day& y) noexcept; - constexpr bool operator< (const day& x, const day& y) noexcept; - constexpr bool operator> (const day& x, const day& y) noexcept; - constexpr bool operator<=(const day& x, const day& y) noexcept; - constexpr bool operator>=(const day& x, const day& y) noexcept; - - constexpr day operator+(const day& x, const days& y) noexcept; - constexpr day operator+(const days& x, const day& y) noexcept; - constexpr day operator-(const day& x, const days& y) noexcept; - constexpr days operator-(const day& x, const day& y) noexcept; - - template - basic_ostream& - operator<<(basic_ostream& os, const day& d); - template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, const day& d); - template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - day& d, basic_string* abbrev = nullptr, - minutes* offset = nullptr); - - // \ref{time.cal.month}, class \tcode{month} - class month; - - constexpr bool operator==(const month& x, const month& y) noexcept; - constexpr bool operator!=(const month& x, const month& y) noexcept; - constexpr bool operator< (const month& x, const month& y) noexcept; - constexpr bool operator> (const month& x, const month& y) noexcept; - constexpr bool operator<=(const month& x, const month& y) noexcept; - constexpr bool operator>=(const month& x, const month& y) noexcept; - - constexpr month operator+(const month& x, const months& y) noexcept; - constexpr month operator+(const months& x, const month& y) noexcept; - constexpr month operator-(const month& x, const months& y) noexcept; - constexpr months operator-(const month& x, const month& y) noexcept; - - template - basic_ostream& - operator<<(basic_ostream& os, const month& m); - template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, const month& m); - template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - month& m, basic_string* abbrev = nullptr, - minutes* offset = nullptr); - - // \ref{time.cal.year}, class \tcode{year} - class year; - - constexpr bool operator==(const year& x, const year& y) noexcept; - constexpr bool operator!=(const year& x, const year& y) noexcept; - constexpr bool operator< (const year& x, const year& y) noexcept; - constexpr bool operator> (const year& x, const year& y) noexcept; - constexpr bool operator<=(const year& x, const year& y) noexcept; - constexpr bool operator>=(const year& x, const year& y) noexcept; - - constexpr year operator+(const year& x, const years& y) noexcept; - constexpr year operator+(const years& x, const year& y) noexcept; - constexpr year operator-(const year& x, const years& y) noexcept; - constexpr years operator-(const year& x, const year& y) noexcept; - - template - basic_ostream& - operator<<(basic_ostream& os, const year& y); - - template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, const year& y); - - template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - year& y, basic_string* abbrev = nullptr, - minutes* offset = nullptr); - - // \ref{time.cal.wd}, class \tcode{weekday} - class weekday; - - constexpr bool operator==(const weekday& x, const weekday& y) noexcept; - constexpr bool operator!=(const weekday& x, const weekday& y) noexcept; - - constexpr weekday operator+(const weekday& x, const days& y) noexcept; - constexpr weekday operator+(const days& x, const weekday& y) noexcept; - constexpr weekday operator-(const weekday& x, const days& y) noexcept; - constexpr days operator-(const weekday& x, const weekday& y) noexcept; - - template - basic_ostream& - operator<<(basic_ostream& os, const weekday& wd); - - template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, const weekday& wd); - - template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - weekday& wd, basic_string* abbrev = nullptr, - minutes* offset = nullptr); - - // \ref{time.cal.wdidx}, class \tcode{weekday_indexed} - class weekday_indexed; - - constexpr bool operator==(const weekday_indexed& x, const weekday_indexed& y) noexcept; - constexpr bool operator!=(const weekday_indexed& x, const weekday_indexed& y) noexcept; - - template - basic_ostream& - operator<<(basic_ostream& os, const weekday_indexed& wdi); - - // \ref{time.cal.wdlast}, class \tcode{weekday_last} - class weekday_last; - - constexpr bool operator==(const weekday_last& x, const weekday_last& y) noexcept; - constexpr bool operator!=(const weekday_last& x, const weekday_last& y) noexcept; - - template - basic_ostream& - operator<<(basic_ostream& os, const weekday_last& wdl); - - // \ref{time.cal.md}, class \tcode{month_day} - class month_day; - - constexpr bool operator==(const month_day& x, const month_day& y) noexcept; - constexpr bool operator!=(const month_day& x, const month_day& y) noexcept; - constexpr bool operator< (const month_day& x, const month_day& y) noexcept; - constexpr bool operator> (const month_day& x, const month_day& y) noexcept; - constexpr bool operator<=(const month_day& x, const month_day& y) noexcept; - constexpr bool operator>=(const month_day& x, const month_day& y) noexcept; - - template - basic_ostream& - operator<<(basic_ostream& os, const month_day& md); - - template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, const month_day& md); - - template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - month_day& md, basic_string* abbrev = nullptr, - minutes* offset = nullptr); - - // \ref{time.cal.mdlast}, class \tcode{month_day_last} - class month_day_last; - - constexpr bool operator==(const month_day_last& x, const month_day_last& y) noexcept; - constexpr bool operator!=(const month_day_last& x, const month_day_last& y) noexcept; - constexpr bool operator< (const month_day_last& x, const month_day_last& y) noexcept; - constexpr bool operator> (const month_day_last& x, const month_day_last& y) noexcept; - constexpr bool operator<=(const month_day_last& x, const month_day_last& y) noexcept; - constexpr bool operator>=(const month_day_last& x, const month_day_last& y) noexcept; - - template - basic_ostream& - operator<<(basic_ostream& os, const month_day_last& mdl); - - // \ref{time.cal.mwd}, class \tcode{month_weekday} - class month_weekday; - - constexpr bool operator==(const month_weekday& x, const month_weekday& y) noexcept; - constexpr bool operator!=(const month_weekday& x, const month_weekday& y) noexcept; - - template - basic_ostream& - operator<<(basic_ostream& os, const month_weekday& mwd); - - // \ref{time.cal.mwdlast}, class \tcode{month_weekday_last} - class month_weekday_last; - - constexpr bool operator==(const month_weekday_last& x, const month_weekday_last& y) noexcept; - constexpr bool operator!=(const month_weekday_last& x, const month_weekday_last& y) noexcept; - - template - basic_ostream& - operator<<(basic_ostream& os, const month_weekday_last& mwdl); - - // \ref{time.cal.ym}, class \tcode{year_month} - class year_month; - - constexpr bool operator==(const year_month& x, const year_month& y) noexcept; - constexpr bool operator!=(const year_month& x, const year_month& y) noexcept; - constexpr bool operator< (const year_month& x, const year_month& y) noexcept; - constexpr bool operator> (const year_month& x, const year_month& y) noexcept; - constexpr bool operator<=(const year_month& x, const year_month& y) noexcept; - constexpr bool operator>=(const year_month& x, const year_month& y) noexcept; - - constexpr year_month operator+(const year_month& ym, const months& dm) noexcept; - constexpr year_month operator+(const months& dm, const year_month& ym) noexcept; - constexpr year_month operator-(const year_month& ym, const months& dm) noexcept; - constexpr months operator-(const year_month& x, const year_month& y) noexcept; - constexpr year_month operator+(const year_month& ym, const years& dy) noexcept; - constexpr year_month operator+(const years& dy, const year_month& ym) noexcept; - constexpr year_month operator-(const year_month& ym, const years& dy) noexcept; - - template - basic_ostream& - operator<<(basic_ostream& os, const year_month& ym); - - template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, const year_month& ym); - - template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - year_month& ym, basic_string* abbrev = nullptr, - minutes* offset = nullptr); - - // \ref{time.cal.ymd}, class \tcode{year_month_day} - class year_month_day; - - constexpr bool operator==(const year_month_day& x, const year_month_day& y) noexcept; - constexpr bool operator!=(const year_month_day& x, const year_month_day& y) noexcept; - constexpr bool operator< (const year_month_day& x, const year_month_day& y) noexcept; - constexpr bool operator> (const year_month_day& x, const year_month_day& y) noexcept; - constexpr bool operator<=(const year_month_day& x, const year_month_day& y) noexcept; - constexpr bool operator>=(const year_month_day& x, const year_month_day& y) noexcept; - - constexpr year_month_day operator+(const year_month_day& ymd, const months& dm) noexcept; - constexpr year_month_day operator+(const months& dm, const year_month_day& ymd) noexcept; - constexpr year_month_day operator+(const year_month_day& ymd, const years& dy) noexcept; - constexpr year_month_day operator+(const years& dy, const year_month_day& ymd) noexcept; - constexpr year_month_day operator-(const year_month_day& ymd, const months& dm) noexcept; - constexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept; - - template - basic_ostream& - operator<<(basic_ostream& os, const year_month_day& ymd); - - template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, - const year_month_day& ymd); - - template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - year_month_day& ymd, - basic_string* abbrev = nullptr, - minutes* offset = nullptr); - - // \ref{time.cal.ymdlast}, class \tcode{year_month_day_last} - class year_month_day_last; - - constexpr bool operator==(const year_month_day_last& x, - const year_month_day_last& y) noexcept; - constexpr bool operator!=(const year_month_day_last& x, - const year_month_day_last& y) noexcept; - constexpr bool operator< (const year_month_day_last& x, - const year_month_day_last& y) noexcept; - constexpr bool operator> (const year_month_day_last& x, - const year_month_day_last& y) noexcept; - constexpr bool operator<=(const year_month_day_last& x, - const year_month_day_last& y) noexcept; - constexpr bool operator>=(const year_month_day_last& x, - const year_month_day_last& y) noexcept; - - constexpr year_month_day_last - operator+(const year_month_day_last& ymdl, const months& dm) noexcept; - constexpr year_month_day_last - operator+(const months& dm, const year_month_day_last& ymdl) noexcept; - constexpr year_month_day_last - operator+(const year_month_day_last& ymdl, const years& dy) noexcept; - constexpr year_month_day_last - operator+(const years& dy, const year_month_day_last& ymdl) noexcept; - constexpr year_month_day_last - operator-(const year_month_day_last& ymdl, const months& dm) noexcept; - constexpr year_month_day_last - operator-(const year_month_day_last& ymdl, const years& dy) noexcept; - - template - basic_ostream& - operator<<(basic_ostream& os, const year_month_day_last& ymdl); - - // \ref{time.cal.ymwd}, class \tcode{year_month_weekday} - class year_month_weekday; - - constexpr bool operator==(const year_month_weekday& x, - const year_month_weekday& y) noexcept; - constexpr bool operator!=(const year_month_weekday& x, - const year_month_weekday& y) noexcept; - - constexpr year_month_weekday - operator+(const year_month_weekday& ymwd, const months& dm) noexcept; - constexpr year_month_weekday - operator+(const months& dm, const year_month_weekday& ymwd) noexcept; - constexpr year_month_weekday - operator+(const year_month_weekday& ymwd, const years& dy) noexcept; - constexpr year_month_weekday - operator+(const years& dy, const year_month_weekday& ymwd) noexcept; - constexpr year_month_weekday - operator-(const year_month_weekday& ymwd, const months& dm) noexcept; - constexpr year_month_weekday - operator-(const year_month_weekday& ymwd, const years& dy) noexcept; - - template - basic_ostream& - operator<<(basic_ostream& os, const year_month_weekday& ymwdi); - - // \ref{time.cal.ymwdlast}, class \tcode{year_month_weekday_last} - class year_month_weekday_last; - - constexpr bool operator==(const year_month_weekday_last& x, - const year_month_weekday_last& y) noexcept; - constexpr bool operator!=(const year_month_weekday_last& x, - const year_month_weekday_last& y) noexcept; - - constexpr year_month_weekday_last - operator+(const year_month_weekday_last& ymwdl, const months& dm) noexcept; - constexpr year_month_weekday_last - operator+(const months& dm, const year_month_weekday_last& ymwdl) noexcept; - constexpr year_month_weekday_last - operator+(const year_month_weekday_last& ymwdl, const years& dy) noexcept; - constexpr year_month_weekday_last - operator+(const years& dy, const year_month_weekday_last& ymwdl) noexcept; - constexpr year_month_weekday_last - operator-(const year_month_weekday_last& ymwdl, const months& dm) noexcept; - constexpr year_month_weekday_last - operator-(const year_month_weekday_last& ymwdl, const years& dy) noexcept; - - template - basic_ostream& - operator<<(basic_ostream& os, const year_month_weekday_last& ymwdl); - - // \ref{time.cal.operators}, civil calendar conventional syntax operators - constexpr year_month - operator/(const year& y, const month& m) noexcept; - constexpr year_month - operator/(const year& y, int m) noexcept; - constexpr month_day - operator/(const month& m, const day& d) noexcept; - constexpr month_day - operator/(const month& m, int d) noexcept; - constexpr month_day - operator/(int m, const day& d) noexcept; - constexpr month_day - operator/(const day& d, const month& m) noexcept; - constexpr month_day - operator/(const day& d, int m) noexcept; - constexpr month_day_last - operator/(const month& m, last_spec) noexcept; - constexpr month_day_last - operator/(int m, last_spec) noexcept; - constexpr month_day_last - operator/(last_spec, const month& m) noexcept; - constexpr month_day_last - operator/(last_spec, int m) noexcept; - constexpr month_weekday - operator/(const month& m, const weekday_indexed& wdi) noexcept; - constexpr month_weekday - operator/(int m, const weekday_indexed& wdi) noexcept; - constexpr month_weekday - operator/(const weekday_indexed& wdi, const month& m) noexcept; - constexpr month_weekday - operator/(const weekday_indexed& wdi, int m) noexcept; - constexpr month_weekday_last - operator/(const month& m, const weekday_last& wdl) noexcept; - constexpr month_weekday_last - operator/(int m, const weekday_last& wdl) noexcept; - constexpr month_weekday_last - operator/(const weekday_last& wdl, const month& m) noexcept; - constexpr month_weekday_last - operator/(const weekday_last& wdl, int m) noexcept; - constexpr year_month_day - operator/(const year_month& ym, const day& d) noexcept; - constexpr year_month_day - operator/(const year_month& ym, int d) noexcept; - constexpr year_month_day - operator/(const year& y, const month_day& md) noexcept; - constexpr year_month_day - operator/(int y, const month_day& md) noexcept; - constexpr year_month_day - operator/(const month_day& md, const year& y) noexcept; - constexpr year_month_day - operator/(const month_day& md, int y) noexcept; - constexpr year_month_day_last - operator/(const year_month& ym, last_spec) noexcept; - constexpr year_month_day_last - operator/(const year& y, const month_day_last& mdl) noexcept; - constexpr year_month_day_last - operator/(int y, const month_day_last& mdl) noexcept; - constexpr year_month_day_last - operator/(const month_day_last& mdl, const year& y) noexcept; - constexpr year_month_day_last - operator/(const month_day_last& mdl, int y) noexcept; - constexpr year_month_weekday - operator/(const year_month& ym, const weekday_indexed& wdi) noexcept; - constexpr year_month_weekday - operator/(const year& y, const month_weekday& mwd) noexcept; - constexpr year_month_weekday - operator/(int y, const month_weekday& mwd) noexcept; - constexpr year_month_weekday - operator/(const month_weekday& mwd, const year& y) noexcept; - constexpr year_month_weekday - operator/(const month_weekday& mwd, int y) noexcept; - constexpr year_month_weekday_last - operator/(const year_month& ym, const weekday_last& wdl) noexcept; - constexpr year_month_weekday_last - operator/(const year& y, const month_weekday_last& mwdl) noexcept; - constexpr year_month_weekday_last - operator/(int y, const month_weekday_last& mwdl) noexcept; - constexpr year_month_weekday_last - operator/(const month_weekday_last& mwdl, const year& y) noexcept; - constexpr year_month_weekday_last - operator/(const month_weekday_last& mwdl, int y) noexcept; - - // \ref{time.tod}, class template \tcode{time_of_day} - template class time_of_day; - template<> class time_of_day; - template<> class time_of_day; - template<> class time_of_day; - template class time_of_day>; - - template - basic_ostream& - operator<<(basic_ostream& os, const time_of_day& t); - - template - basic_ostream& - operator<<(basic_ostream& os, const time_of_day& t); - - template - basic_ostream& - operator<<(basic_ostream& os, const time_of_day& t); - - template - basic_ostream& - operator<<(basic_ostream& os, - const time_of_day>& t); - - // \ref{time.zone.db}, time zone database - struct tzdb; - class tzdb_list; - - // \ref{time.zone.db.access}, time zone database access - const tzdb& get_tzdb(); - tzdb_list& get_tzdb_list(); - const time_zone* locate_zone(string_view tz_name); - const time_zone* current_zone(); - - // \ref{time.zone.db.remote}, remote time zone database support - const tzdb& reload_tzdb(); - string remote_version(); - - // \ref{time.zone.exception}, exception classes - class nonexistent_local_time; - class ambiguous_local_time; - - // \ref{time.zone.info}, information classes - struct sys_info; - template - basic_ostream& - operator<<(basic_ostream& os, const sys_info& si); - - struct local_info; - template - basic_ostream& - operator<<(basic_ostream& os, const local_info& li); - - // \ref{time.zone.timezone}, class \tcode{time_zone} - enum class choose {earliest, latest}; - class time_zone; - - bool operator==(const time_zone& x, const time_zone& y) noexcept; - bool operator!=(const time_zone& x, const time_zone& y) noexcept; - - bool operator<(const time_zone& x, const time_zone& y) noexcept; - bool operator>(const time_zone& x, const time_zone& y) noexcept; - bool operator<=(const time_zone& x, const time_zone& y) noexcept; - bool operator>=(const time_zone& x, const time_zone& y) noexcept; - - // \ref{time.zone.zonedtraits}, class template \tcode{zoned_traits} - template struct zoned_traits; - - // \ref{time.zone.zonedtime}, class template \tcode{zoned_time} - template class zoned_time; - - using zoned_seconds = zoned_time; - - template - bool operator==(const zoned_time& x, - const zoned_time& y); - - template - bool operator!=(const zoned_time& x, - const zoned_time& y); - - template - basic_ostream& - operator<<(basic_ostream& os, - const zoned_time& t); - - template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, - const zoned_time& tp); - - // \ref{time.zone.leap}, leap second support - class leap; - - bool operator==(const leap& x, const leap& y); - bool operator!=(const leap& x, const leap& y); - bool operator< (const leap& x, const leap& y); - bool operator> (const leap& x, const leap& y); - bool operator<=(const leap& x, const leap& y); - bool operator>=(const leap& x, const leap& y); - - template - bool operator==(const leap& x, const sys_time& y); - template - bool operator==(const sys_time& x, const leap& y); - template - bool operator!=(const leap& x, const sys_time& y); - template - bool operator!=(const sys_time& x, const leap& y); - template - bool operator< (const leap& x, const sys_time& y); - template - bool operator< (const sys_time& x, const leap& y); - template - bool operator> (const leap& x, const sys_time& y); - template - bool operator> (const sys_time& x, const leap& y); - template - bool operator<=(const leap& x, const sys_time& y); - template - bool operator<=(const sys_time& x, const leap& y); - template - bool operator>=(const leap& x, const sys_time& y); - template - bool operator>=(const sys_time& x, const leap& y); - - // \ref{time.zone.link}, class \tcode{link} - class link; - - bool operator==(const link& x, const link& y); - bool operator!=(const link& x, const link& y); - bool operator< (const link& x, const link& y); - bool operator> (const link& x, const link& y); - bool operator<=(const link& x, const link& y); - bool operator>=(const link& x, const link& y); - - // \ref{time.format}, formatting - template - basic_string - format(const charT* fmt, const Streamable& s); - template - basic_string - format(const locale& loc, const charT* fmt, const Streamable& s); - template - basic_string - format(const basic_string& fmt, const Streamable& s); - template - basic_string - format(const locale& loc, const basic_string& fmt, - const Streamable& s); - - // \ref{time.parse}, parsing - template - @\unspec@ - parse(const basic_string& format, Parsable& tp); - - template - @\unspec@ - parse(const basic_string& format, Parsable& tp, - basic_string& abbrev); - - template - @\unspec@ - parse(const basic_string& format, Parsable& tp, - minutes& offset); - - template - @\unspec@ - parse(const basic_string& format, Parsable& tp, - basic_string& abbrev, minutes& offset); - - // calendrical constants - inline constexpr last_spec last{}; - - inline constexpr weekday Sunday{0}; - inline constexpr weekday Monday{1}; - inline constexpr weekday Tuesday{2}; - inline constexpr weekday Wednesday{3}; - inline constexpr weekday Thursday{4}; - inline constexpr weekday Friday{5}; - inline constexpr weekday Saturday{6}; - - inline constexpr month January{1}; - inline constexpr month February{2}; - inline constexpr month March{3}; - inline constexpr month April{4}; - inline constexpr month May{5}; - inline constexpr month June{6}; - inline constexpr month July{7}; - inline constexpr month August{8}; - inline constexpr month September{9}; - inline constexpr month October{10}; - inline constexpr month November{11}; - inline constexpr month December{12}; - } - - 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); - - // \ref{time.cal.day.nonmembers}, non-member functions - constexpr chrono::day operator""d(unsigned long long d) noexcept; - - // \ref{time.cal.year.nonmembers}, non-member functions - constexpr chrono::year operator""y(unsigned long long y) noexcept; - } - } - - namespace chrono { - using namespace literals::chrono_literals; - } -} -\end{codeblock} - -\rSec2[time.clock.req]{Clock requirements} - -\pnum -A clock is a bundle consisting of a \tcode{duration}, a -\tcode{time_point}, and a function \tcode{now()} to get the current \tcode{time_point}. -The origin of the clock's \tcode{time_point} is referred to as the clock's \defn{epoch}. - A clock shall satisfy the requirements in \tref{time.clock}. - -\pnum -In \tref{time.clock} \tcode{C1} and \tcode{C2} denote clock types. \tcode{t1} and -\tcode{t2} are values returned by \tcode{C1::now()} where the call returning \tcode{t1} happens -before\iref{intro.multithread} the call returning \tcode{t2} and both of these calls -occur -before \tcode{C1::time_point::max()}. -\begin{note} This means \tcode{C1} did not wrap around between \tcode{t1} and -\tcode{t2}. \end{note} - -\begin{libreqtab3a} -{Clock requirements} -{tab:time.clock} -\\ \topline -\lhdr{Expression} & \chdr{Return type} & \rhdr{Operational semantics} \\ \capsep -\endfirsthead -\continuedcaption\\ -\hline -\lhdr{Expression} & \chdr{Return type} & \rhdr{Operational semantics} \\ \capsep -\endhead - -\tcode{C1::rep} & - An arithmetic type or a class emulating an arithmetic type & - The representation type of \tcode{C1::duration}. \\ \rowsep - -\tcode{C1::period} & - a specialization of \tcode{ratio} & - The tick period of the clock in seconds. \\ \rowsep - -\tcode{C1::duration} & - \tcode{chrono::duration} & - The \tcode{duration} type of the clock. \\ \rowsep - -\tcode{C1::time_point} & - \tcode{chrono::time_point} or \tcode{chrono::time_point} & - The \tcode{time_point} type of the clock. \tcode{C1} and \tcode{C2} shall - refer to the same epoch. \\ \rowsep - -\tcode{C1::is_steady} & - \tcode{const bool} & - \tcode{true} if \tcode{t1 <= t2} is always \tcode{true} and the time between clock - ticks is constant, otherwise \tcode{false}. \\ \rowsep - -\tcode{C1::now()} & - \tcode{C1::time_point} & - Returns a \tcode{time_point} object representing the current point in time. \\ - -\end{libreqtab3a} - -\pnum -\begin{note} The relative difference in durations between those reported by a given clock and the -SI definition is a measure of the quality of implementation. \end{note} - -\pnum -A type \tcode{TC} meets the \tcode{TrivialClock} requirements if: - -\begin{itemize} -\item \tcode{TC} satisfies the \tcode{Clock} requirements\iref{time.clock.req}, - -\item the types \tcode{TC::rep}, \tcode{TC::duration}, and \tcode{TC::time_point} -satisfy the \tcode{EqualityComparable} (\tref{equalitycomparable}), -\tcode{LessThanComparable} (\tref{lessthancomparable}), -\tcode{DefaultConstructible} (\tref{defaultconstructible}), -\tcode{CopyCon\-structible} (\tref{copyconstructible}), -\tcode{CopyAssignable} (\tref{copyassignable}), and -\tcode{Destructible} (\tref{destructible}) requirements and the requirements of -numeric types\iref{numeric.requirements}. \begin{note} This means, in particular, -that operations on these types will not throw exceptions. \end{note} - -\item lvalues of the types \tcode{TC::rep}, \tcode{TC::duration}, and -\tcode{TC::time_point} are swappable\iref{swappable.requirements}, - -\item the function \tcode{TC::now()} does not throw exceptions, and - -\item the type \tcode{TC::time_point::clock} meets the \tcode{TrivialClock} -requirements, recursively. -\end{itemize} - -\rSec2[time.traits]{Time-related traits} - -\rSec3[time.traits.is_fp]{\tcode{treat_as_floating_point}} - -\indexlibrary{\idxcode{treat_as_floating_point}}% -\begin{itemdecl} -template struct treat_as_floating_point : is_floating_point { }; -\end{itemdecl} - -\pnum -The \tcode{duration} template uses the \tcode{treat_as_floating_point} trait to -help determine if a \tcode{duration} object can be converted to another -\tcode{duration} with a different tick \tcode{period}. If -\tcode{treat_as_floating_point_v} is \tcode{true}, then implicit conversions -are allowed among \tcode{duration}s. Otherwise, the implicit convertibility -depends on the tick \tcode{period}s of the \tcode{duration}s. -\begin{note} -The intention of this trait is to indicate whether a given class behaves like a floating-point -type, and thus allows division of one value by another with acceptable loss of precision. If -\tcode{treat_as_floating_point_v} is \tcode{false}, \tcode{Rep} will be treated as -if it behaved like an integral type for the purpose of these conversions. -\end{note} - -\rSec3[time.traits.duration_values]{\tcode{duration_values}} - -\indexlibrary{\idxcode{duration_values}}% -\begin{itemdecl} -template - struct duration_values { - public: - static constexpr Rep zero(); - static constexpr Rep min(); - static constexpr Rep max(); -}; -\end{itemdecl} - -\pnum -The \tcode{duration} template uses the \tcode{duration_values} trait to -construct special values of the duration's representation (\tcode{Rep}). This is -done because the representation might be a class type with behavior which -requires some other implementation to return these special values. In that case, -the author of that class type should specialize \tcode{duration_values} to -return the indicated values. - -\indexlibrarymember{zero}{duration_values}% -\begin{itemdecl} -static constexpr Rep zero(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{Rep(0)}. \begin{note} \tcode{Rep(0)} is specified instead of -\tcode{Rep()} because \tcode{Rep()} may have some other meaning, such as an -uninitialized value. \end{note} - -\pnum -\remarks The value returned shall be the additive identity. -\end{itemdescr} - -\indexlibrarymember{min}{duration_values}% -\begin{itemdecl} -static constexpr Rep min(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{numeric_limits::lowest()}. - -\pnum -\remarks The value returned shall compare less than or equal to \tcode{zero()}. -\end{itemdescr} - -\indexlibrarymember{max}{duration_values}% -\begin{itemdecl} -static constexpr Rep max(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{numeric_limits::max()}. - -\pnum -\remarks The value returned shall compare greater than \tcode{zero()}. -\end{itemdescr} - -\rSec3[time.traits.specializations]{Specializations of \tcode{common_type}} - -\indexlibrary{\idxcode{common_type}}% -\begin{itemdecl} -template -struct common_type, chrono::duration> { - using type = chrono::duration, @\seebelow@>; -}; -\end{itemdecl} - -\pnum -The \tcode{period} of the \tcode{duration} indicated by this specialization of -\tcode{common_type} shall be the greatest common divisor of \tcode{Period1} and -\tcode{Period2}. \begin{note} This can be computed by forming a ratio of the -greatest common divisor of \tcode{Period1::num} and \tcode{Period2::num} and the -least common multiple of \tcode{Period1::den} and \tcode{Period2::den}. -\end{note} - -\pnum -\begin{note} The \tcode{typedef} name \tcode{type} is a synonym for the -\tcode{duration} with the largest tick \tcode{period} possible where both -\tcode{duration} arguments will convert to it without requiring a division -operation. The representation of this type is intended to be able to hold any -value resulting from this conversion with no truncation error, although -floating-point durations may have round-off errors. \end{note} - -\indexlibrary{\idxcode{common_type}}% -\begin{itemdecl} -template - struct common_type, chrono::time_point> { - using type = chrono::time_point>; -}; -\end{itemdecl} - -\pnum -The common type of two \tcode{time_point} types is a \tcode{time_point} with the same -clock as the two types and the common type of their two \tcode{duration}s. - -\rSec3[time.traits.is_clock]{Class template \tcode{is_clock}} - -\indexlibrary{\idxcode{is_clock}}% -\begin{itemdecl} -template struct is_clock; -\end{itemdecl} - -\pnum -\tcode{is_clock} is a UnaryTypeTrait\iref{meta.rqmts} -with a base characteristic of \tcode{true_type} -if \tcode{T} meets the Clock requirements\iref{time.clock.req}, -otherwise \tcode{false_type}. -For the purposes of the specification of this trait, -the extent to which an implementation determines -that a type cannot meet the Clock requirements is unspecified, -except that as a minimum -a type \tcode{T} shall not qualify as a Clock -unless it satisfies all of the following conditions: - -\begin{itemize} -\item the \grammarterm{qualified-id}s -\tcode{T::rep}, -\tcode{T::period}, -\tcode{T::duration}, and -\tcode{T::time_point} -are valid and each denotes a type\iref{temp.deduct}, -\item the expression -\tcode{T::is_steady} -is well-formed when treated as an unevaluated operand, -\item the expression -\tcode{T::now()} -is well-formed when treated as an unevaluated operand. -\end{itemize} - -\pnum -The behavior of a program that adds specializations for \tcode{is_clock} is undefined. - -\rSec2[time.duration]{Class template \tcode{duration}} - -\pnum -A \tcode{duration} type measures time between two points in time (\tcode{time_point}s). -A \tcode{duration} has a representation which holds a count of ticks and a tick period. -The tick period is the amount of time which occurs from one tick to the next, in units -of seconds. It is expressed as a rational constant using the template \tcode{ratio}. - -\indexlibrary{\idxcode{duration}}% -\begin{codeblock} -namespace std::chrono { - template> - class duration { - public: - using rep = Rep; - using period = typename Period::type; - - private: - rep rep_; // \expos - - public: - // \ref{time.duration.cons}, construct/copy/destroy - constexpr duration() = default; - template - constexpr explicit duration(const Rep2& r); - template - constexpr duration(const duration& d); - ~duration() = default; - duration(const duration&) = default; - duration& operator=(const duration&) = default; - - // \ref{time.duration.observer}, observer - constexpr rep count() const; - - // \ref{time.duration.arithmetic}, arithmetic - constexpr common_type_t operator+() const; - constexpr common_type_t operator-() const; - constexpr duration& operator++(); - constexpr duration operator++(int); - constexpr duration& operator--(); - constexpr duration operator--(int); - - constexpr duration& operator+=(const duration& d); - constexpr duration& operator-=(const duration& d); - - constexpr duration& operator*=(const rep& rhs); - constexpr duration& operator/=(const rep& rhs); - constexpr duration& operator%=(const rep& rhs); - constexpr duration& operator%=(const duration& rhs); - - // \ref{time.duration.special}, special values - static constexpr duration zero(); - static constexpr duration min(); - static constexpr duration max(); - }; -} -\end{codeblock} - -\pnum -\tcode{Rep} shall be an arithmetic type or a class emulating an arithmetic type. -If \tcode{duration} is instantiated with a \tcode{duration} type as the argument for the template -parameter \tcode{Rep}, the program is ill-formed. - -\pnum -If \tcode{Period} is not a specialization of \tcode{ratio}, the program is ill-formed. -If \tcode{Period::num} is not positive, the program is ill-formed. - -\pnum -Members of \tcode{duration} shall not throw exceptions other than -those thrown by the indicated operations on their representations. - -\pnum -The defaulted copy constructor of duration shall be a -constexpr function if and only if the required initialization -of the member \tcode{rep_} for copy and move, respectively, would -satisfy the requirements for a constexpr function. - -\pnum -\begin{example} -\begin{codeblock} -duration> d0; // holds a count of minutes using a \tcode{long} -duration d1; // holds a count of milliseconds using a \tcode{long long} -duration> d2; // holds a count with a tick period of $\frac{1}{30}$ of a second - // (30 Hz) using a \tcode{double} -\end{codeblock} -\end{example} - -\rSec3[time.duration.cons]{\tcode{duration} constructors} - -\indexlibrary{\idxcode{duration}!constructor}% -\begin{itemdecl} -template - constexpr explicit duration(const Rep2& r); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks This constructor shall not participate in overload -resolution unless -\tcode{Rep2} is implicitly convertible to \tcode{rep} and -\begin{itemize} -\item \tcode{treat_as_floating_point_v} is \tcode{true} or -\item \tcode{treat_as_floating_point_v} is \tcode{false}. -\end{itemize} -\begin{example} -\begin{codeblock} -duration d(3); // OK -duration d(3.5); // error -\end{codeblock} -\end{example} - -\pnum -\effects Constructs an object of type \tcode{duration}. - -\pnum -\postconditions \tcode{count() == static_cast(r)}. -\end{itemdescr} - -\indexlibrary{\idxcode{duration}!constructor}% -\begin{itemdecl} -template - constexpr duration(const duration& d); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks This constructor shall not participate in overload resolution unless -no overflow is induced in the conversion and -\tcode{treat_as_floating_point_v} is \tcode{true} or both -\tcode{ratio_divide::den} is \tcode{1} and -\tcode{treat_as_floating_point_v} is \tcode{false}. \begin{note} This -requirement prevents implicit truncation error when converting between -integral-based \tcode{duration} types. Such a construction could easily lead to -confusion about the value of the \tcode{duration}. \end{note} -\begin{example} -\begin{codeblock} -duration ms(3); -duration us = ms; // OK -duration ms2 = us; // error -\end{codeblock} -\end{example} - -\pnum -\effects Constructs an object of type \tcode{duration}, constructing \tcode{rep_} from\\ -\tcode{duration_cast(d).count()}. -\end{itemdescr} - -\rSec3[time.duration.observer]{\tcode{duration} observer} - -\indexlibrarymember{count}{duration}% -\begin{itemdecl} -constexpr rep count() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{rep_}. -\end{itemdescr} - -\rSec3[time.duration.arithmetic]{\tcode{duration} arithmetic} - -\indexlibrarymember{operator+}{duration}% -\begin{itemdecl} -constexpr common_type_t operator+() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{common_type_t(*this)}. -\end{itemdescr} - -\indexlibrarymember{operator-}{duration}% -\begin{itemdecl} -constexpr common_type_t operator-() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{common_type_t(-rep_)}. -\end{itemdescr} - -\indexlibrarymember{operator++}{duration}% -\begin{itemdecl} -constexpr duration& operator++(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects As if by \tcode{++rep_}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator++}{duration}% -\begin{itemdecl} -constexpr duration operator++(int); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{duration(rep_++)}. -\end{itemdescr} - -\indexlibrarymember{operator\dcr}{duration}% -\begin{itemdecl} -constexpr duration& operator--(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects As if by \tcode{--rep_}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator\dcr}{duration}% -\begin{itemdecl} -constexpr duration operator--(int); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{duration(rep_-{}-)}. -\end{itemdescr} - -\indexlibrarymember{operator+=}{duration}% -\begin{itemdecl} -constexpr duration& operator+=(const duration& d); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects As if by: \tcode{rep_ += d.count();} - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator-=}{duration}% -\begin{itemdecl} -constexpr duration& operator-=(const duration& d); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects As if by: \tcode{rep_ -= d.count();} - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator*=}{duration}% -\begin{itemdecl} -constexpr duration& operator*=(const rep& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects As if by: \tcode{rep_ *= rhs;} - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator/=}{duration}% -\begin{itemdecl} -constexpr duration& operator/=(const rep& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects As if by: \tcode{rep_ /= rhs;} - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator\%=}{duration}% -\begin{itemdecl} -constexpr duration& operator%=(const rep& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects As if by: \tcode{rep_ \%= rhs;} - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator\%=}{duration}% -\begin{itemdecl} -constexpr duration& operator%=(const duration& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects As if by: \tcode{rep_ \%= rhs.count();} - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - - -\rSec3[time.duration.special]{\tcode{duration} special values} - -\indexlibrarymember{zero}{duration}% -\begin{itemdecl} -static constexpr duration zero(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{duration(duration_values::zero())}. -\end{itemdescr} - -\indexlibrarymember{min}{duration}% -\begin{itemdecl} -static constexpr duration min(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{duration(duration_values::min())}. -\end{itemdescr} - -\indexlibrarymember{max}{duration}% -\begin{itemdecl} -static constexpr duration max(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{duration(duration_values::max())}. -\end{itemdescr} - -\rSec3[time.duration.nonmember]{\tcode{duration} non-member arithmetic} - -\pnum -In the function descriptions that follow, \tcode{CD} represents the return type -of the function. - -\indexlibrary{\idxcode{common_type}}% -\begin{itemdecl} -template - constexpr common_type_t, duration> - operator+(const duration& lhs, const duration& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{CD(CD(lhs).count() + CD(rhs).count())}. -\end{itemdescr} - -\indexlibrary{\idxcode{common_type}}% -\begin{itemdecl} -template - constexpr common_type_t, duration> - operator-(const duration& lhs, const duration& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{CD(CD(lhs).count() - CD(rhs).count())}. -\end{itemdescr} - -\indexlibrarymember{operator*}{duration}% -\begin{itemdecl} -template - constexpr duration, Period> - operator*(const duration& d, const Rep2& s); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks This operator shall not participate in overload -resolution unless \tcode{Rep2} is implicitly convertible to \tcode{common_type_t}. - -\pnum -\returns \tcode{CD(CD(d).count() * s)}. -\end{itemdescr} - -\indexlibrarymember{operator*}{duration}% -\begin{itemdecl} -template - constexpr duration, Period> - operator*(const Rep1& s, const duration& d); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks This operator shall not participate in overload -resolution unless \tcode{Rep1} is implicitly convertible to \tcode{common_type_t}. - -\pnum -\returns \tcode{d * s}. -\end{itemdescr} - -\indexlibrarymember{operator/}{duration}% -\begin{itemdecl} -template - constexpr duration, Period> - operator/(const duration& d, const Rep2& s); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks This operator shall not participate in overload -resolution unless \tcode{Rep2} is implicitly convertible to \tcode{common_type_t} -and \tcode{Rep2} is not a specialization of \tcode{duration}. - -\pnum -\returns \tcode{CD(CD(d).count() / s)}. -\end{itemdescr} - -\indexlibrarymember{operator/}{duration}% -\begin{itemdecl} -template - constexpr common_type_t - operator/(const duration& lhs, const duration& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{CD(lhs).count() / CD(rhs).count()}. -\end{itemdescr} - -\indexlibrarymember{operator\%}{duration}% -\begin{itemdecl} -template - constexpr duration, Period> - operator%(const duration& d, const Rep2& s); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks This operator shall not participate in overload -resolution unless \tcode{Rep2} is implicitly convertible to \tcode{common_type_t} and -\tcode{Rep2} is not a specialization of \tcode{duration}. - -\pnum -\returns \tcode{CD(CD(d).count() \% s)}. -\end{itemdescr} - -\indexlibrarymember{operator\%}{duration}% -\begin{itemdecl} -template - constexpr common_type_t, duration> - operator%(const duration& lhs, const duration& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{CD(CD(lhs).count() \% CD(rhs).count())}. -\end{itemdescr} - - -\rSec3[time.duration.comparisons]{\tcode{duration} comparisons} - -\pnum -In the function descriptions that follow, \tcode{CT} represents -\tcode{common_type_t}, where \tcode{A} and \tcode{B} are the types of -the two arguments to the function. - -\indexlibrarymember{operator==}{duration}% -\begin{itemdecl} -template - constexpr bool operator==(const duration& lhs, - const duration& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{CT(lhs).count() == CT(rhs).count()}. -\end{itemdescr} - -\indexlibrarymember{operator"!=}{duration}% -\begin{itemdecl} -template - constexpr bool operator!=(const duration& lhs, - const duration& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{!(lhs == rhs)}. -\end{itemdescr} - -\indexlibrarymember{operator<}{duration}% -\begin{itemdecl} -template - constexpr bool operator<(const duration& lhs, - const duration& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{CT(lhs).count() < CT(rhs).count()}. -\end{itemdescr} - -\indexlibrarymember{operator>}{duration}% -\begin{itemdecl} -template - constexpr bool operator>(const duration& lhs, - const duration& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{rhs < lhs}. -\end{itemdescr} - -\indexlibrarymember{operator<=}{duration}% -\begin{itemdecl} -template - constexpr bool operator<=(const duration& lhs, - const duration& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{!(rhs < lhs)}. -\end{itemdescr} - -\indexlibrarymember{operator>=}{duration}% -\begin{itemdecl} -template - constexpr bool operator>=(const duration& lhs, - const duration& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{!(lhs < rhs)}. -\end{itemdescr} - -\rSec3[time.duration.cast]{\tcode{duration_cast}} - -\indexlibrary{\idxcode{duration}!\idxcode{duration_cast}}% -\indexlibrary{\idxcode{duration_cast}}% -\begin{itemdecl} -template - constexpr ToDuration duration_cast(const duration& d); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks This function shall not participate in overload resolution -unless \tcode{ToDuration} is a specialization of \tcode{duration}. - -\pnum -\returns Let \tcode{CF} be \tcode{ratio_divide}, and \tcode{CR} be \tcode{common_type::type}. -\begin{itemize} -\item If \tcode{CF::num == 1} and \tcode{CF::den == 1}, returns -\begin{codeblock} -ToDuration(static_cast(d.count())) -\end{codeblock} - -\item otherwise, if \tcode{CF::num != 1} and \tcode{CF::den == 1}, returns -\begin{codeblock} -ToDuration(static_cast( - static_cast(d.count()) * static_cast(CF::num))) -\end{codeblock} - -\item otherwise, if \tcode{CF::num == 1} and \tcode{CF::den != 1}, returns -\begin{codeblock} -ToDuration(static_cast( - static_cast(d.count()) / static_cast(CF::den))) -\end{codeblock} - -\item otherwise, returns -\begin{codeblock} -ToDuration(static_cast( - static_cast(d.count()) * static_cast(CF::num) / static_cast(CF::den))) -\end{codeblock} -\end{itemize} - -\pnum -\begin{note} -This function does not use any implicit conversions; all conversions -are done with \tcode{static_cast}. It avoids multiplications and divisions when -it is known at compile time that one or more arguments is 1. Intermediate -computations are carried out in the widest representation and only converted to -the destination representation at the final step. -\end{note} -\end{itemdescr} - -\indexlibrarymember{floor}{duration}% -\begin{itemdecl} -template - constexpr ToDuration floor(const duration& d); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks This function shall not participate in overload resolution -unless \tcode{ToDuration} is a specialization of \tcode{duration}. - -\pnum -\returns The greatest result \tcode{t} representable in \tcode{ToDuration} -for which \tcode{t <= d}. -\end{itemdescr} - -\indexlibrarymember{ceil}{duration}% -\begin{itemdecl} -template - constexpr ToDuration ceil(const duration& d); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks This function shall not participate in overload resolution -unless \tcode{ToDuration} is a specialization of \tcode{duration}. - -\pnum -\returns The least result \tcode{t} representable in \tcode{ToDuration} -for which \tcode{t >= d}. -\end{itemdescr} - -\indexlibrarymember{round}{duration}% -\begin{itemdecl} -template - constexpr ToDuration round(const duration& d); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks This function shall not participate in overload resolution -unless \tcode{ToDuration} is a specialization of \tcode{duration}, -and \tcode{treat_as_floating_point_v} -is \tcode{false}. - -\pnum -\returns The value of \tcode{ToDuration} that is closest to \tcode{d}. -If there are two closest values, then return the value \tcode{t} -for which \tcode{t \% 2 == 0}. -\end{itemdescr} - -\rSec3[time.duration.literals]{Suffixes for duration literals} - -\pnum -This subclause describes literal suffixes for constructing duration literals. The -suffixes \tcode{h}, \tcode{min}, \tcode{s}, \tcode{ms}, \tcode{us}, \tcode{ns} -denote duration values of the corresponding types \tcode{hours}, \tcode{minutes}, -\tcode{seconds}, \tcode{milliseconds}, \tcode{microseconds}, and \tcode{nanoseconds} -respectively if they are applied to integral literals. - -\pnum -If any of these suffixes are applied to a floating-point literal the result is a -\tcode{chrono::duration} literal with an unspecified floating-point representation. - -\pnum -If any of these suffixes are applied to an integer literal and the resulting -\tcode{chrono::duration} value cannot be represented in the result type because -of overflow, the program is ill-formed. - -\pnum -\begin{example} -The following code shows some duration literals. -\begin{codeblock} -using namespace std::chrono_literals; -auto constexpr aday=24h; -auto constexpr lesson=45min; -auto constexpr halfanhour=0.5h; -\end{codeblock} -\end{example} - -\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); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -A \tcode{duration} literal representing \tcode{hours} hours. -\end{itemdescr} - -\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); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -A \tcode{duration} literal representing \tcode{minutes} minutes. -\end{itemdescr} - -\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); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -A \tcode{duration} literal representing \tcode{sec} seconds. - -\pnum -\begin{note} -The same suffix \tcode{s} is used for \tcode{basic_string} but there is no -conflict, since duration suffixes apply to numbers and string literal suffixes -apply to character array literals. -\end{note} -\end{itemdescr} - -\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); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -A \tcode{duration} literal representing \tcode{msec} milliseconds. -\end{itemdescr} - -\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); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -A \tcode{duration} literal representing \tcode{usec} microseconds. -\end{itemdescr} - -\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); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -A \tcode{duration} literal representing \tcode{nsec} nanoseconds. -\end{itemdescr} - -\rSec3[time.duration.alg]{\tcode{duration} algorithms} - -\indexlibrarymember{abs}{duration}% -\begin{itemdecl} -template - constexpr duration abs(duration d); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks This function shall not participate in overload resolution -unless \tcode{numeric_limits::is_signed} is \tcode{true}. - -\pnum -\returns If \tcode{d >= d.zero()}, return \tcode{d}, -otherwise return \tcode{-d}. -\end{itemdescr} - -\rSec3[time.duration.io]{\tcode{duration} I/O} - -\indexlibrarymember{operator<<}{duration}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const duration& d); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires \tcode{Rep} is an integral type -whose integer conversion rank\iref{conv.rank} -is greater than or equal to that of \tcode{short}, -or a floating point type. -\tcode{charT} is \tcode{char} or \tcode{wchar_t}. - -\pnum -\effects -Forms a \tcode{basic_string} from \tcode{d.count()} -using \tcode{to_string} if \tcode{charT} is \tcode{char}, -or \tcode{to_wstring} if \tcode{charT} is \tcode{wchar_t}. -Appends the units suffix described below to the \tcode{basic_string}. -Inserts the resulting \tcode{basic_string} into \tcode{os}. -\begin{note} -This specification ensures that the result of this streaming operation -will obey the width and alignment properties of the stream. -\end{note} - -\pnum -The units suffix depends on the type \tcode{Period::type} as follows: -\begin{itemize} -\item If \tcode{Period::type} is \tcode{atto}, the suffix is \tcode{"as"}. -\item Otherwise, if \tcode{Period::type} is \tcode{femto}, the suffix is \tcode{"fs"}. -\item Otherwise, if \tcode{Period::type} is \tcode{pico}, the suffix is \tcode{"ps"}. -\item Otherwise, if \tcode{Period::type} is \tcode{nano}, the suffix is \tcode{"ns"}. -\item Otherwise, if \tcode{Period::type} is \tcode{micro}, the suffix is \tcode{"\textmu{}s"} (\tcode{"\textbackslash{}u00b5\textbackslash{}u0073"}). -\item Otherwise, if \tcode{Period::type} is \tcode{milli}, the suffix is \tcode{"ms"}. -\item Otherwise, if \tcode{Period::type} is \tcode{centi}, the suffix is \tcode{"cs"}. -\item Otherwise, if \tcode{Period::type} is \tcode{deci}, the suffix is \tcode{"ds"}. -\item Otherwise, if \tcode{Period::type} is \tcode{ratio<1>}, the suffix is \tcode{"s"}. -\item Otherwise, if \tcode{Period::type} is \tcode{deca}, the suffix is \tcode{"das"}. -\item Otherwise, if \tcode{Period::type} is \tcode{hecto}, the suffix is \tcode{"hs"}. -\item Otherwise, if \tcode{Period::type} is \tcode{kilo}, the suffix is \tcode{"ks"}. -\item Otherwise, if \tcode{Period::type} is \tcode{mega}, the suffix is \tcode{"Ms"}. -\item Otherwise, if \tcode{Period::type} is \tcode{giga}, the suffix is \tcode{"Gs"}. -\item Otherwise, if \tcode{Period::type} is \tcode{tera}, the suffix is \tcode{"Ts"}. -\item Otherwise, if \tcode{Period::type} is \tcode{peta}, the suffix is \tcode{"Ps"}. -\item Otherwise, if \tcode{Period::type} is \tcode{exa}, the suffix is \tcode{"Es"}. -\item Otherwise, if \tcode{Period::type} is \tcode{ratio<60>}, the suffix is \tcode{"min"}. -\item Otherwise, if \tcode{Period::type} is \tcode{ratio<3600>}, the suffix is \tcode{"h"}. -\item Otherwise, if \tcode{Period::type::den == 1}, the suffix is \tcode{"[\placeholder{num}]s"}. -\item Otherwise, the suffix is \tcode{"[\placeholder{num}/\placeholder{den}]s"}. -\end{itemize} -In the list above the use of \tcode{\placeholder{num}} and \tcode{\placeholder{den}} -refer to the static data members of \tcode{Period::type}, -which are converted to arrays of \tcode{charT} using a decimal conversion with no leading zeroes. - -\pnum -For streams where \tcode{charT} has an 8-bit representation, -\tcode{"\textmu{}s"} should be encoded as UTF-8. Otherwise UTF-16 or UTF-32 is encouraged. -The implementation may substitute other encodings, including \tcode{"us"}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{to_stream}{duration}% -\begin{itemdecl} -template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, - const duration& d); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Streams \tcode{d} into \tcode{os} using -the format specified by the NTCTS \tcode{fmt}. -\tcode{fmt} encoding follows the rules specified in \ref{time.format}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{from_stream}{duration}% -\begin{itemdecl} -template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - duration& d, - basic_string* abbrev = nullptr, - minutes* offset = nullptr); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Attempts to parse the input stream \tcode{is} -into the duration \tcode{d} -using the format flags given in the NTCTS \tcode{fmt} -as specified in \ref{time.parse}. -If the parse parses everything specified by the parsing format flags without error, -and yet none of the flags impacts a duration, -\tcode{d} will be assigned a zero value. -If \tcode{\%Z} is used and successfully parsed, -that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. -If \tcode{\%z} (or a modified variant) is used and successfully parsed, -that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. - -\pnum -\returns \tcode{is}. -\end{itemdescr} - -\rSec2[time.point]{Class template \tcode{time_point}} - -\indexlibrary{\idxcode{time_point}}% -\begin{codeblock} -namespace std::chrono { - template - class time_point { - public: - using clock = Clock; - using duration = Duration; - using rep = typename duration::rep; - using period = typename duration::period; - - private: - duration d_; // \expos - - public: - // \ref{time.point.cons}, construct - constexpr time_point(); // has value epoch - constexpr explicit time_point(const duration& d); // same as \tcode{time_point() + d} - template - constexpr time_point(const time_point& t); - - // \ref{time.point.observer}, observer - constexpr duration time_since_epoch() const; - - // \ref{time.point.arithmetic}, arithmetic - constexpr time_point& operator++(); - constexpr time_point operator++(int); - constexpr time_point& operator--(); - constexpr time_point operator--(int); - constexpr time_point& operator+=(const duration& d); - constexpr time_point& operator-=(const duration& d); - - // \ref{time.point.special}, special values - static constexpr time_point min(); - static constexpr time_point max(); - }; -} -\end{codeblock} - -\pnum -\tcode{Clock} shall either -satisfy the Clock requirements\iref{time.clock.req} -or be the type \tcode{local_t}. - -\pnum -If \tcode{Duration} is not an instance of \tcode{duration}, -the program is ill-formed. - -\rSec3[time.point.cons]{\tcode{time_point} constructors} - -\indexlibrary{\idxcode{time_point}!constructor}% -\begin{itemdecl} -constexpr time_point(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Constructs an object of type \tcode{time_point}, initializing -\tcode{d_} with \tcode{duration::zero()}. Such a \tcode{time_point} object -represents the epoch. -\end{itemdescr} - -\indexlibrary{\idxcode{time_point}!constructor}% -\begin{itemdecl} -constexpr explicit time_point(const duration& d); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Constructs an object of type \tcode{time_point}, initializing -\tcode{d_} with \tcode{d}. Such a \tcode{time_point} object represents the epoch -\tcode{+ d}. -\end{itemdescr} - -\indexlibrary{\idxcode{time_point}!constructor}% -\begin{itemdecl} -template - constexpr time_point(const time_point& t); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks This constructor shall not participate in overload resolution unless \tcode{Duration2} -is implicitly convertible to \tcode{duration}. - -\pnum -\effects Constructs an object of type \tcode{time_point}, initializing -\tcode{d_} with \tcode{t.time_since_epoch()}. -\end{itemdescr} - -\rSec3[time.point.observer]{\tcode{time_point} observer} - -\indexlibrarymember{time_since_epoch}{time_point}% -\begin{itemdecl} -constexpr duration time_since_epoch() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{d_}. -\end{itemdescr} - -\rSec3[time.point.arithmetic]{\tcode{time_point} arithmetic} - -\indexlibrarymember{operator++}{time_point}% -\begin{itemdecl} -constexpr time_point& operator++(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{++d_}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator++}{time_point}% -\begin{itemdecl} -constexpr time_point operator++(int); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{time_point\{d_++\}}. -\end{itemdescr} - -\indexlibrarymember{operator--}{time_point}% -\begin{itemdecl} -constexpr time_point& operator--(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{--d_}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator--}{time_point}% -\begin{itemdecl} -constexpr time_point operator--(int); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{time_point\{d_--\}}. -\end{itemdescr} - -\indexlibrarymember{operator+=}{time_point}% -\begin{itemdecl} -constexpr time_point& operator+=(const duration& d); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects As if by: \tcode{d_ += d;} - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator-=}{time_point}% -\begin{itemdecl} -constexpr time_point& operator-=(const duration& d); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects As if by: \tcode{d_ -= d;} - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\rSec3[time.point.special]{\tcode{time_point} special values} - -\indexlibrarymember{min}{time_point}% -\begin{itemdecl} -static constexpr time_point min(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{time_point(duration::min())}. -\end{itemdescr} - -\indexlibrarymember{max}{time_point}% -\begin{itemdecl} -static constexpr time_point max(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{time_point(duration::max())}. -\end{itemdescr} - -\rSec3[time.point.nonmember]{\tcode{time_point} non-member arithmetic} - -\indexlibrarymember{operator+}{time_point}% -\indexlibrarymember{operator+}{duration}% -\begin{itemdecl} -template - constexpr time_point>> - operator+(const time_point& lhs, const duration& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{CT(lhs.time_since_epoch() + rhs)}, where \tcode{CT} is the type of the return value. -\end{itemdescr} - -\indexlibrarymember{operator+}{time_point}% -\indexlibrarymember{operator+}{duration}% -\begin{itemdecl} -template - constexpr time_point, Duration2>> - operator+(const duration& lhs, const time_point& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{rhs + lhs}. -\end{itemdescr} - -\indexlibrarymember{operator-}{time_point}% -\indexlibrarymember{operator-}{duration}% -\begin{itemdecl} -template - constexpr time_point>> - operator-(const time_point& lhs, const duration& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{CT(lhs.time_since_epoch() - rhs)}, -where \tcode{CT} is the type of the return value. -\end{itemdescr} - -\indexlibrarymember{operator-}{time_point}% -\begin{itemdecl} -template - constexpr common_type_t - operator-(const time_point& lhs, const time_point& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{lhs.time_since_epoch() - rhs.time_since_epoch()}. -\end{itemdescr} - -\rSec3[time.point.comparisons]{\tcode{time_point} comparisons} - -\indexlibrarymember{operator==}{time_point}% -\begin{itemdecl} -template - constexpr bool operator==(const time_point& lhs, - const time_point& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{lhs.time_since_epoch() == rhs.time_since_epoch()}. -\end{itemdescr} - -\indexlibrarymember{operator"!=}{time_point}% -\begin{itemdecl} -template - constexpr bool operator!=(const time_point& lhs, - const time_point& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{!(lhs == rhs)}. -\end{itemdescr} - -\indexlibrarymember{operator<}{time_point}% -\begin{itemdecl} -template - constexpr bool operator<(const time_point& lhs, - const time_point& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{lhs.time_since_epoch() < rhs.time_since_epoch()}. -\end{itemdescr} - -\indexlibrarymember{operator>}{time_point}% -\begin{itemdecl} -template - constexpr bool operator>(const time_point& lhs, - const time_point& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{rhs < lhs}. -\end{itemdescr} - -\indexlibrarymember{operator<=}{time_point}% -\begin{itemdecl} -template - constexpr bool operator<=(const time_point& lhs, - const time_point& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{!(rhs < lhs)}. -\end{itemdescr} - -\indexlibrarymember{operator>=}{time_point}% -\begin{itemdecl} -template - constexpr bool operator>=(const time_point& lhs, - const time_point& rhs); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{!(lhs < rhs)}. -\end{itemdescr} - -\rSec3[time.point.cast]{\tcode{time_point_cast}} - -\indexlibrary{\idxcode{time_point}!\idxcode{time_point_cast}}% -\indexlibrary{\idxcode{time_point_cast}}% -\begin{itemdecl} -template - constexpr time_point time_point_cast(const time_point& t); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks This function shall not participate in overload resolution -unless \tcode{ToDuration} is a specialization of \tcode{duration}. - -\pnum -\returns -\begin{codeblock} -time_point(duration_cast(t.time_since_epoch())) -\end{codeblock} -\end{itemdescr} - -\indexlibrarymember{floor}{time_point}% -\begin{itemdecl} -template - constexpr time_point floor(const time_point& tp); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks This function shall not participate in overload resolution -unless \tcode{ToDuration} is a specialization of \tcode{duration}. - -\pnum -\returns \tcode{time_point(floor(tp.time_since_epoch()))}. -\end{itemdescr} - -\indexlibrarymember{ceil}{time_point}% -\begin{itemdecl} -template - constexpr time_point ceil(const time_point& tp); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks This function shall not participate in overload resolution -unless \tcode{ToDuration} is a specialization of \tcode{duration}. - -\pnum -\returns \tcode{time_point(ceil(tp.time_since_epoch()))}. -\end{itemdescr} - -\indexlibrarymember{round}{time_point}% -\begin{itemdecl} -template - constexpr time_point round(const time_point& tp); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks This function shall not participate in overload resolution -unless \tcode{ToDuration} is a specialization of \tcode{duration}, and -\tcode{treat_as_floating_point_v} is \tcode{false}. - -\pnum -\returns \tcode{time_point(round(tp.time_since_epoch()))}. -\end{itemdescr} - -\rSec2[time.clock]{Clocks} - -\pnum -The types defined in this subclause shall satisfy the -\tcode{TrivialClock} -requirements\iref{time.clock.req} -unless otherwise specified. - -\rSec3[time.clock.system]{Class \tcode{system_clock}} - -\rSec4[time.clock.system.overview]{Overview} -\indexlibrary{\idxcode{system_clock}}% - -\begin{codeblock} -namespace std::chrono { - class system_clock { - public: - using rep = @\seebelow@; - using period = ratio<@\unspecnc@, @\unspec{}@>; - using duration = chrono::duration; - using time_point = chrono::time_point; - static constexpr bool is_steady = @\unspec;@ - - static time_point now() noexcept; - - // mapping to/from C type \tcode{time_t} - static time_t to_time_t (const time_point& t) noexcept; - static time_point from_time_t(time_t t) noexcept; - }; -} -\end{codeblock} - -\pnum -Objects of type \tcode{system_clock} represent wall clock time from the system-wide -realtime clock. -Objects of type \tcode{sys_time} measure time since (and before) -1970-01-01 00:00:00 UTC excluding leap seconds. -This measure is commonly referred to as \defn{Unix time}. -This measure facilitates an efficient mapping between -\tcode{sys_time} and calendar types\iref{time.cal}. -\begin{example} \\ -\tcode{sys_seconds\{sys_days\{1970y/January/1\}\}.time_since_epoch()} is \tcode{0s}. \\ -\tcode{sys_seconds\{sys_days\{2000y/January/1\}\}.time_since_epoch()} is \tcode{946'684'800s}, -which is \tcode{10'957 * 86'400s}. \\ -\end{example} - -\rSec4[time.clock.system.members]{Members} - -\indexlibrarymember{rep}{system_clock}% -\begin{itemdecl} -using system_clock::rep = @\unspec@; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires \tcode{system_clock::duration::min() < system_clock::duration::zero()} shall -be \tcode{true}.\\ -\begin{note} This implies that \tcode{rep} is a signed type. \end{note} -\end{itemdescr} - -\indexlibrarymember{to_time_t}{system_clock}% -\begin{itemdecl} -static time_t to_time_t(const time_point& t) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns A \tcode{time_t} object that represents the same point in time as \tcode{t} -when both values are restricted to the coarser of the precisions of \tcode{time_t} and -\tcode{time_point}. -It is \impldef{whether values are rounded or truncated to the -required precision when converting between \tcode{time_t} values and \tcode{time_point} objects} -whether values are rounded or truncated to the required precision. -\end{itemdescr} - -\indexlibrarymember{from_time_t}{system_clock}% -\begin{itemdecl} -static time_point from_time_t(time_t t) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns A \tcode{time_point} object that represents the same point in time as \tcode{t} -when both values are restricted to the coarser of the precisions of \tcode{time_t} and -\tcode{time_point}. -It is \impldef{whether values are rounded or truncated to the -required precision when converting between \tcode{time_t} values and \tcode{time_point} objects} -whether values are rounded or truncated to the required precision. -\end{itemdescr} - -\rSec4[time.clock.system.nonmembers]{Non-member functions} - -\indexlibrarymember{operator<<}{sys_time}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const sys_time& tp); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -This operator shall not participate in overload resolution if -\tcode{treat_as_floating_point_v} is \tcode{true}, -or if \tcode{Duration\{1\} >= days\{1\}}. - -\pnum -\effects -\begin{codeblock} -auto const dp = floor(tp); -os << year_month_day{dp} << ' ' << time_of_day{tp-dp}; -\end{codeblock} - -\pnum -\returns \tcode{os}. - -\pnum -\begin{example} -\begin{codeblock} -cout << sys_seconds{0s} << '\n'; // 1970-01-01 00:00:00 -cout << sys_seconds{946'684'800s} << '\n'; // 2000-01-01 00:00:00 -cout << sys_seconds{946'688'523s} << '\n'; // 2000-01-01 01:02:03 -\end{codeblock} -\end{example} -\end{itemdescr} - -\indexlibrarymember{operator<<}{sys_days}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const sys_days& dp); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{os << year_month_day\{dp\}}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{to_stream}{sys_time}% -\begin{itemdecl} -template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, const sys_time& tp); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Streams \tcode{tp} into \tcode{os} using -the format specified by the NTCTS \tcode{fmt}. -\tcode{fmt} encoding follows the rules specified in \ref{time.format}. -If \tcode{\%Z} is used, it will be replaced with -\tcode{"UTC"} widened to \tcode{charT}. -If \tcode{\%z} is used (or a modified variant of \tcode{\%z}), -an offset of \tcode{0min} will be formatted. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{from_stream}{sys_time}% -\begin{itemdecl} -template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - sys_time& tp, basic_string* abbrev = nullptr, - minutes* offset = nullptr); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Attempts to parse the input stream \tcode{is} -into the \tcode{sys_time} \tcode{tp} using -the format flags given in the NTCTS \tcode{fmt} -as specified in \ref{time.parse}. -If the parse fails to decode a valid date, -\tcode{is.setstate(ios_base::failbit)} -shall be called and \tcode{tp} shall not be modified. -If \tcode{\%Z} is used and successfully parsed, -that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. -If \tcode{\%z} (or a modified variant) is used and successfully parsed, -that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. -Additionally, the parsed offset will be subtracted -from the successfully parsed timestamp -prior to assigning that difference to \tcode{tp}. - -\pnum -\returns is. -\end{itemdescr} - -\rSec3[time.clock.utc]{Class \tcode{utc_clock}} - -\rSec4[time.clock.utc.overview]{Overview} -\indexlibrary{\idxcode{utc_clock}}% - -\begin{codeblock} -namespace std::chrono { - class utc_clock { - public: - using rep = @\textit{a signed arithmetic type}@; - using period = ratio<@\unspecnc@, @\unspec@>; - using duration = chrono::duration; - using time_point = chrono::time_point; - static constexpr bool is_steady = @\unspec@; - - static time_point now(); - - template - static sys_time> - to_sys(const utc_time& t); - template - static utc_time> - from_sys(const sys_time& t); - }; -} -\end{codeblock} - -\pnum -In contrast to \tcode{sys_time}, -which does not take leap seconds into account, -\tcode{utc_clock} and its associated \tcode{time_point}, \tcode{utc_time}, -count time, including leap seconds, since 1970-01-01 00:00:00 UTC. -\begin{example} \\ -\tcode{clock_cast(sys_seconds\{sys_days\{1970y/January/1\}\}).time_since_epoch()} is \tcode{0s}. \\ -\tcode{clock_cast(sys_seconds\{sys_days\{2000y/January/1\}\}).time_since_epoch()} \\ -is \tcode{946'684'822s}, which is \tcode{10'957 * 86'400s + 22s}. \\ -\end{example} - -\pnum -\tcode{utc_clock} is not a TrivialClock -unless the implementation can guarantee that \tcode{utc_clock::now()} -does not propagate an exception. -\begin{note} \tcode{noexcept(from_sys(system_clock::now()))} is \tcode{false}. \end{note} - -\rSec4[time.clock.utc.members]{Member functions} - -\indexlibrarymember{now}{utc_clock}% -\begin{itemdecl} -static time_point now(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{from_sys(system_clock::now())}, or a more accurate value of \tcode{utc_time}. -\end{itemdescr} - -\indexlibrarymember{to_sys}{utc_clock}% -\begin{itemdecl} -template - static sys_time> - to_sys(const utc_time& u); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -A \tcode{sys_time} \tcode{t}, -such that \tcode{from_sys(t) == u} if such a mapping exists. -Otherwise \tcode{u} represents a \tcode{time_point} -during a leap second insertion -and the last representable value of \tcode{sys_time} -prior to the insertion of the leap second is returned. -\end{itemdescr} - -\indexlibrarymember{from_sys}{utc_clock}% -\begin{itemdecl} -template - static utc_time> - from_sys(const sys_time& t); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -A \tcode{utc_time} \tcode{u}, such that -\tcode{u.time_since_epoch() - t.time_since_epoch()} -is equal to the number of leap seconds that were inserted -between \tcode{t} and 1970-01-01. -If \tcode{t} is exactly the date of leap second insertion, -then the conversion counts that leap second as inserted. - -\begin{example} -\begin{codeblock} -auto t = sys_days{July/1/2015} - 2ns; -auto u = utc_clock::from_sys(t); -assert(u.time_since_epoch() - t.time_since_epoch() == 25s); -t += 1ns; -u = utc_clock::from_sys(t); -assert(u.time_since_epoch() - t.time_since_epoch() == 25s); -t += 1ns; -u = utc_clock::from_sys(t); -assert(u.time_since_epoch() - t.time_since_epoch() == 26s); -t += 1ns; -u = utc_clock::from_sys(t); -assert(u.time_since_epoch() - t.time_since_epoch() == 26s); -\end{codeblock} -\end{example} -\end{itemdescr} - -\rSec4[time.clock.utc.nonmembers]{Non-member functions} - -\indexlibrarymember{operator<<}{utc_time}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const utc_time& t); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Calls \tcode{to_stream(os, fmt, t)}, -where \tcode{fmt} is a string containing \tcode{"\%F \%T"} -widened to \tcode{charT}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{to_stream}{utc_time}% -\begin{itemdecl} -template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, const utc_time& tp); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Streams \tcode{tp} into \tcode{os} using -the format specified by the NTCTS \tcode{fmt}. -\tcode{fmt} encoding follows the rules specified in \ref{time.format}. -If \tcode{\%Z} is used, it will be replaced with \tcode{"UTC"} widened to \tcode{charT}. -If \tcode{\%z} is used (or a modified variant of \tcode{\%z}), -an offset of \tcode{0min} will be formatted. -If \tcode{tp} represents a time during a leap second insertion, -and if a seconds field is formatted, -the integral portion of that format shall be \tcode{"60"} widened to \tcode{charT}. - -\pnum -\returns \tcode{os}. - -\pnum -\begin{example} -\begin{codeblock} -auto t = sys_days{July/1/2015} - 500ms; -auto u = clock_cast(t); -for (auto i = 0; i < 8; ++i, u += 250ms) - cout << u << " UTC\n"; -\end{codeblock} - -Produces this output: - -\begin{codeblock} -2015-06-30 23:59:59.500 UTC -2015-06-30 23:59:59.750 UTC -2015-06-30 23:59:60.000 UTC -2015-06-30 23:59:60.250 UTC -2015-06-30 23:59:60.500 UTC -2015-06-30 23:59:60.750 UTC -2015-07-01 00:00:00.000 UTC -2015-07-01 00:00:00.250 UTC -\end{codeblock} -\end{example} -\end{itemdescr} - -\indexlibrarymember{from_stream}{utc_time}% -\begin{itemdecl} -template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - utc_time& tp, basic_string* abbrev = nullptr, - minutes* offset = nullptr); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Attempts to parse the input stream \tcode{is} -into the \tcode{utc_time} \tcode{tp} using -the format flags given in the NTCTS \tcode{fmt} -as specified in \ref{time.parse}. -If the parse fails to decode a valid date, -\tcode{is.setstate(ios_base::failbit)} shall be called -and \tcode{tp} shall not be modified. -If \tcode{\%Z} is used and successfully parsed, -that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. -If \tcode{\%z} (or a modified variant) is used and successfully parsed, -that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. -Additionally, the parsed offset will be subtracted from -the successfully parsed timestamp -prior to assigning that difference to \tcode{tp}. - -\pnum -\returns \tcode{is}. -\end{itemdescr} - -\rSec3[time.clock.tai]{Class \tcode{tai_clock}} - -\rSec4[time.clock.tai.overview]{Overview} -\indexlibrary{\idxcode{tai_clock}}% - -\begin{codeblock} -namespace std::chrono { - class tai_clock { - public: - using rep = @\textit{a signed arithmetic type}@; - using period = ratio<@\unspecnc@, @\unspec@>; - using duration = chrono::duration; - using time_point = chrono::time_point; - static constexpr bool is_steady = @\unspec@; - - static time_point now(); - - template - static utc_time> - to_utc(const tai_time&) noexcept; - template - static tai_time> - from_utc(const utc_time&) noexcept; - }; -} -\end{codeblock} - -\pnum -The clock \tcode{tai_clock} measures seconds since 1958-01-01 00:00:00 -and is offset 10s ahead of UTC at this date. -That is, 1958-01-01 00:00:00 TAI is equivalent to 1957-12-31 23:59:50 UTC. -Leap seconds are not inserted into TAI. -Therefore every time a leap second is inserted into UTC, -UTC falls another second behind TAI. -For example by 2000-01-01 there had been 22 leap seconds inserted -so 2000-01-01 00:00:00 UTC is equivalent to 2000-01-01 00:00:32 TAI -(22s plus the initial 10s offset). - -\pnum -\tcode{tai_clock} is not a TrivialClock -unless the implementation can guarantee that \tcode{tai_clock::now()} -does not propagate an exception. -\begin{note} -\tcode{noexcept(from_utc(utc_clock::now()))} is \tcode{false}. -\end{note} - -\rSec4[time.clock.tai.members]{Member functions} - -\indexlibrarymember{now}{tai_clock}% -\begin{itemdecl} -static time_point now(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{from_utc(utc_clock::now())}, or a more accurate value of \tcode{tai_time}. -\end{itemdescr} - -\indexlibrarymember{to_utc}{tai_clock}% -\begin{itemdecl} -template - static utc_time> - to_utc(const tai_time& t) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\begin{codeblock} -utc_time>{t.time_since_epoch()} - 378691210s -\end{codeblock} -\begin{note} -\begin{codeblock} -378691210s == sys_days{1970y/January/1} - sys_days{1958y/January/1} + 10s -\end{codeblock} -\end{note} -\end{itemdescr} - -\indexlibrarymember{from_utc}{tai_clock}% -\begin{itemdecl} -template - static tai_time> - from_utc(const utc_time& t) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\begin{codeblock} -tai_time>{t.time_since_epoch()} + 378691210s -\end{codeblock} -\begin{note} -\begin{codeblock} -378691210s == sys_days{1970y/January/1} - sys_days{1958y/January/1} + 10s -\end{codeblock} -\end{note} -\end{itemdescr} - -\rSec4[time.clock.tai.nonmembers]{Non-member functions} - -\indexlibrarymember{operator<<}{tai_time}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const tai_time& t); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Calls \tcode{to_stream(os, fmt, t)}, -where \tcode{fmt} is a string containing -\tcode{"\%F \%T"} widened to \tcode{charT}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{to_stream}{tai_time}% -\begin{itemdecl} -template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, const tai_time& tp); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Streams \tcode{tp} into \tcode{os} using -the format specified by the NTCTS \tcode{fmt}. -\tcode{fmt} encoding follows the rules specified in \ref{time.format}. -If \tcode{\%Z} is used, it will be replaced with \tcode{"TAI"}. -If \tcode{\%z} is used (or a modified variant of \tcode{\%z}), -an offset of \tcode{0min} will be formatted. -The date and time formatted shall be equivalent to -that formatted by a \tcode{sys_time} initialized with: -\begin{codeblock} -sys_time{tp.time_since_epoch()} - - (sys_days{1970y/January/1} - sys_days{1958y/January/1}) -\end{codeblock} - -\pnum -\returns os. - -\pnum -\begin{example} -\begin{codeblock} -auto st = sys_days{2000y/January/1}; -auto tt = clock_cast(st); -cout << format("%F %T %Z == ", st) << format("%F %T %Z\n", tt); -\end{codeblock} - -Produces this output: - -\begin{codeblock} -2000-01-01 00:00:00 UTC == 2000-01-01 00:00:32 TAI -\end{codeblock} -\end{example} -\end{itemdescr} - -\indexlibrarymember{from_stream}{tai_time}% -\begin{itemdecl} -template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - tai_time& tp, basic_string* abbrev = nullptr, - minutes* offset = nullptr); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Attempts to parse the input stream \tcode{is} -into the \tcode{tai_time} \tcode{tp} using -the format flags given in the NTCTS \tcode{fmt} -as specified in \ref{time.parse}. -If the parse fails to decode a valid date, -\tcode{is.setstate(ios_base::failbit)} shall be called -and \tcode{tp} shall not be modified. -If \tcode{\%Z} is used and successfully parsed, -that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. -If \tcode{\%z} (or a modified variant) is used and successfully parsed, -that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. -Additionally, the parsed offset will be subtracted from -the successfully parsed timestamp prior to assigning that difference to \tcode{tp}. - -\pnum -\returns \tcode{is}. -\end{itemdescr} - -\rSec3[time.clock.gps]{Class \tcode{gps_clock}} - -\rSec4[time.clock.gps.overview]{Overview} -\indexlibrary{\idxcode{gps_clock}}% - -\begin{codeblock} -namespace std::chrono { - class gps_clock { - public: - using rep = @\textit{a signed arithmetic type}@; - using period = ratio<@\unspecnc@, @\unspec@>; - using duration = chrono::duration; - using time_point = chrono::time_point; - static constexpr bool is_steady = @\unspec@; - - static time_point now(); - - template - static utc_time> - to_utc(const gps_time&) noexcept; - template - static gps_time> - from_utc(const utc_time&) noexcept; - }; -} -\end{codeblock} - -\pnum -The clock \tcode{gps_clock} measures -seconds since the first Sunday of January, 1980 00:00:00 UTC. -Leap seconds are not inserted into GPS. -Therefore every time a leap second is inserted into UTC, -UTC falls another second behind GPS. -Aside from the offset from \tcode{1958y/January/1} to \tcode{1980y/January/Sunday[1]}, -GPS is behind TAI by 19s due to the 10s offset between 1958 and 1970 -and the additional 9 leap seconds inserted between 1970 and 1980. - -\pnum -\tcode{gps_clock} is not a TrivialClock -unless the implementation can guarantee that -\tcode{gps_clock::now()} does not propagate an exception. -\begin{note} -\tcode{noexcept(from_utc(utc_clock::now()))} is \tcode{false}. -\end{note} - -\rSec4[time.clock.gps.members]{Member functions} - -\indexlibrarymember{now}{gps_clock}% -\begin{itemdecl} -static time_point now(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{from_utc(utc_clock::now())}, or a more accurate value of \tcode{gps_time}. -\end{itemdescr} - -\indexlibrarymember{to_utc}{gps_clock}% -\begin{itemdecl} -template - static utc_time> - to_utc(const gps_time& t) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\begin{codeblock} -gps_time>{t.time_since_epoch()} + 315964809s -\end{codeblock} -\begin{note} -\begin{codeblock} -315964809s == sys_days{1980y/January/Sunday[1]} - sys_days{1970y/January/1} + 9s -\end{codeblock} -\end{note} -\end{itemdescr} - -\indexlibrarymember{from_utc}{gps_clock}% -\begin{itemdecl} -template - static gps_time> - from_utc(const utc_time& t) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\begin{codeblock} -gps_time>{t.time_since_epoch()} - 315964809s -\end{codeblock} -\begin{note} -\begin{codeblock} -315964809s == sys_days{1980y/January/Sunday[1]} - sys_days{1970y/January/1} + 9s -\end{codeblock} -\end{note} -\end{itemdescr} - -\rSec4[time.clock.gps.nonmembers]{Non-member functions} - -\indexlibrarymember{operator<<}{gps_time}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const gps_time& t); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Calls \tcode{to_stream(os, fmt, t)}, -where \tcode{fmt} is a string containing -\tcode{"\%F \%T"} widened to \tcode{charT}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{to_stream}{gps_time}% -\begin{itemdecl} -template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, const gps_time& tp); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Streams \tcode{tp} into \tcode{os} using -the format specified by the NTCTS \tcode{fmt}. -\tcode{fmt} encoding follows the rules specified in \ref{time.format}. -If \tcode{\%Z} is used, it will be replaced with \tcode{"GPS"}. -If \tcode{\%z} is used (or a modified variant of \tcode{\%z}), -an offset of \tcode{0min} will be formatted. -The date and time formatted -shall be equivalent to that formatted by a \tcode{sys_time} initialized with: -\begin{codeblock} -sys_time{tp.time_since_epoch()} + - (sys_days{1980y/January/Sunday[1]} - sys_days{1970y/January/1}) -\end{codeblock} - -\pnum -\returns os. - -\pnum -\begin{example} -\begin{codeblock} -auto st = sys_days{2000y/January/1}; -auto gt = clock_cast(st); -cout << format("%F %T %Z == ", st) << format("%F %T %Z\n", gt); -\end{codeblock} - -Produces this output: - -\begin{codeblock} -2000-01-01 00:00:00 UTC == 2000-01-01 00:00:13 GPS -\end{codeblock} -\end{example} -\end{itemdescr} - -\indexlibrarymember{from_stream}{gps_time}% -\begin{itemdecl} -template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - gps_time& tp, basic_string* abbrev = nullptr, - minutes* offset = nullptr); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Attempts to parse the input stream \tcode{is} -into the \tcode{gps_time} \tcode{tp} using -the format flags given in the NTCTS \tcode{fmt} -as specified in \ref{time.parse}. -If the parse fails to decode a valid date, -\tcode{is.setstate(ios_base::failbit)} shall be called -and \tcode{tp} shall not be modified. -If \tcode{\%Z} is used and successfully parsed, -that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. -If \tcode{\%z} (or a modified variant) is used and successfully parsed, -that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. -Additionally, the parsed offset will be subtracted from -the successfully parsed timestamp prior to assigning that difference to \tcode{tp}. - -\pnum -\returns \tcode{is}. -\end{itemdescr} - -\rSec3[time.clock.file]{Class \tcode{file_clock}} - -\rSec4[time.clock.file.overview]{Overview} -\indexlibrary{\idxcode{file_clock}}% - -\begin{codeblock} -namespace std::chrono { - class file_clock { - public: - using rep = @\textit{a signed arithmetic type}@; - using period = ratio<@\unspecnc@, @\unspec@>; - using duration = chrono::duration; - using time_point = chrono::time_point; - static constexpr bool is_steady = @\unspec@; - - static time_point now() noexcept; - - // Conversion functions, see below - }; -} -\end{codeblock} - -\pnum -The clock \tcode{file_clock} is used to create the \tcode{time_point} system -used for \tcode{file_time_type}\iref{filesystems}. Its epoch is unspecified. - -\rSec4[time.clock.file.members]{Member functions} - -\indexlibrarymember{now}{file_clock}% -\begin{itemdecl} -static time_point now(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns A \tcode{file_clock::time_point} indicating the current time. -\end{itemdescr} - -\pnum -The class \tcode{file_clock} shall provide -precisely one of the following two sets of static member functions: - -\begin{codeblock} -template - static sys_time<@\seebelow@> - to_sys(const file_time&); -template - static file_time<@\seebelow@> - from_sys(const sys_time&); -\end{codeblock} - -or: - -\begin{codeblock} -template - static utc_time<@\seebelow@> - to_utc(const file_time&); -template - static file_time<@\seebelow@> - from_utc(const utc_time&); -\end{codeblock} - -These member functions shall provide \tcode{time_point} conversions -consistent with those specified by -\tcode{utc_clock}, \tcode{tai_clock}, and \tcode{gps_clock}. -The \tcode{Duration} of the resultant \tcode{time_point} -is computed from the \tcode{Duration} of the input \tcode{time_point}. - -\rSec4[time.clock.file.nonmembers]{Non-member functions} - -\indexlibrarymember{operator<<}{file_time}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const file_time& t); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects Calls \tcode{to_stream(os, fmt, t)}, -where \tcode{fmt} is a string containing -\tcode{"\%F \%T"} widened to \tcode{charT}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{to_stream}{file_time}% -\begin{itemdecl} -template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, const file_time& tp); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Streams \tcode{tp} into \tcode{os} using -the format specified by the NTCTS \tcode{fmt}. -\tcode{fmt} encoding follows the rules specified in \ref{time.format}. -If \tcode{\%Z} is used, it will be replaced with \tcode{"UTC"} widened to \tcode{charT}. -If \tcode{\%z} is used (or a modified variant of \tcode{\%z}), -an offset of \tcode{0min} will be formatted. -The date and time formatted shall be equivalent to -that formatted by a \tcode{sys_time} initialized with -\tcode{clock_cast(tp)}, -or by a \tcode{utc_time} initialized with -\tcode{clock_cast(tp)}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{from_stream}{file_time}% -\begin{itemdecl} -template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - file_time& tp, basic_string* abbrev = nullptr, - minutes* offset = nullptr); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Attempts to parse the input stream \tcode{is} -into the \tcode{file_time} \tcode{tp} using -the format flags given in the NTCTS \tcode{fmt} -as specified in \ref{time.parse}. -If the parse fails to decode a valid date, -\tcode{is.setstate(ios_base::failbit)} shall be called -and \tcode{tp} shall not be modified. -If \tcode{\%Z} is used and successfully parsed, -that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. -If \tcode{\%z} (or a modified variant) is used and successfully parsed, -that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. -Additionally, the parsed offset will be subtracted from -the successfully parsed timestamp prior to assigning that difference to \tcode{tp}. - -\pnum -\returns \tcode{is}. -\end{itemdescr} - -\rSec3[time.clock.steady]{Class \tcode{steady_clock}} -\indexlibrary{\idxcode{steady_clock}}% - -\begin{codeblock} -namespace std::chrono { - class steady_clock { - public: - using rep = @\unspec@; - using period = ratio<@\unspecnc@, @\unspec{}@>; - using duration = chrono::duration; - using time_point = chrono::time_point<@\unspecnc@, duration>; - static constexpr bool is_steady = true; - - static time_point now() noexcept; - }; -} -\end{codeblock} - -\pnum -Objects of class \tcode{steady_clock} represent clocks for which values of \tcode{time_point} -never decrease as physical time advances and for which values of \tcode{time_point} advance at -a steady rate relative to real time. That is, the clock may not be adjusted. - -\rSec3[time.clock.hires]{Class \tcode{high_resolution_clock}} -\indexlibrary{\idxcode{high_resolution_clock}}% - -\begin{codeblock} -namespace std::chrono { - class high_resolution_clock { - public: - using rep = @\unspec@; - using period = ratio<@\unspecnc@, @\unspec{}@>; - using duration = chrono::duration; - using time_point = chrono::time_point<@\unspecnc@, duration>; - static constexpr bool is_steady = @\unspec@; - - static time_point now() noexcept; - }; -} -\end{codeblock} - -\pnum -Objects of class \tcode{high_resolution_clock} represent clocks with the -shortest tick period. \tcode{high_resolution_clock} may be a synonym for -\tcode{system_clock} or \tcode{steady_clock}. - -\rSec3[time.clock.local]{Local time} -\indexlibrary{\idxcode{local_time}}% - -\pnum -The family of time points -denoted by \tcode{local_time} -are based on the pseudo clock \tcode{local_t}. -\tcode{local_t} has no member \tcode{now()} -and thus does not meet the clock requirements. -Nevertheless \tcode{local_time} serves the vital role of -representing local time with respect to a not-yet-specified time zone. -Aside from being able to get the current time, -the complete \tcode{time_point} algebra is available -for \tcode{local_time} (just as for \tcode{sys_time}). - -\indexlibrarymember{operator<<}{local_time}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const local_time& lt); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -\begin{codeblock} -os << sys_time{lt.time_since_epoch()}; -\end{codeblock} - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{to_stream}{local_time}% -\begin{itemdecl} -template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, const local_time& tp, - const string* abbrev = nullptr, const seconds* offset_sec = nullptr); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Streams \tcode{tp} into \tcode{os} using -the format specified by the NTCTS \tcode{fmt}. -\tcode{fmt} encoding follows the rules specified in \ref{time.format}. -If \tcode{\%Z} is used, -it will be replaced with \tcode{*abbrev} if \tcode{abbrev} is not equal to \tcode{nullptr}. -If \tcode{abbrev} is equal to \tcode{nullptr} (and \tcode{\%Z} is used), -\tcode{os.setstate(ios_base::failbit)} shall be called. -If \tcode{\%z} is used (or a modified variant of \tcode{\%z}), -it will be formatted with the value of \tcode{*offset_sec} -if \tcode{offset_sec} is not equal to \tcode{nullptr}. -If \tcode{\%z} (or a modified variant of \tcode{\%z}) is used, -and \tcode{offset_sec} is equal to \tcode{nullptr}, then -\tcode{os.setstate(ios_base::failbit)} shall be called. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{from_stream}{local_time}% -\begin{itemdecl} -template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - local_time& tp, basic_string* abbrev = nullptr, - minutes* offset = nullptr); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Attempts to parse the input stream \tcode{is} -into the \tcode{local_time} \tcode{tp} using -the format flags given in the NTCTS \tcode{fmt} -as specified in \ref{time.parse}. -If the parse fails to decode a valid date, -\tcode{is.setstate(ios_base::failbit)} shall be called -and \tcode{tp} shall not be modified. -If \tcode{\%Z} is used and successfully parsed, -that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. -If \tcode{\%z} (or a modified variant) is used and successfully parsed, -that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. - -\pnum -\returns \tcode{is}. -\end{itemdescr} - -\rSec3[time.clock.cast]{\tcode{time_point} conversions} - -\rSec4[time.clock.conv]{Class template \tcode{clock_time_conversion}} -\indexlibrary{\idxcode{clock_time_conversion}}% - -\begin{codeblock} -namespace std::chrono { - template - struct clock_time_conversion {}; -} -\end{codeblock} - -\pnum -\tcode{clock_time_conversion} serves as a trait -which can be used to specify how to convert -a source \tcode{time_point} of type -\tcode{time_point} -to a destination \tcode{time_point} of type -\tcode{time_point} -via a specialization: -\tcode{clock_time_conversion}. -A specialization of \tcode{clock_time_conversion} -shall provide a const-qualified \tcode{operator()} -that takes a parameter of type \tcode{time_point} -and returns a \tcode{time_point} -representing an equivalent point in time. -\tcode{OtherDuration} is a \tcode{chrono::duration} -whose specialization is computed from the input \tcode{Duration} -in a manner which can vary for each \tcode{clock_time_conversion} specialization. -A program may specialize \tcode{clock_time_conversion} -if at least one of the template parameters is a user-defined clock type. - -\pnum -Several specializations are provided by the implementation, -as described in -\ref{time.clock.cast.id}, -\ref{time.clock.cast.sys.utc}, -\ref{time.clock.cast.sys}, and -\ref{time.clock.cast.utc}. - -\rSec4[time.clock.cast.id]{Identity conversions} - -\begin{codeblock} -template -struct clock_time_conversion { - template - time_point - operator()(const time_point& t) const; -}; -\end{codeblock} - -\indexlibrarymember{operator()}{clock_time_conversion}% -\begin{itemdecl} -template - time_point - operator()(const time_point& t) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{t}. -\end{itemdescr} - -\begin{codeblock} -template<> -struct clock_time_conversion { - template - sys_time - operator()(const sys_time& t) const; -}; -\end{codeblock} - -\indexlibrarymember{operator()}{clock_time_conversion}% -\begin{itemdecl} -template - sys_time - operator()(const sys_time& t) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{t}. -\end{itemdescr} - -\begin{codeblock} -template<> -struct clock_time_conversion { - template - utc_time - operator()(const utc_time& t) const; -}; -\end{codeblock} - -\indexlibrarymember{operator()}{clock_time_conversion}% -\begin{itemdecl} -template - utc_time - operator()(const utc_time& t) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{t}. -\end{itemdescr} - -\rSec4[time.clock.cast.sys.utc]{Conversions between \tcode{system_clock} and \tcode{utc_clock}} - -\begin{codeblock} -template<> -struct clock_time_conversion { - template - utc_time> - operator()(const sys_time& t) const; -}; -\end{codeblock} - -\indexlibrarymember{operator()}{clock_time_conversion}% -\begin{itemdecl} -template - utc_time> - operator()(const sys_time& t) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{utc_clock::from_sys(t)}. -\end{itemdescr} - -\begin{codeblock} -template<> -struct clock_time_conversion { - template - sys_time> - operator()(const utc_time& t) const; -}; -\end{codeblock} - -\indexlibrarymember{operator()}{clock_time_conversion}% -\begin{itemdecl} -template - sys_time> - operator()(const utc_time& t) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{utc_clock::to_sys(t)}. -\end{itemdescr} - -\rSec4[time.clock.cast.sys]{Conversions between \tcode{system_clock} and other clocks} - -\begin{codeblock} -template -struct clock_time_conversion { - template - auto operator()(const time_point& t) const - -> decltype(SourceClock::to_sys(t)); -}; -\end{codeblock} - -\indexlibrarymember{operator()}{clock_time_conversion}% -\begin{itemdecl} -template - auto operator()(const time_point& t) const - -> decltype(SourceClock::to_sys(t)); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -This function does not participate in overload resolution unless -\tcode{SourceClock::to_sys(t)} is well-formed. -If \tcode{SourceClock::to_sys(t)} -does not return \tcode{sys_time}, -where \tcode{Duration} is a valid \tcode{chrono::duration} specialization, -the program is ill-formed. - -\pnum -\returns \tcode{SourceClock::to_sys(t)}. -\end{itemdescr} - -\begin{codeblock} -template -struct clock_time_conversion { - template - auto operator()(const sys_time& t) const - -> decltype(DestClock::from_sys(t)); -}; -\end{codeblock} - -\indexlibrarymember{operator()}{clock_time_conversion}% -\begin{itemdecl} -template - auto operator()(const sys_time& t) const - -> decltype(DestClock::from_sys(t)); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -This function does not participate in overload resolution unless -\tcode{DestClock::from_sys(t)} is well-formed. -If \tcode{DestClock::from_sys(t)} does not return -\tcode{time_point}, -where \tcode{Duration} is a valid \tcode{chrono::duration} specialization, -the program is ill-formed. - -\pnum -\returns \tcode{DestClock::from_sys(t)}. -\end{itemdescr} - -\rSec4[time.clock.cast.utc]{Conversions between \tcode{utc_clock} and other clocks} - -\begin{codeblock} -template -struct clock_time_conversion { - template - auto operator()(const time_point& t) const - -> decltype(SourceClock::to_utc(t)); -}; -\end{codeblock} - -\indexlibrarymember{operator()}{clock_time_conversion}% -\begin{itemdecl} -template - auto operator()(const time_point& t) const - -> decltype(SourceClock::to_utc(t)); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -This function does not participate in overload resolution unless -\tcode{SourceClock::to_utc(t)} is well-formed. -If \tcode{SourceClock::to_utc(t)} does not return -\tcode{utc_time}, -where \tcode{Duration} is a valid \tcode{chrono::duration} specialization, -the program is ill-formed. - -\pnum -\returns \tcode{SourceClock::to_utc(t)}. -\end{itemdescr} - -\begin{codeblock} -template -struct clock_time_conversion { - template - auto operator()(const utc_time& t) const - -> decltype(DestClock::from_utc(t)); -}; -\end{codeblock} - -\indexlibrarymember{operator()}{clock_time_conversion}% -\begin{itemdecl} -template - auto operator()(const utc_time& t) const - -> decltype(DestClock::from_utc(t)); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -This function does not participate in overload resolution unless -\tcode{DestClock::from_utc(t)} is well-formed. -If \tcode{DestClock::from_utc(t)} does not return -\tcode{time_point}, -where \tcode{Duration} is a valid \tcode{chrono::duration} specialization, -the program is ill-formed. - -\pnum -\returns \tcode{DestClock::from_utc(t)}. -\end{itemdescr} - -\rSec4[time.clock.cast.fn]{Function template \tcode{clock_cast}} - -\indexlibrary{\idxcode{clock_cast}}% -\begin{itemdecl} -template - auto clock_cast(const time_point& t); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -This function does not participate in overload resolution unless -at least one of the following clock time conversion expressions -is well-formed: - -\begin{itemize} -\item -\begin{codeblock} -clock_time_conversion{}(t) -\end{codeblock} - -\item -\begin{codeblock} -clock_time_conversion{}( - clock_time_conversion{}(t)) -\end{codeblock} - -\item -\begin{codeblock} -clock_time_conversion{}( - clock_time_conversion{}(t)) -\end{codeblock} - -\item -\begin{codeblock} -clock_time_conversion{}( - clock_time_conversion{}( - clock_time_conversion{}(t))) -\end{codeblock} - -\item -\begin{codeblock} -clock_time_conversion{}( - clock_time_conversion{}( - clock_time_conversion{}(t))) -\end{codeblock} -\end{itemize} - -A clock time conversion expression is considered better than -another clock time conversion expression if it involves fewer -\tcode{operator()} calls on \tcode{clock_time_conversion} -specializations. -If, among the well-formed clock time conversion expressions -from the above list, there is not a unique best expression, -the \tcode{clock_cast} is ambiguous and the program is ill-formed. - -\pnum -\returns -The best well-formed clock time conversion expression in the above list. -\end{itemdescr} - -\rSec2[time.cal]{The civil calendar} - -\rSec3[time.cal.general]{In general} - -\pnum -The types in \ref{time.cal} describe the civil (Gregorian) calendar -and its relationship to \tcode{sys_days} and \tcode{local_days}. - -\rSec3[time.cal.last]{Class \tcode{last_spec}} -\indexlibrary{\idxcode{last_spec}}% - -\begin{codeblock} -namespace std::chrono { - struct last_spec { - explicit last_spec() = default; - }; -} -\end{codeblock} - -\pnum -The type \tcode{last_spec} is used -in conjunction with other calendar types -to specify the last in a sequence. -For example, depending on context, -it can represent the last day of a month, -or the last day of the week of a month. - -\rSec3[time.cal.day]{Class \tcode{day}} - -\rSec4[time.cal.day.overview]{Overview} -\indexlibrary{\idxcode{day}} - -\begin{codeblock} -namespace std::chrono { - class day { - unsigned char d_; // \expos - public: - day() = default; - explicit constexpr day(unsigned d) noexcept; - - constexpr day& operator++() noexcept; - constexpr day operator++(int) noexcept; - constexpr day& operator--() noexcept; - constexpr day operator--(int) noexcept; - - constexpr day& operator+=(const days& d) noexcept; - constexpr day& operator-=(const days& d) noexcept; - - explicit constexpr operator unsigned() const noexcept; - constexpr bool ok() const noexcept; - }; -} -\end{codeblock} - -\pnum -\tcode{day} represents a day of a month. -It normally holds values in the range 1 to 31, -but may hold non-negative values outside this range. -It can be constructed with any \tcode{unsigned} value, -which will be subsequently truncated to fit into \tcode{day}'s unspecified internal storage. -\tcode{day} is \tcode{EqualityComparable} (Table~\ref{tab:equalitycomparable}) -and \tcode{LessThanComparable} (Table~\ref{tab:lessthancomparable}), -and participates in basic arithmetic with \tcode{days} objects, -which represent a difference between two \tcode{day} objects. - -\pnum -\tcode{day} is a trivially copyable and standard-layout class type. - -\rSec4[time.cal.day.members]{Member functions} - -\indexlibrary{\idxcode{day}!constructor}% -\begin{itemdecl} -explicit constexpr day(unsigned d) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{day} by -initializing \tcode{d_} with \tcode{d}. -The value held is unspecified if \tcode{d} is not in the range \crange{0}{255}. -\end{itemdescr} - -\indexlibrarymember{operator++}{day}% -\begin{itemdecl} -constexpr day& operator++() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{++d_}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator++}{day}% -\begin{itemdecl} -constexpr day operator++(int) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{++(*this)}. - -\pnum -\returns A copy of \tcode{*this} as it existed on entry to this member function. -\end{itemdescr} - -\indexlibrarymember{operator--}{day}% -\begin{itemdecl} -constexpr day& operator--() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{--d_}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator--}{day}% -\begin{itemdecl} -constexpr day operator--(int) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{--(*this)}. - -\pnum -\returns A copy of \tcode{*this} as it existed on entry to this member function. -\end{itemdescr} - -\indexlibrarymember{operator+=}{day}% -\begin{itemdecl} -constexpr day& operator+=(const days& d) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this + d}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator-=}{day}% -\begin{itemdecl} -constexpr day& operator-=(const days& d) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this - d}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator unsigned}{day}% -\begin{itemdecl} -explicit constexpr operator unsigned() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{d_}. -\end{itemdescr} - -\indexlibrarymember{ok}{day}% -\begin{itemdecl} -constexpr bool ok() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{1 <= d_ \&\& d_ <= 31}. -\end{itemdescr} - -\rSec4[time.cal.day.nonmembers]{Non-member functions} - -\indexlibrarymember{operator==}{day}% -\begin{itemdecl} -constexpr bool operator==(const day& x, const day& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{unsigned\{x\} == unsigned\{y\}}. -\end{itemdescr} - -\indexlibrarymember{operator<}{day}% -\begin{itemdecl} -constexpr bool operator<(const day& x, const day& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{unsigned\{x\} < unsigned\{y\}}. -\end{itemdescr} - -\indexlibrarymember{operator+}{day}% -\begin{itemdecl} -constexpr day operator+(const day& x, const days& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{day(unsigned\{x\} + y.count())}. -\end{itemdescr} - -\indexlibrarymember{operator+}{day}% -\begin{itemdecl} -constexpr day operator+(const days& x, const day& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y + x}. -\end{itemdescr} - -\indexlibrarymember{operator-}{day}% -\begin{itemdecl} -constexpr day operator-(const day& x, const days& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x + -y}. -\end{itemdescr} - -\indexlibrarymember{operator-}{day}% -\begin{itemdecl} -constexpr days operator-(const day& x, const day& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{days\{int(unsigned\{x\}) - int(unsigned\{y\})}. -\end{itemdescr} - -\indexlibrarymember{operator<<}{day}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const day& d); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Inserts \tcode{format(fmt, d)} -where \tcode{fmt} is \tcode{"\%d"} widened to \tcode{charT}. -If \tcode{!d.ok()}, appends with \tcode{" is not a valid day"}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{to_stream}{day}% -\begin{itemdecl} -template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, const day& d); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Streams \tcode{d} into \tcode{os} using -the format specified by the NTCTS \tcode{fmt}. -\tcode{fmt} encoding follows the rules specified in \ref{time.format}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{from_stream}{day}% -\begin{itemdecl} -template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - day& d, basic_string* abbrev = nullptr, - minutes* offset = nullptr); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Attempts to parse the input stream \tcode{is} -into the \tcode{day} \tcode{d} using -the format flags given in the NTCTS \tcode{fmt} -as specified in \ref{time.parse}. -If the parse fails to decode a valid day, -\tcode{is.setstate(ios_base::failbit)} shall be called -and \tcode{d} shall not be modified. -If \tcode{\%Z} is used and successfully parsed, -that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. -If \tcode{\%z} (or a modified variant) is used and successfully parsed, -that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. - -\pnum -\returns \tcode{is}. -\end{itemdescr} - -\indexlibrarymember{operator""""d}{day}% -\begin{itemdecl} -constexpr day operator""d(unsigned long long d) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{day\{static_cast(d)\}}. -\end{itemdescr} - -\rSec3[time.cal.month]{Class \tcode{month}} - -\rSec4[time.cal.month.overview]{Overview} -\indexlibrary{\idxcode{month}} - -\begin{codeblock} -namespace std::chrono { - class month { - unsigned char m_; // \expos - public: - month() = default; - explicit constexpr month(unsigned m) noexcept; - - constexpr month& operator++() noexcept; - constexpr month operator++(int) noexcept; - constexpr month& operator--() noexcept; - constexpr month operator--(int) noexcept; - - constexpr month& operator+=(const months& m) noexcept; - constexpr month& operator-=(const months& m) noexcept; - - explicit constexpr operator unsigned() const noexcept; - constexpr bool ok() const noexcept; - }; -} -\end{codeblock} - -\pnum -\tcode{month} represents a month of a year. -It normally holds values in the range 1 to 12, -but may hold non-negative values outside this range. -It can be constructed with any \tcode{unsigned} value, -which will be subsequently truncated to fit into \tcode{month}'s unspecified internal storage. -\tcode{month} is \tcode{EqualityComparable} (Table~\ref{tab:equalitycomparable}) -and \tcode{LessThanComparable} (Table~\ref{tab:lessthancomparable}), -and participates in basic arithmetic with \tcode{months} objects, -which represent a difference between two \tcode{month} objects. - -\pnum -\tcode{month} is a trivially copyable and standard-layout class type. - -\rSec4[time.cal.month.members]{Member functions} - -\indexlibrary{\idxcode{month}!constructor}% -\begin{itemdecl} -explicit constexpr month(unsigned m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{month} by -initializing \tcode{m_} with \tcode{m}. -The value held is unspecified if \tcode{m} is not in the range \crange{0}{255}. -\end{itemdescr} - -\indexlibrarymember{operator++}{month}% -\begin{itemdecl} -constexpr month& month::operator++() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this += months\{1\}}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator++}{month}% -\begin{itemdecl} -constexpr month operator++(int) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{++(*this)}. - -\pnum -\returns A copy of \tcode{*this} as it existed on entry to this member function. -\end{itemdescr} - -\indexlibrarymember{operator--}{month}% -\begin{itemdecl} -constexpr month& operator--() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this -= months\{1\}}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator--}{month}% -\begin{itemdecl} -constexpr month operator--(int) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{--(*this)}. - -\pnum -\returns A copy of \tcode{*this} as it existed on entry to this member function. -\end{itemdescr} - -\indexlibrarymember{operator+=}{month}% -\begin{itemdecl} -constexpr month& operator+=(const months& m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this + m}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator-=}{month}% -\begin{itemdecl} -constexpr month& operator-=(const months& m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this - m}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator unsigned}{month}% -\begin{itemdecl} -explicit constexpr month::operator unsigned() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{m_}. -\end{itemdescr} - -\indexlibrarymember{ok}{month}% -\begin{itemdecl} -constexpr bool month::ok() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{1 <= m_ \&\& m_ <= 12}. -\end{itemdescr} - -\rSec4[time.cal.month.nonmembers]{Non-member functions} - -\indexlibrarymember{operator==}{month}% -\begin{itemdecl} -constexpr bool operator==(const month& x, const month& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{unsigned\{x\} == unsigned\{y\}}. -\end{itemdescr} - -\indexlibrarymember{operator<}{month}% -\begin{itemdecl} -constexpr bool operator<(const month& x, const month& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{unsigned\{x\} < unsigned\{y\}}. -\end{itemdescr} - -\indexlibrarymember{operator+}{month}% -\begin{itemdecl} -constexpr month operator+(const month& x, const months& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\begin{codeblock} -month{modulo(static_cast(unsigned{x}) + (y.count() - 1), 12) + 1} -\end{codeblock} -where \tcode{modulo(n, 12)} computes the remainder of \tcode{n} divided by 12 using Euclidean division. -\begin{note} -Given a divisor of 12, Euclidean division truncates towards negative infinity and -always produces a remainder in the range of \crange{0}{11}. -Assuming no overflow in the signed summation, -this operation results in a \tcode{month} holding a value in the range \crange{1}{12} even if \tcode{!x.ok()}. -\end{note} -\begin{example} -\tcode{February + months\{11\} == January}. -\end{example} -\end{itemdescr} - -\indexlibrarymember{operator+}{month}% -\begin{itemdecl} -constexpr month operator+(const months& x, const month& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y + x}. -\end{itemdescr} - -\indexlibrarymember{operator-}{month}% -\begin{itemdecl} -constexpr month operator-(const month& x, const months& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x + -y}. -\end{itemdescr} - -\indexlibrarymember{operator-}{month}% -\begin{itemdecl} -constexpr months operator-(const month& x, const month& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -If \tcode{x.ok() == true} -and \tcode{y.ok() == true}, -returns a value \tcode{m} -in the range \crange{months\{0\}}{months\{11\}} -satisfying \tcode{y + m == x}. -Otherwise the value returned is unspecified. -\begin{example} -\tcode{January - February == months\{11\}}. -\end{example} -\end{itemdescr} - -\indexlibrarymember{operator<<}{month}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const month& m); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -If \tcode{m.ok() == true} -inserts \tcode{format(os.getloc(), fmt, m)} -where fmt is \tcode{"\%b"} widened to \tcode{charT}. -Otherwise inserts \tcode{unsigned\{m\} << " is not a valid month"}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{to_stream}{month}% -\begin{itemdecl} -template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, const month& m); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Streams \tcode{m} into \tcode{os} using -the format specified by the NTCTS \tcode{fmt}. -\tcode{fmt} encoding follows the rules specified in \ref{time.format}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{from_stream}{month}% -\begin{itemdecl} -template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - month& m, basic_string* abbrev = nullptr, - minutes* offset = nullptr); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Attempts to parse the input stream \tcode{is} -into the \tcode{month} \tcode{m} using -the format flags given in the NTCTS \tcode{fmt} -as specified in \ref{time.parse}. -If the parse fails to decode a valid month, -\tcode{is.setstate(ios_base::failbit)} shall be called -and \tcode{m} shall not be modified. -If \tcode{\%Z} is used and successfully parsed, -that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. -If \tcode{\%z} (or a modified variant) is used and successfully parsed, -that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. - -\pnum -\returns \tcode{is}. -\end{itemdescr} - -\rSec3[time.cal.year]{Class \tcode{year}} - -\rSec4[time.cal.year.overview]{Overview} -\indexlibrary{\idxcode{year}} - -\begin{codeblock} -namespace std::chrono { - class year { - short y_; // \expos - public: - year() = default; - explicit constexpr year(int y) noexcept; - - constexpr year& operator++() noexcept; - constexpr year operator++(int) noexcept; - constexpr year& operator--() noexcept; - constexpr year operator--(int) noexcept; - - constexpr year& operator+=(const years& y) noexcept; - constexpr year& operator-=(const years& y) noexcept; - - constexpr year operator+() const noexcept; - constexpr year operator-() const noexcept; - - constexpr bool is_leap() const noexcept; - - explicit constexpr operator int() const noexcept; - constexpr bool ok() const noexcept; - - static constexpr year min() noexcept; - static constexpr year max() noexcept; - }; -} -\end{codeblock} - -\pnum -\tcode{year} represents a year in the civil calendar. -It can represent values in the range \crange{min()}{max()}. -It can be constructed with any \tcode{int} value, -which will be subsequently truncated to fit into \tcode{year}'s unspecified internal storage. -\tcode{year} is \tcode{EqualityComparable} (Table~\ref{tab:equalitycomparable}) -and \tcode{LessThanComparable} (Table~\ref{tab:lessthancomparable}), -and participates in basic arithmetic with \tcode{years} objects, -which represent a difference between two \tcode{year} objects. - -\pnum -\tcode{year} is a trivially copyable and standard-layout class type. - -\rSec4[time.cal.year.members]{Member functions} - -\indexlibrary{\idxcode{year}!constructor}% -\begin{itemdecl} -explicit constexpr year(int y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{year} by -initializing \tcode{y_} with \tcode{y}. -The value held is unspecified if \tcode{y} is not in the range \crange{-32767}{32767}. -\end{itemdescr} - -\indexlibrarymember{operator++}{year}% -\begin{itemdecl} -constexpr year& operator++() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{++y_}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator++}{year}% -\begin{itemdecl} -constexpr year operator++(int) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{++(*this)}. - -\pnum -\returns A copy of \tcode{*this} as it existed on entry to this member function. -\end{itemdescr} - -\indexlibrarymember{operator--}{year}% -\begin{itemdecl} -constexpr year& operator--() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{--y_}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator--}{year}% -\begin{itemdecl} -constexpr year operator--(int) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{--(*this)}. - -\pnum -\returns A copy of \tcode{*this} as it existed on entry to this member function. -\end{itemdescr} - -\indexlibrarymember{operator+=}{year}% -\begin{itemdecl} -constexpr year& operator+=(const years& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this + y}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator-=}{year}% -\begin{itemdecl} -constexpr year& operator-=(const years& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this - y}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator+}{year}% -\begin{itemdecl} -constexpr year operator+() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator-}{year}% -\begin{itemdecl} -constexpr year year::operator-() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{year\{-y_\}}. -\end{itemdescr} - -\indexlibrarymember{is_leap}{year}% -\begin{itemdecl} -constexpr bool is_leap() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y_ \% 4 == 0 \&\& (y_ \% 100 != 0 || y_ \% 400 == 0)}. -\end{itemdescr} - -\indexlibrarymember{operator int}{year}% -\begin{itemdecl} -explicit constexpr operator int() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y_}. -\end{itemdescr} - -\indexlibrarymember{ok}{year}% -\begin{itemdecl} -constexpr bool ok() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{min() <= y_ \&\& y_ <= max()}. -\end{itemdescr} - -\indexlibrarymember{min}{year}% -\begin{itemdecl} -static constexpr year min() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{year\{-32767\}}. -\end{itemdescr} - -\indexlibrarymember{max}{year}% -\begin{itemdecl} -static constexpr year max() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{year\{32767\}}. -\end{itemdescr} - -\rSec4[time.cal.year.nonmembers]{Non-member functions} - -\indexlibrarymember{operator==}{year}% -\begin{itemdecl} -constexpr bool operator==(const year& x, const year& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{int\{x\} == int\{y\}}. -\end{itemdescr} - -\indexlibrarymember{operator<}{year}% -\begin{itemdecl} -constexpr bool operator<(const year& x, const year& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{int\{x\} < int\{y\}}. -\end{itemdescr} - -\indexlibrarymember{operator+}{year}% -\begin{itemdecl} -constexpr year operator+(const year& x, const years& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{year\{int\{x\} + y.count()\}}. -\end{itemdescr} - -\indexlibrarymember{operator+}{year}% -\begin{itemdecl} -constexpr year operator+(const years& x, const year& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y + x}. -\end{itemdescr} - -\indexlibrarymember{operator-}{year}% -\begin{itemdecl} -constexpr year operator-(const year& x, const years& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x + -y}. -\end{itemdescr} - -\indexlibrarymember{operator-}{year}% -\begin{itemdecl} -constexpr years operator-(const year& x, const year& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{years\{int\{x\} - int\{y\}\}}. -\end{itemdescr} - -\indexlibrarymember{operator<<}{year}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const year& y); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Inserts \tcode{format(fmt, y)} where \tcode{fmt} is -\tcode{"\%Y"} widened to \tcode{charT}. -If \tcode{!y.ok()}, appends with \tcode{" is not a valid year"}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{to_stream}{year}% -\begin{itemdecl} -template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, const year& y); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Streams \tcode{y} into \tcode{os} using -the format specified by the NTCTS \tcode{fmt}. -\tcode{fmt} encoding follows the rules specified in \ref{time.format}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{from_stream}{year}% -\begin{itemdecl} -template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - year& y, basic_string* abbrev = nullptr, - minutes* offset = nullptr); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Attempts to parse the input stream \tcode{is} -into the \tcode{year} \tcode{y} using -the format flags given in the NTCTS \tcode{fmt} -as specified in \ref{time.parse}. -If the parse fails to decode a valid year, -\tcode{is.setstate(ios_base::failbit)} shall be called -and \tcode{y} shall not be modified. -If \tcode{\%Z} is used and successfully parsed, -that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. -If \tcode{\%z} (or a modified variant) is used and successfully parsed, -that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. - -\pnum -\returns \tcode{is}. -\end{itemdescr} - -\indexlibrarymember{operator""""y}{year}% -\begin{itemdecl} -constexpr year operator""y(unsigned long long y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{year\{static_cast(y)\}}. -\end{itemdescr} - -\rSec3[time.cal.wd]{Class \tcode{weekday}} - -\rSec4[time.cal.wd.overview]{Overview} -\indexlibrary{\idxcode{weekday}} - -\begin{codeblock} -namespace std::chrono { - class weekday { - unsigned char wd_; // \expos - public: - weekday() = default; - explicit constexpr weekday(unsigned wd) noexcept; - constexpr weekday(const sys_days& dp) noexcept; - explicit constexpr weekday(const local_days& dp) noexcept; - - constexpr weekday& operator++() noexcept; - constexpr weekday operator++(int) noexcept; - constexpr weekday& operator--() noexcept; - constexpr weekday operator--(int) noexcept; - - constexpr weekday& operator+=(const days& d) noexcept; - constexpr weekday& operator-=(const days& d) noexcept; - - explicit constexpr operator unsigned() const noexcept; - constexpr bool ok() const noexcept; - - constexpr weekday_indexed operator[](unsigned index) const noexcept; - constexpr weekday_last operator[](last_spec) const noexcept; - }; -} -\end{codeblock} - -\pnum -\tcode{weekday} represents a day of the week in the civil calendar. -It normally holds values in the range \tcode{0} to \tcode{6}, -corresponding to Sunday through Saturday, but -it may hold non-negative values outside this range. -It can be constructed with any \tcode{unsigned} value, -which will be subsequently truncated to fit into \tcode{weekday}'s unspecified internal storage. -\tcode{weekday} is \tcode{EqualityComparable} (Table~\ref{tab:equalitycomparable}). -\begin{note} -\tcode{weekday} is not -\tcode{LessThanComparable} -because there is no universal consensus on which day is the first day of the week. -\tcode{weekday}'s arithmetic operations treat the days of the week as a circular range, -with no beginning and no end. -\end{note} - -\pnum -\tcode{weekday} is a trivially copyable and standard-layout class type. - -\rSec4[time.cal.wd.members]{Member functions} - -\indexlibrary{\idxcode{weekday}!constructor}% -\begin{itemdecl} -explicit constexpr weekday(unsigned wd) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{weekday} by -initializing \tcode{wd_} with \tcode{wd}. -The value held is unspecified if \tcode{wd} is not in the range \crange{0}{255}. -\end{itemdescr} - -\indexlibrary{\idxcode{weekday}!constructor}% -\begin{itemdecl} -constexpr weekday(const sys_days& dp) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{weekday} by -computing what day of the week corresponds to the \tcode{sys_days} \tcode{dp}, -and representing that day of the week in \tcode{wd_}. - -\pnum -\begin{example} -If \tcode{dp} represents 1970-01-01, -the constructed \tcode{weekday} represents Thursday -by storing \tcode{4} in \tcode{wd_}. -\end{example} -\end{itemdescr} - -\indexlibrary{\idxcode{weekday}!constructor}% -\begin{itemdecl} -explicit constexpr weekday(const local_days& dp) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{weekday} by -computing what day of the week corresponds to the \tcode{local_days} \tcode{dp}, -and representing that day of the week in \tcode{wd_}. - -\pnum -\remarks -The value after construction is identical to that constructed from -\tcode{sys_days\{dp.time_since_epoch()\}}. -\end{itemdescr} - -\indexlibrarymember{operator++}{weekday}% -\begin{itemdecl} -constexpr weekday& operator++() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this += days\{1\}}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator++}{weekday}% -\begin{itemdecl} -constexpr weekday operator++(int) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{++(*this)}. - -\pnum -\returns A copy of \tcode{*this} as it existed on entry to this member function. -\end{itemdescr} - -\indexlibrarymember{operator--}{weekday}% -\begin{itemdecl} -constexpr weekday& operator--() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this -= days\{1\}}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator--}{weekday}% -\begin{itemdecl} -constexpr weekday operator--(int) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{--(*this)}. - -\pnum -\returns A copy of \tcode{*this} as it existed on entry to this member function. -\end{itemdescr} - -\indexlibrarymember{operator+=}{weekday}% -\begin{itemdecl} -constexpr weekday& operator+=(const days& d) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this + d}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator-=}{weekday}% -\begin{itemdecl} -constexpr weekday& operator-=(const days& d) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this - d}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator unsigned}{weekday}% -\begin{itemdecl} -explicit constexpr operator unsigned() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{wd_}. -\end{itemdescr} - -\indexlibrarymember{ok}{weekday}% -\begin{itemdecl} -constexpr bool ok() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{wd_ <= 6}. -\end{itemdescr} - -\indexlibrarymember{operator[]}{weekday}% -\begin{itemdecl} -constexpr weekday_indexed operator[](unsigned index) const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{\{*this, index\}}. -\end{itemdescr} - -\indexlibrarymember{operator[]}{weekday}% -\begin{itemdecl} -constexpr weekday_last operator[](last_spec) const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{weekday_last\{*this\}}. -\end{itemdescr} - -\rSec4[time.cal.wd.nonmembers]{Non-member functions} - -\indexlibrarymember{operator==}{weekday}% -\begin{itemdecl} -constexpr bool operator==(const weekday& x, const weekday& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{unsigned\{x\} == unsigned\{y\}}. -\end{itemdescr} - -\indexlibrarymember{operator+}{weekday}% -\begin{itemdecl} -constexpr weekday operator+(const weekday& x, const days& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\begin{codeblock} -weekday{modulo(static_cast(unsigned{x}) + y.count(), 7)} -\end{codeblock} -where \tcode{modulo(n, 7)} computes the remainder of \tcode{n} divided by 7 using Euclidean division. -\begin{note} -Given a divisor of 7, Euclidean division truncates towards negative infinity and -always produces a remainder in the range of \crange{0}{6}. -Assuming no overflow in the signed summation, -this operation results in a \tcode{weekday} holding a value in the range \crange{0}{6} even if \tcode{!x.ok()}. -\end{note} -\begin{example} -\tcode{Monday + days\{6\} == Sunday}. -\end{example} -\end{itemdescr} - -\indexlibrarymember{operator+}{weekday}% -\begin{itemdecl} -constexpr weekday operator+(const days& x, const weekday& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y + x}. -\end{itemdescr} - -\indexlibrarymember{operator-}{weekday}% -\begin{itemdecl} -constexpr weekday operator-(const weekday& x, const days& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x + -y}. -\end{itemdescr} - -\indexlibrarymember{operator-}{weekday}% -\begin{itemdecl} -constexpr days operator-(const weekday& x, const weekday& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -If \tcode{x.ok() == true} -and \tcode{y.ok() == true}, -returns a value \tcode{d} -in the range \crange{days\{0\}}{days\{6\}} -satisfying \tcode{y + d == x}. -Otherwise the value returned is unspecified. -\begin{example} -\tcode{Sunday - Monday == days\{6\}}. -\end{example} -\end{itemdescr} - -\indexlibrarymember{operator<<}{weekday}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const weekday& wd); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -If \tcode{wd.ok() == true} -inserts \tcode{format(os.getloc(), fmt, wd)} -where \tcode{fmt} is \tcode{"\%a"} widened to \tcode{charT}. -Otherwise inserts \tcode{unsigned\{wd\} << " is not a valid weekday"}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{to_stream}{weekday}% -\begin{itemdecl} -template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, const weekday& wd); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Streams \tcode{wd} into \tcode{os} using -the format specified by the NTCTS \tcode{fmt}. -\tcode{fmt} encoding follows the rules specified in \ref{time.format}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{from_stream}{weekday}% -\begin{itemdecl} -template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - weekday& wd, basic_string* abbrev = nullptr, - minutes* offset = nullptr); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Attempts to parse the input stream \tcode{is} -into the \tcode{weekday} \tcode{wd} using -the format flags given in the NTCTS \tcode{fmt} -as specified in \ref{time.parse}. -If the parse fails to decode a valid weekday, -\tcode{is.setstate(ios_base::failbit)} shall be called -and \tcode{wd} shall not be modified. -If \tcode{\%Z} is used and successfully parsed, -that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. -If \tcode{\%z} (or a modified variant) is used and successfully parsed, -that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. - -\pnum -\returns \tcode{is}. -\end{itemdescr} - -\rSec3[time.cal.wdidx]{Class \tcode{weekday_indexed}} - -\rSec4[time.cal.wdidx.overview]{Overview} -\indexlibrary{\idxcode{weekday_indexed}} - -\begin{codeblock} -namespace std::chrono { - class weekday_indexed { - chrono::weekday wd_; // \expos - unsigned char index_; // \expos - - public: - weekday_indexed() = default; - constexpr weekday_indexed(const chrono::weekday& wd, unsigned index) noexcept; - - constexpr chrono::weekday weekday() const noexcept; - constexpr unsigned index() const noexcept; - constexpr bool ok() const noexcept; - }; -} -\end{codeblock} - -\pnum -\tcode{weekday_indexed} represents a \tcode{weekday} -and a small index in the range 1 to 5. -This class is used to represent the -first, second, third, fourth, or fifth weekday of a month. - -\pnum -\begin{note} -A \tcode{weekday_indexed} object -can be constructed by indexing a \tcode{weekday} -with an \tcode{unsigned}. -\end{note} -\begin{example} -\begin{codeblock} -constexpr auto wdi = Sunday[2]; // \tcode{wdi} is the second Sunday of an as yet unspecified month -static_assert(wdi.weekday() == Sunday); -static_assert(wdi.index() == 2); -\end{codeblock} -\end{example} - -\pnum -\tcode{weekday_indexed} is a trivially copyable and standard-layout class type. - -\rSec4[time.cal.wdidx.members]{Member functions} - -\indexlibrary{\idxcode{weekday_indexed}!constructor}% -\begin{itemdecl} -constexpr weekday_indexed(const chrono::weekday& wd, unsigned index) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{weekday_indexed} by -initializing \tcode{wd_} with \tcode{wd} and \tcode{index_} with \tcode{index}. -The values held are unspecified if \tcode{!wd.ok()} or \tcode{index} is not in the range \crange{1}{5}. -\end{itemdescr} - -\indexlibrarymember{weekday}{weekday_indexed}% -\begin{itemdecl} -constexpr chrono::weekday weekday() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{wd_}. -\end{itemdescr} - -\indexlibrarymember{index}{weekday_indexed}% -\begin{itemdecl} -constexpr unsigned index() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{index_}. -\end{itemdescr} - -\indexlibrarymember{ok}{weekday_indexed}% -\begin{itemdecl} -constexpr bool ok() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{wd_.ok() \&\& 1 <= index_ \&\& index_ <= 5}. -\end{itemdescr} - -\rSec4[time.cal.wdidx.nonmembers]{Non-member functions} - -\indexlibrarymember{operator==}{weekday_indexed}% -\begin{itemdecl} -constexpr bool operator==(const weekday_indexed& x, const weekday_indexed& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x.weekday() == y.weekday() \&\& x.index() == y.index()}. -\end{itemdescr} - -\indexlibrarymember{operator<<}{weekday_indexed}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const weekday_indexed& wdi); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -\tcode{os << wdi.weekday() << '[' << wdi.index()}. -If \tcode{wdi.index()} is in the range \crange{1}{5}, -appends with \tcode{']'}, -otherwise -appends with \tcode{" is not a valid index]"}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\rSec3[time.cal.wdlast]{Class \tcode{weekday_last}} - -\rSec4[time.cal.wdlast.overview]{Overview} -\indexlibrary{\idxcode{weekday_last}} - -\begin{codeblock} -namespace std::chrono { - class weekday_last { - chrono::weekday wd_; // \expos - - public: - explicit constexpr weekday_last(const chrono::weekday& wd) noexcept; - - constexpr chrono::weekday weekday() const noexcept; - constexpr bool ok() const noexcept; - }; -} -\end{codeblock} - -\pnum -\tcode{weekday_last} represents the last weekday of a month. - -\pnum -\begin{note} -A \tcode{weekday_last} object -can be constructed by indexing a \tcode{weekday} with \tcode{last}. -\end{note} -\begin{example} -\begin{codeblock} -constexpr auto wdl = Sunday[last]; // \tcode{wdl} is the last Sunday of an as yet unspecified month -static_assert(wdl.weekday() == Sunday); -\end{codeblock} -\end{example} - -\pnum -\tcode{weekday_last} is a trivially copyable and standard-layout class type. - -\rSec4[time.cal.wdlast.members]{Member functions} - -\indexlibrary{\idxcode{weekday_last}!constructor}% -\begin{itemdecl} -explicit constexpr weekday_last(const chrono::weekday& wd) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{weekday_last} by -initializing \tcode{wd_} with \tcode{wd}. -\end{itemdescr} - -\indexlibrarymember{weekday_last}{weekday}% -\begin{itemdecl} -constexpr chrono::weekday weekday() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{wd_}. -\end{itemdescr} - -\indexlibrarymember{ok}{weekday_last}% -\begin{itemdecl} -constexpr bool ok() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{wd_.ok()}. -\end{itemdescr} - -\rSec4[time.cal.wdlast.nonmembers]{Non-member functions} - -\indexlibrarymember{operator==}{weekday_last}% -\begin{itemdecl} -constexpr bool operator==(const weekday_last& x, const weekday_last& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x.weekday() == y.weekday()}. -\end{itemdescr} - -\indexlibrarymember{operator<<}{weekday_last}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const weekday_last& wdl); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{os << wdl.weekday() << "[last]"}. -\end{itemdescr} - -\rSec3[time.cal.md]{Class \tcode{month_day}} - -\rSec4[time.cal.md.overview]{Overview} -\indexlibrary{\idxcode{month_day}} - -\begin{codeblock} -namespace std::chrono { - class month_day { - chrono::month m_; // \expos - chrono::day d_; // \expos - - public: - month_day() = default; - constexpr month_day(const chrono::month& m, const chrono::day& d) noexcept; - - constexpr chrono::month month() const noexcept; - constexpr chrono::day day() const noexcept; - constexpr bool ok() const noexcept; - }; -} -\end{codeblock} - -\pnum -\tcode{month_day} represents a specific day of a specific month, -but with an unspecified year. -\tcode{month_day} is \tcode{EqualityComparable} (Table~\ref{tab:equalitycomparable}) -and \tcode{LessThanComparable} (Table~\ref{tab:lessthancomparable}). - -\pnum -\tcode{month_day} is a trivially copyable and standard-layout class type. - -\rSec4[time.cal.md.members]{Member functions} - -\indexlibrary{\idxcode{month_day}!constructor}% -\begin{itemdecl} -constexpr month_day(const chrono::month& m, const chrono::day& d) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{month_day} by -initializing \tcode{m_} with \tcode{m}, and \tcode{d_} with \tcode{d}. -\end{itemdescr} - -\indexlibrarymember{month}{month_day}% -\begin{itemdecl} -constexpr chrono::month month() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{m_}. -\end{itemdescr} - -\indexlibrarymember{day}{month_day}% -\begin{itemdecl} -constexpr chrono::day day() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{d_}. -\end{itemdescr} - -\indexlibrarymember{ok}{month_day}% -\begin{itemdecl} -constexpr bool ok() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{true} if -\tcode{m_.ok()} is \tcode{true}, -\tcode{1d <= d_}, and -\tcode{d_} is less than or equal to the number of days in month \tcode{m_}; -otherwise returns \tcode{false}. -When \tcode{m_ == February}, -the number of days is considered to be 29. -\end{itemdescr} - -\rSec4[time.cal.md.nonmembers]{Non-member functions} - -\indexlibrarymember{operator==}{month_day}% -\begin{itemdecl} -constexpr bool operator==(const month_day& x, const month_day& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x.month() == y.month() \&\& x.day() == y.day()}. -\end{itemdescr} - -\indexlibrarymember{operator<}{month_day}% -\begin{itemdecl} -constexpr bool operator<(const month_day& x, const month_day& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -If \tcode{x.month() < y.month()} returns \tcode{true}. -Otherwise, if \tcode{x.month() > y.month()} returns \tcode{false}. -Otherwise, returns \tcode{x.day() < y.day()}. -\end{itemdescr} - -\indexlibrarymember{operator<<}{month_day}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const month_day& md); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{os << md.month() << '/' << md.day()}. -\end{itemdescr} - -\indexlibrarymember{to_stream}{month_day}% -\begin{itemdecl} -template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, const month_day& md); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Streams \tcode{md} into \tcode{os} using -the format specified by the NTCTS \tcode{fmt}. -\tcode{fmt} encoding follows the rules specified in \ref{time.format}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{from_stream}{month_day}% -\begin{itemdecl} -template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - month_day& md, basic_string* abbrev = nullptr, - minutes* offset = nullptr); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Attempts to parse the input stream \tcode{is} -into the \tcode{month_day} \tcode{md} using -the format flags given in the NTCTS \tcode{fmt} -as specified in \ref{time.parse}. -If the parse fails to decode a valid \tcode{month_day}, -\tcode{is.setstate(ios_base::failbit)} shall be called -and \tcode{md} shall not be modified. -If \tcode{\%Z} is used and successfully parsed, -that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. -If \tcode{\%z} (or a modified variant) is used and successfully parsed, -that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. - -\pnum -\returns \tcode{is}. -\end{itemdescr} - -\rSec3[time.cal.mdlast]{Class \tcode{month_day_last}} -\indexlibrary{\idxcode{month_day_last}} - -\begin{codeblock} -namespace std::chrono { - class month_day_last { - chrono::month m_; // \expos - - public: - explicit constexpr month_day_last(const chrono::month& m) noexcept; - - constexpr chrono::month month() const noexcept; - constexpr bool ok() const noexcept; - }; -} -\end{codeblock} - -\pnum -\tcode{month_day_last} represents the last day of a month. - -\pnum -\begin{note} -A \tcode{month_day_last} object -can be constructed using the expression \tcode{m/last} or \tcode{last/m}, -where \tcode{m} is an expression of type \tcode{month}. -\end{note} -\begin{example} -\begin{codeblock} -constexpr auto mdl = February/last; // \tcode{mdl} is the last day of February of an as yet unspecified year -static_assert(mdl.month() == February); -\end{codeblock} -\end{example} - -\pnum -\tcode{month_day_last} is a trivially copyable and standard-layout class type. - -\indexlibrary{\idxcode{month_day_last}!constructor}% -\begin{itemdecl} -explicit constexpr month_day_last(const chrono::month& m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{month_day_last} by -initializing \tcode{m_} with \tcode{m}. -\end{itemdescr} - -\indexlibrarymember{month}{month_day_last}% -\begin{itemdecl} -constexpr month month() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{m_}. -\end{itemdescr} - -\indexlibrarymember{ok}{month_day_last}% -\begin{itemdecl} -constexpr bool ok() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{m_.ok()}. -\end{itemdescr} - -\indexlibrarymember{operator==}{month_day_last}% -\begin{itemdecl} -constexpr bool operator==(const month_day_last& x, const month_day_last& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x.month() == y.month()}. -\end{itemdescr} - -\indexlibrarymember{operator<}{month_day_last}% -\begin{itemdecl} -constexpr bool operator<(const month_day_last& x, const month_day_last& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x.month() < y.month()}. -\end{itemdescr} - -\indexlibrarymember{operator<<}{month_day_last}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const month_day_last& mdl); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{os << mdl.month() << "/last"}. -\end{itemdescr} - -\rSec3[time.cal.mwd]{Class \tcode{month_weekday}} - -\rSec4[time.cal.mwd.overview]{Overview} -\indexlibrary{\idxcode{month_weekday}} - -\begin{codeblock} -namespace std::chrono { - class month_weekday { - chrono::month m_; // \expos - chrono::weekday_indexed wdi_; // \expos - public: - constexpr month_weekday(const chrono::month& m, const chrono::weekday_indexed& wdi) noexcept; - - constexpr chrono::month month() const noexcept; - constexpr chrono::weekday_indexed weekday_indexed() const noexcept; - constexpr bool ok() const noexcept; - }; -} -\end{codeblock} - -\pnum -\tcode{month_weekday} represents the n$^\textrm{th}$ weekday of a month, -of an as yet unspecified year. -To do this the \tcode{month_weekday} stores a \tcode{month} and a \tcode{weekday_indexed}. - -\pnum -\begin{example} -\begin{codeblock} -constexpr auto mwd - = February/Tueday[3]; // \tcode{mwd} is the third Tuesday of February of an as yet unspecified year -static_assert(mwd.month() == February); -static_assert(mwd.weekday_indexed() == Tueday[3]); -\end{codeblock} -\end{example} - -\pnum -\tcode{month_weekday} is a trivially copyable and standard-layout class type. - -\rSec4[time.cal.mwd.members]{Member functions} - -\indexlibrary{\idxcode{month_weekday}!constructor}% -\begin{itemdecl} -constexpr month_weekday(const chrono::month& m, const chrono::weekday_indexed& wdi) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{month_weekday} by -initializing \tcode{m_} with \tcode{m}, and \tcode{wdi_} with \tcode{wdi}. -\end{itemdescr} - -\indexlibrarymember{month}{month_weekday}% -\begin{itemdecl} -constexpr chrono::month month() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{m_}. -\end{itemdescr} - -\indexlibrarymember{weekday_indexed}{month_weekday}% -\begin{itemdecl} -constexpr chrono::weekday_indexed weekday_indexed() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{wdi_}. -\end{itemdescr} - -\indexlibrarymember{ok}{month_weekday}% -\begin{itemdecl} -constexpr bool ok() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{m_.ok() \&\& wdi_.ok()}. -\end{itemdescr} - -\rSec4[time.cal.mwd.nonmembers]{Non-member functions} - -\indexlibrarymember{operator==}{month_weekday}% -\begin{itemdecl} -constexpr bool operator==(const month_weekday& x, const month_weekday& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x.month() == y.month() \&\& x.weekday_indexed() == y.weekday_indexed()}. -\end{itemdescr} - -\indexlibrarymember{operator<<}{month_weekday}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const month_weekday& mwd); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{os << mwd.month() << '/' << mwd.weekday_indexed()}. -\end{itemdescr} - -\rSec3[time.cal.mwdlast]{Class \tcode{month_weekday_last}} - -\rSec4[time.cal.mwdlast.overview]{Overview} -\indexlibrary{\idxcode{month_weekday_last}} - -\begin{codeblock} -namespace std::chrono { - class month_weekday_last { - chrono::month m_; // \expos - chrono::weekday_last wdl_; // \expos - public: - constexpr month_weekday_last(const chrono::month& m, - const chrono::weekday_last& wdl) noexcept; - - constexpr chrono::month month() const noexcept; - constexpr chrono::weekday_last weekday_last() const noexcept; - constexpr bool ok() const noexcept; - }; -} -\end{codeblock} - -\pnum -\tcode{month_weekday_last} represents the last weekday of a month, -of an as yet unspecified year. -To do this the \tcode{month_weekday_last} stores a \tcode{month} and a \tcode{weekday_last}. - -\pnum -\begin{example} -\begin{codeblock} -constexpr auto mwd - = February/Tueday[last]; // \tcode{mwd} is the last Tuesday of February of an as yet unspecified year -static_assert(mwd.month() == February); -static_assert(mwd.weekday_last() == Tueday[last]); -\end{codeblock} -\end{example} - -\pnum -\tcode{month_weekday_last} is a trivially copyable and standard-layout class type. - -\rSec4[time.cal.mwdlast.members]{Member functions} - -\indexlibrary{\idxcode{month_weekday_last}!constructor}% -\begin{itemdecl} -constexpr month_weekday_last(const chrono::month& m, - const chrono::weekday_last& wdl) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{month_weekday_last} by -initializing \tcode{m_} with \tcode{m}, and \tcode{wdl_} with \tcode{wdl}. -\end{itemdescr} - -\indexlibrarymember{month}{month_weekday_last}% -\begin{itemdecl} -constexpr chrono::month month() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{m_}. -\end{itemdescr} - -\indexlibrarymember{weekday_last}{month_weekday_last}% -\begin{itemdecl} -constexpr chrono::weekday_last weekday_last() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{wdl_}. -\end{itemdescr} - -\indexlibrarymember{ok}{month_weekday_last}% -\begin{itemdecl} -constexpr bool ok() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{m_.ok() \&\& wdl_.ok()}. -\end{itemdescr} - -\rSec4[time.cal.mwdlast.nonmembers]{Non-member functions} - -\indexlibrarymember{operator==}{month_weekday_last}% -\begin{itemdecl} -constexpr bool operator==(const month_weekday_last& x, const month_weekday_last& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x.month() == y.month() \&\& x.weekday_last() == y.weekday_last()}. -\end{itemdescr} - -\indexlibrarymember{operator<<}{month_weekday_last}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const month_weekday_last& mwdl); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{os << mwdl.month() << '/' << mwdl.weekday_last()}. -\end{itemdescr} - -\rSec3[time.cal.ym]{Class \tcode{year_month}} - -\rSec4[time.cal.ym.overview]{Overview} -\indexlibrary{\idxcode{year_month}} - -\begin{codeblock} -namespace std::chrono { - class year_month { - chrono::year y_; // \expos - chrono::month m_; // \expos - - public: - year_month() = default; - constexpr year_month(const chrono::year& y, const chrono::month& m) noexcept; - - constexpr chrono::year year() const noexcept; - constexpr chrono::month month() const noexcept; - - constexpr year_month& operator+=(const months& dm) noexcept; - constexpr year_month& operator-=(const months& dm) noexcept; - constexpr year_month& operator+=(const years& dy) noexcept; - constexpr year_month& operator-=(const years& dy) noexcept; - - constexpr bool ok() const noexcept; - }; -} -\end{codeblock} - -\pnum -\tcode{year_month} represents a specific month of a specific year, -but with an unspecified day. -\tcode{year_month} is a field-based time point with a resolution of \tcode{months}. -\tcode{year_month} is \tcode{EqualityComparable} (Table~\ref{tab:equalitycomparable}) -and \tcode{LessThanComparable} (Table~\ref{tab:lessthancomparable}). - -\pnum -\tcode{year_month} is a trivially copyable and standard-layout class type. - -\rSec4[time.cal.ym.members]{Member functions} - -\indexlibrary{\idxcode{year_month}!constructor}% -\begin{itemdecl} -constexpr year_month(const chrono::year& y, const chrono::month& m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{year_month} by -initializing \tcode{y_} with \tcode{y}, and \tcode{m_} with \tcode{m}. -\end{itemdescr} - -\indexlibrarymember{year}{year_month}% -\begin{itemdecl} -constexpr chrono::year year() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y_}. -\end{itemdescr} - -\indexlibrarymember{month}{year_month}% -\begin{itemdecl} -constexpr chrono::month month() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{m_}. -\end{itemdescr} - -\indexlibrarymember{operator+=}{year_month}% -\begin{itemdecl} -constexpr year_month& operator+=(const months& dm) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this + dm}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator-=}{year_month}% -\begin{itemdecl} -constexpr year_month& operator-=(const months& dm) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this - dm}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator+=}{year_month}% -\begin{itemdecl} -constexpr year_month& operator+=(const years& dy) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this + dy}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator-=}{year_month}% -\begin{itemdecl} -constexpr year_month& operator-=(const years& dy) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this - dy}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{ok}{year_month}% -\begin{itemdecl} -constexpr bool ok() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y_.ok() \&\& m_.ok()}. -\end{itemdescr} - -\rSec4[time.cal.ym.nonmembers]{Non-member functions} - -\indexlibrarymember{operator==}{year_month}% -\begin{itemdecl} -constexpr bool operator==(const year_month& x, const year_month& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x.year() == y.year() \&\& x.month() == y.month()}. -\end{itemdescr} - -\indexlibrarymember{operator<}{year_month}% -\begin{itemdecl} -constexpr bool operator<(const year_month& x, const year_month& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -If \tcode{x.year() < y.year()} returns \tcode{true}. -Otherwise, if \tcode{x.year() > y.year()} returns \tcode{false}. -Otherwise, returns \tcode{x.month() < y.month()}. -\end{itemdescr} - -\indexlibrarymember{operator+}{year_month}% -\begin{itemdecl} -constexpr year_month operator+(const year_month& ym, const months& dm) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns A \tcode{year_month} value \tcode{z} such that \tcode{z - ym == dm}. - -\complexity -\bigoh{1} with respect to the value of \tcode{dm}. -\end{itemdescr} - -\indexlibrarymember{operator+}{year_month}% -\begin{itemdecl} -constexpr year_month operator+(const months& dm, const year_month& ym) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{ym + dm}. -\end{itemdescr} - -\indexlibrarymember{operator-}{year_month}% -\begin{itemdecl} -constexpr year_month operator-(const year_month& ym, const months& dm) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{ym + -dm}. -\end{itemdescr} - -\indexlibrarymember{operator-}{year_month}% -\begin{itemdecl} -constexpr months operator-(const year_month& x, const year_month& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\begin{codeblock} -x.year() - y.year() + months{static_cast(unsigned{x.month()}) - - static_cast(unsigned{y.month()})} -\end{codeblock} -\end{itemdescr} - -\indexlibrarymember{operator+}{year_month}% -\begin{itemdecl} -constexpr year_month operator+(const year_month& ym, const years& dy) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{(ym.year() + dy) / ym.month()}. -\end{itemdescr} - -\indexlibrarymember{operator+}{year_month}% -\begin{itemdecl} -constexpr year_month operator+(const years& dy, const year_month& ym) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{ym + dy}. -\end{itemdescr} - -\indexlibrarymember{operator-}{year_month}% -\begin{itemdecl} -constexpr year_month operator-(const year_month& ym, const years& dy) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{ym + -dy}. -\end{itemdescr} - -\indexlibrarymember{operator<<}{year_month}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const year_month& ym); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{os << ym.year() << '/' << ym.month()}. -\end{itemdescr} - -\indexlibrarymember{to_stream}{year_month}% -\begin{itemdecl} -template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, const year_month& ym); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Streams \tcode{ym} into \tcode{os} using -the format specified by the NTCTS \tcode{fmt}. -\tcode{fmt} encoding follows the rules specified in \ref{time.format}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{from_stream}{year_month}% -\begin{itemdecl} -template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - year_month& ym, basic_string* abbrev = nullptr, - minutes* offset = nullptr); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Attempts to parse the input stream \tcode{is} -into the \tcode{year_month} \tcode{ym} using -the format flags given in the NTCTS \tcode{fmt} -as specified in \ref{time.parse}. -If the parse fails to decode a valid \tcode{year_month}, -\tcode{is.setstate(ios_base::failbit)} shall be called -and \tcode{ym} shall not be modified. -If \tcode{\%Z} is used and successfully parsed, -that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. -If \tcode{\%z} (or a modified variant) is used and successfully parsed, -that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. - -\pnum -\returns \tcode{is}. -\end{itemdescr} - -\rSec3[time.cal.ymd]{Class \tcode{year_month_day}} - -\rSec4[time.cal.ymd.overview]{Overview} -\indexlibrary{\idxcode{year_month_day}} - -\begin{codeblock} -namespace std::chrono { - class year_month_day { - chrono::year y_; // \expos - chrono::month m_; // \expos - chrono::day d_; // \expos - - public: - year_month_day() = default; - constexpr year_month_day(const chrono::year& y, const chrono::month& m, - const chrono::day& d) noexcept; - constexpr year_month_day(const year_month_day_last& ymdl) noexcept; - constexpr year_month_day(const sys_days& dp) noexcept; - explicit constexpr year_month_day(const local_days& dp) noexcept; - - constexpr year_month_day& operator+=(const months& m) noexcept; - constexpr year_month_day& operator-=(const months& m) noexcept; - constexpr year_month_day& operator+=(const years& y) noexcept; - constexpr year_month_day& operator-=(const years& y) noexcept; - - constexpr chrono::year year() const noexcept; - constexpr chrono::month month() const noexcept; - constexpr chrono::day day() const noexcept; - - constexpr operator sys_days() const noexcept; - explicit constexpr operator local_days() const noexcept; - constexpr bool ok() const noexcept; - }; -} -\end{codeblock} - -\pnum -\tcode{year_month_day} represents a specific year, month, and day. -\tcode{year_month_day} is a field-based time point with a resolution of \tcode{days}. -\begin{note} -\tcode{year_month_day} supports \tcode{years}- and \tcode{months}-oriented arithmetic, -but not \tcode{days}-oriented arithmetic. -For the latter, there is a conversion to \tcode{sys_days}, -which efficiently supports \tcode{days}-oriented arithmetic. -\end{note} -\tcode{year_month_day} is \tcode{EqualityComparable} (Table~\ref{tab:equalitycomparable}) -and \tcode{LessThanComparable} (Table~\ref{tab:lessthancomparable}), - -\pnum -\tcode{year_month_day} is a trivially copyable and standard-layout class type. - -\rSec4[time.cal.ymd.members]{Member functions} - -\indexlibrary{\idxcode{year_month_day}!constructor}% -\begin{itemdecl} -constexpr year_month_day(const chrono::year& y, const chrono::month& m, - const chrono::day& d) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{year_month_day} by -initializing -\tcode{y_} with \tcode{y}, -\tcode{m_} with \tcode{m}, and -\tcode{d_} with \tcode{d}. -\end{itemdescr} - -\indexlibrary{\idxcode{year_month_day}!constructor}% -\begin{itemdecl} -constexpr year_month_day(const year_month_day_last& ymdl) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{year_month_day} by -initializing -\tcode{y_} with \tcode{ymdl.year()}, -\tcode{m_} with \tcode{ymdl.month()}, and -\tcode{d_} with \tcode{ymdl.day()}. -\begin{note} -This conversion from \tcode{year_month_day_last} to \tcode{year_month_day} -may be more efficient than converting a \tcode{year_month_day_last} to a \tcode{sys_days}, -and then converting that \tcode{sys_days} to a \tcode{year_month_day}. -\end{note} -\end{itemdescr} - -\indexlibrary{\idxcode{year_month_day}!constructor}% -\begin{itemdecl} -constexpr year_month_day(const sys_days& dp) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{year_month_day} -that corresponds to the date represented by \tcode{dp}. - -\pnum -\remarks -For any value \tcode{ymd} of type \tcode{year_month_day} -for which \tcode{ymd.ok()} is \tcode{true}, -\tcode{ymd == year_month_day\{sys_days\{ymd\}\}} -is \tcode{true}. -\end{itemdescr} - -\indexlibrary{\idxcode{year_month_day}!constructor}% -\begin{itemdecl} -explicit constexpr year_month_day(const local_days& dp) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{year_month_day} -that corresponds to the date represented by \tcode{dp}. - -\pnum -\remarks -Equivalent to constructing with \tcode{sys_days\{dp.time_since_epoch()\}}. -\end{itemdescr} - -\indexlibrarymember{operator+=}{year_month_day}% -\begin{itemdecl} -constexpr year_month_day& operator+=(const months& m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this + m}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator-=}{year_month_day}% -\begin{itemdecl} -constexpr year_month_day& operator-=(const months& m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this - m}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator+=}{year_month_day}% -\begin{itemdecl} -constexpr year_month_day& year_month_day::operator+=(const years& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this + y}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator-=}{year_month_day}% -\begin{itemdecl} -constexpr year_month_day& year_month_day::operator-=(const years& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this - y}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{year}{year_month_day}% -\begin{itemdecl} -constexpr chrono::year year() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y_}. -\end{itemdescr} - -\indexlibrarymember{month}{year_month_day}% -\begin{itemdecl} -constexpr chrono::month month() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{m_}. -\end{itemdescr} - -\indexlibrarymember{day}{year_month_day}% -\begin{itemdecl} -constexpr chrono::day day() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{d_}. -\end{itemdescr} - -\indexlibrarymember{operator sys_days}{year_month_day}% -\begin{itemdecl} -constexpr operator sys_days() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -If \tcode{ok()}, -returns a \tcode{sys_days} -holding a count of days from the \tcode{sys_days} epoch to \tcode{*this} -(a negative value if \tcode{*this} represents a date prior to the \tcode{sys_days} epoch). -Otherwise, if \tcode{y_.ok() \&\& m_.ok()} is \tcode{true}, -returns a \tcode{sys_days} -which is offset from \tcode{sys_days\{y_/m_/last\}} -by the number of days \tcode{d_} is offset from \tcode{sys_days\{y_/m_/last\}.day()}. -Otherwise the value returned is unspecified. - -\pnum -\remarks -A \tcode{sys_days} in the range \crange{days\{-12687428\}}{days\{11248737\}} -which is converted to a \tcode{year_month_day} -shall have the same value when converted back to a \tcode{sys_days}. - -\pnum -\begin{example} -\begin{codeblock} -static_assert(year_month_day{sys_days{2017y/January/0}} == 2016y/December/31); -static_assert(year_month_day{sys_days{2017y/January/31}} == 2017y/January/31); -static_assert(year_month_day{sys_days{2017y/January/32}} == 2017y/February/1); -\end{codeblock} -\end{example} -\end{itemdescr} - -\indexlibrarymember{operator local_days}{year_month_day}% -\begin{itemdecl} -explicit constexpr operator local_days() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{local_days\{sys_days\{*this\}.time_since_epoch()\}}. -\end{itemdescr} - -\indexlibrarymember{ok}{year_month_day}% -\begin{itemdecl} -constexpr bool ok() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -If \tcode{y_.ok()} is \tcode{true}, -and \tcode{m_.ok()} is \tcode{true}, -and \tcode{d_} is in the range \crange{1d}{(y_/m_/last).day()}, -then returns \tcode{true}; otherwise returns \tcode{false}. -\end{itemdescr} - -\rSec4[time.cal.ymd.nonmembers]{Non-member functions} - -\indexlibrarymember{operator==}{year_month_day}% -\begin{itemdecl} -constexpr bool operator==(const year_month_day& x, const year_month_day& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x.year() == y.year() \&\& x.month() == y.month() \&\& x.day() == y.day()}. -\end{itemdescr} - -\indexlibrarymember{operator<}{year_month_day}% -\begin{itemdecl} -constexpr bool operator<(const year_month_day& x, const year_month_day& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -If \tcode{x.year() < y.year()}, returns \tcode{true}. -Otherwise, if \tcode{x.year() > y.year()}, returns \tcode{false}. -Otherwise, if \tcode{x.month() < y.month()}, returns \tcode{true}. -Otherwise, if \tcode{x.month() > y.month()}, returns \tcode{false}. -Otherwise, returns \tcode{x.day() < y.day()}. -\end{itemdescr} - -\indexlibrarymember{operator+}{year_month_day}% -\begin{itemdecl} -constexpr year_month_day operator+(const year_month_day& ymd, const months& dm) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{(ymd.year() / ymd.month() + dm) / ymd.day()}. - -\pnum -\begin{note} -If \tcode{ymd.day()} is in the range \crange{1d}{28d}, -\tcode{ok()} will return \tcode{true} for -the resultant \tcode{year_month_day}. -\end{note} -\end{itemdescr} - -\indexlibrarymember{operator+}{year_month_day}% -\begin{itemdecl} -constexpr year_month_day operator+(const months& dm, const year_month_day& ymd) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{ymd + dm}. -\end{itemdescr} - -\indexlibrarymember{operator-}{year_month_day}% -\begin{itemdecl} -constexpr year_month_day operator-(const year_month_day& ymd, const months& dm) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{ymd + (-dm)}. -\end{itemdescr} - -\indexlibrarymember{operator+}{year_month_day}% -\begin{itemdecl} -constexpr year_month_day operator+(const year_month_day& ymd, const years& dy) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{(ymd.year() + dy) / ymd.month() / ymd.day()}. - -\pnum -\begin{note} -If \tcode{ymd.month()} is February -and \tcode{ymd.day()} is not in the range \crange{1d}{28d}, -\tcode{ok()} may return \tcode{false} for -the resultant \tcode{year_month_day}. -\end{note} -\end{itemdescr} - -\indexlibrarymember{operator+}{year_month_day}% -\begin{itemdecl} -constexpr year_month_day operator+(const years& dy, const year_month_day& ymd) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{ymd + dy}. -\end{itemdescr} - -\indexlibrarymember{operator-}{year_month_day}% -\begin{itemdecl} -constexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{ymd + (-dy)}. -\end{itemdescr} - -\indexlibrarymember{operator<<}{year_month_day}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const year_month_day& ymd); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Inserts \tcode{format(fmt, ymd)} -where \tcode{fmt} is \tcode{"\%F"} widened to \tcode{charT}. -If \tcode{!ymd.ok()}, appends with \tcode{" is not a valid date"}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{to_stream}{year_month_day}% -\begin{itemdecl} -template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, const year_month_day& ymd); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Streams \tcode{ymd} into \tcode{os} using -the format specified by the NTCTS \tcode{fmt}. -\tcode{fmt} encoding follows the rules specified in \ref{time.format}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{from_stream}{year_month_day}% -\begin{itemdecl} -template> - basic_istream& - from_stream(basic_istream& is, const charT* fmt, - year_month_day& ymd, basic_string* abbrev = nullptr, - minutes* offset = nullptr); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Attempts to parse the input stream \tcode{is} -into the \tcode{year_month_day} \tcode{ymd} using -the format flags given in the NTCTS \tcode{fmt} -as specified in \ref{time.parse}. -If the parse fails to decode a valid \tcode{year_month_day}, -\tcode{is.setstate(ios_base::failbit)} shall be called -and \tcode{ymd} shall not be modified. -If \tcode{\%Z} is used and successfully parsed, -that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null. -If \tcode{\%z} (or a modified variant) is used and successfully parsed, -that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null. - -\pnum -\returns \tcode{is}. -\end{itemdescr} - -\rSec3[time.cal.ymdlast]{Class \tcode{year_month_day_last}} - -\rSec4[time.cal.ymdlast.overview]{Overview} -\indexlibrary{\idxcode{year_month_day_last}} - -\begin{codeblock} -namespace std::chrono { - class year_month_day_last { - chrono::year y_; // \expos - chrono::month_day_last mdl_; // \expos - - public: - constexpr year_month_day_last(const chrono::year& y, - const chrono::month_day_last& mdl) noexcept; - - constexpr year_month_day_last& operator+=(const months& m) noexcept; - constexpr year_month_day_last& operator-=(const months& m) noexcept; - constexpr year_month_day_last& operator+=(const years& y) noexcept; - constexpr year_month_day_last& operator-=(const years& y) noexcept; - - constexpr chrono::year year() const noexcept; - constexpr chrono::month month() const noexcept; - constexpr chrono::month_day_last month_day_last() const noexcept; - constexpr chrono::day day() const noexcept; - - constexpr operator sys_days() const noexcept; - explicit constexpr operator local_days() const noexcept; - constexpr bool ok() const noexcept; - }; -} -\end{codeblock} - -\pnum -\tcode{year_month_day_last} represents the last day of a specific year and month. -\tcode{year_month_day_last} is a field-based time point with a resolution of \tcode{days}, -except that it is restricted to pointing to the last day of a year and month. -\begin{note} -\tcode{year_month_day_last} supports \tcode{years}- and \tcode{months}-oriented arithmetic, -but not \tcode{days}-oriented arithmetic. -For the latter, there is a conversion to \tcode{sys_days}, -which efficiently supports \tcode{days}-oriented arithmetic. -\end{note} -\tcode{year_month_day_last} is \tcode{EqualityComparable} (Table~\ref{tab:equalitycomparable}) -and \tcode{LessThanComparable} (Table~\ref{tab:lessthancomparable}), - -\pnum -\tcode{year_month_day_last} is a trivially copyable and standard-layout class type. - -\rSec4[time.cal.ymdlast.members]{Member functions} - -\indexlibrary{\idxcode{year_month_day_last}!constructor}% -\begin{itemdecl} -constexpr year_month_day_last(const chrono::year& y, - const chrono::month_day_last& mdl) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{year_month_day_last} by -initializing \tcode{y_} with \tcode{y} and \tcode{mdl_} with \tcode{mdl}. -\end{itemdescr} - -\indexlibrarymember{operator+=}{year_month_day_last}% -\begin{itemdecl} -constexpr year_month_day_last& operator+=(const months& m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this + m}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator-=}{year_month_day_last}% -\begin{itemdecl} -constexpr year_month_day_last& operator-=(const months& m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this - m}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator+=}{year_month_day_last}% -\begin{itemdecl} -constexpr year_month_day_last& operator+=(const years& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this + y}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator-=}{year_month_day_last}% -\begin{itemdecl} -constexpr year_month_day_last& operator-=(const years& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this - y}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{year}{year_month_day_last}% -\begin{itemdecl} -constexpr chrono::year year() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y_}. -\end{itemdescr} - -\indexlibrarymember{month}{year_month_day_last}% -\begin{itemdecl} -constexpr chrono::month month() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{mdl_.month()}. -\end{itemdescr} - -\indexlibrarymember{month_day_last}{year_month_day_last}% -\begin{itemdecl} -constexpr chrono::month_day_last month_day_last() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{mdl_}. -\end{itemdescr} - -\indexlibrarymember{day}{year_month_day_last}% -\begin{itemdecl} -constexpr chrono::day day() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -A \tcode{day} representing the last day of the (\tcode{year}, \tcode{month}) pair -represented by \tcode{*this}. - -\pnum -\begin{note} -This value may be computed on demand. -\end{note} -\end{itemdescr} - -\indexlibrarymember{operator sys_days}{year_month_day_last}% -\begin{itemdecl} -constexpr operator sys_days() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{sys_days\{year()/month()/day()\}}. -\end{itemdescr} - -\indexlibrarymember{operator local_days}{year_month_day_last}% -\begin{itemdecl} -explicit constexpr operator local_days() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{local_days\{sys_days\{*this\}.time_since_epoch()\}}. -\end{itemdescr} - -\indexlibrarymember{ok}{year_month_day_last}% -\begin{itemdecl} -constexpr bool ok() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y_.ok() \&\& mdl_.ok()}. -\end{itemdescr} - -\rSec4[time.cal.ymdlast.nonmembers]{Non-member functions} - -\indexlibrarymember{operator==}{year_month_day_last}% -\begin{itemdecl} -constexpr bool operator==(const year_month_day_last& x, const year_month_day_last& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x.year() == y.year() \&\& x.month_day_last() == y.month_day_last()}. -\end{itemdescr} - -\indexlibrarymember{operator<}{year_month_day_last}% -\begin{itemdecl} -constexpr bool operator<(const year_month_day_last& x, const year_month_day_last& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -If \tcode{x.year() < y.year()}, returns \tcode{true}. -Otherwise, if \tcode{x.year() > y.year()}, returns \tcode{false}. -Otherwise, returns \tcode{x.month_day_last() < y.month_day_last()}. -\end{itemdescr} - -\indexlibrarymember{operator+}{year_month_day_last}% -\begin{itemdecl} -constexpr year_month_day_last - operator+(const year_month_day_last& ymdl, const months& dm) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{(ymdl.year() / ymdl.month() + dm) / last}. -\end{itemdescr} - -\indexlibrarymember{operator+}{year_month_day_last}% -\begin{itemdecl} -constexpr year_month_day_last - operator+(const months& dm, const year_month_day_last& ymdl) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{ymdl + dm}. -\end{itemdescr} - -\indexlibrarymember{operator-}{year_month_day_last}% -\begin{itemdecl} -constexpr year_month_day_last - operator-(const year_month_day_last& ymdl, const months& dm) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{ymdl + (-dm)}. -\end{itemdescr} - -\indexlibrarymember{operator+}{year_month_day_last}% -\begin{itemdecl} -constexpr year_month_day_last - operator+(const year_month_day_last& ymdl, const years& dy) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{\{ymdl.year()+dy, ymdl.month_day_last()\}}. -\end{itemdescr} - -\indexlibrarymember{operator+}{year_month_day_last}% -\begin{itemdecl} -constexpr year_month_day_last - operator+(const years& dy, const year_month_day_last& ymdl) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{ymdl + dy}. -\end{itemdescr} - -\indexlibrarymember{operator-}{year_month_day_last}% -\begin{itemdecl} -constexpr year_month_day_last - operator-(const year_month_day_last& ymdl, const years& dy) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{ymdl + (-dy)}. -\end{itemdescr} - -\indexlibrarymember{operator<<}{year_month_day_last}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const year_month_day_last& ymdl); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{os << ymdl.year() << '/' << ymdl.month_day_last()}. -\end{itemdescr} - -\rSec3[time.cal.ymwd]{Class \tcode{year_month_weekday}} - -\rSec4[time.cal.ymwd.overview]{Overview} -\indexlibrary{\idxcode{year_month_weekday}} - -\begin{codeblock} -namespace std::chrono { - class year_month_weekday { - chrono::year y_; // \expos - chrono::month m_; // \expos - chrono::weekday_indexed wdi_; // \expos - - public: - year_month_weekday() = default; - constexpr year_month_weekday(const chrono::year& y, const chrono::month& m, - const chrono::weekday_indexed& wdi) noexcept; - constexpr year_month_weekday(const sys_days& dp) noexcept; - explicit constexpr year_month_weekday(const local_days& dp) noexcept; - - constexpr year_month_weekday& operator+=(const months& m) noexcept; - constexpr year_month_weekday& operator-=(const months& m) noexcept; - constexpr year_month_weekday& operator+=(const years& y) noexcept; - constexpr year_month_weekday& operator-=(const years& y) noexcept; - - constexpr chrono::year year() const noexcept; - constexpr chrono::month month() const noexcept; - constexpr chrono::weekday weekday() const noexcept; - constexpr unsigned index() const noexcept; - constexpr chrono::weekday_indexed weekday_indexed() const noexcept; - - constexpr operator sys_days() const noexcept; - explicit constexpr operator local_days() const noexcept; - constexpr bool ok() const noexcept; - }; -} -\end{codeblock} - -\pnum -\tcode{year_month_weekday} represents a specific year, month, -and n$^\textrm{th}$ weekday of the month. -\tcode{year_month_weekday} is a field-based time point with a resolution of \tcode{days}. -\begin{note} -\tcode{year_month_weekday} supports \tcode{years}- and \tcode{months}-oriented arithmetic, -but not \tcode{days}-oriented arithmetic. -For the latter, there is a conversion to \tcode{sys_days}, -which efficiently supports \tcode{days}-oriented arithmetic. -\end{note} -\tcode{year_month_weekday} is \tcode{EqualityComparable} (Table~\ref{tab:equalitycomparable}). - -\pnum -\tcode{year_month_weekday} is a trivially copyable and standard-layout class type. - -\rSec4[time.cal.ymwd.members]{Member functions} - -\indexlibrary{\idxcode{year_month_weekday}!constructor}% -\begin{itemdecl} -constexpr year_month_weekday(const chrono::year& y, const chrono::month& m, - const chrono::weekday_indexed& wdi) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{year_month_weekday} by -initializing \tcode{y_} with \tcode{y}, \tcode{m_} with \tcode{m}, and \tcode{wdi_} with \tcode{wdi}. -\end{itemdescr} - -\indexlibrary{\idxcode{year_month_weekday}!constructor}% -\begin{itemdecl} -constexpr year_month_weekday(const sys_days& dp) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{year_month_weekday} -which corresponds to the date represented by \tcode{dp}. - -\pnum -\remarks -For any value \tcode{ymdl} of type \tcode{year_month_weekday} -for which \tcode{ymdl.ok()} is \tcode{true}, -\tcode{ymdl == year_month_weekday\{sys_days\{ymdl\}\}} is \tcode{true}. -\end{itemdescr} - -\indexlibrary{\idxcode{year_month_weekday}!constructor}% -\begin{itemdecl} -explicit constexpr year_month_weekday(const local_days& dp) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{year_month_weekday} -that corresponds to the date represented by \tcode{dp}. - -\pnum -\remarks -Equivalent to constructing with \tcode{sys_days\{dp.time_since_epoch()\}}. -\end{itemdescr} - -\indexlibrarymember{operator+=}{year_month_weekday}% -\begin{itemdecl} -constexpr year_month_weekday& operator+=(const months& m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this + m}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator-=}{year_month_weekday}% -\begin{itemdecl} -constexpr year_month_weekday& operator-=(const months& m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this - m}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator+=}{year_month_weekday}% -\begin{itemdecl} -constexpr year_month_weekday& operator+=(const years& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this + y}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator-=}{year_month_weekday}% -\begin{itemdecl} -constexpr year_month_weekday& operator-=(const years& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this - y}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{year}{year_month_weekday}% -\begin{itemdecl} -constexpr chrono::year year() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y_}. -\end{itemdescr} - -\indexlibrarymember{month}{year_month_weekday}% -\begin{itemdecl} -constexpr chrono::month month() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{m_}. -\end{itemdescr} - -\indexlibrarymember{weekday}{year_month_weekday}% -\begin{itemdecl} -constexpr chrono::weekday weekday() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{wdi_.weekday()}. -\end{itemdescr} - -\indexlibrarymember{index}{year_month_weekday}% -\begin{itemdecl} -constexpr unsigned index() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{wdi_.index()}. -\end{itemdescr} - -\indexlibrarymember{weekday_indexed}{year_month_weekday}% -\begin{itemdecl} -constexpr chrono::weekday_indexed weekday_indexed() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{wdi_}. -\end{itemdescr} - -\indexlibrarymember{operator sys_days}{year_month_weekday}% -\begin{itemdecl} -constexpr operator sys_days() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -If \tcode{y_.ok() \&\& m_.ok() \&\& wdi_.weekday().ok()}, -returns a \tcode{sys_days} that -represents the date \tcode{(index() - 1) * 7} days after -the first \tcode{weekday()} of \tcode{year()/month()}. -If \tcode{index()} is 0 -the returned \tcode{sys_days} -represents the date 7 days prior to -the first \tcode{weekday()} of \tcode{year()/month()}. -Otherwise the returned value is unspecified. -\end{itemdescr} - -\indexlibrarymember{operator local_days}{year_month_weekday}% -\begin{itemdecl} -explicit constexpr operator local_days() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{local_days\{sys_days\{*this\}.time_since_epoch()\}}. -\end{itemdescr} - -\indexlibrarymember{ok}{year_month_weekday}% -\begin{itemdecl} -constexpr bool ok() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -If any of -\tcode{y_.ok()}, -\tcode{m_.ok()}, or -\tcode{wdi_.ok()} -is \tcode{false}, returns \tcode{false}. -Otherwise, if \tcode{*this} represents a valid date, -returns \tcode{true}. -Otherwise, returns \tcode{false}. -\end{itemdescr} - -\rSec4[time.cal.ymwd.nonmembers]{Non-member functions} - -\indexlibrarymember{operator==}{year_month_weekday}% -\begin{itemdecl} -constexpr bool operator==(const year_month_weekday& x, const year_month_weekday& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\begin{codeblock} -x.year() == y.year() && x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed() -\end{codeblock} -\end{itemdescr} - -\indexlibrarymember{operator+}{year_month_weekday}% -\begin{itemdecl} -constexpr year_month_weekday operator+(const year_month_weekday& ymwd, const months& dm) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{(ymwd.year() / ymwd.month() + dm) / ymwd.weekday_indexed()}. -\end{itemdescr} - -\indexlibrarymember{operator+}{year_month_weekday}% -\begin{itemdecl} -constexpr year_month_weekday operator+(const months& dm, const year_month_weekday& ymwd) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{ymwd + dm}. -\end{itemdescr} - -\indexlibrarymember{operator-}{year_month_weekday}% -\begin{itemdecl} -constexpr year_month_weekday operator-(const year_month_weekday& ymwd, const months& dm) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{ymwd + (-dm)}. -\end{itemdescr} - -\indexlibrarymember{operator+}{year_month_weekday}% -\begin{itemdecl} -constexpr year_month_weekday operator+(const year_month_weekday& ymwd, const years& dy) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{\{ymwd.year()+dy, ymwd.month(), ymwd.weekday_indexed()\}}. -\end{itemdescr} - -\indexlibrarymember{operator+}{year_month_weekday}% -\begin{itemdecl} -constexpr year_month_weekday operator+(const years& dy, const year_month_weekday& ymwd) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{ymwd + dm}. -\end{itemdescr} - -\indexlibrarymember{operator-}{year_month_weekday}% -\begin{itemdecl} -constexpr year_month_weekday operator-(const year_month_weekday& ymwd, const years& dy) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{ymwd + (-dm)}. -\end{itemdescr} - -\indexlibrarymember{operator<<}{year_month_weekday}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const year_month_weekday& ymwd); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{os << ymwdi.year() << '/' << ymwdi.month() << '/' << ymwdi.weekday_indexed()}. -\end{itemdescr} - -\rSec3[time.cal.ymwdlast]{Class \tcode{year_month_weekday_last}} - -\rSec4[time.cal.ymwdlast.overview]{Overview} -\indexlibrary{\idxcode{year_month_weekday_last}} - -\begin{codeblock} -namespace std::chrono { - class year_month_weekday_last { - chrono::year y_; // \expos - chrono::month m_; // \expos - chrono::weekday_last wdl_; // \expos - - public: - constexpr year_month_weekday_last(const chrono::year& y, const chrono::month& m, - const chrono::weekday_last& wdl) noexcept; - - constexpr year_month_weekday_last& operator+=(const months& m) noexcept; - constexpr year_month_weekday_last& operator-=(const months& m) noexcept; - constexpr year_month_weekday_last& operator+=(const years& y) noexcept; - constexpr year_month_weekday_last& operator-=(const years& y) noexcept; - - constexpr chrono::year year() const noexcept; - constexpr chrono::month month() const noexcept; - constexpr chrono::weekday weekday() const noexcept; - constexpr chrono::weekday_last weekday_last() const noexcept; - - constexpr operator sys_days() const noexcept; - explicit constexpr operator local_days() const noexcept; - constexpr bool ok() const noexcept; - }; -} -\end{codeblock} - -\pnum -\tcode{year_month_weekday_last} represents a specific year, month, -and last weekday of the month. -\tcode{year_month_weekday_last} is a field-based time point with a resolution of \tcode{days}, -except that it is restricted to pointing to the last weekday of a year and month. -\begin{note} -\tcode{year_month_weekday_last} supports \tcode{years}- and \tcode{months}-oriented arithmetic, -but not \tcode{days}-oriented arithmetic. -For the latter, there is a conversion to \tcode{sys_days}, -which efficiently supports \tcode{days}-oriented arithmetic. -\end{note} -\tcode{year_month_weekday_last} is \tcode{EqualityComparable} (Table~\ref{tab:equalitycomparable}). - -\rSec4[time.cal.ymwdlast.members]{Member functions} - -\pnum -\tcode{year_month_weekday_last} is a trivially copyable and standard-layout class type. - -\indexlibrary{\idxcode{year_month_weekday_last}!constructor}% -\begin{itemdecl} -constexpr year_month_weekday_last(const chrono::year& y, const chrono::month& m, - const chrono::weekday_last& wdl) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{year_month_weekday_last} by -initializing \tcode{y_} with \tcode{y}, \tcode{m_} with \tcode{m}, and \tcode{wdl_} with \tcode{wdl}. -\end{itemdescr} - -\indexlibrarymember{operator+=}{year_month_weekday_last}% -\begin{itemdecl} -constexpr year_month_weekday_last& operator+=(const months& m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this + m}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator-=}{year_month_weekday_last}% -\begin{itemdecl} -constexpr year_month_weekday_last& operator-=(const months& m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this - m}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator+=}{year_month_weekday_last}% -\begin{itemdecl} -constexpr year_month_weekday_last& operator+=(const years& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this + y}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator-=}{year_month_weekday_last}% -\begin{itemdecl} -constexpr year_month_weekday_last& operator-=(const years& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects \tcode{*this = *this - y}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{year}{year_month_weekday_last}% -\begin{itemdecl} -constexpr chrono::year year() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y_}. -\end{itemdescr} - -\indexlibrarymember{month}{year_month_weekday_last}% -\begin{itemdecl} -constexpr chrono::month month() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{m_}. -\end{itemdescr} - -\indexlibrarymember{weekday}{year_month_weekday_last}% -\begin{itemdecl} -constexpr chrono::weekday weekday() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{wdl_.weekday()}. -\end{itemdescr} - -\indexlibrarymember{weekday_last}{year_month_weekday_last}% -\begin{itemdecl} -constexpr chrono::weekday_last weekday_last() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{wdl_}. -\end{itemdescr} - -\indexlibrarymember{operator sys_days}{year_month_weekday_last}% -\begin{itemdecl} -constexpr operator sys_days() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -If \tcode{ok() == true}, -returns a \tcode{sys_days} that represents -the last \tcode{weekday()} of \tcode{year()/month()}. -Otherwise the returned value is unspecified. -\end{itemdescr} - -\indexlibrarymember{operator local_days}{year_month_weekday_last}% -\begin{itemdecl} -explicit constexpr operator local_days() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{local_days\{sys_days\{*this\}.time_since_epoch()\}}. -\end{itemdescr} - -\indexlibrarymember{ok}{year_month_weekday_last}% -\begin{itemdecl} -constexpr bool ok() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y_.ok() \&\& m_.ok() \&\& wdl_.ok()}. -\end{itemdescr} - -\rSec4[time.cal.ymwdlast.nonmembers]{Non-member functions} - -\indexlibrarymember{operator==}{year_month_weekday_last}% -\begin{itemdecl} -constexpr bool operator==(const year_month_weekday_last& x, - const year_month_weekday_last& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\begin{codeblock} -x.year() == y.year() && x.month() == y.month() && x.weekday_last() == y.weekday_last() -\end{codeblock} -\end{itemdescr} - -\indexlibrarymember{operator+}{year_month_weekday_last}% -\begin{itemdecl} -constexpr year_month_weekday_last - operator+(const year_month_weekday_last& ymwdl, const months& dm) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{(ymwdl.year() / ymwdl.month() + dm) / ymwdl.weekday_last()}. -\end{itemdescr} - -\indexlibrarymember{operator+}{year_month_weekday_last}% -\begin{itemdecl} -constexpr year_month_weekday_last - operator+(const months& dm, const year_month_weekday_last& ymwdl) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{ymwdl + dm}. -\end{itemdescr} - -\indexlibrarymember{operator-}{year_month_weekday_last}% -\begin{itemdecl} -constexpr year_month_weekday_last - operator-(const year_month_weekday_last& ymwdl, const months& dm) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{ymwdl + (-dm)}. -\end{itemdescr} - -\indexlibrarymember{operator+}{year_month_weekday_last}% -\begin{itemdecl} -constexpr year_month_weekday_last - operator+(const year_month_weekday_last& ymwdl, const years& dy) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{\{ymwdl.year()+dy, ymwdl.month(), ymwdl.weekday_last()\}}. -\end{itemdescr} - -\indexlibrarymember{operator+}{year_month_weekday_last}% -\begin{itemdecl} -constexpr year_month_weekday_last - operator+(const years& dy, const year_month_weekday_last& ymwdl) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{ymwdl + dy}. -\end{itemdescr} - -\indexlibrarymember{operator-}{year_month_weekday_last}% -\begin{itemdecl} -constexpr year_month_weekday_last - operator-(const year_month_weekday_last& ymwdl, const years& dy) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{ymwdl + (-dy)}. -\end{itemdescr} - -\indexlibrarymember{operator<<}{year_month_weekday_last}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const year_month_weekday_last& ymwdl); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{os << ymwdl.year() << '/' << ymwdl.month() << '/' << ymwdl.weekday_last()}. -\end{itemdescr} - -\rSec3[time.cal.operators]{Conventional syntax operators} -\indexlibrary{\idxcode{operator/}!calendar types|(} - -\pnum -A set of overloaded \tcode{operator/} functions provides -a conventional syntax for the creation of civil calendar dates. - -\pnum -\begin{note} -The year, month, and day are accepted in any of the following 3 orders: - -\begin{codeblock} -@\tcode{\placeholder{year}}@/@\tcode{\placeholder{month}}@/@\tcode{\placeholder{day}}@ -@\tcode{\placeholder{month}}@/@\tcode{\placeholder{day}}@/@\tcode{\placeholder{year}}@ -@\tcode{\placeholder{day}}@/@\tcode{\placeholder{month}}@/@\tcode{\placeholder{year}}@ -\end{codeblock} - -Anywhere a \tcode{\placeholder{day}} is required, any of the following can also be specified: - -\begin{codeblock} -last -@\tcode{\placeholder{weekday}}@[@\tcode{\placeholder{i}}@] -@\tcode{\placeholder{weekday}}@[last] -\end{codeblock} -\end{note} - -\pnum -\begin{note} -Partial-date types such as \tcode{year_month} and \tcode{month_day} -can be created by not applying the second division operator -for any of the three orders. For example: - -\begin{codeblock} -year_month ym = 2015y/April; -month_day md1 = April/4; -month_day md2 = 4d/April; -\end{codeblock} -\end{note} - -\pnum -\begin{example} -\begin{codeblock} -auto a = 2015/4/4; // \tcode{a == int(125)} -auto b = 2015y/4/4; // \tcode{b == year_month_day\{year(2015), month(4), day(4)\}} -auto c = 2015y/4d/April; // error: no viable \tcode{operator/} for first \tcode{/} -auto d = 2015/April/4; // error: no viable \tcode{operator/} for first \tcode{/} -\end{codeblock} -\end{example} - -\begin{itemdecl} -constexpr year_month - operator/(const year& y, const month& m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{\{y, m\}}. -\end{itemdescr} - -\begin{itemdecl} -constexpr year_month - operator/(const year& y, int m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y / month(m)}. -\end{itemdescr} - -\begin{itemdecl} -constexpr month_day - operator/(const month& m, const day& d) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{\{m, d\}}. -\end{itemdescr} - -\begin{itemdecl} -constexpr month_day - operator/(const month& m, int d) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{m / day(d)}. -\end{itemdescr} - -\begin{itemdecl} -constexpr month_day - operator/(int m, const day& d) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{month(m) / d}. -\end{itemdescr} - -\begin{itemdecl} -constexpr month_day - operator/(const day& d, const month& m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{m / d}. -\end{itemdescr} - -\begin{itemdecl} -constexpr month_day - operator/(const day& d, int m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{month(m) / d}. -\end{itemdescr} - -\begin{itemdecl} -constexpr month_day_last - operator/(const month& m, last_spec) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{month_day_last\{m\}}. -\end{itemdescr} - -\begin{itemdecl} -constexpr month_day_last - operator/(int m, last_spec) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{month(m) / last}. -\end{itemdescr} - -\begin{itemdecl} -constexpr month_day_last - operator/(last_spec, const month& m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{m / last}. -\end{itemdescr} - -\begin{itemdecl} -constexpr month_day_last - operator/(last_spec, int m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{month(m) / last}. -\end{itemdescr} - -\begin{itemdecl} -constexpr month_weekday - operator/(const month& m, const weekday_indexed& wdi) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{\{m, wdi\}}. -\end{itemdescr} - -\begin{itemdecl} -constexpr month_weekday - operator/(int m, const weekday_indexed& wdi) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{month(m) / wdi}. -\end{itemdescr} - -\begin{itemdecl} -constexpr month_weekday - operator/(const weekday_indexed& wdi, const month& m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{m / wdi}. -\end{itemdescr} - -\begin{itemdecl} -constexpr month_weekday - operator/(const weekday_indexed& wdi, int m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{month(m) / wdi}. -\end{itemdescr} - -\begin{itemdecl} -constexpr month_weekday_last - operator/(const month& m, const weekday_last& wdl) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{\{m, wdl\}}. -\end{itemdescr} - -\begin{itemdecl} -constexpr month_weekday_last - operator/(int m, const weekday_last& wdl) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{month(m) / wdl}. -\end{itemdescr} - -\begin{itemdecl} -constexpr month_weekday_last - operator/(const weekday_last& wdl, const month& m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{m / wdl}. -\end{itemdescr} - -\begin{itemdecl} -constexpr month_weekday_last - operator/(const weekday_last& wdl, int m) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{month(m) / wdl}. -\end{itemdescr} - -\begin{itemdecl} -constexpr year_month_day - operator/(const year_month& ym, const day& d) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{\{ym.year(), ym.month(), d\}}. -\end{itemdescr} - -\begin{itemdecl} -constexpr year_month_day - operator/(const year_month& ym, int d) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{ym / day(d)}. -\end{itemdescr} - -\begin{itemdecl} -constexpr year_month_day - operator/(const year& y, const month_day& md) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y / md.month() / md.day()}. -\end{itemdescr} - -\begin{itemdecl} -constexpr year_month_day - operator/(int y, const month_day& md) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{year(y) / md}. -\end{itemdescr} - -\begin{itemdecl} -constexpr year_month_day - operator/(const month_day& md, const year& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y / md}. -\end{itemdescr} - -\begin{itemdecl} -constexpr year_month_day - operator/(const month_day& md, int y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{year(y) / md}. -\end{itemdescr} - -\begin{itemdecl} -constexpr year_month_day_last - operator/(const year_month& ym, last_spec) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{\{ym.year(), month_day_last\{ym.month()\}\}}. -\end{itemdescr} - -\begin{itemdecl} -constexpr year_month_day_last - operator/(const year& y, const month_day_last& mdl) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{\{y, mdl\}}. -\end{itemdescr} - -\begin{itemdecl} -constexpr year_month_day_last - operator/(int y, const month_day_last& mdl) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{year(y) / mdl}. -\end{itemdescr} - -\begin{itemdecl} -constexpr year_month_day_last - operator/(const month_day_last& mdl, const year& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y / mdl}. -\end{itemdescr} - -\begin{itemdecl} -constexpr year_month_day_last - operator/(const month_day_last& mdl, int y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{year(y) / mdl}. -\end{itemdescr} - -\begin{itemdecl} -constexpr year_month_weekday - operator/(const year_month& ym, const weekday_indexed& wdi) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{\{ym.year(), ym.month(), wdi\}}. -\end{itemdescr} - -\begin{itemdecl} -constexpr year_month_weekday - operator/(const year& y, const month_weekday& mwd) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{\{y, mwd.month(), mwd.weekday_indexed()\}}. -\end{itemdescr} - -\begin{itemdecl} -constexpr year_month_weekday - operator/(int y, const month_weekday& mwd) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{year(y) / mwd}. -\end{itemdescr} - -\begin{itemdecl} -constexpr year_month_weekday - operator/(const month_weekday& mwd, const year& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y / mwd}. -\end{itemdescr} - -\begin{itemdecl} -constexpr year_month_weekday - operator/(const month_weekday& mwd, int y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{year(y) / mwd}. -\end{itemdescr} - -\begin{itemdecl} -constexpr year_month_weekday_last - operator/(const year_month& ym, const weekday_last& wdl) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{\{ym.year(), ym.month(), wdl\}}. -\end{itemdescr} - -\begin{itemdecl} -constexpr year_month_weekday_last - operator/(const year& y, const month_weekday_last& mwdl) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{\{y, mwdl.month(), mwdl.weekday_last()\}}. -\end{itemdescr} - -\begin{itemdecl} -constexpr year_month_weekday_last - operator/(int y, const month_weekday_last& mwdl) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{year(y) / mwdl}. -\end{itemdescr} - -\begin{itemdecl} -constexpr year_month_weekday_last - operator/(const month_weekday_last& mwdl, const year& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y / mwdl}. -\end{itemdescr} - -\begin{itemdecl} -constexpr year_month_weekday_last - operator/(const month_weekday_last& mwdl, int y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{year(y) / mwdl}. -\end{itemdescr} - -\indexlibrary{\idxcode{operator/}!calendar types|)} - -\rSec2[time.tod]{Class template \tcode{time_of_day}} - -\rSec3[time.tod.overview]{Overview} -\indexlibrary{\idxcode{time_of_day}} - -\begin{codeblock} -namespace std::chrono { - template class time_of_day; - - template<> class time_of_day; - template<> class time_of_day; - template<> class time_of_day; - template class time_of_day>; -} -\end{codeblock} - -\pnum -The \tcode{time_of_day} class template -splits a \tcode{duration} representing the time elapsed since midnight -into a ``broken down'' time of day such as -$hours$:$minutes$:$seconds$. -The \tcode{Duration} template parameter dictates -the precision to which the time is broken down. -\begin{note} -This can vary from a coarse precision of hours -to a very fine precision of nanoseconds. -\end{note} -A \tcode{time_of_day} object also tracks -whether it should be output -as a 12-hour time format or a 24-hour time format. - -\pnum -The primary \tcode{time_of_day} template is not defined. -Four specializations are provided to handle four different -levels of precision. - -\pnum -Each specialization of \tcode{time_of_day} is a trivially copyable -and standard-layout class type. - -\rSec3[time.tod.hours]{Hours precision} -\indexlibrary{\idxcode{time_of_day}} - -\begin{codeblock} -namespace std::chrono { - template<> - class time_of_day { - public: - using precision = chrono::hours; - - time_of_day() = default; - explicit constexpr time_of_day(chrono::hours since_midnight) noexcept; - - constexpr chrono::hours hours() const noexcept; - - explicit constexpr operator precision() const noexcept; - constexpr precision to_duration() const noexcept; - - constexpr void make24() noexcept; - constexpr void make12() noexcept; - }; -} -\end{codeblock} - -\pnum -\begin{note} -This specialization handles hours since midnight. -\end{note} - -\indexlibrary{\idxcode{time_of_day}!constructor}% -\begin{itemdecl} -explicit constexpr time_of_day(chrono::hours since_midnight) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{time_of_day} in 24-hour format -corresponding to \tcode{since_midnight} hours after 00:00:00. - -\pnum -\postconditions -\tcode{hours()} returns the integral number of hours \tcode{since_midnight} is after 00:00:00. -\end{itemdescr} - -\indexlibrarymember{hours}{time_of_day}% -\begin{itemdecl} -constexpr chrono::hours hours() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns The stored hour of \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator precision}{time_of_day}% -\begin{itemdecl} -explicit constexpr operator precision() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns The number of hours since midnight. -\end{itemdescr} - -\indexlibrarymember{to_duration}{time_of_day}% -\begin{itemdecl} -constexpr precision to_duration() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{precision\{*this\}}. -\end{itemdescr} - -\indexlibrarymember{make24}{time_of_day}% -\begin{itemdecl} -constexpr void make24() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -If \tcode{*this} is a 12-hour time, -converts to a 24-hour time. -Otherwise, no effects. -\end{itemdescr} - -\indexlibrarymember{make12}{time_of_day}% -\begin{itemdecl} -constexpr void make12() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -If \tcode{*this} is a 24-hour time, -converts to a 12-hour time. -Otherwise, no effects. -\end{itemdescr} - -\rSec3[time.tod.minutes]{Minutes precision} -\indexlibrary{\idxcode{time_of_day}} - -\begin{codeblock} -namespace std::chrono { - template<> - class time_of_day { - public: - using precision = chrono::minutes; - - time_of_day() = default; - explicit constexpr time_of_day(chrono::minutes since_midnight) noexcept; - - constexpr chrono::hours hours() const noexcept; - constexpr chrono::minutes minutes() const noexcept; - - explicit constexpr operator precision() const noexcept; - constexpr precision to_duration() const noexcept; - - constexpr void make24() noexcept; - constexpr void make12() noexcept; - }; -} -\end{codeblock} - -\pnum -\begin{note} -This specialization handles hours and minutes since midnight. -\end{note} - -\indexlibrary{\idxcode{time_of_day}!constructor}% -\begin{itemdecl} -explicit constexpr time_of_day(minutes since_midnight) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{time_of_day} -in 24-hour format -corresponding to \tcode{since_midnight} minutes after 00:00:00. - -\pnum -\postconditions -\tcode{hours()} returns the integral number of hours -\tcode{since_midnight} is after 00:00:00. -\tcode{minutes()} returns the integral number of minutes -\tcode{since_midnight} is after \tcode{(\textrm{00:00:00} + hours())}. -\end{itemdescr} - -\indexlibrarymember{hours}{time_of_day}% -\begin{itemdecl} -constexpr chrono::hours hours() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns The stored hour of \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{minutes}{time_of_day}% -\begin{itemdecl} -constexpr chrono::minutes minutes() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns The stored minute of \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator precision}{time_of_day}% -\begin{itemdecl} -explicit constexpr operator precision() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns The number of minutes since midnight. -\end{itemdescr} - -\indexlibrarymember{to_duration}{time_of_day}% -\begin{itemdecl} -constexpr precision to_duration() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{precision\{*this\}}. -\end{itemdescr} - -\indexlibrarymember{make24}{time_of_day}% -\begin{itemdecl} -constexpr void make24() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -If \tcode{*this} is a 12-hour time, -converts to a 24-hour time. -Otherwise, no effects. -\end{itemdescr} - -\indexlibrarymember{make12}{time_of_day}% -\begin{itemdecl} -constexpr void make12() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -If \tcode{*this} is a 24-hour time, -converts to a 12-hour time. -Otherwise, no effects. -\end{itemdescr} - -\rSec3[time.tod.seconds]{Seconds precision} -\indexlibrary{\idxcode{time_of_day}} - -\begin{codeblock} -namespace std::chrono { - template<> - class time_of_day { - public: - using precision = chrono::seconds; - - time_of_day() = default; - explicit constexpr time_of_day(chrono::seconds since_midnight) noexcept; - - constexpr chrono::hours hours() const noexcept; - constexpr chrono::minutes minutes() const noexcept; - constexpr chrono::seconds seconds() const noexcept; - - explicit constexpr operator precision() const noexcept; - constexpr precision to_duration() const noexcept; - - constexpr void make24() noexcept; - constexpr void make12() noexcept; - }; -} -\end{codeblock} - -\pnum -\begin{note} -This specialization handles hours, minutes, and seconds since midnight. -\end{note} - -\indexlibrary{\idxcode{time_of_day}!constructor}% -\begin{itemdecl} -explicit constexpr time_of_day(seconds since_midnight) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{time_of_day} -in 24-hour format -corresponding to \tcode{since_midnight} seconds after 00:00:00. - -\pnum -\postconditions -\tcode{hours()} returns the integral number of hours -\tcode{since_midnight} is after 00:00:00. -\tcode{minutes()} returns the integral number of minutes -\tcode{since_midnight} is after \tcode{(\textrm{00:00:00} + hours())}. -\tcode{seconds()} returns the integral number of seconds -\tcode{since_midnight} is after \tcode{(\textrm{00:00:00} + hours() + minutes())}. -\end{itemdescr} - -\indexlibrarymember{hours}{time_of_day}% -\begin{itemdecl} -constexpr chrono::hours hours() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -The stored hour of \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{minutes}{time_of_day}% -\begin{itemdecl} -constexpr chrono::minutes minutes() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -The stored minute of \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{seconds}{time_of_day}% -\begin{itemdecl} -constexpr chrono::seconds seconds() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -The stored second of \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator precision}{time_of_day}% -\begin{itemdecl} -explicit constexpr operator precision() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -The number of seconds since midnight. -\end{itemdescr} - -\indexlibrarymember{to_duration}{time_of_day}% -\begin{itemdecl} -constexpr precision to_duration() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{precision\{*this\}}. -\end{itemdescr} - -\indexlibrarymember{make24}{time_of_day}% -\begin{itemdecl} -constexpr void make24() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -If \tcode{*this} is a 12-hour time, -converts to a 24-hour time. -Otherwise, no effects. -\end{itemdescr} - -\indexlibrarymember{make12}{time_of_day}% -\begin{itemdecl} -constexpr void make12() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -If \tcode{*this} is a 24-hour time, -converts to a 12-hour time. -Otherwise, no effects. -\end{itemdescr} - -\rSec3[time.tod.subsecond]{Sub-second precision} -\indexlibrary{\idxcode{time_of_day<\placeholder{sub-second duration}>}} - -\begin{codeblock} -namespace std::chrono { - template - class time_of_day> { - public: - using precision = duration; - - time_of_day() = default; - explicit constexpr time_of_day(precision since_midnight) noexcept; - - constexpr chrono::hours hours() const noexcept; - constexpr chrono::minutes minutes() const noexcept; - constexpr chrono::seconds seconds() const noexcept; - constexpr precision subseconds() const noexcept; - - explicit constexpr operator precision() const noexcept; - constexpr precision to_duration() const noexcept; - - constexpr void make24() noexcept; - constexpr void make12() noexcept; - }; -} -\end{codeblock} - -\pnum -This specialization shall not exist unless -\tcode{treat_as_floating_point_v} is \tcode{false} -and -\tcode{duration} is not convertible to \tcode{seconds}. -\begin{note} -This specialization handles hours, minutes, seconds, and fractional seconds since midnight. -Typical uses are with \tcode{milliseconds}, \tcode{microseconds} and \tcode{nanoseconds}. -\end{note} - -\indexlibrary{\idxcode{time_of_day<\placeholder{sub-second duration}>}!constructor}% -\begin{itemdecl} -explicit constexpr time_of_day(precision since_midnight) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Constructs an object of type \tcode{time_of_day} -in 24-hour format -corresponding to \tcode{since_midnight} fractional seconds after 00:00:00. - -\pnum -\postconditions -\tcode{hours()} returns the integral number of hours -\tcode{since_midnight} is after 00:00:00. -\tcode{minutes()} returns the integral number of minutes -\tcode{since_midnight }is after \tcode{(\textrm{00:00:00} + hours())}. -\tcode{seconds()} returns the integral number of seconds -\tcode{since_midnight }is after \tcode{(\textrm{00:00:00} + hours() + minutes())}. -\tcode{subseconds()} returns the integral number of fractional seconds -\tcode{since_midnight} is after \tcode{(\textrm{00:00:00} + hours() + minutes() + seconds())}. -\end{itemdescr} - -\indexlibrarymember{hours}{time_of_day<\placeholder{sub-second duration}>}% -\begin{itemdecl} -constexpr chrono::hours hours() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -The stored hour of \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{minutes}{time_of_day<\placeholder{sub-second duration}>}% -\begin{itemdecl} -constexpr chrono::minutes minutes() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -The stored minute of \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{seconds}{time_of_day<\placeholder{sub-second duration}>}% -\begin{itemdecl} -constexpr chrono::seconds seconds() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -The stored second of \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{subseconds}{time_of_day<\placeholder{sub-second duration}>}% -\begin{itemdecl} -constexpr duration subseconds() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -The stored subsecond of \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator precision}{time_of_day<\placeholder{sub-second duration}>}% -\begin{itemdecl} -explicit constexpr operator precision() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -The number of subseconds since midnight. -\end{itemdescr} - -\indexlibrarymember{to_duration}{time_of_day<\placeholder{sub-second duration}>}% -\begin{itemdecl} -constexpr precision to_duration() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{precision\{*this\}}. -\end{itemdescr} - -\indexlibrarymember{make24}{time_of_day<\placeholder{sub-second duration}>}% -\begin{itemdecl} -constexpr void make24() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -If \tcode{*this} is a 12-hour time, -converts to a 24-hour time. -Otherwise, no effects. -\end{itemdescr} - -\indexlibrarymember{make12}{time_of_day<\placeholder{sub-second duration}>}% -\begin{itemdecl} -constexpr void make12() noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -If \tcode{*this} is a 24-hour time, -converts to a 12-hour time. -Otherwise, no effects. -\end{itemdescr} - -\rSec3[time.tod.io]{Formatted output} - -\indexlibrarymember{operator<<}{time_of_day}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const time_of_day& t); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -If \tcode{t} is a 24-hour time, -outputs to \tcode{os} according to the format -\tcode{"\%H00"}\iref{time.format}. -Otherwise -outputs to \tcode{os} according to the format -\tcode{"\%I\%p"}\iref{time.format}. - -\pnum -\returns \tcode{os}. - -\pnum -\begin{example} -\begin{codeblock} -for (hours h : {1h, 18h}) { - time_of_day tod(h); - os << tod << '\n'; - tod.make12(); - os << tod << '\n'; -} -\end{codeblock} - -Produces the output: - -\begin{codeblock} -0100 -1am -1800 -6pm -\end{codeblock} -\end{example} -\end{itemdescr} - -\indexlibrarymember{operator<<}{time_of_day}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const time_of_day& t); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -If \tcode{t} is a 24-hour time, -outputs to \tcode{os} according to the format -\tcode{"\%H:\%M"}\iref{time.format}. -Otherwise -outputs to \tcode{os} according to the format -\tcode{"\%I:\%M\%p"}\iref{time.format}. - -\pnum -\returns \tcode{os}. - -\begin{example} -\begin{codeblock} -for (minutes m : {68min, 1095min}) { - time_of_day tod(m); - os << tod << '\n'; - tod.make12(); - os << tod << '\n'; -} -\end{codeblock} - -Produces the output: - -\begin{codeblock} -01:08 -1:08am -18:15 -6:15pm -\end{codeblock} -\end{example} -\end{itemdescr} - -\indexlibrarymember{operator<<}{time_of_day}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const time_of_day& t); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -If \tcode{t} is a 24-hour time, -outputs to \tcode{os} according to the format -\tcode{"\%T"}\iref{time.format}. -Otherwise -outputs to \tcode{os} according to the format -\tcode{"\%I:\%M:\%S\%p"}\iref{time.format}. - -\pnum -\returns \tcode{os}. - -\begin{example} -\begin{codeblock} -for (seconds s : {4083s, 65745s}) { - time_of_day tod(s); - os << tod << '\n'; - tod.make12(); - os << tod << '\n'; -} -\end{codeblock} - -Produces the output: - -\begin{codeblock} -01:08:03 -1:08:03am -18:15:45 -6:15:45pm -\end{codeblock} -\end{example} -\end{itemdescr} - -\indexlibrarymember{operator<<}{time_of_day<\placeholder{sub-second duration}>}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const time_of_day>& t); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -If \tcode{t} is a 24-hour time, -outputs to \tcode{os} according to the format -\tcode{"\%T"}\iref{time.format}. -Otherwise -outputs to \tcode{os} according to the format -\tcode{"\%I:\%M:\%S\%p"}\iref{time.format}. - -\pnum -\returns \tcode{os}. - -\begin{example} -\begin{codeblock} -for (milliseconds ms : {4083007ms, 65745123ms}) { - time_of_day tod(ms); - os << tod << '\n'; - tod.make12(); - os << tod << '\n'; -} -\end{codeblock} - -Produces the output: - -\begin{codeblock} -01:08:03.007 -1:08:03.007am -18:15:45.123 -6:15:45.123pm -\end{codeblock} -\end{example} -\end{itemdescr} - -\rSec2[time.zone]{Time zones} - -\rSec3[time.zone.general]{In general} - -\pnum -\ref{time.zone} describes an interface for accessing -the IANA Time Zone database described in RFC 6557, -that interoperates with \tcode{sys_time} and \tcode{local_time}. -This interface provides time zone support to -both the civil calendar types\iref{time.cal} -and to user-defined calendars. - -\rSec3[time.zone.db]{Time zone database} - -\rSec4[time.zone.db.tzdb]{Class \tcode{tzdb}} -\indexlibrary{\idxcode{tzdb}} - -\begin{codeblock} -namespace std::chrono { - struct tzdb { - string version; - vector zones; - vector links; - vector leaps; - - const time_zone* locate_zone(string_view tz_name) const; - const time_zone* current_zone() const; - }; -} -\end{codeblock} - -\pnum -Each \tcode{vector} in a \tcode{tzdb} object -is sorted to enable fast lookup. - -\indexlibrarymember{locate_zone}{tzdb}% -\begin{itemdecl} -const time_zone* locate_zone(string_view tz_name) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -If a \tcode{time_zone} is found -for which \tcode{name() == tz_name}, -returns a pointer to that \tcode{time_zone}. -Otherwise -if a \tcode{link} is found -for which \tcode{tz_name == link.name()}, -then a pointer is returned -to the \tcode{time_zone} for which \tcode{zone.name() == link.target()}. -\begin{note} -A \tcode{link} specifies an alternative name for a \tcode{time_zone}. -\end{note} - -\throws -If a \tcode{const time_zone*} cannot be found -as described in the \returns clause, -throws a \tcode{runtime_error}. -\begin{note} -On non-exceptional return, the return value is always a pointer to a valid \tcode{time_zone}. -\end{note} -\end{itemdescr} - -\indexlibrarymember{current_zone}{tzdb}% -\begin{itemdecl} -const time_zone* current_zone() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -A pointer to the time zone which the computer has set as its local time zone. -\end{itemdescr} - -\rSec4[time.zone.db.list]{Class \tcode{tzdb_list}} -\indexlibrary{\idxcode{tzdb_list}} - -\begin{codeblock} -namespace std::chrono { - class tzdb_list { - public: - tzdb_list(const tzdb_list&) = delete; - tzdb_list& operator=(const tzdb_list&) = delete; - - // unspecified additional constructors - - class const_iterator; - - const tzdb& front() const noexcept; - - const_iterator erase_after(const_iterator p); - - const_iterator begin() const noexcept; - const_iterator end() const noexcept; - - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - }; -} -\end{codeblock} - -\pnum -The \tcode{tzdb_list} database is a singleton; -the unique object of type \tcode{tzdb_list} can be -accessed via the \tcode{get_tzdb_list()} function. -\begin{note} -This access is only needed for those applications -that need to have long uptimes and -have a need to update the time zone database while running. -Other applications can implicitly access the \tcode{front()} of this list -via the read-only namespace scope functions -\tcode{get_tzdb()}, -\tcode{locate_zone()}, and -\tcode{current_zone()}. -\end{note} -The \tcode{tzdb_list} object contains a list of \tcode{tzdb} objects. - -\pnum -\tcode{tzdb_list::const_iterator} is a constant iterator -which meets the forward iterator requirements -and has a value type of \tcode{tzdb}. - -\indexlibrarymember{front}{tzdb_list}% -\begin{itemdecl} -const tzdb& front() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -A reference to the first \tcode{tzdb} in the container. - -\pnum -\remarks -This operation is thread-safe with respect to \tcode{reload_tzdb()}. -\begin{note} -\tcode{reload_tzdb()} pushes a new \tcode{tzdb} -onto the front of this container. -\end{note} -\end{itemdescr} - -\indexlibrarymember{erase_after}{tzdb_list}% -\begin{itemdecl} -const_iterator erase_after(const_iterator p); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires -The iterator following \tcode{p} is dereferenceable. - -\pnum -\effects -Erases the \tcode{tzdb} referred to by the iterator following \tcode{p}. - -\pnum -\returns -An iterator pointing to the element following the one that was erased, -or \tcode{end()} if no such element exists. - -\pnum -\remarks -No pointers, references, or iterators are invalidated -except those referring to the erased \tcode{tzdb}. -\begin{note} -It is not possible to erase the \tcode{tzdb} -referred to by \tcode{begin()}. -\end{note} - -\pnum -\throws Nothing. -\end{itemdescr} - -\indexlibrarymember{begin}{tzdb_list}% -\begin{itemdecl} -const_iterator begin() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -An iterator referring to the first \tcode{tzdb} in the container. -\end{itemdescr} - -\indexlibrarymember{end}{tzdb_list}% -\begin{itemdecl} -const_iterator end() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -An iterator referring to the position one past the last \tcode{tzdb} in the container. -\end{itemdescr} - -\indexlibrarymember{cbegin}{tzdb_list}% -\begin{itemdecl} -const_iterator cbegin() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{begin()}. -\end{itemdescr} - -\indexlibrarymember{cend}{tzdb_list}% -\begin{itemdecl} -const_iterator cend() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{end()}. -\end{itemdescr} - -\rSec4[time.zone.db.access]{Time zone database access} - -\indexlibrary{\idxcode{get_tzdb_list}}% -\begin{itemdecl} -tzdb_list& get_tzdb_list(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -If this is the first access to the time zone database, -initializes the database. -If this call initializes the database, -the resulting database will be a \tcode{tzdb_list} -holding a single initialized \tcode{tzdb}. - -\pnum -\returns -A reference to the database. - -\pnum -\remarks -It is safe to call this function from multiple threads at one time. - -\pnum -\throws -\tcode{runtime_error} if for any reason -a reference cannot be returned to a valid \tcode{tzdb_list} -containing one or more valid \tcode{tzdb}s. -\end{itemdescr} - -\indexlibrary{\idxcode{get_tzdb}}% -\begin{itemdecl} -const tzdb& get_tzdb(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{get_tzdb_list().front()}. -\end{itemdescr} - -\indexlibrary{\idxcode{locate_zone}}% -\begin{itemdecl} -const time_zone* locate_zone(string_view tz_name); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{get_tzdb().locate_zone(tz_name)}. - -\pnum -\begin{note} -The time zone database will be initialized -if this is the first reference to the database. -\end{note} -\end{itemdescr} - -\indexlibrary{\idxcode{current_zone}}% -\begin{itemdecl} -const time_zone* current_zone(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{get_tzdb().current_zone()}. -\end{itemdescr} - -\rSec4[time.zone.db.remote]{Remote time zone database support} - -\pnum -The local time zone database -is that supplied by the implementation -when the program first accesses the database, -for example via \tcode{current_zone()}. -While the program is running, -the implementation may choose to update the time zone database. -This update shall not impact the program in any way -unless the program calls the functions in this section. -This potentially updated time zone database -is referred to as the \defn{remote time zone database}. - -\indexlibrary{\idxcode{reload_tzdb}}% -\begin{itemdecl} -const tzdb& reload_tzdb(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -This function first checks -the version of the remote time zone database. -If the versions of the local and remote databases are the same, -there are no effects. -Otherwise the remote database is pushed -to the front of the \tcode{tzdb_list} -accessed by \tcode{get_tzdb_list()}. - -\pnum -\returns \tcode{get_tzdb_list().front()}. - -\pnum -\remarks -No pointers, references, or iterators are invalidated. - -\pnum -\remarks -This function is thread-safe with respect to -\tcode{get_tzdb_list().front()} and \tcode{get_tzdb_list().erase_after()}. - -\pnum -\throws -\tcode{runtime_error} if for any reason -a reference cannot be returned to a valid \tcode{tzdb}. -\end{itemdescr} - -\indexlibrary{\idxcode{remote_version}}% -\begin{itemdecl} -string remote_version(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns The latest remote database version. - -\begin{note} -This can be compared with \tcode{get_tzdb().version} -to discover if the local and remote databases are equivalent. -\end{note} -\end{itemdescr} - -\rSec3[time.zone.exception]{Exception classes} - -\rSec4[time.zone.exception.nonexist]{Class \tcode{nonexistent_local_time}} -\indexlibrary{\idxcode{nonexistent_local_time}} - -\begin{codeblock} -namespace std::chrono { - class nonexistent_local_time : public runtime_error { - public: - template - nonexistent_local_time(const local_time& tp, const local_info& i); - }; -} -\end{codeblock} - -\pnum -\tcode{nonexistent_local_time} is thrown when -an attempt is made -to convert a non-existent \tcode{local_time} to a \tcode{sys_time} -without specifying \tcode{choose::earliest} or \tcode{choose::latest}. - -\indexlibrary{\idxcode{nonexistent_local_time}!constructor}% -\begin{itemdecl} -template - nonexistent_local_time(const local_time& tp, const local_info& i); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires \tcode{i.result == local_info::nonexistent}. - -\pnum -\effects -Constructs a \tcode{nonexistent_local_time} -by initializing the base class with a sequence of \tcode{char} -equivalent to that produced by \tcode{os.str()} -initialized as shown below: - -\begin{codeblock} -ostringstream os; -os << tp << " is in a gap between\n" - << local_seconds{i.first.end.time_since_epoch()} + i.first.offset << ' ' - << i.first.abbrev << " and\n" - << local_seconds{i.second.begin.time_since_epoch()} + i.second.offset << ' ' - << i.second.abbrev - << " which are both equivalent to\n" - << i.first.end << " UTC"; -\end{codeblock} - -\pnum -\begin{example} -\begin{codeblock} -#include -#include - -int main() { - using namespace std::chrono; - try { - auto zt = zoned_time{"America/New_York", - local_days{Sunday[2]/March/2016} + 2h + 30min}; - } catch (const nonexistent_local_time& e) { - std::cout << e.what() << '\n'; - } -} -\end{codeblock} - -Produces the output: - -\begin{codeblock} -2016-03-13 02:30:00 is in a gap between -2016-03-13 02:00:00 EST and -2016-03-13 03:00:00 EDT which are both equivalent to -2016-03-13 07:00:00 UTC -\end{codeblock} -\end{example} -\end{itemdescr} - -\rSec4[time.zone.exception.ambig]{Class \tcode{ambiguous_local_time}} -\indexlibrary{\idxcode{ambiguous_local_time}} - -\begin{codeblock} -namespace std::chrono { - class ambiguous_local_time : public runtime_error { - public: - template - ambiguous_local_time(const local_time& tp, const local_info& i); - }; -} -\end{codeblock} - -\pnum -\tcode{ambiguous_local_time} is thrown when -an attempt is made -to convert an ambiguous \tcode{local_time} to a \tcode{sys_time} -without specifying \tcode{choose::earliest} or \tcode{choose::latest}. - -\indexlibrary{\idxcode{ambiguous_local_time}!constructor}% -\begin{itemdecl} -template - ambiguous_local_time(const local_time& tp, const local_info& i); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires \tcode{i.result == local_info::ambiguous}. - -\pnum -\effects -Constructs an \tcode{ambiguous_local_time} -by initializing the base class with a sequence of \tcode{char} -equivalent to that produced by \tcode{os.str()} -initialized as shown below: - -\begin{codeblock} -ostringstream os; -os << tp << " is ambiguous. It could be\n" - << tp << ' ' << i.first.abbrev << " == " - << tp - i.first.offset << " UTC or\n" - << tp << ' ' << i.second.abbrev << " == " - << tp - i.second.offset << " UTC"; -\end{codeblock} - -\pnum -\begin{example} -\begin{codeblock} -#include -#include - -int main() { - using namespace std::chrono; - try { - auto zt = zoned_time{"America/New_York", - local_days{Sunday[1]/November/2016} + 1h + 30min}; - } catch (const ambiguous_local_time& e) { - std::cout << e.what() << '\n'; - } -} -\end{codeblock} - -Produces the output: - -\begin{codeblock} -2016-11-06 01:30:00 is ambiguous. It could be -2016-11-06 01:30:00 EDT == 2016-11-06 05:30:00 UTC or -2016-11-06 01:30:00 EST == 2016-11-06 06:30:00 UTC -\end{codeblock} -\end{example} -\end{itemdescr} - -\rSec3[time.zone.info]{Information classes} - -\rSec4[time.zone.info.sys]{Class \tcode{sys_info}} -\indexlibrary{\idxcode{sys_info}} - -\begin{codeblock} -namespace std::chrono { - struct sys_info { - sys_seconds begin; - sys_seconds end; - seconds offset; - minutes save; - string abbrev; - }; -} -\end{codeblock} - -\pnum -A \tcode{sys_info} structure can be obtained -from the combination of a \tcode{time_zone} and -either a \tcode{sys_time} or \tcode{local_time}. -It can also be obtained from a \tcode{zoned_time}, -which is effectively a pair of a \tcode{time_zone} and \tcode{sys_time}. - -\pnum -\begin{note} -This type provides a low-level interface to time zone information. -Typical conversions from \tcode{sys_time} to \tcode{local_time} -will use this structure implicitly, not explicitly. -\end{note} - -\pnum -\indexlibrarymember{begin}{sys_info}% -\indexlibrarymember{end}{sys_info}% -The \tcode{begin} and \tcode{end} data members indicate that, -for the associated \tcode{time_zone} and \tcode{time_point}, -the \tcode{offset} and \tcode{abbrev} are in effect in the range \range{begin}{end}. -This information can be used to efficiently iterate the transitions of a \tcode{time_zone}. - -\pnum -\indexlibrarymember{offset}{sys_info}% -The \tcode{offset} data member indicates -the UTC offset in effect -for the associated \tcode{time_zone} and \tcode{time_point}. -The relationship between \tcode{local_time} and \tcode{sys_time} is: - -\begin{codeblock} -offset = local_time - sys_time -\end{codeblock} - -\pnum -\indexlibrarymember{save}{sys_info}% -The \tcode{save} data member is extra information not normally needed -for conversion between \tcode{local_time} and \tcode{sys_time}. -If \tcode{save != 0min}, this \tcode{sys_info} is said to be on ``daylight saving'' time, -and \tcode{offset - save} suggests what offset this \tcode{time_zone} might use -if it were off daylight saving time. -However, this information should not be taken as authoritative. -The only sure way to get such information -is to query the \tcode{time_zone} with a \tcode{time_point} -that returns a \tcode{sys_info} where \tcode{save == 0min}. -There is no guarantee what \tcode{time_point} might return such a \tcode{sys_info} -except that it is guaranteed not to be in the range \range{begin}{end} -(if \tcode{save != 0min} for this \tcode{sys_info}). - -\pnum -\indexlibrarymember{abbrev}{sys_info}% -The \tcode{abbrev} data member indicates -the current abbreviation used for the associated \tcode{time_zone} and \tcode{time_point}. -Abbreviations are not unique among the \tcode{time_zones}, -and so one cannot reliably map abbreviations back to a \tcode{time_zone} and UTC offset. - -\indexlibrarymember{operator<<}{sys_info} -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const sys_info& r); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Streams out the \tcode{sys_info} object \tcode{r} in an unspecified format. -\end{itemdescr} - -\rSec4[time.zone.info.local]{Class \tcode{local_info}} -\indexlibrary{\idxcode{local_info}} - -\indexlibrarymember{unique}{local_info}% -\indexlibrarymember{nonexistent}{local_info}% -\indexlibrarymember{ambiguous}{local_info}% -\indexlibrarymember{result}{local_info}% -\indexlibrarymember{first}{local_info}% -\indexlibrarymember{second}{local_info}% -\begin{codeblock} -namespace std::chrono { - struct local_info { - static constexpr int unique = 0; - static constexpr int nonexistent = 1; - static constexpr int ambiguous = 2; - - int result; - sys_info first; - sys_info second; - }; -} -\end{codeblock} - -\pnum -\begin{note} -This type provides a low-level interface to time zone information. -Typical conversions from \tcode{local_time} to \tcode{sys_time} -will use this structure implicitly, not explicitly. -\end{note} - -\pnum -Describes the result of converting a \tcode{local_time} to a \tcode{sys_time} -as follows: -\begin{itemize} -\item -When a \tcode{local_time} to \tcode{sys_time} conversion is unique, -\tcode{result == unique}, -\tcode{first} will be filled out with the correct \tcode{sys_info}, -and -\tcode{second} will be zero-initialized. - -\item -If the conversion stems from a nonexistent \tcode{local_time} -then \tcode{result == nonexistent}, -\tcode{first} will be filled out with the \tcode{sys_info} -that ends just prior to the \tcode{local_time}, -and -\tcode{second} will be filled out with the \tcode{sys_info} -that begins just after the \tcode{local_time}. - -\item -If the conversion stems from an ambiguous \tcode{local_time}, -then \tcode{result == ambiguous}, -\tcode{first} will be filled out with the \tcode{sys_info} -that ends just after the \tcode{local_time}, -and -\tcode{second} will be filled out with the \tcode{sys_info} -that starts just before the \tcode{local_time}. -\end{itemize} - -\indexlibrarymember{operator<<}{local_info}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, const local_info& r); -\end{itemdecl} - -\begin{itemdescr} -\pnum -Streams out the \tcode{local_info} object \tcode{r} in an unspecified format. -\end{itemdescr} - -\rSec3[time.zone.timezone]{Class \tcode{time_zone}} - -\rSec4[time.zone.overview]{Overview} -\indexlibrary{\idxcode{time_zone}} - -\begin{codeblock} -namespace std::chrono { - class time_zone { - public: - time_zone(time_zone&&) = default; - time_zone& operator=(time_zone&&) = default; - - // unspecified additional constructors - - string_view name() const noexcept; - - template sys_info get_info(const sys_time& st) const; - template local_info get_info(const local_time& tp) const; - - template - sys_time> - to_sys(const local_time& tp) const; - - template - sys_time> - to_sys(const local_time& tp, choose z) const; - - template - local_time> - to_local(const sys_time& tp) const; - }; -} -\end{codeblock} - -\pnum -A \tcode{time_zone} represents all time zone transitions -for a specific geographic area. -\tcode{time_zone} construction is unspecified, -and performed as part of database initialization. -\begin{note} -\tcode{const time_zone} objects can be accessed -via functions such as \tcode{locate_zone}. -\end{note} - -\rSec4[time.zone.members]{Member functions} - -\indexlibrarymember{name}{time_zone}% -\begin{itemdecl} -string_view name() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns The name of the \tcode{time_zone}. - -\pnum -\begin{example} -\tcode{"America/New_York"}. -\end{example} -\end{itemdescr} - -\indexlibrarymember{get_info}{time_zone}% -\begin{itemdecl} -template - sys_info get_info(const sys_time& st) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -A \tcode{sys_info} \tcode{i} for which -\tcode{st} is in the range \range{i.begin}{i.end}. -\end{itemdescr} - -\indexlibrarymember{get_info}{time_zone}% -\begin{itemdecl} -template - local_info get_info(const local_time& tp) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -A \tcode{local_info} for \tcode{tp}. -\end{itemdescr} - -\indexlibrarymember{to_sys}{time_zone}% -\begin{itemdecl} -template - sys_time> - to_sys(const local_time& tp) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -A \tcode{sys_time} that is at least as fine as \tcode{seconds}, -and will be finer if the argument \tcode{tp} has finer precision. -This \tcode{sys_time} is the UTC equivalent of \tcode{tp} -according to the rules of this \tcode{time_zone}. - -\pnum -\throws -If the conversion from \tcode{tp} to a \tcode{sys_time} is ambiguous, -throws \tcode{ambiguous_local_time}. -If the \tcode{tp} represents a non-existent time between two UTC \tcode{time_points}, -throws \tcode{nonexistent_local_time}. -\end{itemdescr} - -\indexlibrarymember{to_sys}{time_zone}% -\begin{itemdecl} -template - sys_time> - to_sys(const local_time& tp, choose z) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -A \tcode{sys_time} that is at least as fine as \tcode{seconds}, -and will be finer if the argument \tcode{tp} has finer precision. -This \tcode{sys_time} is the UTC equivalent of \tcode{tp} -according to the rules of this \tcode{time_zone}. -If the conversion from \tcode{tp} to a \tcode{sys_time} is ambiguous, -returns the earlier \tcode{sys_time} if \tcode{z == choose::earliest}, and -returns the later \tcode{sys_time} if \tcode{z == choose::latest}. -If the \tcode{tp} represents a non-existent time between two UTC \tcode{time_points}, -then the two UTC \tcode{time_points} will be the same, -and that UTC \tcode{time_point} will be returned. -\end{itemdescr} - -\indexlibrarymember{to_local}{time_zone}% -\begin{itemdecl} -template - local_time> - to_local(const sys_time& tp) const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -The \tcode{local_time} associated with \tcode{tp} and this \tcode{time_zone}. -\end{itemdescr} - -\rSec4[time.zone.nonmembers]{Non-member functions} - -\indexlibrarymember{operator==}{time_zone}% -\begin{itemdecl} -bool operator==(const time_zone& x, const time_zone& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x.name() == y.name()}. -\end{itemdescr} - -\indexlibrarymember{operator<}{time_zone}% -\begin{itemdecl} -bool operator<(const time_zone& x, const time_zone& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x.name() < y.name()}. -\end{itemdescr} - -\rSec3[time.zone.zonedtraits]{Class template \tcode{zoned_traits}} -\indexlibrary{\idxcode{zoned_traits}} - -\begin{codeblock} -namespace std::chrono { - template struct zoned_traits {}; -} -\end{codeblock} - -\pnum -\tcode{zoned_traits} provides a means for customizing -the behavior of \tcode{zoned_time} -for the \tcode{zoned_time} default constructor, -and constructors taking \tcode{string_view}. -A specialization for \tcode{const time_zone*} is provided by the implementation: - -\begin{codeblock} -namespace std::chrono { - template<> struct zoned_traits { - static const time_zone* default_zone(); - static const time_zone* locate_zone(string_view name); - }; -} -\end{codeblock} - -\indexlibrarymember{default_zone}{zoned_traits}% -\begin{itemdecl} -static const time_zone* default_zone(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{std::chrono::locate_zone("UTC")}. -\end{itemdescr} - -\indexlibrarymember{locate_zone}{zoned_traits}% -\begin{itemdecl} -static const time_zone* locate_zone(string_view name); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{std::chrono::locate_zone(name)}. -\end{itemdescr} - -\rSec3[time.zone.zonedtime]{Class template \tcode{zoned_time}} - -\rSec4[time.zone.zonedtime.overview]{Overview} -\indexlibrary{\idxcode{zoned_time}} - -\begin{codeblock} -namespace std::chrono { - template - class zoned_time { - public: - using duration = common_type_t; - - private: - TimeZonePtr zone_; // \expos - sys_time tp_; // \expos - - using traits = zoned_traits; // \expos - - public: - zoned_time(); - zoned_time(const zoned_time&) = default; - zoned_time& operator=(const zoned_time&) = default; - - zoned_time(const sys_time& st); - explicit zoned_time(TimeZonePtr z); - explicit zoned_time(string_view name); - - template - zoned_time(const zoned_time& zt) noexcept; - - zoned_time(TimeZonePtr z, const sys_time& st); - zoned_time(string_view name, const sys_time& st); - - zoned_time(TimeZonePtr z, const local_time& tp); - zoned_time(string_view name, const local_time& tp); - zoned_time(TimeZonePtr z, const local_time& tp, choose c); - zoned_time(string_view name, const local_time& tp, choose c); - - template - zoned_time(TimeZonePtr z, const zoned_time& zt); - template - zoned_time(TimeZonePtr z, const zoned_time& zt, choose); - - zoned_time(string_view name, const zoned_time& zt); - zoned_time(string_view name, const zoned_time& zt, choose); - - zoned_time& operator=(const sys_time& st); - zoned_time& operator=(const local_time& ut); - - operator sys_time() const; - explicit operator local_time() const; - - TimeZonePtr get_time_zone() const; - local_time get_local_time() const; - sys_time get_sys_time() const; - sys_info get_info() const; - }; - - zoned_time() -> zoned_time; - - template - zoned_time(sys_time) - -> zoned_time>; - - template - zoned_time(TimeZonePtr, sys_time) - -> zoned_time, TimeZonePtr>; - - template - zoned_time(TimeZonePtr, local_time, choose = choose::earliest) - -> zoned_time, TimeZonePtr>; - - template - zoned_time(TimeZonePtr, zoned_time, choose = choose::earliest) - -> zoned_time, TimeZonePtr>; - - zoned_time(string_view) -> zoned_time; - - template - zoned_time(string_view, sys_time) - -> zoned_time>; - - template - zoned_time(string_view, local_time, choose = choose::earliest) - -> zoned_time>; - - template - zoned_time(TimeZonePtr, zoned_time, choose = choose::earliest) - -> zoned_time; -} -\end{codeblock} - -\pnum -\tcode{zoned_time} represents a logical pairing of -a \tcode{time_zone} and a \tcode{time_point} with precision \tcode{Duration}. -\tcode{zoned_time} maintains the invariant that -it always refers to a valid time zone and -represents a point in time that exists and is not ambiguous -in that time zone. - -\pnum -If \tcode{Duration} is not a specialization of \tcode{chrono::duration}, -the program is ill-formed. - -\rSec4[time.zone.zonedtime.ctor]{Constructors} - -\indexlibrary{\idxcode{zoned_time}!constructor|(}% -\begin{itemdecl} -zoned_time(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -This constructor does not participate in overload resolution unless -\tcode{traits::default_zone()} is a well-formed expression. - -\pnum -\effects -Constructs a \tcode{zoned_time} by -initializing \tcode{zone_} with \tcode{traits::default_zone()} and -default constructing \tcode{tp_}. -\end{itemdescr} - -\begin{itemdecl} -zoned_time(const sys_time& st); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -This constructor does not participate in overload resolution unless -\tcode{traits::default_zone()} is a well-formed expression. - -\pnum -\effects -Constructs a \tcode{zoned_time} by -initializing \tcode{zone_} with \tcode{traits::default_zone()} and \tcode{tp_} with \tcode{st}. -\end{itemdescr} - -\begin{itemdecl} -explicit zoned_time(TimeZonePtr z); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires \tcode{z} refers to a time zone. - -\pnum -\effects Constructs a \tcode{zoned_time} by -initializing \tcode{zone_} with \tcode{std::move(z)}. -% FIXME: What about tp_? -\end{itemdescr} - -\begin{itemdecl} -explicit zoned_time(string_view name); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -This constructor does not participate in overload resolution unless -\tcode{traits::locate_zone(string_view\{\})} is a well-formed expression and -\tcode{zoned_time} is constructible from the return type of \tcode{traits::locate_zone(string_view\{\})}. - -\pnum -\effects -Constructs a \tcode{zoned_time} by -initializing \tcode{zone_} with \tcode{traits::locate_zone(name)} and -default constructing \tcode{tp_}. -\end{itemdescr} - -\begin{itemdecl} -template - zoned_time(const zoned_time& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -Does not participate in overload resolution unless -\tcode{sys_time} is implicitly convertible to \tcode{sys_time}. - -\pnum -\effects -Constructs a \tcode{zoned_time} by -initializing \tcode{zone_} with \tcode{y.zone_} and \tcode{tp_} with \tcode{y.tp_}. -\end{itemdescr} - -\begin{itemdecl} -zoned_time(TimeZonePtr z, const sys_time& st); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires \tcode{z} refers to a time zone. - -\pnum -\effects -Constructs a \tcode{zoned_time} by -initializing \tcode{zone_} with \tcode{std::move(z)} and \tcode{tp_} with \tcode{st}. -\end{itemdescr} - -\begin{itemdecl} -zoned_time(string_view name, const sys_time& st); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -This constructor does not participate in overload resolution unless -\tcode{zoned_time} is constructible from the return type of \tcode{traits::locate_zone(name)} and \tcode{st}. - -\pnum -\effects -Equivalent to construction with \tcode{\{traits::locate_zone(name), st\}}. -\end{itemdescr} - -\begin{itemdecl} -zoned_time(TimeZonePtr z, const local_time& tp); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires \tcode{z} refers to a time zone. - -\pnum -\remarks -This constructor does not participate in overload resolution unless -\begin{codeblock} -decltype(declval()->to_sys(local_time{})) -\end{codeblock} -is convertible to \tcode{sys_time}. - -\pnum -\effects -Constructs a \tcode{zoned_time} by -initializing \tcode{zone_} with \tcode{std::move(z)} and \tcode{tp_} with \tcode{zone_->to_sys(tp)}. -\end{itemdescr} - -\begin{itemdecl} -zoned_time(string_view name, const local_time& tp); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -This constructor does not participate in overload resolution unless -\tcode{zoned_time} is constructible from the return type of \tcode{traits::locate_zone(name)} and \tcode{tp}. - -\pnum -\effects -Equivalent to construction with \tcode{\{traits::locate_zone(name), tp\}}. -\end{itemdescr} - -\begin{itemdecl} -zoned_time(TimeZonePtr z, const local_time& tp, choose c); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\requires \tcode{z} refers to a time zone. - -\pnum -\remarks -This constructor does not participate in overload resolution unless -\begin{codeblock} -decltype(declval()->to_sys(local_time{}, choose::earliest)) -\end{codeblock} -is convertible to \tcode{sys_time}. - -\pnum -\effects -Constructs a \tcode{zoned_time} by -initializing \tcode{zone_} with \tcode{std::move(z)} and \tcode{tp_} with \tcode{zone_->to_sys(tp, c)}. -\end{itemdescr} - -\begin{itemdecl} -zoned_time(string_view name, const local_time& tp, choose c); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -This constructor does not participate in overload resolution unless -\tcode{zoned_time} is constructible from -the return type of \tcode{traits::locate_zone(name)}, \tcode{local_time}, and \tcode{choose}. - -\pnum -\effects -Equivalent to construction with \tcode{\{traits::locate_zone(name), tp, c\}}. -\end{itemdescr} - -\begin{itemdecl} -template - zoned_time(TimeZonePtr z, const zoned_time& y); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -Does not participate in overload resolution unless -\tcode{sys_time} is implicitly convertible to \tcode{sys_time}. - -\pnum -\requires \tcode{z} refers to a valid time zone. - -\pnum -\effects Constructs a \tcode{zoned_time} by -initializing \tcode{zone_} with \tcode{std::move(z)} and \tcode{tp_} with \tcode{y.tp_}. -\end{itemdescr} - -\begin{itemdecl} -template - zoned_time(TimeZonePtr z, const zoned_time& y, choose); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -Does not participate in overload resolution unless -\tcode{sys_time} is implicitly convertible to \tcode{sys_time}. - -\pnum -\requires \tcode{z} refers to a valid time zone. - -\pnum -\effects -Equivalent to construction with \tcode{\{z, y\}}. - -\pnum -\begin{note} -The \tcode{choose} parameter has no effect. -\end{note} -\end{itemdescr} - -\begin{itemdecl} -zoned_time(string_view name, const zoned_time& y); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -This constructor does not participate in overload resolution unless -\tcode{zoned_time} is constructible from the return type of \tcode{traits::locate_zone(name)} and \tcode{zoned_time}. - -\pnum -\effects -Equivalent to construction with \tcode{\{traits::locate_zone(name), y\}}. -\end{itemdescr} - -\begin{itemdecl} -zoned_time(string_view name, const zoned_time& y, choose c); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -This constructor does not participate in overload resolution unless -\tcode{zoned_time} is constructible from -the return type of \tcode{traits::locate_zone(name)}, \tcode{zoned_time}, and \tcode{choose}. - -\pnum -\effects -Equivalent to construction with \tcode{\{traits::locate_zone(name), y, c\}}. - -\pnum -\begin{note} -The \tcode{choose} parameter has no effect. -\end{note} -\end{itemdescr} -\indexlibrary{\idxcode{zoned_time}!constructor|)}% - -\rSec4[time.zone.zonedtime.members]{Member functions} - -\indexlibrarymember{operator=}{zoned_time}% -\begin{itemdecl} -zoned_time& operator=(const sys_time& st); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -After assignment, \tcode{get_sys_time() == st}. -This assignment has no effect on the return value of \tcode{get_time_zone()}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator=}{zoned_time}% -\begin{itemdecl} -zoned_time& operator=(const local_time& lt); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -After assignment, \tcode{get_local_time() == lt}. -This assignment has no effect on the return value of \tcode{get_time_zone()}. - -\pnum -\returns \tcode{*this}. -\end{itemdescr} - -\indexlibrarymember{operator sys_time}{zoned_time}% -\begin{itemdecl} -operator sys_time() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{get_sys_time()}. -\end{itemdescr} - -\indexlibrarymember{operator local_time}{zoned_time}% -\begin{itemdecl} -explicit operator local_time() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{get_local_time()}. -\end{itemdescr} - -\indexlibrarymember{get_time_zone}{zoned_time}% -\begin{itemdecl} -TimeZonePtr get_time_zone() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{zone_}. -\end{itemdescr} - -\indexlibrarymember{get_local_time}{zoned_time}% -\begin{itemdecl} -local_time get_local_time() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{zone_->to_local(tp_)}. -\end{itemdescr} - -\indexlibrarymember{get_sys_time}{zoned_time}% -\begin{itemdecl} -sys_time get_sys_time() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{tp_}. -\end{itemdescr} - -\indexlibrarymember{get_info}{zoned_time}% -\begin{itemdecl} -sys_info get_info() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{zone_->get_info(tp_)}. -\end{itemdescr} - -\rSec4[time.zone.zonedtime.nonmembers]{Non-member functions} - -\indexlibrarymember{operator==}{zoned_time}% -\begin{itemdecl} -template - bool operator==(const zoned_time& x, - const zoned_time& y); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x.zone_ == y.zone_ \&\& x.tp_ == y.tp_}. -\end{itemdescr} - -\indexlibrarymember{operator"!=}{zoned_time}% -\begin{itemdecl} -template - bool operator!=(const zoned_time& x, - const zoned_time& y); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{!(x == y)}. -\end{itemdescr} - -\indexlibrarymember{operator<<}{zoned_time}% -\begin{itemdecl} -template - basic_ostream& - operator<<(basic_ostream& os, - const zoned_time& t); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Streams -the value returned from \tcode{t.get_local_time()} -to \tcode{os} -using the format \tcode{"\%F \%T \%Z"}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\indexlibrarymember{to_stream}{zoned_time}% -\begin{itemdecl} -template - basic_ostream& - to_stream(basic_ostream& os, const charT* fmt, - const zoned_time& tp); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -First obtains a \tcode{sys_info} via \tcode{tp.get_info()} -which for exposition purposes will be referred to as \tcode{info}. -Then calls \tcode{to_stream(os, fmt, tp.get_local_time(), \&info.abbrev, \&info.offset)}. - -\pnum -\returns \tcode{os}. -\end{itemdescr} - -\rSec3[time.zone.leap]{Class \tcode{leap}} - -\rSec4[time.zone.leap.overview]{Overview} -\indexlibrary{\idxcode{leap}} - -\begin{codeblock} -namespace std::chrono { - class leap { - public: - leap(const leap&) = default; - leap& operator=(const leap&) = default; - - // unspecified additional constructors - - constexpr sys_seconds date() const noexcept; - }; -} -\end{codeblock} - -\pnum -Objects of type \tcode{leap} representing -the date of the leap second insertions -are constructed and stored in the time zone database when initialized. - -\pnum -\begin{example} -\begin{codeblock} -for (auto& l : get_tzdb().leaps) - if (l <= 2018y/March/17d) - cout << l.date() << '\n'; -\end{codeblock} - -Produces the output: - -\begin{codeblock} -1972-07-01 00:00:00 -1973-01-01 00:00:00 -1974-01-01 00:00:00 -1975-01-01 00:00:00 -1976-01-01 00:00:00 -1977-01-01 00:00:00 -1978-01-01 00:00:00 -1979-01-01 00:00:00 -1980-01-01 00:00:00 -1981-07-01 00:00:00 -1982-07-01 00:00:00 -1983-07-01 00:00:00 -1985-07-01 00:00:00 -1988-01-01 00:00:00 -1990-01-01 00:00:00 -1991-01-01 00:00:00 -1992-07-01 00:00:00 -1993-07-01 00:00:00 -1994-07-01 00:00:00 -1996-01-01 00:00:00 -1997-07-01 00:00:00 -1999-01-01 00:00:00 -2006-01-01 00:00:00 -2009-01-01 00:00:00 -2012-07-01 00:00:00 -2015-07-01 00:00:00 -2017-01-01 00:00:00 -\end{codeblock} -\end{example} - -\rSec4[time.zone.leap.members]{Member functions} - -\indexlibrarymember{date}{leap}% -\begin{itemdecl} -constexpr sys_seconds date() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns The date and time at which the leap second was inserted. -\end{itemdescr} - -\rSec4[time.zone.leap.nonmembers]{Non-member functions} - -\indexlibrarymember{operator==}{leap}% -\begin{itemdecl} -constexpr bool operator==(const leap& x, const leap& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x.date() == y.date()}. -\end{itemdescr} - -\indexlibrarymember{operator<}{leap}% -\begin{itemdecl} -constexpr bool operator<(const leap& x, const leap& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x.date() < y.date()}. -\end{itemdescr} - -\indexlibrarymember{operator==}{leap}% -\indexlibrarymember{operator==}{sys_time}% -\begin{itemdecl} -template - constexpr bool operator==(const leap& x, const sys_time& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x.date() == y}. -\end{itemdescr} - -\indexlibrarymember{operator==}{leap}% -\indexlibrarymember{operator==}{sys_time}% -\begin{itemdecl} -template - constexpr bool operator==(const sys_time& x, const leap& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y == x}. -\end{itemdescr} - -\indexlibrarymember{operator"!=}{leap}% -\indexlibrarymember{operator"!=}{sys_time}% -\begin{itemdecl} -template - constexpr bool operator!=(const leap& x, const sys_time& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{!(x == y)}. -\end{itemdescr} - -\indexlibrarymember{operator"!=}{leap}% -\indexlibrarymember{operator"!=}{sys_time}% -\begin{itemdecl} -template - constexpr bool operator!=(const sys_time& x, const leap& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{!(x == y)}. -\end{itemdescr} - -\indexlibrarymember{operator<}{leap}% -\indexlibrarymember{operator<}{sys_time}% -\begin{itemdecl} -template - constexpr bool operator<(const leap& x, const sys_time& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x.date() < y}. -\end{itemdescr} - -\indexlibrarymember{operator<}{leap}% -\indexlibrarymember{operator<}{sys_time}% -\begin{itemdecl} -template - constexpr bool operator<(const sys_time& x, const leap& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x < y.date()}. -\end{itemdescr} - -\indexlibrarymember{operator>}{leap}% -\indexlibrarymember{operator>}{sys_time}% -\begin{itemdecl} -template - constexpr bool operator>(const leap& x, const sys_time& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y < x}. -\end{itemdescr} - -\indexlibrarymember{operator>}{leap}% -\indexlibrarymember{operator>}{sys_time}% -\begin{itemdecl} -template - constexpr bool operator>(const sys_time& x, const leap& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{y < x}. -\end{itemdescr} - -\indexlibrarymember{operator<=}{leap}% -\indexlibrarymember{operator<=}{sys_time}% -\begin{itemdecl} -template - constexpr bool operator<=(const leap& x, const sys_time& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{!(y < x)}. -\end{itemdescr} - -\indexlibrarymember{operator<=}{leap}% -\indexlibrarymember{operator<=}{sys_time}% -\begin{itemdecl} -template - constexpr bool operator<=(const sys_time& x, const leap& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{!(y < x)}. -\end{itemdescr} - -\indexlibrarymember{operator>=}{leap}% -\indexlibrarymember{operator>=}{sys_time}% -\begin{itemdecl} -template - constexpr bool operator>=(const leap& x, const sys_time& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{!(x < y)}. -\end{itemdescr} - -\indexlibrarymember{operator>=}{leap}% -\indexlibrarymember{operator>=}{sys_time}% -\begin{itemdecl} -template - constexpr bool operator>=(const sys_time& x, const leap& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{!(x < y)}. -\end{itemdescr} - -\rSec3[time.zone.link]{Class \tcode{link}} - -\rSec4[time.zone.link.overview]{Overview} -\indexlibrary{\idxcode{link}} - -\begin{codeblock} -namespace std::chrono { - class link { - public: - link(link&&) = default; - link& operator=(link&&) = default; - - // unspecified additional constructors - - string_view name() const noexcept; - string_view target() const noexcept; - }; -} -\end{codeblock} - -\pnum -A \tcode{link} specifies an alternative name for a \tcode{time_zone}. -\tcode{link}s are constructed when the time zone database is initialized. - -\rSec4[time.zone.link.members]{Member functions} - -\indexlibrarymember{name}{link}% -\begin{itemdecl} -string_view name() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -The alternative name for the time zone. -\end{itemdescr} - -\indexlibrarymember{target}{link}% -\begin{itemdecl} -string_view target() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -The name of the \tcode{time_zone} for which -this \tcode{link} provides an alternative name. -\end{itemdescr} - -\rSec4[time.zone.link.nonmembers]{Non-member functions} - -\indexlibrarymember{operator==}{link}% -\begin{itemdecl} -bool operator==(const link& x, const link& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x.name() == y.name()}. -\end{itemdescr} - -\indexlibrarymember{operator<}{link}% -\begin{itemdecl} -bool operator<(const link& x, const link& y) noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns \tcode{x.name() < y.name()}. -\end{itemdescr} - -\rSec2[time.format]{Formatting} - -\pnum -Each \tcode{format} overload specified in this subclause -calls \tcode{to_stream} unqualified, -so as to enable argument dependent lookup\iref{basic.lookup.argdep}. - -\indexlibrary{\idxcode{format}|(}% -\begin{itemdecl} -template - basic_string - format(const charT* fmt, const Streamable& s); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -This function shall not participate in overload resolution unless -\begin{codeblock} -to_stream(declval&>(), fmt, s) -\end{codeblock} -is a valid expression. - -\pnum -\effects -Constructs a local variable of type -\tcode{basic_ostringstream} -(named \tcode{os} for exposition purposes). -Executes \tcode{os.exceptions(ios::failbit | ios::badbit)}. -Then calls \tcode{to_stream(os, fmt, s)}. - -\pnum -\returns \tcode{os.str()}. -\end{itemdescr} - -\begin{itemdecl} -template - basic_string - format(const locale& loc, const charT* fmt, const Streamable& s); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -This function shall not participate in overload resolution unless -\begin{codeblock} -to_stream(declval&>(), fmt, s) -\end{codeblock} -is a valid expression. - -\pnum -\effects -Constructs a local variable of type -\tcode{basic_ostringstream} -(named \tcode{os} for exposition purposes). -Executes \tcode{os.exceptions(ios::failbit | ios::badbit)}. -Then calls \tcode{os.imbue(loc)}. -Then calls \tcode{to_stream(os, fmt, s)}. - -\pnum -\returns \tcode{os.str()}. -\end{itemdescr} - -\begin{itemdecl} -template - basic_string - format(const basic_string& fmt, const Streamable& s); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -This function shall not participate in overload resolution unless -\begin{codeblock} -to_stream(declval&>(), fmt.c_str(), s) -\end{codeblock} -is a valid expression. - -\pnum -\effects -Constructs a local variable of type -\tcode{basic_ostringstream} -(named \tcode{os} for exposition purposes). -Executes \tcode{os.exceptions(ios::failbit | ios::badbit)}. -Then calls \tcode{to_stream(os, fmt.c_str(), s)}. - -\pnum -\returns \tcode{os.str()}. -\end{itemdescr} - -\begin{itemdecl} -template - basic_string - format(const locale& loc, const basic_string& fmt, const Streamable& s); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -This function shall not participate in overload resolution unless -\begin{codeblock} -to_stream(declval&>(), fmt.c_str(), s) -\end{codeblock} -is a valid expression. - -\pnum -\effects -Constructs a local variable of type -\tcode{basic_ostringstream} -(named \tcode{os} for exposition purposes). -Then calls \tcode{os.imbue(loc)}. -Executes \tcode{os.exceptions(ios::failbit | ios::badbit)}. -Then calls \tcode{to_stream(os, fmt.c_str(), s)}. - -\pnum -\returns \tcode{os.str()}. -\end{itemdescr} - -\pnum -The \tcode{format} functions call a \tcode{to_stream} function with -a \tcode{basic_ostream}, -a formatting string specifier, -and a \tcode{Streamable} argument. -Each \tcode{to_stream} overload is customized for each \tcode{Streamable} type. -However all \tcode{to_stream} overloads -treat the formatting string specifier -according to the following specification: - -\pnum -The \tcode{fmt} string consists of zero or more conversion specifiers -and ordinary multibyte characters. -A conversion specifier consists of -a \tcode{\%} character, -possibly followed by an \tcode{E} or \tcode{O} modifier character (described below), -followed by a character that determines the behavior of the conversion specifier. -All ordinary multibyte characters (excluding the terminating null character) -are streamed unchanged into the \tcode{basic_ostream}. - -\pnum -Each conversion specifier is replaced by appropriate characters -as described in Table~\ref{tab:time.format.spec}. -Some of the conversion specifiers -depend on the locale which is imbued to the \tcode{basic_ostream}. -If the \tcode{Streamable} object does not contain -the information the conversion specifier refers to, -the value streamed to the \tcode{basic_ostream} is unspecified. - -\pnum -Unless explicitly specified, -\tcode{Streamable} types will not contain time zone abbreviation -and time zone offset information. -If available, -the conversion specifiers \tcode{\%Z} and \tcode{\%z} -will format this information (respectively). -If the information is not available, -and \tcode{\%Z} or \tcode{\%z} are contained in \tcode{fmt}, -\tcode{os.setstate(ios_base::failbit)} shall be called. - -\begin{LongTable}{Meaning of \tcode{format} conversion specifiers}{tab:time.format.spec}{lx{.8\hsize}} -\\ \topline -\lhdr{Specifier} & \rhdr{Replacement} \\ \capsep -\endfirsthead -\continuedcaption\\ -\hline -\lhdr{Specifier} & \rhdr{Replacement} \\ \capsep -\endhead -\tcode{\%a} & -The locale's abbreviated weekday name. -If the value does not contain a valid weekday, -\tcode{setstate(ios::failbit)} is called. -\\ \rowsep -\tcode{\%A} & -The locale's full weekday name. -If the value does not contain a valid weekday, -\tcode{setstate(ios::failbit)} is called. -\\ \rowsep -\tcode{\%b} & -The locale's abbreviated month name. -If the value does not contain a valid month, -\tcode{setstate(ios::failbit)} is called. -\\ \rowsep -\tcode{\%B} & -The locale's full month name. -If the value does not contain a valid month, -\tcode{setstate(ios::failbit)} is called. -\\ \rowsep -\tcode{\%c} & -The locale's date and time representation. -The modified command \tcode{\%Ec} produces -the locale's alternate date and time representation. -\\ \rowsep -\tcode{\%C} & -The year divided by 100 using floored division. -If the result is a single decimal digit, -it is prefixed with \tcode{0}. -The modified command \tcode{\%EC} produces -the locale's alternative representation of the century. -\\ \rowsep -\tcode{\%d} & -The day of month as a decimal number. -If the result is a single decimal digit, -it is prefixed with \tcode{0}. -The modified command \tcode{\%Od} produces -the locale's alternative representation. -\\ \rowsep -\tcode{\%D} & -Equivalent to \tcode{\%m/\%d/\%y}. -\\ \rowsep -\tcode{\%e} & -The day of month as a decimal number. -If the result is a single decimal digit, -it is prefixed with a space. -The modified command \tcode{\%Oe} produces -the locale's alternative representation. -\\ \rowsep -\tcode{\%F} & -Equivalent to \tcode{\%Y-\%m-\%d}. -\\ \rowsep -\tcode{\%g} & -The last two decimal digits of the ISO week-based year. -If the result is a single digit it is prefixed by \tcode{0}. -\\ \rowsep -\tcode{\%G} & -The ISO week-based year as a decimal number. -If the result is less than four digits -it is left-padded with \tcode{0} to four digits. -\\ \rowsep -\tcode{\%h} & -Equivalent to \tcode{\%b}. -\\ \rowsep -\tcode{\%H} & -The hour (24-hour clock) as a decimal number. -If the result is a single digit, -it is prefixed with \tcode{0}. -The modified command \tcode{\%OH} produces -the locale's alternative representation. -\\ \rowsep -\tcode{\%I} & -The hour (12-hour clock) as a decimal number. -If the result is a single digit, -it is prefixed with \tcode{0}. -The modified command \tcode{\%OI} produces -the locale's alternative representation. -\\ \rowsep -\tcode{\%j} & -The day of the year as a decimal number. -Jan 1 is \tcode{001}. -If the result is less than three digits, -it is left-padded with \tcode{0} to three digits. -\\ \rowsep -\tcode{\%m} & -The month as a decimal number. -Jan is \tcode{01}. -If the result is a single digit, it is prefixed with \tcode{0}. -The modified command \tcode{\%Om} produces -the locale's alternative representation. -\\ \rowsep -\tcode{\%M} & -The minute as a decimal number. -If the result is a single digit, it is prefixed with \tcode{0}. -The modified command \tcode{\%OM} produces -the locale's alternative representation. -\\ \rowsep -\tcode{\%n} & -A new-line character. -\\ \rowsep -\tcode{\%p} & -The locale's equivalent of the AM/PM designations associated with a 12-hour clock. -\\ \rowsep -\tcode{\%r} & -The locale's 12-hour clock time. -\\ \rowsep -\tcode{\%R} & -Equivalent to \tcode{\%H:\%M}. -\\ \rowsep -\tcode{\%S} & -Seconds as a decimal number. -If the number of seconds is less than \tcode{10}, the result is prefixed with \tcode{0}. -If the precision of the input cannot be exactly represented with seconds, -then the format is a decimal floating point number with a fixed format -and a precision matching that of the precision of the input -(or to a microseconds precision if the conversion to floating point decimal seconds -cannot be made within 18 fractional digits). -The character for the decimal point is localized according to the locale. -The modified command \tcode{\%OS} produces -the locale's alternative representation. -\\ \rowsep -\tcode{\%t} & -A horizontal-tab character. -\\ \rowsep -\tcode{\%T} & -Equivalent to \tcode{\%H:\%M:\%S}. -\\ \rowsep -\tcode{\%u} & -The ISO weekday as a decimal number (\tcode{1}-\tcode{7}), -where Monday is \tcode{1}. -The modified command \tcode{\%Ou} produces -the locale's alternative representation. -\\ \rowsep -\tcode{\%U} & -The week number of the year as a decimal number. -The first Sunday of the year is the first day of week \tcode{01}. -Days of the same year prior to that are in week \tcode{00}. -If the result is a single digit, it is prefixed with \tcode{0}. -The modified command \tcode{\%OU} produces -the locale's alternative representation. -\\ \rowsep -\tcode{\%V} & -The ISO week-based week number as a decimal number. -If the result is a single digit, it is prefixed with \tcode{0}. -The modified command \tcode{\%OV} produces -the locale's alternative representation. -\\ \rowsep -\tcode{\%w} & -The weekday as a decimal number (\tcode{0}-\tcode{6}), where Sunday is \tcode{0}. -The modified command \tcode{\%Ow} produces -the locale's alternative representation. -\\ \rowsep -\tcode{\%W} & -The week number of the year as a decimal number. -The first Monday of the year is the first day of week \tcode{01}. -Days of the same year prior to that are in week \tcode{00}. -If the result is a single digit, it is prefixed with \tcode{0}. -The modified command \tcode{\%OW} produces -the locale's alternative representation. -\\ \rowsep -\tcode{\%x} & -The locale's date representation. -The modified command \tcode{\%Ex} produces -the locale's alternate date representation. -\\ \rowsep -\tcode{\%X} & -The locale's time representation. -The modified command \tcode{\%EX} produces -the locale's alternate time representation. -\\ \rowsep -\tcode{\%y} & -The last two decimal digits of the year. -If the result is a single digit it is prefixed by \tcode{0}. -\\ \rowsep -\tcode{\%Y} & -The year as a decimal number. -If the result is less than four digits -it is left-padded with \tcode{0} to four digits. -\\ \rowsep -\tcode{\%z} & -The offset from UTC in the ISO 8601 format. -For example \tcode{-0430} refers to 4 hours 30 minutes behind UTC. -If the offset is zero, \tcode{+0000} is used. -The modified commands \tcode{\%Ez} and \tcode{\%Oz} -insert a \tcode{:} between the hours and minutes: \tcode{-04:30}. -If the offset information is not available, -\tcode{setstate(ios_base::failbit)} shall be called. -\\ \rowsep -\tcode{\%Z} & -The time zone abbreviation. -If the time zone abbreviation is not available, -\tcode{setstate(ios_base::failbit)} shall be called. -\\ \rowsep -\tcode{\%\%} & -A \tcode{\%} character. -\\ -\end{LongTable} - -\indexlibrary{\idxcode{format}|)}% - -\rSec2[time.parse]{Parsing} - -\indexlibrary{\idxcode{parse}|(}% - -\pnum -Each \tcode{parse} overload specified in this subclause -calls \tcode{from_stream} unqualified, -so as to enable argument dependent lookup\iref{basic.lookup.argdep}. - -\begin{itemdecl} -template - @\unspec@ - parse(const basic_string& fmt, Parsable& tp); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -This function shall not participate in overload resolution unless -\begin{codeblock} -from_stream(declval&>(), fmt.c_str(), tp) -\end{codeblock} -is a valid expression. - -\pnum -\returns -A manipulator that, when extracted from a -\tcode{basic_istream} \tcode{is}, -calls \tcode{from_stream(is, fmt.c_str(), tp)}. -\end{itemdescr} - -\begin{itemdecl} -template - @\unspec@ - parse(const basic_string& fmt, Parsable& tp, - basic_string& abbrev); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -This function shall not participate in overload resolution unless -\begin{codeblock} -from_stream(declval&>(), fmt.c_str(), tp, &abbrev) -\end{codeblock} -is a valid expression. - -\pnum -\returns -A manipulator that, when extracted from a -\tcode{basic_istream} \tcode{is}, -calls \tcode{from_stream(is, fmt.c_str(), tp, \&abbrev)}. -\end{itemdescr} - -\begin{itemdecl} -template - @\unspec@ - parse(const basic_string& fmt, Parsable& tp, - minutes& offset); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -This function shall not participate in overload resolution unless -\begin{codeblock} -from_stream(declval&>(), fmt.c_str(), tp, nullptr, &offset) -\end{codeblock} -is a valid expression. - -\pnum -\returns -A manipulator that, when extracted from a -\tcode{basic_istream} \tcode{is}, -calls \tcode{from_stream(is, fmt.c_str(), tp, nullptr, \&offset)}. -\end{itemdescr} - -\begin{itemdecl} -template - @\unspec@ - parse(const basic_string& fmt, Parsable& tp, - basic_string& abbrev, minutes& offset); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\remarks -This function shall not participate in overload resolution unless -\begin{codeblock} -from_stream(declval&>(), fmt.c_str(), tp, &abbrev, &offset) -\end{codeblock} -is a valid expression. - -\pnum -\returns -A manipulator that, when extracted from a -\tcode{basic_istream} \tcode{is}, -calls \tcode{from_stream(is, fmt.c_str(), tp, \&abbrev, \&offset)}. -\end{itemdescr} - -\pnum -All \tcode{from_stream} overloads behave as unformatted input functions, -except that they have an unspecified effect -on the value returned by subsequent calls to \tcode{basic_istream<>::gcount()}. -Each overload takes a format string containing ordinary characters -and flags which have special meaning. -Each flag begins with a \tcode{\%}. -Some flags can be modified by \tcode{E} or \tcode{O}. -During parsing each flag interprets characters as parts of date and time types -according to the table below. -Some flags can be modified by a width parameter -given as a positive decimal integer called out as \tcode{\placeholder{N}} below -which governs how many characters are parsed from the stream in interpreting the flag. -All characters in the format string that are not represented in the table below, -except for white space, are parsed unchanged from the stream. -A white space character matches zero or more white space characters in the input stream. - -\pnum -If the \tcode{from_stream} overload fails to parse -everything specified by the format string, -or if insufficient information is parsed to specify a complete -duration, time point, or calendrical data structure, -\tcode{setstate(ios_base::failbit)} -is called on the \tcode{basic_istream}. - -\begin{LongTable}{Meaning of \tcode{parse} flags}{tab:time.parse.spec}{lx{.8\hsize}} -\\ \topline -\lhdr{Flag} & \rhdr{Parsed value} \\ \capsep -\endfirsthead -\continuedcaption\\ -\hline -\lhdr{Flag} & \rhdr{Parsed value} \\ \capsep -\endhead -\tcode{\%a} & -The locale's full or abbreviated case-insensitive weekday name. -\\ \rowsep -\tcode{\%A} & -Equivalent to \tcode{\%a}. -\\ \rowsep -\tcode{\%b} & -The locale's full or abbreviated case-insensitive month name. -\\ \rowsep -\tcode{\%B} & -Equivalent to \tcode{\%b}. -\\ \rowsep -\tcode{\%c} & -The locale's date and time representation. -The modified command \tcode{\%Ec} interprets -the locale's alternate date and time representation. -\\ \rowsep -\tcode{\%C} & -The century as a decimal number. -The modified command \tcode{\%\placeholder{N}C} specifies -the maximum number of characters to read. -If \tcode{\placeholder{N}} is not specified, the default is 2. -Leading zeroes are permitted but not required. -The modified commands \tcode{\%EC} and \tcode{\%OC} interpret -the locale's alternative representation of the century. -\\ \rowsep -\tcode{\%d} & -The day of the month as a decimal number. -The modified command \tcode{\%\placeholder{N}d} specifies -the maximum number of characters to read. -If \tcode{\placeholder{N}} is not specified, the default is 2. -Leading zeroes are permitted but not required. -The modified command \tcode{\%Ed} interprets -the locale's alternative representation of the day of the month. -\\ \rowsep -\tcode{\%D} & -Equivalent to \tcode{\%m/\%d/\%y}. -\\ \rowsep -\tcode{\%e} & -Equivalent to \tcode{\%d} and can be modified like \tcode{\%d}. -\\ \rowsep -\tcode{\%F} & -Equivalent to \tcode{\%Y-\%m-\%d}. -If modified with a width \tcode{\placeholder{N}}, -the width is applied to only \tcode{\%Y}. -\\ \rowsep -\tcode{\%g} & -The last two decimal digits of the ISO week-based year. -The modified command \tcode{\%\placeholder{N}g} specifies -the maximum number of characters to read. -If \tcode{\placeholder{N}} is not specified, the default is 2. -Leading zeroes are permitted but not required. -\\ \rowsep -\tcode{\%G} & -The ISO week-based year as a decimal number. -The modified command \tcode{\%\placeholder{N}G} specifies -the maximum number of characters to read. -If \tcode{\placeholder{N}} is not specified, the default is 4. -Leading zeroes are permitted but not required. -\\ \rowsep -\tcode{\%h} & -Equivalent to \tcode{\%b}. -\\ \rowsep -\tcode{\%H} & -The hour (24-hour clock) as a decimal number. -The modified command \tcode{\%\placeholder{N}H} specifies -the maximum number of characters to read. -If \tcode{\placeholder{N}} is not specified, the default is 2. -Leading zeroes are permitted but not required. -The modified command \tcode{\%OH} interprets -the locale's alternative representation. -\\ \rowsep -\tcode{\%I} & -The hour (12-hour clock) as a decimal number. -The modified command \tcode{\%\placeholder{N}I} specifies -the maximum number of characters to read. -If \tcode{\placeholder{N}} is not specified, the default is 2. -Leading zeroes are permitted but not required. -\\ \rowsep -\tcode{\%j} & -The day of the year as a decimal number. -Jan 1 is \tcode{1}. -The modified command \tcode{\%\placeholder{N}j} specifies -the maximum number of characters to read. -If \tcode{\placeholder{N}} is not specified, the default is 3. -Leading zeroes are permitted but not required. -\\ \rowsep -\tcode{\%m} & -The month as a decimal number. -Jan is \tcode{1}. -The modified command \tcode{\%\placeholder{N}m} specifies -the maximum number of characters to read. -If \tcode{\placeholder{N}} is not specified, the default is 2. -Leading zeroes are permitted but not required. -The modified command \tcode{\%Om} interprets -the locale's alternative representation. -\\ \rowsep -\tcode{\%M} & -The minutes as a decimal number. -The modified command \tcode{\%\placeholder{N}M} specifies -the maximum number of characters to read. -If \tcode{\placeholder{N}} is not specified, the default is 2. -Leading zeroes are permitted but not required. -The modified command \tcode{\%OM} interprets -the locale's alternative representation. -\\ \rowsep -\tcode{\%n} & -Matches one white space character. -\begin{note} -\tcode{\%n}, \tcode{\%t}, and a space -can be combined to match a wide range of white-space patterns. -For example, -\tcode{"\%n "} matches one or more white space characters, and -\tcode{"\%n\%t\%t"} matches one to three white space characters. -\end{note} -\\ \rowsep -\tcode{\%p} & -The locale's equivalent of the AM/PM designations associated with a 12-hour clock. -The command \tcode{\%I} must precede \tcode{\%p} in the format string. -\\ \rowsep -\tcode{\%r} & -The locale's 12-hour clock time. -\\ \rowsep -\tcode{\%R} & -Equivalent to \tcode{\%H:\%M}. -\\ \rowsep -\tcode{\%S} & -The seconds as a decimal number. -The modified command \tcode{\%\placeholder{N}S} specifies -the maximum number of characters to read. -If \tcode{\placeholder{N}} is not specified, -the default is 2 if the input time has a precision convertible to seconds. -Otherwise the default width is determined by -the decimal precision of the input -and the field is interpreted as a \tcode{long double} in a fixed format. -If encountered, the locale determines the decimal point character. -Leading zeroes are permitted but not required. -The modified command \tcode{\%OS} interprets -the locale's alternative representation. -\\ \rowsep -\tcode{\%t} & -Matches zero or one white space characters. -\\ \rowsep -\tcode{\%T} & -Equivalent to \tcode{\%H:\%M:\%S}. -\\ \rowsep -\tcode{\%u} & -The ISO weekday as a decimal number (\tcode{1}-\tcode{7}), where Monday is \tcode{1}. -The modified command \tcode{\%\placeholder{N}u} specifies -the maximum number of characters to read. -If \tcode{\placeholder{N}} is not specified, the default is \tcode{1}. -Leading zeroes are permitted but not required. -The modified command \tcode{\%Ou} interprets -the locale's alternative representation. -\\ \rowsep -\tcode{\%U} & -The week number of the year as a decimal number. -The first Sunday of the year is the first day of week \tcode{01}. -Days of the same year prior to that are in week \tcode{00}. -The modified command \tcode{\%\placeholder{N}U} specifies -the maximum number of characters to read. -If \tcode{\placeholder{N}} is not specified, the default is 2. -Leading zeroes are permitted but not required. -\\ \rowsep -\tcode{\%V} & -The ISO week-based week number as a decimal number. -The modified command \tcode{\%\placeholder{N}V} specifies -the maximum number of characters to read. -If \tcode{\placeholder{N}} is not specified, the default is 2. -Leading zeroes are permitted but not required. -\\ \rowsep -\tcode{\%w} & -The weekday as a decimal number (\tcode{0}-\tcode{6}), where Sunday is \tcode{0}. -The modified command \tcode{\%\placeholder{N}w} specifies -the maximum number of characters to read. -If \tcode{\placeholder{N}} is not specified, the default is \tcode{1}. -Leading zeroes are permitted but not required. -The modified command \tcode{\%Ow} interprets -the locale's alternative representation. -\\ \rowsep -\tcode{\%W} & -The week number of the year as a decimal number. -The first Monday of the year is the first day of week \tcode{01}. -Days of the same year prior to that are in week \tcode{00}. -The modified command \tcode{\%\placeholder{N}W} specifies -the maximum number of characters to read. -If \tcode{\placeholder{N}} is not specified, the default is 2. -Leading zeroes are permitted but not required. -\\ \rowsep -\tcode{\%x} & -The locale's date representation. -The modified command \tcode{\%Ex} produces the locale's alternate date representation. -\\ \rowsep -\tcode{\%X} & -The locale's time representation. -The modified command \tcode{\%EX} produces the locale's alternate time representation. -\\ \rowsep -\tcode{\%y} & -The last two decimal digits of the year. -If the century is not otherwise specified -(e.g. with \tcode{\%C}), -values in the range \crange{69}{99} -are presumed to refer to the years 1969 to 1999, -and values in the range \crange{00}{68} -are presumed to refer to the years 2000 to 2068. -The modified command \tcode{\%\placeholder{N}y} specifies -the maximum number of characters to read. -If \tcode{\placeholder{N}} is not specified, the default is 2. -Leading zeroes are permitted but not required. -The modified commands \tcode{\%Ey} and \tcode{\%Oy} interpret -the locale's alternative representation. -\\ \rowsep -\tcode{\%Y} & -The year as a decimal number. -The modified command \tcode{\%\placeholder{N}Y} specifies -the maximum number of characters to read. -If \tcode{\placeholder{N}} is not specified, the default is 4. -Leading zeroes are permitted but not required. -The modified command \tcode{\%EY} interprets -the locale's alternative representation. -\\ \rowsep -\tcode{\%z} & -The offset from UTC in the format \tcode{[+|-]hh[mm]}. -For example \tcode{-0430} refers to 4 hours 30 minutes behind UTC, -and \tcode{04} refers to 4 hours ahead of UTC. -The modified commands \tcode{\%Ez} and \tcode{\%Oz} -parse a \tcode{:} between the hours and minutes -and render leading zeroes on the hour field optional: -\tcode{[+|-]h[h][:mm]}. -For example \tcode{-04:30} refers to 4 hours 30 minutes behind UTC, -and \tcode{4} refers to 4 hours ahead of UTC. -\\ \rowsep -\tcode{\%Z} & -The time zone abbreviation or name. -A single word is parsed. -This word can only contain characters -from the basic source character set\iref{lex.charset} -that are alphanumeric, or one of -\tcode{'_'}, \tcode{'/'}, \tcode{'-'}, or \tcode{'+'}. -\\ \rowsep -\tcode{\%\%} & -A \tcode{\%} character is extracted. -\\ -\end{LongTable} - -\indexlibrary{\idxcode{parse}|)} - -\rSec2[ctime.syn]{Header \tcode{} synopsis} - -\indexhdr{ctime}% -\indexlibrary{\idxcode{CLOCKS_PER_SEC}}% -\indexlibrary{\idxcode{NULL}}% -\indexlibrary{\idxcode{TIME_UTC}}% -\indexlibrary{\idxcode{asctime}}% -\indexlibrary{\idxcode{clock_t}}% -\indexlibrary{\idxcode{clock}}% -\indexlibrary{\idxcode{ctime}}% -\indexlibrary{\idxcode{difftime}}% -\indexlibrary{\idxcode{gmtime}}% -\indexlibrary{\idxcode{localtime}}% -\indexlibrary{\idxcode{mktime}}% -\indexlibrary{\idxcode{size_t}}% -\indexlibrary{\idxcode{strftime}}% -\indexlibrary{\idxcode{time_t}}% -\indexlibrary{\idxcode{timespec_get}}% -\indexlibrary{\idxcode{timespec}}% -\indexlibrary{\idxcode{time}}% -\indexlibrary{\idxcode{tm}}% -\begin{codeblock} -#define NULL @\textit{see \ref{support.types.nullptr}}@ -#define CLOCKS_PER_SEC @\seebelow@ -#define TIME_UTC @\seebelow@ - -namespace std { - using size_t = @\textit{see \ref{support.types.layout}}@; - using clock_t = @\seebelow@; - using time_t = @\seebelow@; - - struct timespec; - struct tm; - - clock_t clock(); - double difftime(time_t time1, time_t time0); - time_t mktime(struct tm* timeptr); - time_t time(time_t* timer); - int timespec_get(timespec* ts, int base); - char* asctime(const struct tm* timeptr); - char* ctime(const time_t* timer); - struct tm* gmtime(const time_t* timer); - struct tm* localtime(const time_t* timer); - size_t strftime(char* s, size_t maxsize, const char* format, const struct tm* timeptr); -} -\end{codeblock} - -\pnum -\indexhdr{time.h}% -\indexhdr{ctime}% -The contents of the header \tcode{} are the same as the C standard library header \tcode{}.% -\footnote{\tcode{strftime} supports the C conversion specifiers -\tcode{C}, \tcode{D}, \tcode{e}, \tcode{F}, \tcode{g}, \tcode{G}, \tcode{h}, -\tcode{r}, \tcode{R}, \tcode{t}, \tcode{T}, \tcode{u}, \tcode{V}, and -\tcode{z}, and the modifiers \tcode{E} and \tcode{O}.} - -\pnum -The functions \tcode{asctime}, \tcode{ctime}, \tcode{gmtime}, and -\tcode{localtime} are not required to avoid data -races\iref{res.on.data.races}. - -\xrefc{7.27} - \rSec1[type.index]{Class \tcode{type_index}} \rSec2[type.index.synopsis]{Header \tcode{} synopsis} @@ -28919,7 +17877,7 @@ resolution participation. \pnum -\tcode{is_execution_policy} shall be a \tcode{UnaryTypeTrait} with a +\tcode{is_execution_policy} shall be a \oldconcept{UnaryTypeTrait} with a base characteristic of \tcode{true_type} if \tcode{T} is the type of a standard or \impldef{additional execution policies supported by parallel algorithms} execution policy, otherwise \tcode{false_type}. @@ -29326,7 +18284,7 @@ except that \begin{itemize} \item -the only sign that may appear is \tcode{'-'}; +the sign \tcode{'+'} may only appear in the exponent part; \item if \tcode{fmt} has \tcode{chars_format::scientific} set but not \tcode{chars_format::fixed}, diff --git a/source/xrefdelta.tex b/source/xrefdelta.tex index a3e2b64a83..fb5e04f958 100644 --- a/source/xrefdelta.tex +++ b/source/xrefdelta.tex @@ -103,6 +103,23 @@ \removedxref{reverse.iter.ops} +% Single-item [move.iterators] subclauses were dissolved. +\movedxref{move.iter.op=}{move.iter.cons} +\movedxref{move.iter.op.const}{move.iter.cons} + +\movedxref{move.iter.op.star}{move.iter.elem} +\movedxref{move.iter.op.ref}{move.iter.elem} +\movedxref{move.iter.op.index}{move.iter.elem} + +\movedxref{move.iter.op.+}{move.iter.nav} +\movedxref{move.iter.op.-}{move.iter.nav} +\movedxref{move.iter.op.incr}{move.iter.nav} +\movedxref{move.iter.op.+=}{move.iter.nav} +\movedxref{move.iter.op.decr}{move.iter.nav} +\movedxref{move.iter.op.-=}{move.iter.nav} + +\removedxref{move.iter.ops} + % Individual swap sections were removed. \removedxref{deque.special} \removedxref{forwardlist.special} @@ -117,6 +134,27 @@ \removedxref{unord.set.swap} \removedxref{unord.multiset.swap} +% Deprecated features were removed. +\removedxref{depr.except.spec} +\removedxref{depr.cpp.headers} +\removedxref{depr.uncaught} +\removedxref{depr.func.adaptor.binding} +\removedxref{depr.weak.result_type} +\removedxref{depr.func.adaptor.typedefs} +\removedxref{depr.negators} +\removedxref{depr.default.allocator} +\removedxref{depr.storage.iterator} +\removedxref{depr.temporary.buffer} +\removedxref{depr.util.smartptr.shared.obs} + +% Deprecated headers were removed for some headers +\movedxref{depr.ccomplex.syn}{depr.complex.h.syn} +\movedxref{depr.cstdalign.syn}{depr.stdalign.h.syn} +\movedxref{depr.cstdbool.syn}{depr.stdbool.h.syn} +\movedxref{depr.ctgmath.syn}{depr.tgmath.h.syn} + +\movedxref{class.copy}{class.mem} + % Deprecated features. %\deprxref{old.label} (if moved to depr.old.label, otherwise use \movedxref)