Skip to content
2 changes: 1 addition & 1 deletion source/containers.tex
Original file line number Diff line number Diff line change
Expand Up @@ -20532,7 +20532,7 @@

\pnum
\effects
Initializes \exposid{data_} with \tcode{il.begin()} and
Initializes \exposid{data_} with \tcode{il.data()} and
\exposid{size_} with \tcode{il.size()}.
\end{itemdescr}

Expand Down
174 changes: 92 additions & 82 deletions source/iterators.tex
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
\begin{codeblock}
#include <compare> // see \ref{compare.syn}
#include <concepts> // see \ref{concepts.syn}
#include <initializer_list> // see \ref{initializer.list.syn}

namespace std {
template<class T> using @\exposid{with-reference}@ = T&; // \expos
Expand Down Expand Up @@ -464,53 +465,64 @@
class ostreambuf_iterator;

// \ref{iterator.range}, range access
template<class C> constexpr auto begin(C& c) -> decltype(c.begin()); // freestanding
template<class C> constexpr auto begin(const C& c) -> decltype(c.begin()); // freestanding
template<class C> constexpr auto end(C& c) -> decltype(c.end()); // freestanding
template<class C> constexpr auto end(const C& c) -> decltype(c.end()); // freestanding
template<class C> constexpr auto
begin(C& c) noexcept(noexcept(c.begin())) -> decltype(c.begin()); // freestanding
template<class C> constexpr auto
begin(const C& c) noexcept(noexcept(c.begin())) -> decltype(c.begin()); // freestanding
template<class C> constexpr auto
end(C& c) noexcept(noexcept(c.end())) -> decltype(c.end()); // freestanding
template<class C> constexpr auto
end(const C& c) noexcept(noexcept(c.end())) -> decltype(c.end()); // freestanding
Comment on lines +468 to +475
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest, I liked the style in the paper better,
which is

