From 8ec3c1f283d5e0e546080972741799ca1b4636dd Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sat, 13 Jun 2026 20:35:52 +0200 Subject: [PATCH 1/2] P3793R2 Better shifting --- source/numerics.tex | 66 ++++++++++++++++++++++++++++++++++++++++++++ source/support.tex | 3 +- source/utilities.tex | 48 ++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 1 deletion(-) diff --git a/source/numerics.tex b/source/numerics.tex index ae6be4760a..f60147c4a7 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -17391,6 +17391,16 @@ template<@\exposconcept{simd-vec-type}@ V> constexpr typename V::mask_type has_single_bit(const V& v) noexcept; + template<@\exposconcept{simd-vec-type}@ VX, @\exposconcept{simd-vec-type}@ VS> + constexpr VX shl(const VX& x, const VS& s) noexcept; + template<@\exposconcept{simd-vec-type}@ V, class S> + constexpr V shl(const V& x, S s) noexcept; + + template<@\exposconcept{simd-vec-type}@ VX, @\exposconcept{simd-vec-type}@ VS> + constexpr VX shr(const VX& x, const V1& s) noexcept; + template<@\exposconcept{simd-vec-type}@ V, class S> + constexpr V shr(const V& x, S s) noexcept; + template<@\exposconcept{simd-vec-type}@ V0, @\exposconcept{simd-vec-type}@ V1> constexpr V0 rotl(const V0& v, const V1& s) noexcept; template<@\exposconcept{simd-vec-type}@ V> @@ -17592,6 +17602,8 @@ using simd::bit_ceil; using simd::bit_floor; using simd::has_single_bit; + using simd::shl; + using simd::shr; using simd::rotl; using simd::rotr; using simd::bit_width; @@ -20638,6 +20650,60 @@ \range{0}{V::size()}. \end{itemdescr} +\indexlibrarymember{shl}{simd} +\indexlibrarymember{shr}{simd} +\begin{itemdecl} +template<@\exposconcept{simd-vec-type}@ VX, @\exposconcept{simd-vec-type}@ VS> + constexpr VX shl(const VX& x, const VS& s) noexcept; +template<@\exposconcept{simd-vec-type}@ VX, @\exposconcept{simd-vec-type}@ VS> + constexpr VX shr(const VX& x, const VS& s) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\begin{itemize} +\item +Each of \tcode{VX::value_type} and \tcode{VS::value_type} +is a signed or unsigned integer type\iref{basic.fundamental}, +\item +\tcode{VX::size() == VS::size()} is \tcode{true}, and +\item +\tcode{sizeof(typename VX::value_type) == sizeof(typename VS::value_type)} +is \tcode{true}. +\end{itemize} + +\pnum +\returns +A \tcode{basic_vec} object where the $i^\text{th}$ element is initialized to +the result of \tcode{\placeholder{bit-func}(x[$i$], s[$i$])} +for all $i$ in the range \range{0}{VX::size()}, +where \tcode{\placeholder{bit-func}} is the corresponding scalar function from \libheader{bit}. +\end{itemdescr} + +\indexlibrarymember{shl}{simd} +\indexlibrarymember{shr}{simd} +\begin{itemdecl} +template<@\exposconcept{simd-vec-type}@ V, class S> + constexpr V shl(const V& x, S s) noexcept; +template<@\exposconcept{simd-vec-type}@ V, class S> + constexpr V shr(const V& x, S s) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +Each of \tcode{VX::value_type} and \tcode{S} +is a signed or unsigned integer type\iref{basic.fundamental}. + +\pnum +\returns +A \tcode{basic_vec} object where the $i^\text{th}$ element is initialized to +the result of \tcode{\placeholder{bit-func}(x[$i$], s)} +for all $i$ in the range \range{0}{VX::size()}, +where \tcode{\placeholder{bit-func}} is the corresponding scalar function from \libheader{bit}. +\end{itemdescr} + \indexlibrarymember{rotl}{simd} \indexlibrarymember{rotr}{simd} \begin{itemdecl} diff --git a/source/support.tex b/source/support.tex index 70028e6719..2115fec86a 100644 --- a/source/support.tex +++ b/source/support.tex @@ -602,7 +602,7 @@ #define @\defnlibxname{cpp_lib_bind_back}@ 202306L // freestanding, also in \libheader{functional} #define @\defnlibxname{cpp_lib_bind_front}@ 202306L // freestanding, also in \libheader{functional} #define @\defnlibxname{cpp_lib_bit_cast}@ 201806L // freestanding, also in \libheader{bit} -#define @\defnlibxname{cpp_lib_bitops}@ 201907L // freestanding, also in \libheader{bit} +#define @\defnlibxname{cpp_lib_bitops}@ 202606L // freestanding, also in \libheader{bit} #define @\defnlibxname{cpp_lib_bitset}@ 202306L // also in \libheader{bitset} #define @\defnlibxname{cpp_lib_bool_constant}@ 201505L // freestanding, also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_bounded_array_traits}@ 201902L // freestanding, also in \libheader{type_traits} @@ -838,6 +838,7 @@ #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}@ 202603L // also in \libheader{simd} +#define @\defnlibxname{cpp_lib_simd_bitops}@ 202606L // also in \libheader{simd} #define @\defnlibxname{cpp_lib_simd_complex}@ 202502L // also in \libheader{simd} #define @\defnlibxname{cpp_lib_simd_permutations}@ 202506L // also in \libheader{simd} #define @\defnlibxname{cpp_lib_smart_ptr_for_overwrite}@ 202002L // also in \libheader{memory} diff --git a/source/utilities.tex b/source/utilities.tex index f3e66eb429..f053ba020b 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -16316,6 +16316,12 @@ template constexpr int bit_width(T x) noexcept; + // \ref{bit.shift}, shifting + template + constexpr T shl(T x, S s) noexcept; + template + constexpr T shr(T x, S s) noexcept; + // \ref{bit.rotate}, rotating template constexpr T rotl(T x, int s) noexcept; @@ -16524,6 +16530,48 @@ \end{itemdescr} +\rSec2[bit.shift]{Shifting} + +\pnum +Within this subclause, +the result $r$ of an arithmetic operation is +first represented in a hypothetical integer type with sufficient range, +then converted to \tcode{T} as if by \tcode{static_cast(r)}. + +\indexlibraryglobal{shl}% +\begin{itemdecl} +template + constexpr T shl(T x, S s) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +Each of \tcode{T} and \tcode{S} +is a signed or unsigned integer type\iref{basic.fundamental}. + +\pnum +\returns +$x \times 2^s$ rounded towards negative infinity. +\end{itemdescr} + +\indexlibraryglobal{shr}% +\begin{itemdecl} +template + constexpr T shr(T x, S s) noexcept; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +Each of \tcode{T} and \tcode{S} +is a signed or unsigned integer type\iref{basic.fundamental}. + +\pnum +\returns +$x \times 2^{-s}$ rounded towards negative infinity. +\end{itemdescr} + \rSec2[bit.rotate]{Rotating} \pnum From 13abe7fd25bb6a47cfb17b698afa53b03e741f6d Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sat, 13 Jun 2026 20:36:25 +0200 Subject: [PATCH 2/2] Fixup: paper typo in synopsis The V1->VS rename between paper revisions was accidentally not applied here, and LWG didn't notice the missing change. Oopsie. --- source/numerics.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/numerics.tex b/source/numerics.tex index f60147c4a7..3140446266 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -17397,7 +17397,7 @@ constexpr V shl(const V& x, S s) noexcept; template<@\exposconcept{simd-vec-type}@ VX, @\exposconcept{simd-vec-type}@ VS> - constexpr VX shr(const VX& x, const V1& s) noexcept; + constexpr VX shr(const VX& x, const VS& s) noexcept; template<@\exposconcept{simd-vec-type}@ V, class S> constexpr V shr(const V& x, S s) noexcept;