diff --git a/source/algorithms.tex b/source/algorithms.tex index 0a265e924b..6df42bdf65 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -222,13 +222,13 @@ If \range{a}{b} denotes a range, the semantics of \tcode{b - a} in these cases are the same as those of \begin{codeblock} -iter_difference_t> n = 0; +iter_difference_t n = 0; for (auto tmp = a; tmp != b; ++tmp) ++n; return n; \end{codeblock} and if \range{b}{a} denotes a range, the same as those of \begin{codeblock} -iter_difference_t> n = 0; +iter_difference_t n = 0; for (auto tmp = b; tmp != a; ++tmp) --n; return n; \end{codeblock} diff --git a/source/iterators.tex b/source/iterators.tex index d84e116f0f..8bad7ba9b2 100644 --- a/source/iterators.tex +++ b/source/iterators.tex @@ -50,8 +50,8 @@ template using iter_difference_t = @\seebelow@; - // \ref{readable.traits}, readable traits - template struct readable_traits; + // \ref{readable.traits}, indirectly readable traits + template struct indirectly_readable_traits; template using iter_value_t = @\seebelow@; @@ -59,7 +59,7 @@ template struct iterator_traits; template requires is_object_v struct iterator_traits; - template<@\placeholder{dereferenceable}@ T> + template<@\exposconcept{dereferenceable}@ T> using iter_reference_t = decltype(*declval()); namespace ranges { @@ -73,7 +73,7 @@ } } - template<@\placeholder{dereferenceable}@ T> + template<@\exposconcept{dereferenceable}@ T> requires requires(T& t) { { ranges::iter_move(t) } -> @\placeholder{can-reference}@; } @@ -81,17 +81,17 @@ = decltype(ranges::iter_move(declval())); // \ref{iterator.concepts}, iterator concepts - // \ref{iterator.concept.readable}, concept \libconcept{readable} + // \ref{iterator.concept.readable}, concept \libconcept{indirectly_readable} template - concept readable = @\seebelow@; + concept indirectly_readable = @\seebelow@; - template + template using iter_common_reference_t = common_reference_t, iter_value_t&>; - // \ref{iterator.concept.writable}, concept \libconcept{writable} + // \ref{iterator.concept.writable}, concept \libconcept{indirectly_writable} template - concept writable = @\seebelow@; + concept indirectly_writable = @\seebelow@; // \ref{iterator.concept.winc}, concept \libconcept{weakly_incrementable} template @@ -161,11 +161,11 @@ concept indirect_strict_weak_order = @\seebelow@; template - requires (readable && ...) && invocable...> + requires (indirectly_readable && ...) && invocable...> using indirect_result_t = invoke_result_t...>; // \ref{projected}, projected - template Proj> + template Proj> struct projected; template @@ -474,7 +474,7 @@ \term{value type} of the iterator. An output iterator \tcode{i} has a non-empty set of types that are -\defn{writable} to the iterator; +\libconcept{indirectly_writable} to the iterator; for each such type \tcode{T}, the expression \tcode{*i = o} is valid where \tcode{o} is a value of type \tcode{T}. For every iterator type @@ -715,34 +715,37 @@ \indexlibraryglobal{iter_difference_t}% \pnum +Let $R_\tcode{I}$ be \tcode{remove_cvref_t}. The type \tcode{iter_difference_t} denotes \begin{itemize} \item -\tcode{incrementable_traits::difference_type} -if \tcode{iterator_traits} names a specialization +\tcode{incrementable_traits<$R_\tcode{I}$>::difference_type} +if \tcode{iterator_traits<$R_\tcode{I}$>} names a specialization generated from the primary template, and \item -\tcode{iterator_traits::\brk{}difference_type} otherwise. +\tcode{iterator_traits<$R_\tcode{I}$>::difference_type} otherwise. \end{itemize} \pnum Users may specialize \tcode{incrementable_traits} on program-defined types. -\rSec3[readable.traits]{Readable traits} +\rSec3[readable.traits]{Indirectly readable traits} \pnum -To implement algorithms only in terms of readable types, it is often necessary -to determine the value type that corresponds to a particular readable type. +To implement algorithms only in terms of indirectly readable types, +it is often necessary +to determine the value type that corresponds to +a particular indirectly readable type. Accordingly, it is required that if \tcode{R} is the name of a type that -models the \libconcept{readable} concept\iref{iterator.concept.readable}, +models the \libconcept{indirectly_readable} concept\iref{iterator.concept.readable}, the type \begin{codeblock} iter_value_t \end{codeblock} -be defined as the readable type's value type. +be defined as the indirectly readable type's value type. -\indexlibraryglobal{readable_traits}% +\indexlibraryglobal{indirectly_readable_traits}% \begin{codeblock} template struct @\placeholder{cond-value-type}@ { }; // \expos template @@ -751,30 +754,30 @@ using value_type = remove_cv_t; }; -template struct readable_traits { }; +template struct indirectly_readable_traits { }; template -struct readable_traits +struct indirectly_readable_traits : @\placeholder{cond-value-type}@ { }; template requires is_array_v -struct readable_traits { +struct indirectly_readable_traits { using value_type = remove_cv_t>; }; template -struct readable_traits - : readable_traits { }; +struct indirectly_readable_traits + : indirectly_readable_traits { }; template requires requires { typename T::value_type; } -struct readable_traits +struct indirectly_readable_traits : @\placeholder{cond-value-type}@ { }; template requires requires { typename T::element_type; } -struct readable_traits +struct indirectly_readable_traits : @\placeholder{cond-value-type}@ { }; template using iter_value_t = @\seebelow@; @@ -782,33 +785,35 @@ \indexlibraryglobal{iter_value_t}% \pnum +Let $R_\tcode{I}$ be \tcode{remove_cvref_t}. The type \tcode{iter_value_t} denotes \begin{itemize} \item -\tcode{readable_traits::value_type} -if \tcode{iterator_traits} names a specialization +\tcode{indirectly_readable_traits<$R_\tcode{I}$>::value_type} +if \tcode{iterator_traits<$R_\tcode{I}$>} names a specialization generated from the primary template, and \item -\tcode{iterator_traits::value_type} otherwise. +\tcode{iterator_traits<$R_\tcode{I}$>::value_type} otherwise. \end{itemize} \pnum -Class template \tcode{readable_traits} may be specialized +Class template \tcode{indirectly_readable_traits} may be specialized on program-defined types. \pnum \begin{note} Some legacy output iterators define a nested type named \tcode{value_type} -that is an alias for \tcode{void}. These types are not \tcode{readable} +that is an alias for \tcode{void}. +These types are not \tcode{indirectly_readable} and have no associated value types. \end{note} \pnum \begin{note} -Smart pointers like \tcode{shared_ptr} are \tcode{readable} and +Smart pointers like \tcode{shared_ptr} are \tcode{indirectly_readable} and have an associated value type, but a smart pointer like \tcode{shared_ptr} -is not \tcode{readable} and has no associated value type. +is not \tcode{indirectly_readable} and has no associated value type. \end{note} \rSec3[iterator.traits]{Iterator traits} @@ -870,11 +875,11 @@ concept @\placeholder{cpp17-input-iterator}@ = @\placeholder{cpp17-iterator}@ && equality_comparable && requires(I i) { typename incrementable_traits::difference_type; - typename readable_traits::value_type; + typename indirectly_readable_traits::value_type; typename common_reference_t&&, - typename readable_traits::value_type&>; + typename indirectly_readable_traits::value_type&>; typename common_reference_t::value_type&>; + typename indirectly_readable_traits::value_type&>; requires signed_integral::difference_type>; }; @@ -882,7 +887,8 @@ concept @\placeholder{cpp17-forward-iterator}@ = @\placeholder{cpp17-input-iterator}@ && constructible_from && is_lvalue_reference_v> && - same_as>, typename readable_traits::value_type> && + same_as>, + typename indirectly_readable_traits::value_type> && requires(I i) { { i++ } -> convertible_to; { *i++ } -> same_as>; @@ -941,7 +947,7 @@ publicly accessible members: \begin{codeblock} using iterator_category = @\seebelow@; -using value_type = typename readable_traits::value_type; +using value_type = typename indirectly_readable_traits::value_type; using difference_type = typename incrementable_traits::difference_type; using pointer = @\seebelow@; using reference = @\seebelow@; @@ -1091,9 +1097,9 @@ Let \tcode{\placeholder{iter-exchange-move}} be the exposition-only function: \begin{itemdecl} template - constexpr iter_value_t> @\placeholdernc{iter-exchange-move}@(X&& x, Y&& y) - noexcept(noexcept(iter_value_t>(iter_move(x))) && - noexcept(*x = iter_move(y))); + constexpr iter_value_t @\placeholdernc{iter-exchange-move}@(X&& x, Y&& y) + noexcept(noexcept(iter_value_t(iter_move(x))) && + noexcept(*x = iter_move(y))); \end{itemdecl} \begin{itemdescr} @@ -1101,7 +1107,7 @@ \effects Equivalent to: \begin{codeblock} -iter_value_t> old_value(iter_move(x)); +iter_value_t old_value(iter_move(x)); *x = iter_move(y); return old_value; \end{codeblock} @@ -1123,7 +1129,7 @@ ill-formed with no diagnostic required. \item Otherwise, if the types of \tcode{E1} and \tcode{E2} each model -\tcode{readable}, and if the reference types of \tcode{E1} and \tcode{E2} +\tcode{indirectly_readable}, and if the reference types of \tcode{E1} and \tcode{E2} model \libconcept{swappable_with}\iref{concept.swappable}, then \tcode{ranges::swap(*E1, *E2)}. @@ -1190,43 +1196,51 @@ and \tcode{\placeholder{ITER_CONCEPT}(I)} denotes \tcode{random_access_iterator_tag}. \end{example} -\rSec3[iterator.concept.readable]{Concept \cname{readable}} +\rSec3[iterator.concept.readable]{Concept \cname{indirectly_readable}} \pnum -Types that are readable by applying \tcode{operator*} -model the \libconcept{readable} concept, including +Types that are indirectly readable by applying \tcode{operator*} +model the \libconcept{indirectly_readable} concept, including pointers, smart pointers, and iterators. \begin{codeblock} template - concept @\deflibconcept{readable}@ = - requires { + concept @\defexposconcept{indirectly-readable-impl}@ = + requires(const In in) { typename iter_value_t; typename iter_reference_t; typename iter_rvalue_reference_t; + { *in } -> same_as>; + { iter_move(in) } -> same_as>; } && common_reference_with&&, iter_value_t&> && common_reference_with&&, iter_rvalue_reference_t&&> && common_reference_with&&, const iter_value_t&>; \end{codeblock} +\begin{codeblock} +template + concept @\deflibconcept{indirectly_readable}@ = + @\placeholdernc{indirectly-readable-impl}@>; +\end{codeblock} + \pnum -Given a value \tcode{i} of type \tcode{I}, \tcode{I} models \libconcept{readable} +Given a value \tcode{i} of type \tcode{I}, \tcode{I} models \libconcept{indirectly_readable} only if the expression \tcode{*i} is equality-preserving. \begin{note} The expression \tcode{*i} is indirectly required to be valid via the -exposition-only \placeholder{dereferenceable} concept\iref{iterator.synopsis}. +exposition-only \exposconcept{dereferenceable} concept\iref{iterator.synopsis}. \end{note} -\rSec3[iterator.concept.writable]{Concept \cname{writable}} +\rSec3[iterator.concept.writable]{Concept \cname{indirectly_writable}} \pnum -The \libconcept{writable} concept specifies the requirements for writing a value -into an iterator's referenced object. +The \libconcept{indirectly_writable} concept specifies the requirements +for writing a value into an iterator's referenced object. \begin{codeblock} template - concept @\deflibconcept{writable}@ = + concept @\deflibconcept{indirectly_writable}@ = requires(Out&& o, T&& t) { *o = std::forward(t); // not required to be equality-preserving *std::forward(o) = std::forward(t); // not required to be equality-preserving @@ -1240,10 +1254,10 @@ \pnum Let \tcode{E} be an expression such that \tcode{decltype((E))} is \tcode{T}, and let \tcode{o} be a dereferenceable object of type \tcode{Out}. -\tcode{Out} and \tcode{T} model \tcode{\libconcept{writable}} only if +\tcode{Out} and \tcode{T} model \tcode{\libconcept{indirectly_writable}} only if \begin{itemize} \item If \tcode{Out} and \tcode{T} model - \tcode{readable \&\& same_as, decay_t{>}}, + \tcode{indirectly_readable \&\& same_as, decay_t{>}}, then \tcode{*o} after any above assignment is equal to the value of \tcode{E} before the assignment. \end{itemize} @@ -1258,16 +1272,16 @@ \pnum \begin{note} The only valid use of an \tcode{operator*} is on the left side of the assignment statement. -Assignment through the same value of the writable type happens only once. +Assignment through the same value of the indirectly writable type happens only once. \end{note} \pnum \begin{note} -\tcode{writable} has the awkward \tcode{const_cast} expressions to reject +\tcode{indirectly_writable} has the awkward \tcode{const_cast} expressions to reject iterators with prvalue non-proxy reference types that permit rvalue assignment but do not also permit \tcode{const} rvalue assignment. Consequently, an iterator type \tcode{I} that returns \tcode{std::string} -by value does not model \tcode{\libconcept{writable}}. +by value does not model \tcode{\libconcept{indirectly_writable}}. \end{note} \rSec3[iterator.concept.winc]{Concept \cname{weakly_incrementable}} @@ -1599,8 +1613,8 @@ \pnum The \libconcept{input_iterator} concept defines requirements for a type whose referenced values can be read (from the requirement for -\libconcept{readable}\iref{iterator.concept.readable}) and which can be both pre- and -post-incremented. +\libconcept{indirectly_readable}\iref{iterator.concept.readable}) +and which can be both pre- and post-incremented. \begin{note} Unlike the \oldconcept{InputIterator} requirements\iref{input.iterators}, the \libconcept{input_iterator} concept does not need @@ -1611,7 +1625,7 @@ template concept @\deflibconcept{input_iterator}@ = input_or_output_iterator && - readable && + indirectly_readable && requires { typename @\placeholdernc{ITER_CONCEPT}@(I); } && derived_from<@\placeholdernc{ITER_CONCEPT}@(I), input_iterator_tag>; \end{codeblock} @@ -1621,7 +1635,8 @@ \pnum The \libconcept{output_iterator} concept defines requirements for a type that can be used to write values (from the requirement for -\libconcept{writable}\iref{iterator.concept.writable}) and which can be both pre- and post-incremented. +\libconcept{indirectly_writable}\iref{iterator.concept.writable}) +and which can be both pre- and post-incremented. \begin{note} Output iterators are not required to model \libconcept{equality_comparable}. \end{note} @@ -1630,7 +1645,7 @@ template concept @\deflibconcept{output_iterator}@ = input_or_output_iterator && - writable && + indirectly_writable && requires(I i, T&& t) { *i++ = std::forward(t); // not required to be equality-preserving }; @@ -2302,7 +2317,7 @@ namespace std { template concept @\deflibconcept{indirectly_unary_invocable}@ = - readable && + indirectly_readable && copy_constructible && invocable&> && invocable> && @@ -2313,7 +2328,7 @@ template concept @\deflibconcept{indirectly_regular_unary_invocable}@ = - readable && + indirectly_readable && copy_constructible && regular_invocable&> && regular_invocable> && @@ -2324,7 +2339,7 @@ template concept @\deflibconcept{indirect_unary_predicate}@ = - readable && + indirectly_readable && copy_constructible && predicate&> && predicate> && @@ -2332,7 +2347,7 @@ template concept @\deflibconcept{indirect_binary_predicate}@ = - readable && readable && + indirectly_readable && indirectly_readable && copy_constructible && predicate&, iter_value_t&> && predicate&, iter_reference_t> && @@ -2342,7 +2357,7 @@ template concept @\deflibconcept{indirect_equivalence_relation}@ = - readable && readable && + indirectly_readable && indirectly_readable && copy_constructible && equivalence_relation&, iter_value_t&> && equivalence_relation&, iter_reference_t> && @@ -2352,7 +2367,7 @@ template concept @\deflibconcept{indirect_strict_weak_order}@ = - readable && readable && + indirectly_readable && indirectly_readable && copy_constructible && strict_weak_order&, iter_value_t&> && strict_weak_order&, iter_reference_t> && @@ -2367,15 +2382,15 @@ \pnum Class template \tcode{projected} is used to constrain algorithms that accept callable objects and projections\iref{defns.projection}. -It combines a \libconcept{readable} type \tcode{I} and -a callable object type \tcode{Proj} into a new \libconcept{readable} type +It combines a \libconcept{indirectly_readable} type \tcode{I} and +a callable object type \tcode{Proj} into a new \libconcept{indirectly_readable} type whose \tcode{reference} type is the result of applying \tcode{Proj} to the \tcode{iter_reference_t} of \tcode{I}. \indexlibraryglobal{projected}% \begin{codeblock} namespace std { - template Proj> + template Proj> struct projected { using value_type = remove_cvref_t>; indirect_result_t operator*() const; // \notdef @@ -2397,8 +2412,8 @@ to families of algorithms. These group together iterator requirements of algorithm families. There are three relational concepts that specify -how element values are transferred between \libconcept{readable} and -\libconcept{writable} types: +how element values are transferred between +\libconcept{indirectly_readable} and \libconcept{indirectly_writable} types: \libconcept{indirectly_movable}, \libconcept{indirectly_copyable}, and \libconcept{indirectly_swappable}. @@ -2420,27 +2435,27 @@ \pnum The \libconcept{indirectly_movable} concept specifies the relationship between -a \libconcept{readable} type and a \libconcept{writable} type between which -values may be moved. +a \libconcept{indirectly_readable} type and a \libconcept{indirectly_writable} type +between which values may be moved. \begin{codeblock} template concept @\deflibconcept{indirectly_movable}@ = - readable && - writable>; + indirectly_readable && + indirectly_writable>; \end{codeblock} \pnum The \libconcept{indirectly_movable_storable} concept augments \libconcept{indirectly_movable} with additional requirements enabling the transfer to be performed through an intermediate object of the -\libconcept{readable} type's value type. +\libconcept{indirectly_readable} type's value type. \begin{codeblock} template concept @\deflibconcept{indirectly_movable_storable}@ = indirectly_movable && - writable> && + indirectly_writable> && movable> && constructible_from, iter_rvalue_reference_t> && assignable_from&, iter_rvalue_reference_t>; @@ -2462,28 +2477,28 @@ \pnum The \libconcept{indirectly_copyable} concept specifies the relationship between -a \libconcept{readable} type and a \libconcept{writable} type between which -values may be copied. +a \libconcept{indirectly_readable} type and a \libconcept{indirectly_writable} type +between which values may be copied. \begin{codeblock} template concept @\deflibconcept{indirectly_copyable}@ = - readable && - writable>; + indirectly_readable && + indirectly_writable>; \end{codeblock} \pnum The \libconcept{indirectly_copyable_storable} concept augments \libconcept{indirectly_copyable} with additional requirements enabling the transfer to be performed through an intermediate object of the -\libconcept{readable} type's value type. It also requires the capability +\libconcept{indirectly_readable} type's value type. It also requires the capability to make copies of values. \begin{codeblock} template concept @\deflibconcept{indirectly_copyable_storable}@ = indirectly_copyable && - writable&> && + indirectly_writable&> && copyable> && constructible_from, iter_reference_t> && assignable_from&, iter_reference_t>; @@ -2505,13 +2520,13 @@ \pnum The \libconcept{indirectly_swappable} concept specifies a swappable relationship -between the values referenced by two \libconcept{readable} types. +between the values referenced by two \libconcept{indirectly_readable} types. \begin{codeblock} template concept @\deflibconcept{indirectly_swappable}@ = - readable && readable && - requires(I1& i1, I2& i2) { + indirectly_readable && indirectly_readable && + requires(const I1 i1, const I2 i2) { ranges::iter_swap(i1, i1); ranges::iter_swap(i2, i2); ranges::iter_swap(i1, i2); @@ -4707,7 +4722,7 @@ decltype(auto) operator*(); decltype(auto) operator*() const - requires @\placeholder{dereferenceable}@; + requires @\exposconcept{dereferenceable}@; decltype(auto) operator->() const requires @\seebelow@; @@ -4860,7 +4875,7 @@ \begin{itemdecl} decltype(auto) operator*(); decltype(auto) operator*() const - requires @\placeholder{dereferenceable}@; + requires @\exposconcept{dereferenceable}@; \end{itemdecl} \begin{itemdescr} @@ -4883,7 +4898,7 @@ \pnum The expression in the requires clause is equivalent to: \begin{codeblock} -readable && +indirectly_readable && (requires(const I& i) { i.operator->(); } || is_reference_v> || constructible_from, iter_reference_t>) @@ -5142,7 +5157,7 @@ constexpr iter_difference_t count() const noexcept; constexpr decltype(auto) operator*(); constexpr decltype(auto) operator*() const - requires @\placeholder{dereferenceable}@; + requires @\exposconcept{dereferenceable}@; constexpr counted_iterator& operator++(); decltype(auto) operator++(int); @@ -5301,7 +5316,7 @@ \begin{itemdecl} constexpr decltype(auto) operator*(); constexpr decltype(auto) operator*() const - requires @\placeholder{dereferenceable}@; + requires @\exposconcept{dereferenceable}@; \end{itemdecl} \begin{itemdescr}