  template<class C> constexpr auto begin(C& c)
    noexcept(noexcept(c.begin())) -> decltype(c.begin());

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We usually break after the template-head, and then maybe also break later in the declaration. But I think the <iterator> synopsis is unusual (unique even?) in doing:

template<class C> constexpr auto

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i.e. I think it would be move conventional to do:

template<class C>
  constexpr auto begin(C& c) noexcept(...) -> decltype(...);     // freestanding

and if that doesn't fit, then something like:

template<class C>
  constexpr auto begin(C& c) noexcept(...)
    -> decltype(...);                                            // freestanding

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the more conventional style, but deliberately followed the example of breaking already used throughout this clause. Should I apply our more usual breaking pattern to this header as whole, as a distinct commit?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ping: should I apply a consistent reformatting of the whole header? Or wait until after the motions land to do so as a follow-up? Or do we really want some kind of mix-and-match style in the applied motion?

template<class T, size_t N> constexpr T* begin(T (&array)[N]) noexcept; // freestanding
template<class T, size_t N> constexpr T* end(T (&array)[N]) noexcept; // freestanding
template<class C> constexpr auto cbegin(const C& c) // freestanding
noexcept(noexcept(std::begin(c))) -> decltype(std::begin(c));
template<class C> constexpr auto cend(const C& c) // freestanding
noexcept(noexcept(std::end(c))) -> decltype(std::end(c));
template<class C> constexpr auto rbegin(C& c) -> decltype(c.rbegin()); // freestanding
template<class C> constexpr auto rbegin(const C& c) -> decltype(c.rbegin()); // freestanding
template<class C> constexpr auto rend(C& c) -> decltype(c.rend()); // freestanding
template<class C> constexpr auto rend(const C& c) -> decltype(c.rend()); // freestanding
template<class T, size_t N> constexpr reverse_iterator<T*> rbegin(T (&array)[N]) // freestanding
template<class T, size_t N> constexpr reverse_iterator<T*> rend(T (&array)[N]); // freestanding
template<class C> constexpr auto
cbegin(const C& c) noexcept(noexcept(std::begin(c)))
-> decltype(std::begin(c)); // freestanding
template<class C> constexpr auto
cend(const C& c) noexcept(noexcept(std::end(c))) -> decltype(std::end(c)); // freestanding
template<class C> constexpr auto
rbegin(C& c) noexcept(noexcept(c.rbegin())) -> decltype(c.rbegin()); // freestanding
template<class C> constexpr auto
rbegin(const C& c) noexcept(noexcept(c.rbegin())) -> decltype(c.rbegin()); // freestanding
template<class C> constexpr auto
rend(C& c) noexcept(noexcept(c.rend())) -> decltype(c.rend()); // freestanding
template<class C> constexpr auto
rend(const C& c) noexcept(noexcept(c.rend())) -> decltype(c.rend()); // freestanding
template<class T, size_t N> constexpr reverse_iterator<T*>
rbegin(T (&array)[N]) noexcept; // freestanding
template<class T, size_t N> constexpr reverse_iterator<T*>
rend(T (&array)[N]) noexcept; // freestanding
template<class E> constexpr reverse_iterator<const E*>
rbegin(initializer_list<E> il); // freestanding
rbegin(initializer_list<E> il) noexcept; // freestanding
template<class E> constexpr reverse_iterator<const E*>
rend(initializer_list<E> il); // freestanding
rend(initializer_list<E> il) noexcept; // freestanding
template<class C> constexpr auto
crbegin(const C& c) -> decltype(std::rbegin(c)); // freestanding
crbegin(const C& c) noexcept(noexcept(std::rbegin(c)))
-> decltype(std::rbegin(c)); // freestanding
template<class C> constexpr auto
crend(const C& c) -> decltype(std::rend(c)); // freestanding
crend(const C& c) noexcept(noexcept(std::rend(c))) -> decltype(std::rend(c)); // freestanding

template<class C> constexpr auto
size(const C& c) -> decltype(c.size()); // freestanding
size(const C& c) noexcept(noexcept(c.size())) -> decltype(c.size()); // freestanding
template<class T, size_t N> constexpr size_t
size(const T (&array)[N]) noexcept; // freestanding

template<class C> constexpr auto
ssize(const C& c)
ssize(const C& c) noexcept(noexcept(c.size()))
-> common_type_t<ptrdiff_t, make_signed_t<decltype(c.size())>>; // freestanding
template<class T, ptrdiff_t N> constexpr ptrdiff_t
ssize(const T (&array)[N]) noexcept; // freestanding

template<class C> constexpr auto
empty(const C& c) -> decltype(c.empty()); // freestanding
empty(const C& c) noexcept(noexcept(c.empty())) -> decltype(c.empty()); // freestanding
template<class T, size_t N> constexpr bool
empty(const T (&array)[N]) noexcept; // freestanding
template<class E> constexpr bool
empty(initializer_list<E> il) noexcept; // freestanding

template<class C> constexpr auto data(C& c) -> decltype(c.data()); // freestanding
template<class C> constexpr auto data(const C& c) -> decltype(c.data()); // freestanding
template<class C> constexpr auto
data(C& c) noexcept(noexcept(c.data())) -> decltype(c.data()); // freestanding
template<class C> constexpr auto
data(const C& c) noexcept(noexcept(c.data())) -> decltype(c.data()); // freestanding
template<class T, size_t N> constexpr T* data(T (&array)[N]) noexcept; // freestanding
template<class E> constexpr const E* data(initializer_list<E> il) noexcept; // freestanding
}
\end{codeblock}

Expand Down Expand Up @@ -7241,28 +7253,38 @@
In addition to being available via inclusion of the \libheader{iterator} header,
the function templates in \ref{iterator.range} are available when any of the following
headers are included:
\libheaderref{array},
\libheaderref{deque},
\libheaderrefx{flat_map}{flat.map.syn},
\libheaderrefx{flat_set}{flat.set.syn},
\libheaderrefx{forward_list}{forward.list.syn},
\libheaderref{hive},
\libheaderrefx{inplace_vector}{inplace.vector.syn},
\libheaderref{list},
\libheaderrefx{map}{associative.map.syn},
\libheaderrefx{regex}{re.syn},
\libheaderrefx{set}{associative.set.syn},
\libheaderref{span},
\libheaderref{string},
\libheaderrefx{string_view}{string.view.synop},
\libheaderrefx{unordered_map}{unord.map.syn},
\libheaderrefx{unordered_set}{unord.set.syn}, and
\libheaderref{vector}.
\begin{multicolfloattable}{Additional range function headers}{range.function.headers}
{lll}
\libheaderref{array} \\
\libheaderref{deque} \\
\libheaderrefx{flat_map}{flat.map.syn} \\
\libheaderrefx{flat_set}{flat.set.syn} \\
\libheaderrefx{forward_list}{forward.list.syn} \\
\libheaderref{hive} \\
\libheaderrefx{inplace_vector}{inplace.vector.syn} \\
\columnbreak
\libheaderref{list} \\
\libheaderrefx{map}{associative.map.syn} \\
\libheaderref{optional} \\
\libheaderrefx{regex}{re.syn} \\
\libheaderrefx{set}{associative.set.syn} \\
\libheaderref{span} \\
\libheaderref{stacktrace} \\
\columnbreak
\libheaderref{string} \\
\libheaderrefx{string_view}{string.view.synop} \\
\libheaderrefx{unordered_map}{unord.map.syn} \\
\libheaderrefx{unordered_set}{unord.set.syn} \\
\libheaderref{valarray} \\
\libheaderref{vector} \\
\end{multicolfloattable}

