diff --git a/source/algorithms.tex b/source/algorithms.tex index 1b47c0b20b..ce678c8680 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -6293,7 +6293,7 @@ \effects Equivalent to: \begin{codeblock} -return ranges::rotate_copy(ranges::begin(r), middle, ranges::end(r), result); +return ranges::rotate_copy(ranges::begin(r), middle, ranges::end(r), std::move(result)); \end{codeblock} \end{itemdescr} @@ -11127,7 +11127,7 @@ \effects Equivalent to: \begin{codeblock} -auto t = uninitialized_copy(counted_iterator(ifirst, n), +auto t = uninitialized_copy(counted_iterator(std::move(ifirst), n), default_sentinel, ofirst, olast); return {std::move(t.in).base(), t.out}; \end{codeblock} @@ -11237,7 +11237,7 @@ \effects Equivalent to: \begin{codeblock} -auto t = uninitialized_move(counted_iterator(ifirst, n), +auto t = uninitialized_move(counted_iterator(std::move(ifirst), n), default_sentinel, ofirst, olast); return {std::move(t.in).base(), t.out}; \end{codeblock} @@ -11448,7 +11448,7 @@ \effects Equivalent to: \begin{codeblock} -return destroy(counted_iterator(first, n), default_sentinel).base(); +return destroy(counted_iterator(std::move(first), n), default_sentinel).base(); \end{codeblock} \end{itemdescr} diff --git a/source/containers.tex b/source/containers.tex index 474f7ecae1..143eda4f32 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -79,13 +79,18 @@ \item \tcode{X} denotes a container class containing objects of type \tcode{T}, \item -\tcode{a} and \tcode{b} denote values of type \tcode{X}, +\tcode{a} denotes a value of type \tcode{X}, +\item +\tcode{b} and \tcode{c} denote values of type (possibly const) \tcode{X}, \item \tcode{i} and \tcode{j} denote values of type (possibly const) \tcode{X::iterator}, \item \tcode{u} denotes an identifier, \item -\tcode{r} denotes a non-const value of type \tcode{X}, and +\tcode{v} denotes an lvalue of type (possibly const) \tcode{X} or +an rvalue of type \tcode{const X}, +\item +\tcode{s} and \tcode{t} denote non-const lvalues of type \tcode{X}, and \item \tcode{rv} denotes a non-const rvalue of type \tcode{X}. \end{itemize} @@ -219,8 +224,8 @@ \end{itemdescr} \begin{itemdecl} -X u(a); -X u = a; +X u(v); +X u = v; \end{itemdecl} \begin{itemdescr} @@ -230,7 +235,7 @@ \pnum \ensures -\tcode{u == a} +\tcode{u == v}. \pnum \complexity @@ -252,8 +257,27 @@ Linear for \tcode{array} and constant for all other standard containers. \end{itemdescr} +\indexcont{operator=}% \begin{itemdecl} -a = rv +t = v; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X\&}. + +\pnum +\ensures +\tcode{t == v}. + +\pnum +\complexity +Linear. +\end{itemdescr} + +\begin{itemdecl} +t = rv \end{itemdecl} \begin{itemdescr} @@ -263,12 +287,12 @@ \pnum \effects -All existing elements of \tcode{a} are either move assigned to or destroyed. +All existing elements of \tcode{t} are either move assigned to or destroyed. \pnum \ensures -If \tcode{a} and \tcode{rv} do not refer to the same object, -\tcode{a} is equal to the value that \tcode{rv} had before this assignment. +If \tcode{t} and \tcode{rv} do not refer to the same object, +\tcode{t} is equal to the value that \tcode{rv} had before this assignment. \pnum \complexity @@ -282,7 +306,7 @@ \begin{itemdescr} \pnum \result -\keyword{void} +\keyword{void}. \pnum \effects @@ -295,14 +319,14 @@ \indexcont{begin}% \begin{itemdecl} -a.begin() +b.begin() \end{itemdecl} \begin{itemdescr} \pnum \result \tcode{iterator}; -\tcode{const_iterator} for constant \tcode{a}. +\tcode{const_iterator} for constant \tcode{b}. \pnum \returns @@ -315,14 +339,14 @@ \indexcont{end}% \begin{itemdecl} -a.end() +b.end() \end{itemdecl} \begin{itemdescr} \pnum \result \tcode{iterator}; -\tcode{const_iterator} for constant \tcode{a}. +\tcode{const_iterator} for constant \tcode{b}. \pnum \returns @@ -335,7 +359,7 @@ \indexcont{cbegin}% \begin{itemdecl} -a.cbegin() +b.cbegin() \end{itemdecl} \begin{itemdescr} @@ -345,7 +369,7 @@ \pnum \returns -\tcode{const_cast(a).begin()} +\tcode{const_cast(b).begin()} \pnum \complexity @@ -354,7 +378,7 @@ \indexcont{cend}% \begin{itemdecl} -a.cend() +b.cend() \end{itemdecl} \begin{itemdescr} @@ -364,7 +388,7 @@ \pnum \returns -\tcode{const_cast(a).end()} +\tcode{const_cast(b).end()} \pnum \complexity @@ -391,7 +415,7 @@ \indexcont{operator==}% \begin{itemdecl} -a == b +c == b \end{itemdecl} \begin{itemdescr} @@ -405,7 +429,7 @@ \pnum \returns -\tcode{equal(a.begin(), a.end(), b.begin(), b.end())} +\tcode{equal(c.begin(), c.end(), b.begin(), b.end())} \begin{note} The algorithm \tcode{equal} is defined in \ref{alg.equal}. @@ -413,7 +437,7 @@ \pnum \complexity -Constant if \tcode{a.size() != b.size()}, linear otherwise. +Constant if \tcode{c.size() != b.size()}, linear otherwise. \pnum \remarks @@ -422,28 +446,28 @@ \indexcont{operator"!=}% \begin{itemdecl} -a != b +c != b \end{itemdecl} \begin{itemdescr} \pnum \effects -Equivalent to \tcode{!(a == b)}. +Equivalent to \tcode{!(c == b)}. \end{itemdescr} \indexcont{swap}% \begin{itemdecl} -a.swap(b) +t.swap(s) \end{itemdecl} \begin{itemdescr} \pnum \result -\keyword{void} +\keyword{void}. \pnum \effects -Exchanges the contents of \tcode{a} and \tcode{b}. +Exchanges the contents of \tcode{t} and \tcode{s}. \pnum \complexity @@ -451,37 +475,18 @@ \end{itemdescr} \begin{itemdecl} -swap(a, b) +swap(t, s) \end{itemdecl} \begin{itemdescr} \pnum \effects -Equivalent to \tcode{a.swap(b)}. -\end{itemdescr} - -\indexcont{operator=}% -\begin{itemdecl} -r = a -\end{itemdecl} - -\begin{itemdescr} -\pnum -\result -\tcode{X\&}. - -\pnum -\ensures -\tcode{r == a}. - -\pnum -\complexity -Linear. +Equivalent to \tcode{t.swap(s)}. \end{itemdescr} \indexcont{size}% \begin{itemdecl} -a.size() +c.size() \end{itemdecl} \begin{itemdescr} @@ -491,7 +496,7 @@ \pnum \returns -\tcode{distance(a.begin(), a.end())}, +\tcode{distance(c.begin(), c.end())}, i.e. the number of elements in the container. \pnum @@ -506,7 +511,7 @@ \indexcont{max_size}% \begin{itemdecl} -a.max_size() +c.max_size() \end{itemdecl} \begin{itemdescr} @@ -525,7 +530,7 @@ \indexcont{empty}% \begin{itemdecl} -a.empty() +c.empty() \end{itemdecl} \begin{itemdescr} @@ -535,7 +540,7 @@ \pnum \returns -\tcode{a.begin() == a.end()} +\tcode{c.begin() == c.end()} \pnum \complexity @@ -543,7 +548,7 @@ \pnum \remarks -If the container is empty, then \tcode{a.empty()} is true. +If the container is empty, then \tcode{c.empty()} is \tcode{true}. \end{itemdescr} \pnum @@ -1821,7 +1826,8 @@ \pnum The following operations are provided for some types of sequence containers but not others. -An implementation shall implement them so as to take amortized constant time. +Operations other than \tcode{prepend_range} and \tcode{append_range} +are implemented so as to take amortized constant time. \begin{itemdecl} a.front() @@ -9160,8 +9166,8 @@ }; // construct/copy/destroy - constexpr vector() : vector(Allocator()) { } - constexpr explicit vector(const Allocator&); + constexpr vector() noexcept(noexcept(Allocator())) : vector(Allocator()) { } + constexpr explicit vector(const Allocator&) noexcept; constexpr explicit vector(size_type n, const Allocator& = Allocator()); constexpr vector(size_type n, const bool& value, const Allocator& = Allocator()); template @@ -9169,13 +9175,15 @@ template<@\exposconcept{container-compatible-range}@ R> constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator()); constexpr vector(const vector& x); - constexpr vector(vector&& x); + constexpr vector(vector&& x) noexcept; constexpr vector(const vector&, const type_identity_t&); constexpr vector(vector&&, const type_identity_t&); constexpr vector(initializer_list, const Allocator& = Allocator()); constexpr ~vector(); constexpr vector& operator=(const vector& x); - constexpr vector& operator=(vector&& x); + constexpr vector& operator=(vector&& x) + noexcept(allocator_traits::propagate_on_container_move_assignment::value || + allocator_traits::is_always_equal::value); constexpr vector& operator=(initializer_list); template constexpr void assign(InputIterator first, InputIterator last); @@ -9237,7 +9245,9 @@ constexpr iterator erase(const_iterator position); constexpr iterator erase(const_iterator first, const_iterator last); - constexpr void swap(vector&); + constexpr void swap(vector&) + noexcept(allocator_traits::propagate_on_container_swap::value || + allocator_traits::is_always_equal::value); static constexpr void swap(reference x, reference y) noexcept; constexpr void flip() noexcept; // flips all bits constexpr void clear() noexcept; @@ -13148,18 +13158,6 @@ defined in \ref{associative.general} may appear in deduction guides for container adaptors. -\pnum -The following exposition-only alias templates may appear in deduction guides -for container adaptors: -\begin{codeblock} -template - using @\exposid{cont-key-type}@ = // \expos - remove_const_t; -template - using @\exposid{cont-mapped-type}@ = // \expos - typename Container::value_type::second_type; -\end{codeblock} - \rSec2[queue.syn]{Header \tcode{} synopsis} \indexheader{queue} @@ -13291,6 +13289,7 @@ \indexheader{flat_set}% \begin{codeblock} +#include // see \ref{compare.syn} #include // see \ref{initializer.list.syn} namespace std { diff --git a/source/diagnostics.tex b/source/diagnostics.tex index b75be934c1..b9398520d0 100644 --- a/source/diagnostics.tex +++ b/source/diagnostics.tex @@ -1122,8 +1122,9 @@ \begin{itemdescr} \pnum -\ensures -\tcode{val_ == 0} and \tcode{cat_ == \&system_category()}. +\effects +Initializes \tcode{val_} with \tcode{0} +and \tcode{cat_} with \tcode{\&system_category()}. \end{itemdescr} \indexlibraryctor{error_code}% @@ -1133,8 +1134,9 @@ \begin{itemdescr} \pnum -\ensures -\tcode{val_ == val} and \tcode{cat_ == \&cat}. +\effects +Initializes \tcode{val_} with \tcode{val} +and \tcode{cat_} with \tcode{\&cat}. \end{itemdescr} \indexlibraryctor{error_code}% @@ -1149,8 +1151,12 @@ \tcode{is_error_code_enum_v} is \tcode{true}. \pnum -\ensures -\tcode{*this == make_error_code(e)}. +\effects +Equivalent to: +\begin{codeblock} +error_code ec = make_error_code(e); +assign(ec.value(), ec.category()); +\end{codeblock} \end{itemdescr} \rSec3[syserr.errcode.modifiers]{Modifiers} @@ -1178,8 +1184,12 @@ \tcode{is_error_code_enum_v} is \tcode{true}. \pnum -\ensures -\tcode{*this == make_error_code(e)}. +\effects +Equivalent to: +\begin{codeblock} +error_code ec = make_error_code(e); +assign(ec.value(), ec.category()); +\end{codeblock} \pnum \returns @@ -1332,8 +1342,9 @@ \begin{itemdescr} \pnum -\ensures -\tcode{val_ == 0} and \tcode{cat_ == \&generic_category()}. +\effects +Initializes \tcode{val_} with \tcode{0} +and \tcode{cat_} with \tcode{\&generic_category()}. \end{itemdescr} \indexlibraryctor{error_condition}% @@ -1343,8 +1354,9 @@ \begin{itemdescr} \pnum -\ensures -\tcode{val_ == val} and \tcode{cat_ == \&cat}. +\effects +Initializes \tcode{val_} with \tcode{val} +and \tcode{cat_} with \tcode{\&cat}. \end{itemdescr} \indexlibraryctor{error_condition}% @@ -1359,8 +1371,12 @@ \tcode{is_error_condition_enum_v} is \tcode{true}. \pnum -\ensures -\tcode{*this == make_error_condition(e)}. +\effects +Equivalent to: +\begin{codeblock} +error_condition ec = make_error_condition(e); +assign(ec.value(), ec.category()); +\end{codeblock} \end{itemdescr} @@ -1389,8 +1405,12 @@ \tcode{is_error_condition_enum_v} is \tcode{true}. \pnum -\ensures -\tcode{*this == make_error_condition(e)}. +\effects +Equivalent to: +\begin{codeblock} +error_condition ec = make_error_condition(e); +assign(ec.value(), ec.category()); +\end{codeblock} \pnum \returns diff --git a/source/iostreams.tex b/source/iostreams.tex index fc56636633..0e5ccd6d64 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -1700,7 +1700,7 @@ 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 +\item \tcode{o} and \tcode{o2} refer to values of type \tcode{streamoff} or \tcode{const streamoff}. \end{itemize} @@ -1725,7 +1725,7 @@ & & \effects Value-initializes the state object. \br - \ensures \tcode{p == P(o)} \\ \rowsep + \ensures \tcode{p == P(o)} is \tcode{true}. \\ \rowsep \tcode{P()} & \tcode{P} & \tcode{P(0)} & @@ -1738,8 +1738,20 @@ \tcode{streamoff} & converts to \tcode{offset} & \tcode{P(O(p)) == p} \\ \rowsep +\tcode{p == q} & + \tcode{bool} & + & + \remarks For any two values \tcode{o} and \tcode{o2}, + if \tcode{p} is obtained + from \tcode{o} converted to \tcode{P} or + from a copy of such \tcode{P} value and + if \tcode{q} is obtained + from \tcode{o2} converted to \tcode{P} or + from a copy of such \tcode{P} value, + then \tcode{p == q} is \tcode{true} + only if \tcode{o == o2} is \tcode{true}. \\ \rowsep \tcode{p != q} & - convertible to \tcode{bool} & + \tcode{bool} & \tcode{!(p == q)} & \\ \rowsep \tcode{p + o} & \tcode{P} & diff --git a/source/iterators.tex b/source/iterators.tex index cf6b9b8374..a0c8cbdb8b 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -342,7 +342,7 @@ concept @\exposconcept{constant-iterator}@ = @\seebelow@; // \expos template<@\libconcept{input_iterator}@ I> using const_iterator = @\seebelow@; // freestanding - template + template<@\libconcept{semiregular}@ S> using const_sentinel = @\seebelow@; // freestanding // \ref{const.iterators.iterator}, class template \tcode{basic_const_iterator} @@ -365,7 +365,7 @@ template<@\libconcept{input_iterator}@ I> constexpr const_iterator make_const_iterator(I it) { return it; } // freestanding - template + template<@\libconcept{semiregular}@ S> constexpr const_sentinel make_const_sentinel(S s) { return s; } // freestanding // \ref{move.iterators}, move iterators and sentinels @@ -402,6 +402,11 @@ template constexpr move_iterator make_move_iterator(Iterator i); // freestanding + template + requires (!@\libconcept{sized_sentinel_for}@) + inline constexpr bool disable_sized_sentinel_for, // freestanding + move_iterator> = true; + template<@\libconcept{semiregular}@ S> class move_sentinel; // freestanding // \ref{iterators.common}, common iterators @@ -941,7 +946,7 @@ template concept @\defexposconcept{cpp17-forward-iterator}@ = @\exposconcept{cpp17-input-iterator}@ && @\libconcept{constructible_from}@ && - is_lvalue_reference_v> && + is_reference_v> && @\libconcept{same_as}@>, typename indirectly_readable_traits::value_type> && requires(I i) { @@ -4194,7 +4199,7 @@ \end{itemdescr} \begin{itemdecl} -template +template<@\libconcept{semiregular}@ S> using @\libglobal{const_sentinel}@ = @\seebelow@; \end{itemdecl} @@ -6466,7 +6471,7 @@ constexpr istream_iterator(); constexpr istream_iterator(default_sentinel_t); istream_iterator(istream_type& s); - istream_iterator(const istream_iterator& x) = default; + constexpr istream_iterator(const istream_iterator& x) noexcept(@\seebelow@); ~istream_iterator() = default; istream_iterator& operator=(const istream_iterator&) = default; @@ -6529,18 +6534,22 @@ \indexlibraryctor{istream_iterator}% \begin{itemdecl} -istream_iterator(const istream_iterator& x) = default; +constexpr istream_iterator(const istream_iterator& x) noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} \pnum -\ensures -\tcode{in_stream == x.in_stream} is \tcode{true}. +\effects +Initializes \tcode{in_stream} with \tcode{x.in_stream} and +initializes \tcode{value} with \tcode{x.value}. \pnum \remarks -If \tcode{is_trivially_copy_constructible_v} is \tcode{true}, -then this constructor is trivial. +An invocation of this constructor may be used in a core constant expression +if and only if the initialization of \tcode{value} from \tcode{x.value} +is a constant subexpression\iref{defns.const.subexpr}. +The exception specification is equivalent to +\tcode{is_nothrow_copy_constructible_v}. \end{itemdescr} \indexlibrarydtor{istream_iterator}% diff --git a/source/lib-intro.tex b/source/lib-intro.tex index f8f7ee7823..c7d62f3ce3 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -1024,8 +1024,9 @@ \end{footnote} \pnum -Whenever an unqualified name other than \tcode{swap} is used -in the specification of a declaration \tcode{D} +Whenever an unqualified name other than +\tcode{swap}, \tcode{make_error_code}, or \tcode{make_error_condition} +is used in the specification of a declaration \tcode{D} in \ref{\firstlibchapter} through \ref{\lastlibchapter} or \ref{depr}, its meaning is established as-if by performing unqualified name lookup\iref{basic.lookup.unqual} @@ -1046,6 +1047,10 @@ The meaning of the unqualified name \tcode{swap} is established in an overload resolution context for swappable values\iref{swappable.requirements}. +The meanings of the unqualified names +\tcode{make_error_code} and \tcode{make_error_condition} are established +as-if by performing argument-dependent lookup\iref{basic.lookup.argdep}. + \rSec3[headers]{Headers} @@ -1391,7 +1396,9 @@ additionally exports declarations in the global namespace corresponding to the declarations in namespace \tcode{std} that are provided by -the \Cpp{} headers for C library facilities~(\tref{headers.cpp.c}). +the \Cpp{} headers for C library facilities~(\tref{headers.cpp.c}), +except the explicitly excluded declarations +described in \ref{support.c.headers.other}. \pnum It is unspecified to which module a declaration in the standard library @@ -2042,11 +2049,11 @@ \begin{itemdescr} \pnum \mandates -\tcode{X::pointer} is convertible to \tcode{X::const_pointer}. +\tcode{XX::pointer} is convertible to \tcode{XX::const_pointer}. \pnum \remarks -Default: \tcode{pointer_traits::rebind} +Default: \tcode{pointer_traits::rebind} \end{itemdescr} \begin{itemdecl} @@ -2057,13 +2064,13 @@ \begin{itemdescr} \pnum \mandates -\tcode{X::pointer} is convertible to \tcode{X::void_pointer}. -\tcode{X::void_pointer} and \tcode{Y::void_pointer} are the same type. +\tcode{XX::pointer} is convertible to \tcode{XX::void_pointer}. +\tcode{XX::void_pointer} and \tcode{YY::void_pointer} are the same type. \pnum \remarks Default: -\tcode{pointer_traits::rebind} +\tcode{pointer_traits::rebind} \end{itemdescr} \begin{itemdecl} @@ -2074,15 +2081,15 @@ \begin{itemdescr} \pnum \mandates -\tcode{X::pointer}, \tcode{X::const_pointer}, and \tcode{X::void_pointer} -are convertible to \tcode{X::const_void_pointer}. -\tcode{X::const_void_pointer} and \tcode{Y::const_void_pointer} +\tcode{XX::pointer}, \tcode{XX::const_pointer}, and \tcode{XX::void_pointer} +are convertible to \tcode{XX::const_void_pointer}. +\tcode{XX::const_void_pointer} and \tcode{YY::const_void_pointer} are the same type. \pnum \remarks Default: -\tcode{pointer_traits::rebind} +\tcode{pointer_traits::rebind} \end{itemdescr} \begin{itemdecl} @@ -2108,7 +2115,7 @@ \pnum \remarks Default: -\tcode{make_unsigned_t} +\tcode{make_unsigned_t} \end{itemdescr} \begin{itemdecl} @@ -2124,7 +2131,7 @@ \pnum \remarks Default: -\tcode{pointer_traits::difference_type} +\tcode{pointer_traits::difference_type} \end{itemdescr} \begin{itemdecl} @@ -2139,7 +2146,7 @@ \pnum \ensures For all \tcode{U} (including \tcode{T}), -\tcode{Y::template rebind::other} is \tcode{X}. +\tcode{YY::rebind_alloc} is \tcode{X}. \pnum \remarks @@ -2225,41 +2232,41 @@ \end{itemdescr} \begin{itemdecl} -static_cast(w) +static_cast(w) \end{itemdecl} \begin{itemdescr} \pnum \result -\tcode{X::pointer} +\tcode{XX::pointer} \pnum \ensures -\tcode{static_cast(w) == p}. +\tcode{static_cast(w) == p}. \end{itemdescr} \begin{itemdecl} -static_cast(x) +static_cast(x) \end{itemdecl} \begin{itemdescr} \pnum \result -\tcode{X::const_pointer} +\tcode{XX::const_pointer} \pnum \ensures -\tcode{static_cast(x) == q}. +\tcode{static_cast(x) == q}. \end{itemdescr} \begin{itemdecl} -pointer_traits::pointer_to(r) +pointer_traits::pointer_to(r) \end{itemdecl} \begin{itemdescr} \pnum \result -\tcode{X::pointer} +\tcode{XX::pointer} \pnum \ensures @@ -2273,7 +2280,7 @@ \begin{itemdescr} \pnum \result -\tcode{X::pointer} +\tcode{XX::pointer} \pnum \effects @@ -2311,7 +2318,7 @@ \begin{itemdescr} \pnum \result -\tcode{X::pointer} +\tcode{XX::pointer} \pnum \effects @@ -2330,11 +2337,11 @@ \begin{itemdescr} \pnum \result -\tcode{allocation_result} +\tcode{allocation_result} \pnum \returns -\tcode{allocation_result\{ptr, count\}} +\tcode{allocation_result\{ptr, count\}} where \tcode{ptr} is memory allocated for an array of \tcode{count} \tcode{T} and such an object is created but array elements are not constructed, such that $\tcode{count} \geq \tcode{n}$. @@ -2392,11 +2399,11 @@ \begin{itemdescr} \pnum \result -\tcode{X::size_type} +\tcode{XX::size_type} \pnum \returns -The largest value that can meaningfully be passed to \tcode{X::allocate()}. +The largest value \tcode{n} that can meaningfully be passed to \tcode{a.allocate(n)}. \pnum \remarks @@ -2453,7 +2460,7 @@ \pnum \returns -\tcode{a == Y::rebind::other(b)}. +\tcode{a == YY::rebind_alloc(b)}. \end{itemdescr} \begin{itemdecl} @@ -2672,43 +2679,43 @@ \pnum An allocator type \tcode{X} shall meet the \oldconcept{CopyConstructible} requirements (\tref{cpp17.copyconstructible}). -The \tcode{X::pointer}, \tcode{X::const_pointer}, \tcode{X::void_pointer}, and -\tcode{X::const_void_pointer} types shall meet the +The \tcode{XX::pointer}, \tcode{XX::const_pointer}, \tcode{XX::void_pointer}, and +\tcode{XX::const_void_pointer} types shall meet the \oldconcept{Nullable\-Pointer} requirements (\tref{cpp17.nullablepointer}). No constructor, comparison operator 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 +these pointer types shall exit via an exception. \tcode{XX::pointer} and \tcode{XX::const_pointer} shall also meet the requirements for a \oldconcept{RandomAccessIterator}\iref{random.access.iterators} and -the additional requirement that, when \tcode{a} and \tcode{(a + n)} are +the additional requirement that, when \tcode{p} and \tcode{(p + n)} are dereferenceable pointer values for some integral value \tcode{n}, \begin{codeblock} -addressof(*(a + n)) == addressof(*a) + n +addressof(*(p + n)) == addressof(*p) + n \end{codeblock} is \tcode{true}. \pnum Let \tcode{x1} and \tcode{x2} denote objects of (possibly different) types -\tcode{X::void_pointer}, \tcode{X::const_void_pointer}, \tcode{X::pointer}, -or \tcode{X::const_pointer}. Then, \tcode{x1} and \tcode{x2} are +\tcode{XX::void_pointer}, \tcode{XX::const_void_pointer}, \tcode{XX::pointer}, +or \tcode{XX::const_pointer}. Then, \tcode{x1} and \tcode{x2} are \defn{equivalently-valued} pointer values, if and only if both \tcode{x1} and \tcode{x2} can be explicitly converted to the two corresponding objects \tcode{px1} and \tcode{px2} -of type \tcode{X::const_pointer}, using a sequence of \keyword{static_cast}s +of type \tcode{XX::const_pointer}, using a sequence of \keyword{static_cast}s using only these four types, and the expression \tcode{px1 == px2} evaluates to \tcode{true}. \pnum -Let \tcode{w1} and \tcode{w2} denote objects of type \tcode{X::void_pointer}. +Let \tcode{w1} and \tcode{w2} denote objects of type \tcode{XX::void_pointer}. Then for the expressions \begin{codeblock} w1 == w2 w1 != w2 \end{codeblock} either or both objects may be replaced by an equivalently-valued object of type -\tcode{X::const_void_pointer} with no change in semantics. +\tcode{XX::const_void_pointer} with no change in semantics. \pnum -Let \tcode{p1} and \tcode{p2} denote objects of type \tcode{X::pointer}. +Let \tcode{p1} and \tcode{p2} denote objects of type \tcode{XX::pointer}. Then for the expressions \begin{codeblock} p1 == p2 @@ -2720,7 +2727,7 @@ p1 - p2 \end{codeblock} either or both objects may be replaced by an equivalently-valued object of type -\tcode{X::const_pointer} with no change in semantics. +\tcode{XX::const_pointer} with no change in semantics. \pnum An allocator may constrain the types on which it can be instantiated and the @@ -2818,6 +2825,10 @@ if it declares an explicit or partial specialization of any standard library variable template, except where explicitly permitted by the specification of that variable template. +\begin{note} +The requirements on an explicit or partial specialization +are stated by each variable template that grants such permission. +\end{note} \pnum The behavior of a \Cpp{} program is undefined if it declares diff --git a/source/memory.tex b/source/memory.tex index 9dc24f3078..7bb0f232dc 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -594,13 +594,7 @@ \begin{codeblock} namespace std { template struct pointer_traits { - using pointer = Ptr; - using element_type = @\seebelow@; - using difference_type = @\seebelow@; - - template using rebind = @\seebelow@; - - static pointer pointer_to(@\seebelow@ r); + @\seebelow@; }; template struct pointer_traits { @@ -617,6 +611,46 @@ \rSec3[pointer.traits.types]{Member types} +\pnum +The definitions in this subclause make use of +the following exposition-only class template and concept: +\begin{codeblock} +template +struct @\exposid{ptr-traits-elem}@ // \expos +{ }; + +template requires requires { typename T::element_type; } +struct @\exposid{ptr-traits-elem}@ +{ using type = typename T::element_type; }; + +template class SomePointer, class T, class... Args> + requires (!requires { typename SomePointer::element_type; }) +struct @\exposid{ptr-traits-elem}@> +{ using type = T; }; + +template + concept @\defexposconcept{has-elem-type}@ = // \expos + requires { typename @\exposid{ptr-traits-elem}@::type; } +\end{codeblock} + +\pnum +If \tcode{Ptr} satisfies \exposconcept{has-elem-type}, +a specialization \tcode{pointer_traits} +generated from the \tcode{pointer_traits} primary template +has the following members +as well as those described in~\ref{pointer.traits.functions}; +otherwise, such a specialization has no members by any of those names. + +\indexlibrarymember{pointer}{pointer_traits}% +\begin{itemdecl} +using pointer = @\seebelow@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\ctype \tcode{Ptr}. +\end{itemdescr} + \indexlibrarymember{element_type}{pointer_traits}% \begin{itemdecl} using element_type = @\seebelow@; @@ -624,12 +658,7 @@ \begin{itemdescr} \pnum -\ctype \tcode{Ptr::element_type} if -the \grammarterm{qualified-id} \tcode{Ptr::element_type} is valid and denotes a -type\iref{temp.deduct}; otherwise, \tcode{T} if -\tcode{Ptr} is a class template instantiation of the form \tcode{SomePointer}, -where \tcode{Args} is zero or more type arguments; otherwise, the specialization is -ill-formed. +\ctype \tcode{typename \exposid{ptr-traits-elem}::type}. \end{itemdescr} \indexlibrarymember{difference_type}{pointer_traits}% @@ -697,6 +726,8 @@ \pnum Specializations of \tcode{pointer_traits} may define the member declared in this subclause to customize the behavior of the standard library. +A specialization generated from the \tcode{pointer_traits} primary template +has no member by this name. \indexlibrarymember{to_address}{pointer_traits}% \begin{itemdecl} @@ -1012,18 +1043,18 @@ \begin{itemdescr} \pnum \constraints -\tcode{T} is not a specialization of \tcode{pair}. +\tcode{remove_cv_t} is not a specialization of \tcode{pair}. \pnum \returns A \tcode{tuple} value determined as follows: \begin{itemize} \item - If \tcode{uses_allocator_v} is \tcode{false} and - \tcode{is_constructible_v} is \tcode{true}, + If \tcode{uses_allocator_v, Alloc>} is \tcode{false} and + \tcode{is_constructible_v} is \tcode{true}, return \tcode{forward_as_tuple(std::forward(args)...)}. \item - Otherwise, if \tcode{uses_allocator_v} is \tcode{true} and + Otherwise, if \tcode{uses_allocator_v, Alloc>} is \tcode{true} and \tcode{is_constructible_v} is \tcode{true}, return @@ -1032,7 +1063,7 @@ allocator_arg, alloc, std::forward(args)...) \end{codeblock} \item - Otherwise, if \tcode{uses_allocator_v} is \tcode{true} and + Otherwise, if \tcode{uses_allocator_v, Alloc>} is \tcode{true} and \tcode{is_constructible_v} is \tcode{true}, return \tcode{forward_as_tuple(std::forward(args)..., alloc)}. \item @@ -1053,13 +1084,17 @@ \end{itemdecl} \begin{itemdescr} +\pnum +Let \tcode{T1} be \tcode{T::first_type}. +Let \tcode{T2} be \tcode{T::second_type}. + \pnum \constraints -\tcode{T} is a specialization of \tcode{pair}. +\tcode{remove_cv_t} is a specialization of \tcode{pair}. \pnum \effects -For \tcode{T} specified as \tcode{pair}, equivalent to: +Equivalent to: \begin{codeblock} return make_tuple( piecewise_construct, @@ -1083,7 +1118,7 @@ \begin{itemdescr} \pnum \constraints -\tcode{T} is a specialization of \tcode{pair}. +\tcode{remove_cv_t} is a specialization of \tcode{pair}. \pnum \effects @@ -1104,7 +1139,7 @@ \begin{itemdescr} \pnum \constraints -\tcode{T} is a specialization of \tcode{pair}. +\tcode{remove_cv_t} is a specialization of \tcode{pair}. \pnum \effects @@ -1129,7 +1164,7 @@ \begin{itemdescr} \pnum \constraints -\tcode{T} is a specialization of \tcode{pair}. +\tcode{remove_cv_t} is a specialization of \tcode{pair}. \pnum \effects @@ -1154,7 +1189,7 @@ \begin{itemdescr} \pnum \constraints -\tcode{T} is a specialization of \tcode{pair}. +\tcode{remove_cv_t} is a specialization of \tcode{pair}. \pnum \effects @@ -1182,7 +1217,7 @@ \pnum \constraints -\tcode{T} is a specialization of \tcode{pair}, and +\tcode{remove_cv_t} is a specialization of \tcode{pair}, and the expression \tcode{\exposid{FUN}(u)} is not well-formed when considered as an unevaluated operand. @@ -5193,9 +5228,9 @@ \item otherwise, \begin{codeblock} +@\exposid{release-statement}@; if (p) { apply([&](auto&&... args) { - @\exposid{release-statement}@; s.reset(static_cast(p), std::forward(args)...); }, std::move(a)); } \end{codeblock} @@ -5205,9 +5240,9 @@ \item otherwise, \begin{codeblock} +@\exposid{release-statement}@; if (p) { apply([&](auto&&... args) { - @\exposid{release-statement}@; s = Smart(static_cast(p), std::forward(args)...); }, std::move(a)); } \end{codeblock} diff --git a/source/ranges.tex b/source/ranges.tex index f676751720..32a887d8d0 100644 --- a/source/ranges.tex +++ b/source/ranges.tex @@ -66,6 +66,8 @@ using sentinel_t = decltype(ranges::end(declval())); // freestanding template<@\libconcept{range}@ R> using const_iterator_t = const_iterator>; // freestanding + template<@\libconcept{range}@ R> + using const_sentinel_t = const_sentinel>; // freestanding template<@\libconcept{range}@ R> using range_difference_t = iter_difference_t>; // freestanding template<@\libconcept{sized_range}@ R> @@ -1726,11 +1728,11 @@ constexpr auto size() requires @\libconcept{forward_range}@ && @\libconcept{sized_sentinel_for}@, iterator_t> { - return ranges::end(@\exposid{derived}@()) - ranges::begin(@\exposid{derived}@()); + return @\exposid{to-unsigned-like}@(ranges::end(@\exposid{derived}@()) - ranges::begin(@\exposid{derived}@())); } constexpr auto size() const requires @\libconcept{forward_range}@ && @\libconcept{sized_sentinel_for}@, iterator_t> { - return ranges::end(@\exposid{derived}@()) - ranges::begin(@\exposid{derived}@()); + return @\exposid{to-unsigned-like}@(ranges::end(@\exposid{derived}@()) - ranges::begin(@\exposid{derived}@())); } constexpr decltype(auto) front() requires @\libconcept{forward_range}@; @@ -2298,7 +2300,8 @@ constructed from the elements of \tcode{r} in the following manner: \begin{itemize} \item -If \tcode{\libconcept{convertible_to}, range_value_t>} +If \tcode{C} does not satisfy \libconcept{input_range} or +\tcode{\libconcept{convertible_to}, range_value_t>} is \tcode{true}: \begin{itemize} \item @@ -2338,7 +2341,7 @@ \begin{codeblock} C c(std::forward(args)...); if constexpr (@\libconcept{sized_range}@ && @\exposid{reservable-container}@) - c.reserve(ranges::size(r)); + c.reserve(static_cast>(ranges::size(r))); ranges::copy(r, @\exposid{container-inserter}@>(c)); \end{codeblock} \end{itemize} @@ -2800,6 +2803,8 @@ \expects \tcode{Bound} denotes \tcode{unreachable_sentinel_t} or \tcode{Bound()} is reachable from \tcode{value}. +When \tcode{W} and \tcode{Bound} model \libconcept{totally_ordered_with}, +then \tcode{bool(value <= Bound())} is \tcode{true}. \pnum \effects @@ -3411,7 +3416,7 @@ // \ref{range.repeat.iterator}, class \tcode{repeat_view::\exposid{iterator}} struct @\exposidnc{iterator}@; // \expos - @\exposidnc{movable-box}@ @\exposid{value_}@ = W(); // \expos, see \ref{range.move.wrap} + @\exposidnc{movable-box}@ @\exposid{value_}@; // \expos, see \ref{range.move.wrap} Bound @\exposid{bound_}@ = Bound(); // \expos public: @@ -4273,7 +4278,7 @@ template constexpr void @\exposid{tuple-for-each}@(F&& f, Tuple&& t) { // \expos apply([&](Ts&&... elements) { - (invoke(f, std::forward(elements)), ...); + (static_cast(invoke(f, std::forward(elements))), ...); }, std::forward(t)); } } @@ -5226,7 +5231,7 @@ \tcode{iterator_traits>::iterator_category}. \begin{itemize} \item -If \tcode{is_lvalue_reference_v\&, range_reference_t<\linebreak\exposid{Base}>>>} +If \tcode{is_reference_v\&, range_reference_t<\exposid{Base}>>>} is \tcode{true}, then \begin{itemize} \item @@ -5804,6 +5809,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\expects +\tcode{count >= 0} is \tcode{true}. + \pnum \effects Initializes \exposid{base_} with \tcode{std::move(base)} and @@ -7101,8 +7110,8 @@ \item If \begin{codeblock} -is_lvalue_reference_v, - iter_reference_t<@\exposid{PatternIter}@>>> +is_reference_v, + iter_reference_t<@\exposid{PatternIter}@>>> \end{codeblock} is \tcode{false}, \tcode{iterator_category} denotes \tcode{input_iterator_tag}. @@ -9987,7 +9996,7 @@ let \tcode{FD} be \tcode{decay_t}. \begin{itemize} \item -If \tcode{\libconcept{copy_constructible} \&\& +If \tcode{\libconcept{move_constructible} \&\& \libconcept{regular_invocable}} is \tcode{false}, or if \tcode{decay_t>} is not an object type, \tcode{views::zip_transform(F, Es...)} is ill-formed. @@ -10171,7 +10180,7 @@ \begin{codeblock} invoke_result_t<@\exposid{maybe-const}@&, range_reference_t<@\exposid{maybe-const}@>...> \end{codeblock} -is not an lvalue reference, +is not a reference, \tcode{iterator_category} denotes \tcode{input_iterator_tag}. \item Otherwise, let \tcode{Cs} denote the pack of types @@ -11321,7 +11330,7 @@ \item If \tcode{invoke_result_t<\exposid{maybe-const}\&, \exposid{REPEAT}(range_reference_t<\exposid{Base}>, N)...>} -is\linebreak not an lvalue reference, +is\linebreak not a reference, \tcode{iterator_category} denotes \tcode{input_iterator_tag}. \item Otherwise, let \tcode{C} denote the type @@ -13299,7 +13308,7 @@ requires @\libconcept{view}@ && is_object_v class chunk_by_view : public view_interface> { V @\exposid{base_}@ = V(); // \expos - @\exposidnc{movable-box}@ @\exposid{pred_}@ = Pred(); // \expos + @\exposidnc{movable-box}@ @\exposid{pred_}@; // \expos // \ref{range.chunk.by.iter}, class \tcode{chunk_by_view::\exposid{iterator}} class @\exposidnc{iterator}@; // \expos @@ -14339,7 +14348,9 @@ \pnum \effects Equivalent to: -\tcode{return \exposid{iterator}(\exposid{tuple-transform}(ranges::begin, \exposid{bases_}));} +\begin{codeblock} +return @\exposid{iterator}@(*this, @\exposid{tuple-transform}@(ranges::begin, @\exposid{bases_}@)); +\end{codeblock} \end{itemdescr} \begin{itemdecl} @@ -14351,7 +14362,9 @@ \pnum \effects Equivalent to: -\tcode{return \exposid{iterator}(\exposid{tuple-transform}(ranges::begin, \exposid{bases_}));} +\begin{codeblock} +return @\exposid{iterator}@(*this, @\exposid{tuple-transform}@(ranges::begin, @\exposid{bases_}@)); +\end{codeblock} \end{itemdescr} \begin{itemdecl} @@ -14385,7 +14398,7 @@ \effects Equivalent to: \begin{codeblock} -@\exposid{iterator}@<@\exposid{is-const}@> it(@\exposid{tuple-transform}@( +@\exposid{iterator}@<@\exposid{is-const}@> it(*this, @\exposid{tuple-transform}@( [](auto& rng){ return @\exposid{begin-or-first-end}@(rng); }, @\exposid{bases_}@)); return it; \end{codeblock} @@ -14488,9 +14501,9 @@ friend constexpr difference_type operator-(const @\exposid{iterator}@& x, const @\exposid{iterator}@& y) requires @\exposconcept{cartesian-is-sized-sentinel}@; - friend constexpr difference_type operator-(@\exposid{iterator}@ i, default_sentinel_t) + friend constexpr difference_type operator-(const @\exposid{iterator}@& i, default_sentinel_t) requires @\exposconcept{cartesian-is-sized-sentinel}@; - friend constexpr difference_type operator-(default_sentinel_t, @\exposid{iterator}@ i) + friend constexpr difference_type operator-(default_sentinel_t, const @\exposid{iterator}@& i) requires @\exposconcept{cartesian-is-sized-sentinel}@; friend constexpr auto iter_move(const @\exposid{iterator}@& i) noexcept(@\seebelow@); @@ -14500,21 +14513,22 @@ @\libconcept{indirectly_swappable}@>>); private: - @\exposid{maybe-const}@* @\exposid{parent_}@ = nullptr; // \expos + using @\exposidnc{Parent}@ = @\exposidnc{maybe-const}@; // \expos + @\exposidnc{Parent}@* @\exposidnc{parent_}@ = nullptr; // \expos tuple>, - iterator_t<@\exposid{maybe-const}@>...> @\exposid{current_}@; // \expos + iterator_t<@\exposidnc{maybe-const}@>...> @\exposidnc{current_}@; // \expos template - constexpr void @\exposid{next}@(); // \expos + constexpr void @\exposidnc{next}@(); // \expos template - constexpr void @\exposid{prev}@(); // \expos + constexpr void @\exposidnc{prev}@(); // \expos template - constexpr difference_type @\exposid{distance-from}@(Tuple t); // \expos + constexpr difference_type @\exposidnc{distance-from}@(const Tuple& t) const; // \expos - constexpr explicit @\exposid{iterator}@(tuple>, - iterator_t<@\exposid{maybe-const}@>...> current); // \expos + constexpr @\exposid{iterator}@(@\exposid{Parent}@& parent, tuple>, + iterator_t<@\exposidnc{maybe-const}@>...> current); // \expos }; } \end{codeblock} @@ -14597,7 +14611,7 @@ \begin{itemdecl} template - constexpr difference_type @\exposid{distance-from}@(Tuple t); + constexpr difference_type @\exposid{distance-from}@(const Tuple& t) const; \end{itemdecl} \begin{itemdescr} @@ -14608,7 +14622,7 @@ $\exposid{scaled-size}(N)$ be the product of \tcode{static_cast(ranges::size(std::get<\brk{}$N$>(\exposid{parent_}->\exposid{bases_})))} and $\exposid{scaled-size}(N+1)$ -if $N < \tcode{sizeof...(Vs)}$, otherwise \tcode{static_cast(1)}; +if $N \le \tcode{sizeof...(Vs)}$, otherwise \tcode{static_cast(1)}; \item $\exposid{scaled-distance}(N)$ be the product of \tcode{static_cast(std::get<$N$>(\exposid{cur\-rent_}) - std::get<$N$>(t))} and $\exposid{scaled-size}(N+1)$; and @@ -14627,14 +14641,16 @@ \end{itemdescr} \begin{itemdecl} -constexpr explicit @\exposid{iterator}@(tuple>, +constexpr @\exposid{iterator}@(@\exposid{Parent}@& parent, tuple>, iterator_t<@\exposid{maybe-const}@>...> current); \end{itemdecl} \begin{itemdescr} \pnum \effects -Initializes \exposid{current_} with \tcode{std::move(current)}. +Initializes +\exposid{parent_} with \tcode{addressof(parent)} and +\exposid{current_} with \tcode{std::move(current)}. \end{itemdescr} \begin{itemdecl} @@ -14646,7 +14662,9 @@ \begin{itemdescr} \pnum \effects -Initializes \exposid{current_} with \tcode{std::move(i.\exposid{current_})}. +Initializes +\exposid{parent_} with \tcode{i.\exposid{parent_}} and +\exposid{current_} with \tcode{std::move(i.\exposid{current_})}. \end{itemdescr} \begin{itemdecl} @@ -14878,7 +14896,7 @@ \end{itemdescr} \begin{itemdecl} -friend constexpr difference_type operator-(@\exposid{iterator}@ i, default_sentinel_t) +friend constexpr difference_type operator-(const @\exposid{iterator}@& i, default_sentinel_t) requires @\exposconcept{cartesian-is-sized-sentinel}@; \end{itemdecl} @@ -14902,7 +14920,7 @@ \end{itemdescr} \begin{itemdecl} -friend constexpr difference_type operator-(default_sentinel_t s, @\exposid{iterator}@ i) +friend constexpr difference_type operator-(default_sentinel_t s, const @\exposid{iterator}@& i) requires @\exposconcept{cartesian-is-sized-sentinel}@; \end{itemdecl} @@ -15510,7 +15528,7 @@ @\exposid{iterator}@& operator++(); void operator++(int); - friend bool operator==(@\exposid{iterator}@ i, default_sentinel_t); + friend bool operator==(const @\exposid{iterator}@& i, default_sentinel_t); private: coroutine_handle @\exposid{coroutine_}@; // \expos @@ -15598,7 +15616,7 @@ \indexlibrarymember{operator==}{generator::\exposid{iterator}}% \begin{itemdecl} -friend bool operator==(@\exposid{iterator}@ i, default_sentinel_t); +friend bool operator==(const @\exposid{iterator}@& i, default_sentinel_t); \end{itemdecl} \begin{itemdescr} diff --git a/source/support.tex b/source/support.tex index 3cba171dd8..f7e00951ff 100644 --- a/source/support.tex +++ b/source/support.tex @@ -591,7 +591,7 @@ #define @\defnlibxname{cpp_lib_clamp}@ 201603L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_complex_udls}@ 201309L // also in \libheader{complex} #define @\defnlibxname{cpp_lib_concepts}@ 202207L // also in \libheader{concepts}, \libheader{compare} -#define @\defnlibxname{cpp_lib_constexpr_algorithms}@ 201806L // also in \libheader{algorithm} +#define @\defnlibxname{cpp_lib_constexpr_algorithms}@ 201806L // also in \libheader{algorithm}, \libheader{utility} #define @\defnlibxname{cpp_lib_constexpr_bitset}@ 202202L // also in \libheader{bitset} #define @\defnlibxname{cpp_lib_constexpr_charconv}@ 202207L // also in \libheader{charconv} #define @\defnlibxname{cpp_lib_constexpr_cmath}@ 202202L // also in \libheader{cmath}, \libheader{cstdlib} @@ -623,7 +623,9 @@ #define @\defnlibxname{cpp_lib_filesystem}@ 201703L // also in \libheader{filesystem} #define @\defnlibxname{cpp_lib_find_last}@ 202207L // also in \libheader{algorithm} #define @\defnlibxname{cpp_lib_flat_map}@ 202207L // also in \libheader{flat_map} +#define @\defnlibxname{cpp_lib_flat_set}@ 202207L // also in \libheader{flat_set} #define @\defnlibxname{cpp_lib_format}@ 202207L // also in \libheader{format} +#define @\defnlibxname{cpp_lib_format_ranges}@ 202207L // also in \libheader{format} #define @\defnlibxname{cpp_lib_forward_like}@ 202207L // also in \libheader{utility} #define @\defnlibxname{cpp_lib_gcd_lcm}@ 201606L // also in \libheader{numeric} #define @\defnlibxname{cpp_lib_generator}@ 202207L // also in \libheader{generator} @@ -6156,6 +6158,7 @@ header is placed within the global namespace scope, except for the functions described in \ref{sf.cmath}, +the \tcode{std::lerp} function overloads\iref{c.math.lerp}, the declaration of \tcode{std::byte}\iref{cstddef.syn}, and the functions and function templates described in \ref{support.types.byteops}. It is unspecified whether these names are first declared or defined within diff --git a/source/threads.tex b/source/threads.tex index 55dbadb167..c40a7c6511 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -1756,19 +1756,18 @@ \begin{itemdescr} \pnum \effects -If \tcode{joinable()} is \tcode{true}, -calls \tcode{request_stop()} and then \tcode{join()}. -Assigns the state of \tcode{x} to \tcode{*this} +If \tcode{\&x == this} is \tcode{true}, there are no effects. +Otherwise, if \tcode{joinable()} is \tcode{true}, +calls \tcode{request_stop()} and then \tcode{join()}, +then assigns the state of \tcode{x} to \tcode{*this} and sets \tcode{x} to a default constructed state. \pnum \ensures -\tcode{x.get_id() == id()} -and \tcode{get_id()} returns the value of \tcode{x.get_id()} +\tcode{get_id()} returns the value of \tcode{x.get_id()} prior to the assignment. \tcode{ssource} has the value of \tcode{x.ssource} -prior to the assignment -and \tcode{x.ssource.stop_possible()} is \tcode{false}. +prior to the assignment. \pnum \returns @@ -2222,24 +2221,25 @@ memory_order) noexcept; template - void atomic_wait(const volatile atomic*, typename atomic::value_type); // freestanding + void atomic_wait(const volatile atomic*, // freestanding + typename atomic::value_type) noexcept; template - void atomic_wait(const atomic*, typename atomic::value_type); // freestanding + void atomic_wait(const atomic*, typename atomic::value_type) noexcept; // freestanding template void atomic_wait_explicit(const volatile atomic*, // freestanding typename atomic::value_type, - memory_order); + memory_order) noexcept; template void atomic_wait_explicit(const atomic*, typename atomic::value_type, // freestanding - memory_order); + memory_order) noexcept; template - void atomic_notify_one(volatile atomic*); // freestanding + void atomic_notify_one(volatile atomic*) noexcept; // freestanding template - void atomic_notify_one(atomic*); // freestanding + void atomic_notify_one(atomic*) noexcept; // freestanding template - void atomic_notify_all(volatile atomic*); // freestanding + void atomic_notify_all(volatile atomic*) noexcept; // freestanding template - void atomic_notify_all(atomic*); // freestanding + void atomic_notify_all(atomic*) noexcept; // freestanding // \ref{atomics.alias}, type aliases using atomic_bool = atomic; // freestanding @@ -10576,6 +10576,8 @@ \begin{itemdescr} \pnum \effects +If \tcode{addressof(rhs) == this} is \tcode{true}, there are no effects. +Otherwise: \begin{itemize} \item Releases any shared state\iref{futures.state}. @@ -10591,6 +10593,7 @@ assignment. \item +If \tcode{addressof(rhs) == this} is \tcode{false}, \tcode{rhs.valid() == false}. \end{itemize} \end{itemdescr} @@ -10897,6 +10900,8 @@ \begin{itemdescr} \pnum \effects +If \tcode{addressof(rhs) == this} is \tcode{true}, there are no effects. +Otherwise: \begin{itemize} \item Releases any shared state\iref{futures.state}; @@ -10912,6 +10917,7 @@ the assignment. \item +If \tcode{addressof(rhs) == this} is \tcode{false}, \tcode{rhs.valid() == false}. \end{itemize} \end{itemdescr} @@ -10924,6 +10930,8 @@ \begin{itemdescr} \pnum \effects +If \tcode{addressof(rhs) == this} is \tcode{true}, there are no effects. +Otherwise: \begin{itemize} \item Releases any shared state\iref{futures.state}; diff --git a/source/time.tex b/source/time.tex index 1f97197252..f45b163df2 100644 --- a/source/time.tex +++ b/source/time.tex @@ -10963,7 +10963,7 @@ : formatter, charT> { template typename FormatContext::iterator - format(const chrono::zoned_time& tp, FormatContext& ctx); + format(const chrono::zoned_time& tp, FormatContext& ctx) const; }; \end{codeblock} @@ -10971,7 +10971,7 @@ \begin{itemdecl} template typename FormatContext::iterator - format(const chrono::zoned_time& tp, FormatContext& ctx); + format(const chrono::zoned_time& tp, FormatContext& ctx) const; \end{itemdecl} \begin{itemdescr} diff --git a/source/utilities.tex b/source/utilities.tex index 30f814b68d..f815f22eab 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -367,6 +367,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\mandates +\tcode{T} is a referenceable type\iref{defns.referenceable}. + \pnum \begin{itemize} \item @@ -3131,9 +3135,9 @@ class optional; template - constexpr bool @\exposid{is-optional}@ = false; // \expos - template - constexpr bool @\exposid{is-optional}@> = true; // \expos + concept @\defexposconcept{is-derived-from-optional}@ = requires(const T& t) { // \expos + [](const optional&){ }(t); + }; // \ref{optional.nullopt}, no-value state indicator struct nullopt_t{@\seebelow@}; @@ -3177,7 +3181,8 @@ template constexpr bool operator<=(const T&, const optional&); template constexpr bool operator>=(const optional&, const U&); template constexpr bool operator>=(const T&, const optional&); - template requires (!@\exposid{is-optional}@) && @\libconcept{three_way_comparable_with}@ + template + requires (!@\exposconcept{is-derived-from-optional}@) && @\libconcept{three_way_comparable_with}@ constexpr compare_three_way_result_t operator<=>(const optional&, const U&); @@ -4748,7 +4753,8 @@ \indexlibrarymember{operator<=>}{optional}% \begin{itemdecl} -template requires (!@\exposid{is-optional}@) && @\libconcept{three_way_comparable_with}@ +template + requires (!@\exposconcept{is-derived-from-optional}@) && @\libconcept{three_way_comparable_with}@ constexpr compare_three_way_result_t operator<=>(const optional& x, const U& v); \end{itemdecl} @@ -7237,9 +7243,9 @@ constexpr explicit(@\seebelow@) expected(U&& v); template - constexpr expected(const unexpected&); + constexpr explicit(@\seebelow@) expected(const unexpected&); template - constexpr expected(unexpected&&); + constexpr explicit(@\seebelow@) expected(unexpected&&); template constexpr explicit expected(in_place_t, Args&&...); @@ -8312,9 +8318,9 @@ constexpr explicit(@\seebelow@) expected(expected&&); template - constexpr expected(const unexpected&); + constexpr explicit(@\seebelow@) expected(const unexpected&); template - constexpr expected(unexpected&&); + constexpr explicit(@\seebelow@) expected(unexpected&&); constexpr explicit expected(in_place_t) noexcept; template @@ -10182,7 +10188,8 @@ // \ref{refwrap.invoke}, invocation template - constexpr invoke_result_t operator()(ArgTypes&&...) const; + constexpr invoke_result_t operator()(ArgTypes&&...) const + noexcept(is_nothrow_invocable_v); }; template @@ -10291,7 +10298,7 @@ \begin{itemdecl} template constexpr invoke_result_t - operator()(ArgTypes&&... args) const; + operator()(ArgTypes&&... args) const noexcept(is_nothrow_invocable_v); \end{itemdecl} \begin{itemdescr} @@ -15034,7 +15041,8 @@ \tcode{Out}, and formatting argument type \tcode{T}, in \tref{formatter.basic} and \tref{formatter}: \begin{itemize} -\item \tcode{f} is a value of type \tcode{F}, +\item \tcode{f} is a value of type (possibly \tcode{const}) \tcode{F}, +\item \tcode{g} is an lvalue of type \tcode{F}, \item \tcode{u} is an lvalue of type \tcode{T}, \item \tcode{t} is a value of a type convertible to (possibly const) \tcode{T}, \item \tcode{PC} is \tcode{basic_format_parse_context}, @@ -15054,7 +15062,7 @@ {p{1.2in}p{1in}p{2.9in}} \topline \hdstyle{Expression} & \hdstyle{Return type} & \hdstyle{Requirement} \\ \capsep -\tcode{f.parse(pc)} & +\tcode{g.parse(pc)} & \tcode{PC::iterator} & Parses \fmtgrammarterm{format-spec}\iref{format.string} for type \tcode{T} @@ -15252,7 +15260,7 @@ const char* color_names[] = { "red", "green", "blue" }; template<> struct std::formatter : std::formatter { - auto format(color c, format_context& ctx) { + auto format(color c, format_context& ctx) const { return formatter::format(color_names[c], ctx); } }; @@ -15685,7 +15693,7 @@ } // Formats an \tcode{S} with width given by the argument \tcode{width_arg_id}. - auto format(S s, format_context& ctx) { + auto format(S s, format_context& ctx) const { int width = visit_format_arg([](auto value) -> int { if constexpr (!is_integral_v) throw format_error("width is not integral");