Skip to content

Commit 407e8b9

Browse files
committed
[2025-02 LWG Motion 13] P2933R4 Extend <bit> header function with overloads for std::simd
1 parent 805aac8 commit 407e8b9

File tree

2 files changed

+191
-1
lines changed

2 files changed

+191
-1
lines changed

source/numerics.tex

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16123,6 +16123,11 @@
1612316123

1612416124
template<class V, class T> using @\exposidnc{make-compatible-simd-t} = \seebelownc@; // \expos
1612516125

16126+
template<class V>
16127+
concept @\defexposconceptnc{simd-type}@ = // \expos
16128+
@\libconcept{same_as}@<V, basic_simd<typename V::value_type, typename V::abi_type>> &&
16129+
is_default_constructible_v<V>;
16130+
1612616131
template<class V>
1612716132
concept @\defexposconceptnc{simd-floating-point}@ = // \expos
1612816133
@\libconcept{same_as}@<V, basic_simd<typename V::value_type, typename V::abi_type>> &&
@@ -16736,6 +16741,37 @@
1673616741
template<@\exposconcept{math-floating-point}@ V>
1673716742
@\exposid{deduced-simd-t}@<V>
1673816743
sph_neumann(const rebind_simd_t<unsigned, @\exposid{deduced-simd-t}@<V>>& n, const V& x);
16744+
16745+
// \ref{simd.bit}, Bit manipulation
16746+
template<@\exposconcept{simd-type}@ V> constexpr V byteswap(const V& v) noexcept;
16747+
template<@\exposconcept{simd-type}@ V> constexpr V bit_ceil(const V& v) noexcept;
16748+
template<@\exposconcept{simd-type}@ V> constexpr V bit_floor(const V& v) noexcept;
16749+
16750+
template<@\exposconcept{simd-type}@ V>
16751+
constexpr typename V::mask_type has_single_bit(const V& v) noexcept;
16752+
16753+
template<@\exposconcept{simd-type}@ V0, @\exposconcept{simd-type}@ V1>
16754+
constexpr V0 rotl(const V0& v, const V1& s) noexcept;
16755+
template<@\exposconcept{simd-type}@ V>
16756+
constexpr V rotl(const V& v, int s) noexcept;
16757+
16758+
template<@\exposconcept{simd-type}@ V0, @\exposconcept{simd-type}@ V1>
16759+
constexpr V0 rotr(const V0& v, const V1& s) noexcept;
16760+
template<@\exposconcept{simd-type}@ V>
16761+
constexpr V rotr(const V& v, int s) noexcept;
16762+
16763+
template<@\exposconcept{simd-type}@ V>
16764+
constexpr rebind_simd_t<make_signed_t<typename V::value_type>, V> bit_width(const V& v) noexcept;
16765+
template<@\exposconcept{simd-type}@ V>
16766+
constexpr rebind_simd_t<make_signed_t<typename V::value_type>, V> countl_zero(const V& v) noexcept;
16767+
template<@\exposconcept{simd-type}@ V>
16768+
constexpr rebind_simd_t<make_signed_t<typename V::value_type>, V> countl_one(const V& v) noexcept;
16769+
template<@\exposconcept{simd-type}@ V>
16770+
constexpr rebind_simd_t<make_signed_t<typename V::value_type>, V> countr_zero(const V& v) noexcept;
16771+
template<@\exposconcept{simd-type}@ V>
16772+
constexpr rebind_simd_t<make_signed_t<typename V::value_type>, V> countr_one(const V& v) noexcept;
16773+
template<@\exposconcept{simd-type}@ V>
16774+
constexpr rebind_simd_t<make_signed_t<typename V::value_type>, V> popcount(const V& v) noexcept;
1673916775
}
1674016776
\end{codeblock}
1674116777

@@ -18436,6 +18472,160 @@
1843618472
\tcode{ret.first}.
1843718473
\end{itemdescr}
1843818474

