Skip to content

LWG Motion 11 #8074

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 15, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
276 changes: 276 additions & 0 deletions source/numerics.tex
Original file line number Diff line number Diff line change
Expand Up @@ -16509,6 +16509,10 @@
template<size_t N> requires (has_single_bit(N))
constexpr flags<@\exposid{overaligned-flag}<N>@> flag_overaligned{};

// \ref{simd.iterator}, Class template \exposid{simd-iterator}
template<class V>
class @\exposidnc{simd-iterator}@; // \expos

// \ref{simd.class}, Class template \tcode{basic_simd}
template<class T, class Abi = @\exposid{native-abi}@<T>> class basic_simd;
template<class T, @\exposid{simd-size-type}@ N = @\exposid{simd-size-v}@<T, @\exposid{native-abi}@<T>>>
Expand Down Expand Up @@ -17204,6 +17208,262 @@
specialization \tcode{\exposid{overaligned-flag}<std::min(N1, N2)>}.
\end{itemdescr}

\rSec2[simd.iterator]{Class template \exposid{simd-iterator}}
\begin{codeblock}
namespace std::datapar {
template<class V>
class @\exposidnc{simd-iterator}@ { // \expos
V* @\exposid{data_}@ = nullptr; // \expos
@\exposid{simd-size-type}@ @\exposidnc{offset_}@ = 0; // \expos

constexpr @\exposidnc{simd-iterator}@(V& d, @\exposidnc{simd-size-type}@ off) noexcept; // \expos

public:
using value_type = typename V::value_type;
using iterator_category = input_iterator_tag;
using iterator_concept = random_access_iterator_tag;
using difference_type = @\exposid{simd-size-type}@;

constexpr @\exposid{simd-iterator}@() = default;

constexpr @\exposid{simd-iterator}@(const @\exposid{simd-iterator}@&) = default;
constexpr @\exposid{simd-iterator}@& operator=(const @\exposid{simd-iterator}@&) = default;

constexpr @\exposid{simd-iterator}@(const @\exposid{simd-iterator}@<remove_const_t<V>>&) requires is_const_v<V>;

constexpr value_type operator*() const;

constexpr @\exposid{simd-iterator}@& operator++();
constexpr @\exposid{simd-iterator}@ operator++(int);
constexpr @\exposid{simd-iterator}@& operator--();
constexpr @\exposid{simd-iterator}@ operator--(int);

constexpr @\exposid{simd-iterator}@& operator+=(difference_type n);
constexpr @\exposid{simd-iterator}@& operator-=(difference_type n);

constexpr value_type operator[](difference_type n) const;

friend constexpr bool operator==(@\exposid{simd-iterator}@ a, @\exposid{simd-iterator}@ b) = default;
friend constexpr bool operator==(@\exposid{simd-iterator}@ a, default_sentinel_t) noexcept;
friend constexpr auto operator<=>(@\exposid{simd-iterator}@ a, @\exposid{simd-iterator}@ b);

friend constexpr @\exposid{simd-iterator}@ operator+(@\exposid{simd-iterator}@ i, difference_type n);
friend constexpr @\exposid{simd-iterator}@ operator+(difference_type n, @\exposid{simd-iterator}@ i);
friend constexpr @\exposid{simd-iterator}@ operator-(@\exposid{simd-iterator}@ i, difference_type n);

friend constexpr difference_type operator-(@\exposid{simd-iterator}@ a, @\exposid{simd-iterator}@ b);
friend constexpr difference_type operator-(@\exposid{simd-iterator}@ i, default_sentinel_t) noexcept;
friend constexpr difference_type operator-(default_sentinel_t, @\exposid{simd-iterator}@ i) noexcept;
};
}
\end{codeblock}

\begin{itemdecl}
constexpr @\exposid{simd-iterator}@(V& d, @\exposid{simd-size-type}@ off) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \exposid{data_} with \tcode{addressof(d)} and \exposid{offset_} with \tcode{off}.
\end{itemdescr}

\begin{itemdecl}
constexpr @\exposid{simd-iterator}@(const @\exposid{simd-iterator}@<remove_const_t<V>>& i) requires is_const_v<V>;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \exposid{data_} with \tcode{i.\exposid{data_}} and \exposid{offset_} with \tcode{i.\exposid{offset_}}.
\end{itemdescr}

\begin{itemdecl}
constexpr value_type operator*() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return (*\exposid{data_})[\exposid{offset_}];}
\end{itemdescr}

\begin{itemdecl}
constexpr @\exposid{simd-iterator}@& operator++();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return *this += 1;}
\end{itemdescr}

\begin{itemdecl}
constexpr @\exposid{simd-iterator}@ operator++(int);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
@\exposid{simd-iterator}@ tmp = *this;
*this += 1;
return tmp;
\end{codeblock}
\end{itemdescr}

\begin{itemdecl}
constexpr @\exposid{simd-iterator}@& operator--();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return *this -= 1;}
\end{itemdescr}

\begin{itemdecl}
constexpr @\exposid{simd-iterator}@ operator--(int);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
@\exposid{simd-iterator}@ tmp = *this;
*this -= 1;
return tmp;
\end{codeblock}
\end{itemdescr}

