From 868ad5df894c915055ea7ba5f4bc44f74cfb03b4 Mon Sep 17 00:00:00 2001 From: Matthias Kretz Date: Mon, 17 Feb 2025 17:08:06 +0100 Subject: [PATCH] P2933R4 Extend header function with overloads for std::simd --- source/numerics.tex | 201 ++++++++++++++++++++++++++++++++++++++++++++ source/support.tex | 2 +- 2 files changed, 202 insertions(+), 1 deletion(-) diff --git a/source/numerics.tex b/source/numerics.tex index 30dcecd86f..92e486285d 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -16125,6 +16125,11 @@ template using @\exposidnc{make-compatible-simd-t} = \seebelownc@; // \expos +template + concept @\defexposconceptnc{simd-type}@ = // \expos + @\libconcept{same_as}@> && + is_default_constructible_v; + template concept @\defexposconceptnc{simd-floating-point}@ = // \expos @\libconcept{same_as}@> && @@ -16743,6 +16748,43 @@ template<@\exposconcept{math-floating-point}@ V> @\exposid{deduced-simd-t}@ sph_neumann(const rebind_simd_t>& n, const V& x); + + // \ref{simd.bit}, Bit manipulation + template<@\exposconcept{simd-type}@ V> constexpr V byteswap(const V& v) noexcept; + template<@\exposconcept{simd-type}@ V> constexpr V bit_ceil(const V& v) noexcept; + template<@\exposconcept{simd-type}@ V> constexpr V bit_floor(const V& v) noexcept; + + template<@\exposconcept{simd-type}@ V> + constexpr typename V::mask_type has_single_bit(const V& v) noexcept; + + template<@\exposconcept{simd-type}@ V0, @\exposconcept{simd-type}@ V1> + constexpr V0 rotl(const V0& v, const V1& s) noexcept; + template<@\exposconcept{simd-type}@ V> + constexpr V rotl(const V& v, int s) noexcept; + + template<@\exposconcept{simd-type}@ V0, @\exposconcept{simd-type}@ V1> + constexpr V0 rotr(const V0& v, const V1& s) noexcept; + template<@\exposconcept{simd-type}@ V> + constexpr V rotr(const V& v, int s) noexcept; + + template<@\exposconcept{simd-type}@ V> + constexpr rebind_simd_t, V> + bit_width(const V& v) noexcept; + template<@\exposconcept{simd-type}@ V> + constexpr rebind_simd_t, V> + countl_zero(const V& v) noexcept; + template<@\exposconcept{simd-type}@ V> + constexpr rebind_simd_t, V> + countl_one(const V& v) noexcept; + template<@\exposconcept{simd-type}@ V> + constexpr rebind_simd_t, V> + countr_zero(const V& v) noexcept; + template<@\exposconcept{simd-type}@ V> + constexpr rebind_simd_t, V> + countr_one(const V& v) noexcept; + template<@\exposconcept{simd-type}@ V> + constexpr rebind_simd_t, V> + popcount(const V& v) noexcept; } \end{codeblock} @@ -18471,6 +18513,165 @@ \tcode{ret.first}. \end{itemdescr} +\rSec3[simd.bit]{\tcode{basic_simd} bit library} + +\begin{itemdecl} +template<@\exposconcept{simd-type}@ V> constexpr V byteswap(const V& v) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The type \tcode{V::value_type} models \tcode{integral}. + +\pnum +\returns +A \tcode{basic_simd} object where the $i^\text{th}$ element is initialized to +the result of \tcode{std::byteswap(v[$i$])} for all $i$ in the range +\range{0}{V::size()}. +\end{itemdescr} + +\begin{itemdecl} +template<@\exposconcept{simd-type}@ V> constexpr V bit_ceil(const V& v) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The type \tcode{V::value_type} is an unsigned integer type\iref{basic.fundamental}. + +\pnum +\expects +For every $i$ in the range \range{0}{V::size()}, the smallest power of 2 +greater than or equal to \tcode{v[$i$]} is representable as a value of type +\tcode{V::value_type}. + +\pnum +\returns +A \tcode{basic_simd} object where the $i^\text{th}$ element is initialized to +the result of \tcode{std::bit_ceil(v[$i$])} for all $i$ in the range +\range{0}{V::size()}. + +\pnum +\remarks +A function call expression that violates the precondition in the \expects +element is not a core constant expression\iref{expr.const}. +\end{itemdescr} + +\begin{itemdecl} +template<@\exposconcept{simd-type}@ V> constexpr V bit_floor(const V& v) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The type \tcode{V::value_type} is an unsigned integer type\iref{basic.fundamental}. + +\pnum +\returns +A \tcode{basic_simd} object where the $i^\text{th}$ element is initialized to +the result of \tcode{std::bit_floor(v[$i$])} for all $i$ in the range +\range{0}{V::size()}. +\end{itemdescr} + +\begin{itemdecl} +template<@\exposconcept{simd-type}@ V> + constexpr typename V::mask_type has_single_bit(const V& v) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The type \tcode{V::value_type} is an unsigned integer type\iref{basic.fundamental}. + +\pnum +\returns +A \tcode{basic_simd_mask} object where the $i^\text{th}$ element is initialized +to the result of \tcode{std::has_single_bit(v[$i$])} for all $i$ in the range +\range{0}{V::size()}. +\end{itemdescr} + +\begin{itemdecl} +template<@\exposconcept{simd-type}@ V0, @\exposconcept{simd-type}@ V1> + constexpr V0 rotl(const V0& v0, const V1& v1) noexcept; +template<@\exposconcept{simd-type}@ V0, @\exposconcept{simd-type}@ V1> + constexpr V0 rotr(const V0& v0, const V1& v1) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} + \item + The type \tcode{V0::value_type} is an unsigned integer type\iref{basic.fundamental}, + \item + the type \tcode{V1::value_type} models \tcode{integral}, + \item + \tcode{V0::size() == V1::size()} is \tcode{true}, and + \item + \tcode{sizeof(typename V0::value_type) == sizeof(typename V1::value_type)} is \tcode{true}. +\end{itemize} + +\pnum +\returns +A \tcode{basic_simd} object where the $i^\text{th}$ element is initialized to +the result of \tcode{\placeholder{bit-func}(v0[$i$], +static_cast(v1[$i$]))} for all $i$ in the range \range{0}{V0::size()}, +where \placeholder{bit-func} is the corresponding scalar function from \libheader{bit}. +\end{itemdescr} + +\begin{itemdecl} +template<@\exposconcept{simd-type}@ V> constexpr V rotl(const V& v, int s) noexcept; +template<@\exposconcept{simd-type}@ V> constexpr V rotr(const V& v, int s) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The type \tcode{V::value_type} is an unsigned integer type\iref{basic.fundamental} + +\pnum +\returns +A \tcode{basic_simd} object where the $i^\text{th}$ element is initialized to +the result of \tcode{\placeholder{bit-func}(v[$i$], s)} for all $i$ in the +range \range{0}{V::size()}, where \placeholder{bit-func} is the corresponding +scalar function from \libheader{bit}. +\end{itemdescr} + +\begin{itemdecl} +template<@\exposconcept{simd-type}@ V> + constexpr rebind_simd_t, V> + bit_width(const V& v) noexcept; +template<@\exposconcept{simd-type}@ V> + constexpr rebind_simd_t, V> + countl_zero(const V& v) noexcept; +template<@\exposconcept{simd-type}@ V> + constexpr rebind_simd_t, V> + countl_one(const V& v) noexcept; +template<@\exposconcept{simd-type}@ V> + constexpr rebind_simd_t, V> + countr_zero(const V& v) noexcept; +template<@\exposconcept{simd-type}@ V> + constexpr rebind_simd_t, V> + countr_one(const V& v) noexcept; +template<@\exposconcept{simd-type}@ V> + constexpr rebind_simd_t, V> + popcount(const V& v) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The type \tcode{V::value_type} is an unsigned integer type\iref{basic.fundamental} + +\pnum +\returns +A \tcode{basic_simd} object where the $i^\text{th}$ element is initialized to +the result of \tcode{\placeholder{bit-func}(v[$i$])} for all $i$ in the range +\range{0}{V::size()}, where \placeholder{bit-func} is the corresponding scalar +function from \libheader{bit}. +\end{itemdescr} + \rSec2[simd.mask.class]{Class template \tcode{basic_simd_mask}} \rSec3[simd.mask.overview]{Class template \tcode{basic_simd_mask} overview} diff --git a/source/support.tex b/source/support.tex index 2165a48957..d3934b799f 100644 --- a/source/support.tex +++ b/source/support.tex @@ -799,7 +799,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}@ 202411L // also in \libheader{simd} +#define @\defnlibxname{cpp_lib_simd}@ 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} #define @\defnlibxname{cpp_lib_source_location}@ 201907L // freestanding, also in \libheader{source_location}