18475+
\rSec3[simd.bit]{\tcode{basic_simd} bit library}
18476+
18477+
\begin{itemdecl}
18478+
template<@\exposconcept{simd-type}@ V> constexpr V byteswap(const V& v) noexcept;
18479+
\end{itemdecl}
18480+
18481+
\begin{itemdescr}
18482+
\pnum
18483+
\constraints
18484+
The type \tcode{V::value_type} models \tcode{integral}.
18485+
18486+
\pnum
18487+
\returns
18488+
A \tcode{basic_simd} object where the $i^\text{th}$ element is initialized to
18489+
the result of \tcode{std::byteswap(v[$i$])} for all $i$ in the range
18490+
\range{0}{V::size()}.
18491+
\end{itemdescr}
18492+
18493+
\begin{itemdecl}
18494+
template<@\exposconcept{simd-type}@ V> constexpr V bit_ceil(const V& v) noexcept;
18495+
\end{itemdecl}
18496+
18497+
\begin{itemdescr}
18498+
\pnum
18499+
\constraints
18500+
The type \tcode{V::value_type} is an unsigned integer type
18501+
\iref{basic.fundamental}.
18502+
18503+
\pnum
18504+
\expects
18505+
For every $i$ in the range \range{0}{V::size()}, the smallest power of 2
18506+
greater than or equal to \tcode{v[$i$]} is representable as a value of type
18507+
\tcode{V::value_type}.
18508+
18509+
\pnum
18510+
\returns
18511+
A \tcode{basic_simd} object where the $i^\text{th}$ element is initialized to
18512+
the result of \tcode{std::bit_ceil(v[$i$])} for all $i$ in the range
18513+
\range{0}{V::size()}.
18514+
18515+
\pnum
18516+
\remarks
18517+
A function call expression that violates the precondition in the \expects
18518+
element is not a core constant expression \iref{expr.const}.
18519+
\end{itemdescr}
18520+
18521+
\begin{itemdecl}
18522+
template<@\exposconcept{simd-type}@ V> constexpr V bit_floor(const V& v) noexcept;
18523+
\end{itemdecl}
18524+
18525+
\begin{itemdescr}
18526+
\pnum
18527+
\constraints
18528+
The type \tcode{V::value_type} is an unsigned integer type \iref{basic.fundamental}.
18529+
18530+
\pnum
18531+
\returns
18532+
A \tcode{basic_simd} object where the $i^\text{th}$ element is initialized to
18533+
the result of \tcode{std::bit_floor(v[$i$])} for all $i$ in the range
18534+
\range{0}{V::size()}.
18535+
\end{itemdescr}
18536+
18537+
\begin{itemdecl}
18538+
template<@\exposconcept{simd-type}@ V>
18539+
constexpr typename V::mask_type has_single_bit(const V& v) noexcept;
18540+
\end{itemdecl}
18541+
18542+
\begin{itemdescr}
18543+
\pnum
18544+
\constraints
18545+
The type \tcode{V::value_type} is an unsigned integer type \iref{basic.fundamental}.
18546+
18547+
\pnum
18548+
\returns
18549+
A \tcode{basic_simd_mask} object where the $i^\text{th}$ element is initialized
18550+
to the result of \tcode{std::has_single_bit(v[$i$])} for all $i$ in the range
18551+
\range{0}{V::size()}.
18552+
\end{itemdescr}
18553+
18554+
\begin{itemdecl}
18555+
template<@\exposconcept{simd-type}@ V0, @\exposconcept{simd-type}@ V1>
18556+
constexpr V0 rotl(const V0& v0, const V1& v1) noexcept;
18557+
template<@\exposconcept{simd-type}@ V0, @\exposconcept{simd-type}@ V1>
18558+
constexpr V0 rotr(const V0& v0, const V1& v1) noexcept;
18559+
\end{itemdecl}
18560+
18561+
\begin{itemdescr}
18562+
\pnum
18563+
\constraints
18564+
\begin{itemize}
18565+
\item
18566+
The type \tcode{V0::value_type} is an unsigned integer type \iref{basic.fundamental},
18567+
\item
18568+
the type \tcode{V1::value_type} models \tcode{integral},
18569+
\item
18570+
\tcode{V0::size() == V1::size()} is \tcode{true}, and
18571+
\item
18572+
\tcode{sizeof(typename V0::value_type) == sizeof(typename V1::value_type)} is \tcode{true}.
18573+
\end{itemize}
18574+
18575+
\pnum
18576+
\returns
18577+
A \tcode{basic_simd} object where the $i^\text{th}$ element is initialized to
18578+
the result of \tcode{\placeholder{bit-func}(v0[$i$],
18579+
static_cast<int>(v1[$i$]))} for all $i$ in the range \range{0}{V0::size()},
18580+
where \placeholder{bit-func} is the corresponding scalar function from \tcode{<bit>}.
18581+
\end{itemdescr}
18582+
18583+
\begin{itemdecl}
18584+
template<@\exposconcept{simd-type}@ V> constexpr V rotl(const V& v, int s) noexcept;
18585+
template<@\exposconcept{simd-type}@ V> constexpr V rotr(const V& v, int s) noexcept;
18586+
\end{itemdecl}
18587+
18588+
\begin{itemdescr}
18589+
\pnum
18590+
\constraints
18591+
The type \tcode{V::value_type} is an unsigned integer type \iref{basic.fundamental}
18592+
18593+
\pnum
18594+
\returns
18595+
A \tcode{basic_simd} object where the $i^\text{th}$ element is initialized to
18596+
the result of \tcode{\placeholder{bit-func}(v[$i$], s)} for all $i$ in the
18597+
range \range{0}{V::size()}, where \placeholder{bit-func} is the corresponding
18598+
scalar function from \tcode{<bit>}.
18599+
\end{itemdescr}
18600+
18601+
\begin{itemdecl}
18602+
template<@\exposconcept{simd-type}@ V>
18603+
constexpr rebind_simd_t<make_signed_t<typename V::value_type>, V> bit_width(const V& v) noexcept;
18604+
template<@\exposconcept{simd-type}@ V>
18605+
constexpr rebind_simd_t<make_signed_t<typename V::value_type>, V> countl_zero(const V& v) noexcept;
18606+
template<@\exposconcept{simd-type}@ V>
18607+
constexpr rebind_simd_t<make_signed_t<typename V::value_type>, V> countl_one(const V& v) noexcept;
18608+
template<@\exposconcept{simd-type}@ V>
18609+
constexpr rebind_simd_t<make_signed_t<typename V::value_type>, V> countr_zero(const V& v) noexcept;
18610+
template<@\exposconcept{simd-type}@ V>
18611+
constexpr rebind_simd_t<make_signed_t<typename V::value_type>, V> countr_one(const V& v) noexcept;
18612+
template<@\exposconcept{simd-type}@ V>
18613+
constexpr rebind_simd_t<make_signed_t<typename V::value_type>, V> popcount(const V& v) noexcept;
18614+
\end{itemdecl}
18615+
18616+
\begin{itemdescr}
18617+
\pnum
18618+
\constraints
18619+
The type \tcode{V::value_type} is an unsigned integer type \iref{basic.fundamental}
18620+
18621+
\pnum
18622+
\returns
18623+
A \tcode{basic_simd} object where the $i^\text{th}$ element is initialized to
18624+
the result of \tcode{\placeholder{bit-func}(v[$i$])} for all $i$ in the range
18625+
\range{0}{V::size()}, where \placeholder{bit-func} is the corresponding scalar
18626+
function from \tcode{<bit>}.
18627+
\end{itemdescr}
18628+
1843918629
\rSec2[simd.mask.class]{Class template \tcode{basic_simd_mask}}
1844018630

1844118631
\rSec3[simd.mask.overview]{Class template \tcode{basic_simd_mask} overview}

source/support.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,7 @@
782782
#define @\defnlibxname{cpp_lib_shared_ptr_weak_type}@ 201606L // also in \libheader{memory}
783783
#define @\defnlibxname{cpp_lib_shared_timed_mutex}@ 201402L // also in \libheader{shared_mutex}
784784
#define @\defnlibxname{cpp_lib_shift}@ 202202L // also in \libheader{algorithm}
785-
#define @\defnlibxname{cpp_lib_simd}@ 202411L // also in \libheader{simd}
785+
#define @\defnlibxname{cpp_lib_simd}@ 202502L // also in \libheader{simd}
786786
#define @\defnlibxname{cpp_lib_smart_ptr_for_overwrite}@ 202002L // also in \libheader{memory}
787787
#define @\defnlibxname{cpp_lib_smart_ptr_owner_equality}@ 202306L // also in \libheader{memory}
788788
#define @\defnlibxname{cpp_lib_source_location}@ 201907L // freestanding, also in \libheader{source_location}

0 commit comments

Comments
 (0)