\indexlibrary{\idxcode{begin(C\&)}}%
\begin{itemdecl}
template<class C> constexpr auto begin(C& c) -> decltype(c.begin());
template<class C> constexpr auto begin(const C& c) -> decltype(c.begin());
template<class C> constexpr auto begin(C& c) noexcept(noexcept(c.begin()))
-> decltype(c.begin());
template<class C> constexpr auto begin(const C& c) noexcept(noexcept(c.begin()))
-> decltype(c.begin());
\end{itemdecl}

\begin{itemdescr}
Expand All @@ -7273,8 +7295,8 @@

\indexlibrary{\idxcode{end(C\&)}}%
\begin{itemdecl}
template<class C> constexpr auto end(C& c) -> decltype(c.end());
template<class C> constexpr auto end(const C& c) -> decltype(c.end());
template<class C> constexpr auto end(C& c) noexcept(noexcept(c.end())) -> decltype(c.end());
template<class C> constexpr auto end(const C& c) noexcept(noexcept(c.end())) -> decltype(c.end());
\end{itemdecl}

\begin{itemdescr}
Expand Down Expand Up @@ -7329,8 +7351,10 @@

\indexlibrary{\idxcode{rbegin(C\&)}}%
\begin{itemdecl}
template<class C> constexpr auto rbegin(C& c) -> decltype(c.rbegin());
template<class C> constexpr auto rbegin(const C& c) -> decltype(c.rbegin());
template<class C> constexpr auto rbegin(C& c) noexcept(noexcept(c.rbegin()))
-> decltype(c.rbegin());
template<class C> constexpr auto rbegin(const C& c) noexcept(noexcept(c.rbegin()))
-> decltype(c.rbegin());
\end{itemdecl}
\begin{itemdescr}
\pnum
Expand All @@ -7340,8 +7364,9 @@

\indexlibrary{\idxcode{rend(C\&)}}%
\begin{itemdecl}
template<class C> constexpr auto rend(C& c) -> decltype(c.rend());
template<class C> constexpr auto rend(const C& c) -> decltype(c.rend());
template<class C> constexpr auto rend(C& c) noexcept(noexcept(c.rend())) -> decltype(c.rend());
template<class C> constexpr auto rend(const C& c) noexcept(noexcept(c.rend()))
-> decltype(c.rend());
\end{itemdecl}
\begin{itemdescr}
\pnum
Expand All @@ -7351,7 +7376,7 @@

\indexlibrary{\idxcode{rbegin(T (\&array)[N])}}%
\begin{itemdecl}
template<class T, size_t N> constexpr reverse_iterator<T*> rbegin(T (&array)[N]);
template<class T, size_t N> constexpr reverse_iterator<T*> rbegin(T (&array)[N]) noexcept;
\end{itemdecl}
\begin{itemdescr}
\pnum
Expand All @@ -7361,7 +7386,7 @@

\indexlibrary{\idxcode{rend(T (\&array)[N])}}%
\begin{itemdecl}
template<class T, size_t N> constexpr reverse_iterator<T*> rend(T (&array)[N]);
template<class T, size_t N> constexpr reverse_iterator<T*> rend(T (&array)[N]) noexcept;
\end{itemdecl}
\begin{itemdescr}
\pnum
Expand All @@ -7371,7 +7396,7 @@

