diff --git a/source/numerics.tex b/source/numerics.tex index 529ed10969..44d47184cb 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -17187,6 +17187,262 @@ specialization \tcode{\exposid{overaligned-flag}}. \end{itemdescr} +\rSec2[simd.iterator]{Class \exposid{simd-iterator}} +\begin{codeblock} +namespace std::datapar { + template + class @\exposidnc{simd-iterator}@ { // \expos + V* @\exposidnc{data_}@ = nullptr; // \expos + @\exposidnc{simd-size-type} \exposidnc{offset_}@ = 0; // \expos + + constexpr @\exposid{simd-iterator}@(V& d, @\exposid{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}@>&) requires is_const_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}@>& i) requires is_const_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} @@ -17198,6 +17454,14 @@ using value_type = T; using mask_type = basic_simd_mask; using abi_type = Abi; + using iterator = \exposid{simd-iterator}; + using const_iterator = \exposid{simd-iterator}; + + constexpr iterator begin() noexcept { return {*this, 0}; } + constexpr const_iterator begin() const noexcept { return {*this, 0}; } + constexpr const_iterator cbegin() const noexcept { return {*this, 0}; } + constexpr default_sentinel_t end() const noexcept { return {}; } + constexpr default_sentinel_t cend() const noexcept { return {}; } static constexpr integral_constant<@\exposid{simd-size-type}@, @\exposid{simd-size-v}@> size {}; @@ -19084,6 +19348,14 @@ public: using value_type = bool; using abi_type = Abi; + using iterator = \exposid{simd-iterator}; + using const_iterator = \exposid{simd-iterator}; + + constexpr iterator begin() noexcept { return {*this, 0}; } + constexpr const_iterator begin() const noexcept { return {*this, 0}; } + constexpr const_iterator cbegin() const noexcept { return {*this, 0}; } + constexpr default_sentinel_t end() const noexcept { return {}; } + constexpr default_sentinel_t cend() const noexcept { return {}; } static constexpr integral_constant<@\exposid{simd-size-type}@, @\exposid{simd-size-v}@<@\exposid{integer-from}@, Abi>> size {}; @@ -19095,6 +19367,8 @@ template constexpr explicit basic_simd_mask(const basic_simd_mask&) noexcept; template constexpr explicit basic_simd_mask(G&& gen) noexcept; + constexpr basic_simd_mask(const bitset& b) noexcept; + constexpr explicit basic_simd_mask(@\libconcept{unsigned_integral}@ auto val) noexcept; // \ref{simd.mask.subscr}, \tcode{basic_simd_mask} subscript operators constexpr value_type operator[](@\exposid{simd-size-type}@) const; @@ -19109,6 +19383,10 @@ template constexpr explicit(sizeof(U) != Bytes) operator basic_simd() const noexcept; + // \ref{simd.mask.namedconv}, \tcode{basic_simd_mask} named type convertors + constexpr bitset to_bitset() const noexcept; + constexpr unsigned long long to_ullong() const; + // \ref{simd.mask.binary}, \tcode{basic_simd_mask} binary operators friend constexpr basic_simd_mask operator&&(const basic_simd_mask&, const basic_simd_mask&) noexcept; @@ -19241,6 +19519,31 @@ \tcode{gen} is invoked exactly once for each $i$, in increasing order of $i$. \end{itemdescr} +\begin{itemdecl} +constexpr basic_simd_mask(const bitset& b) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes the $i^\text{th}$ element with \tcode{b[$i$]} for all $i$ in the +range \range{0}{size()}. +\end{itemdescr} + +\begin{itemdecl} +constexpr explicit basic_simd_mask(@\libconcept{unsigned_integral}@ auto val) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Initializes the first $M$ elements to the corresponding bit values in +\tcode{val}, where $M$ is the smaller of \tcode{size()} and the number of bits in +the value representation\iref{basic.types.general} of the type of \tcode{val}. If +$M$ is less than \tcode{size()}, the remaining elements are initialized to +zero. +\end{itemdescr} + \rSec3[simd.mask.subscr]{\tcode{basic_simd_mask} subscript operator} \begin{itemdecl} @@ -19299,6 +19602,43 @@ \tcode{static_cast(operator[]($i$))}. \end{itemdescr} +\rSec3[simd.mask.namedconv]{\tcode{basic_simd_mask} named conversion operators} + +\begin{itemdecl} +constexpr bitset to_bitset() const noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +A \tcode{bitset} object where the $i^\text{th}$ element is initialized to +\tcode{operator[]($i$)} for all $i$ in the range \range{0}{size()}. +\end{itemdescr} + +\begin{itemdecl} +constexpr unsigned long long to_ullong() const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +Let $N$ be the width of \tcode{unsigned long long}. + +\pnum +\expects +\begin{itemize} +\item \tcode{size()} $\le N$, or +\item for all $i$ in the range \range{$N$}{size()}, \tcode{operator[]($i$)} returns \tcode{false}. +\end{itemize} + +\pnum +\returns +The integral value corresponding to the bits in \tcode{*this}. + +\pnum +\throws +Nothing. +\end{itemdescr} + \rSec2[simd.mask.nonmembers]{Non-member operations} \rSec3[simd.mask.binary]{\tcode{basic_simd_mask} binary operators} diff --git a/source/support.tex b/source/support.tex index 95d674aafb..1486b6f39e 100644 --- a/source/support.tex +++ b/source/support.tex @@ -805,7 +805,7 @@ #define @\defnlibxname{cpp_lib_shared_ptr_weak_type}@ 201606L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_shared_timed_mutex}@ 201402L // also in \libheader{shared_mutex} #define @\defnlibxname{cpp_lib_shift}@ 202202L // also in \libheader{algorithm} -#define @\defnlibxname{cpp_lib_simd}@ 202502L // also in \libheader{simd} +#define @\defnlibxname{cpp_lib_simd}@ 202506L // also in \libheader{simd} #define @\defnlibxname{cpp_lib_simd_complex}@ 202502L // also in \libheader{simd} #define @\defnlibxname{cpp_lib_smart_ptr_for_overwrite}@ 202002L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_smart_ptr_owner_equality}@ 202306L // also in \libheader{memory}