\begin{itemdecl}
constexpr @\exposid{simd-iterator}@& operator+=(difference_type n);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{\exposid{offset_} + n} is in the range \crange{0}{V::size()}.

\pnum
\effects
Equivalent to:
\begin{codeblock}
@\exposid{offset_}@ += n;
return *this;
\end{codeblock}
\end{itemdescr}

\begin{itemdecl}
constexpr @\exposid{simd-iterator}@& operator-=(difference_type n);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{\exposid{offset_} - n} is in the range \crange{0}{V::size()}.

\pnum
\effects
Equivalent to:
\begin{codeblock}
@\exposid{offset_}@ -= n;
return *this;
\end{codeblock}
\end{itemdescr}

\begin{itemdecl}
constexpr value_type operator[](difference_type n) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return (*\exposid{data_})[\exposid{offset_} + n];}
\end{itemdescr}

\begin{itemdecl}
friend constexpr bool operator==(@\exposid{simd-iterator}@ i, default_sentinel_t) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return i.\exposid{offset_} == V::size();}
\end{itemdescr}

\begin{itemdecl}
friend constexpr auto operator<=>(@\exposid{simd-iterator}@ a, @\exposid{simd-iterator}@ b);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{a.\exposid{data_} == b.\exposid{data_}} is \tcode{true}.

\pnum
\effects
Equivalent to: \tcode{return a.\exposid{offset_} <=> b.\exposid{offset_};}
\end{itemdescr}

\begin{itemdecl}
friend constexpr @\exposid{simd-iterator}@ operator+(@\exposid{simd-iterator}@ i, difference_type n);
friend constexpr @\exposid{simd-iterator}@ operator+(difference_type n, @\exposid{simd-iterator}@ i);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return i += n;}
\end{itemdescr}

\begin{itemdecl}
friend constexpr @\exposid{simd-iterator}@ operator-(@\exposid{simd-iterator}@ i, difference_type n);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return i -= n;}
\end{itemdescr}

\begin{itemdecl}
friend constexpr difference_type operator-(@\exposid{simd-iterator}@ a, @\exposid{simd-iterator}@ b);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{a.\exposid{data_} == b.\exposid{data_}} is \tcode{true}.

\pnum
\effects
Equivalent to: \tcode{return a.\exposid{offset_} - b.\exposid{offset_};}
\end{itemdescr}

\begin{itemdecl}
friend constexpr difference_type operator-(@\exposid{simd-iterator}@ i, default_sentinel_t) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return i.\exposid{offset_} - V::size();}
\end{itemdescr}


\begin{itemdecl}
friend constexpr difference_type operator-(default_sentinel_t, @\exposid{simd-iterator}@ i) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return V::size() - i.\exposid{offset_};}
\end{itemdescr}

\rSec2[simd.class]{Class template \tcode{basic_simd}}

\rSec3[simd.overview]{Class template \tcode{basic_simd} overview}
Expand All @@ -17215,6 +17475,14 @@
using value_type = T;
using mask_type = basic_simd_mask<sizeof(T), Abi>;
using abi_type = Abi;
using @\libmember{iterator}{basic_simd}@ = @\exposid{simd-iterator}@<basic_simd>;
using @\libmember{const_iterator}{basic_simd}@ = @\exposid{simd-iterator}@<const basic_simd>;

constexpr iterator @\libmember{begin}{basic_simd}@() noexcept { return {*this, 0}; }
constexpr const_iterator @\libmember{begin}{basic_simd}@() const noexcept { return {*this, 0}; }
constexpr const_iterator @\libmember{cbegin}{basic_simd}@() const noexcept { return {*this, 0}; }
constexpr default_sentinel_t @\libmember{end}{basic_simd}@() const noexcept { return {}; }
constexpr default_sentinel_t @\libmember{cend}{basic_simd}@() const noexcept { return {}; }

static constexpr integral_constant<@\exposid{simd-size-type}@, @\exposid{simd-size-v}@<T, Abi>> size {};

Expand Down Expand Up @@ -19101,6 +19369,14 @@
public:
using value_type = bool;
using abi_type = Abi;
using @\libmember{iterator}{basic_simd_mask}@ = @\exposid{simd-iterator}@<basic_simd_mask>;
using @\libmember{const_iterator}{basic_simd_mask}@ = @\exposid{simd-iterator}@<const basic_simd_mask>;

constexpr iterator @\libmember{begin}{basic_simd_mask}@() noexcept { return {*this, 0}; }
constexpr const_iterator @\libmember{begin}{basic_simd_mask}@() const noexcept { return {*this, 0}; }
constexpr const_iterator @\libmember{cbegin}{basic_simd_mask}@() const noexcept { return {*this, 0}; }
constexpr default_sentinel_t @\libmember{end}{basic_simd_mask}@() const noexcept { return {}; }
constexpr default_sentinel_t @\libmember{cend}{basic_simd_mask}@() const noexcept { return {}; }

static constexpr integral_constant<@\exposid{simd-size-type}@, @\exposid{simd-size-v}@<@\exposid{integer-from}@<Bytes>, Abi>>
size {};
Expand Down