\indexlibrary{\idxcode{rbegin(initializer_list<E>)}}%
\begin{itemdecl}
template<class E> constexpr reverse_iterator<const E*> rbegin(initializer_list<E> il);
template<class E> constexpr reverse_iterator<const E*> rbegin(initializer_list<E> il) noexcept;
\end{itemdecl}
\begin{itemdescr}
\pnum
Expand All @@ -7381,7 +7406,7 @@

\indexlibrary{\idxcode{rend(initializer_list<E>)}}%
\begin{itemdecl}
template<class E> constexpr reverse_iterator<const E*> rend(initializer_list<E> il);
template<class E> constexpr reverse_iterator<const E*> rend(initializer_list<E> il) noexcept;
\end{itemdecl}
\begin{itemdescr}
\pnum
Expand All @@ -7391,7 +7416,8 @@

\indexlibrary{\idxcode{crbegin(const C\& c)}}%
\begin{itemdecl}
template<class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c));
template<class C> constexpr auto crbegin(const C& c) noexcept(noexcept(std::rbegin(c)))
-> decltype(std::rbegin(c));
\end{itemdecl}
\begin{itemdescr}
\pnum
Expand All @@ -7401,7 +7427,8 @@

\indexlibrary{\idxcode{crend(const C\& c)}}%
\begin{itemdecl}
template<class C> constexpr auto crend(const C& c) -> decltype(std::rend(c));
template<class C> constexpr auto crend(const C& c) noexcept(noexcept(c.crend()))
-> decltype(std::rend(c));
\end{itemdecl}
\begin{itemdescr}
\pnum
Expand All @@ -7411,7 +7438,8 @@

\indexlibrary{\idxcode{size(C\& c)}}%
\begin{itemdecl}
template<class C> constexpr auto size(const C& c) -> decltype(c.size());
template<class C> constexpr auto size(const C& c) noexcept(noexcept(c.size()))
-> decltype(c.size());
\end{itemdecl}
\begin{itemdescr}
\pnum
Expand All @@ -7431,7 +7459,7 @@

\indexlibrary{\idxcode{ssize(C\& c)}}%
\begin{itemdecl}
template<class C> constexpr auto ssize(const C& c)
template<class C> constexpr auto ssize(const C& c) noexcept(noexcept(c.size()))
-> common_type_t<ptrdiff_t, make_signed_t<decltype(c.size())>>;
\end{itemdecl}
\begin{itemdescr}
Expand All @@ -7455,7 +7483,8 @@

\indexlibrary{\idxcode{empty(C\& c)}}%
\begin{itemdecl}
template<class C> constexpr auto empty(const C& c) -> decltype(c.empty());
template<class C> constexpr auto empty(const C& c) noexcept(noexcept(c.empty()))
-> decltype(c.empty());
\end{itemdecl}
\begin{itemdescr}
\pnum
Expand All @@ -7473,20 +7502,11 @@
\tcode{false}.
\end{itemdescr}

\indexlibrary{\idxcode{empty(initializer_list<E>)}}%
\begin{itemdecl}
template<class E> constexpr bool empty(initializer_list<E> il) noexcept;
\end{itemdecl}
\begin{itemdescr}
\pnum
\returns
\tcode{il.size() == 0}.
\end{itemdescr}

\indexlibrary{\idxcode{data(C\& c)}}%
\begin{itemdecl}
template<class C> constexpr auto data(C& c) -> decltype(c.data());
template<class C> constexpr auto data(const C& c) -> decltype(c.data());
template<class C> constexpr auto data(C& c) noexcept(noexcept(c.data())) -> decltype(c.data());
template<class C> constexpr auto data(const C& c) noexcept(noexcept(c.data()))
-> decltype(c.data());
\end{itemdecl}
\begin{itemdescr}
\pnum
Expand All @@ -7503,13 +7523,3 @@
\returns
\tcode{array}.
\end{itemdescr}

\indexlibrary{\idxcode{data(initializer_list<E>)}}%
\begin{itemdecl}
template<class E> constexpr const E* data(initializer_list<E> il) noexcept;
\end{itemdecl}
\begin{itemdescr}
\pnum
\returns
\tcode{il.begin()}.
\end{itemdescr}
Loading