23 constexpr simd()
noexcept =
default;
24 constexpr simd(
simd const&)
noexcept =
default;
25 constexpr simd(
simd&&)
noexcept =
default;
26 constexpr simd& operator=(
simd const&)
noexcept =
default;
27 constexpr simd& operator=(
simd&&)
noexcept =
default;
29 template<std::same_as<value_type>... Args>
31 requires(
sizeof...(Args) == N)
32 : array_type(generic_type::set(
args...))
36 constexpr explicit simd(value_type a)
noexcept : array_type(generic_type::set(a)) {}
45 return simd{generic_type::undefined()};
50 return simd{generic_type::set_zero()};
55 return simd{generic_type::set_one()};
60 return simd{generic_type::set_all_ones()};
63 [[
nodiscard]]
constexpr static simd broadcast(value_type a)
noexcept
65 return simd{generic_type::broadcast(a)};
68 [[
nodiscard]]
constexpr static simd broadcast(array_type a)
noexcept
70 return simd{generic_type::broadcast(a)};
83 [[
nodiscard]]
constexpr value_type x()
const noexcept
85 return generic_type::template
get<0>(*
this);
88 [[
nodiscard]]
constexpr value_type y()
const noexcept
90 return generic_type::template
get<1>(*
this);
93 [[
nodiscard]]
constexpr value_type z()
const noexcept
95 return generic_type::template
get<2>(*
this);
98 [[
nodiscard]]
constexpr value_type w()
const noexcept
100 return generic_type::template
get<3>(*
this);
103 [[
nodiscard]]
constexpr value_type& x()
noexcept
105 return std::get<0>(*
this);
108 [[
nodiscard]]
constexpr value_type& y()
noexcept
110 return std::get<1>(*
this);
113 [[
nodiscard]]
constexpr value_type& z()
noexcept
115 return std::get<2>(*
this);
118 [[
nodiscard]]
constexpr value_type& w()
noexcept
120 return std::get<3>(*
this);
123 [[
nodiscard]]
constexpr value_type r()
const noexcept
125 return generic_type::template
get<0>(*
this);
128 [[
nodiscard]]
constexpr value_type g()
const noexcept
130 return generic_type::template
get<1>(*
this);
133 [[
nodiscard]]
constexpr value_type b()
const noexcept
135 return generic_type::template
get<2>(*
this);
138 [[
nodiscard]]
constexpr value_type a()
const noexcept
140 return generic_type::template
get<3>(*
this);
143 [[
nodiscard]]
constexpr value_type& r()
noexcept
145 return std::get<0>(*
this);
148 [[
nodiscard]]
constexpr value_type& g()
noexcept
150 return std::get<1>(*
this);
153 [[
nodiscard]]
constexpr value_type& b()
noexcept
155 return std::get<2>(*
this);
158 [[
nodiscard]]
constexpr value_type& a()
noexcept
160 return std::get<3>(*
this);
163 [[
nodiscard]]
constexpr value_type width()
const noexcept
165 return generic_type::template
get<0>(*
this);
168 [[
nodiscard]]
constexpr value_type height()
const noexcept
170 return generic_type::template
get<1>(*
this);
173 [[
nodiscard]]
constexpr value_type depth()
const noexcept
175 return generic_type::template
get<2>(*
this);
178 [[
nodiscard]]
constexpr value_type& width()
noexcept
180 return std::get<0>(*
this);
183 [[
nodiscard]]
constexpr value_type& height()
noexcept
185 return std::get<1>(*
this);
188 [[
nodiscard]]
constexpr value_type& depth()
noexcept
190 return std::get<2>(*
this);
193 [[
nodiscard]]
constexpr friend simd operator-(array_type a)
noexcept
195 return simd{generic_type::neg(a)};
198 template<std::
size_t Mask>
199 [[
nodiscard]]
constexpr friend simd neg_mask(array_type a)
noexcept
204 [[
nodiscard]]
constexpr friend simd operator~(array_type a)
noexcept
206 return simd{generic_type::inv(a)};
209 [[
nodiscard]]
constexpr friend simd rcp(array_type a)
noexcept
211 return simd{generic_type::rcp(a)};
214 [[
nodiscard]]
constexpr friend simd sqrt(array_type a)
noexcept
216 return simd{generic_type::sqrt(a)};
219 [[
nodiscard]]
constexpr friend simd rsqrt(array_type a)
noexcept
221 return simd{generic_type::rsqrt(a)};
224 [[
nodiscard]]
constexpr friend simd abs(array_type a)
noexcept
226 return simd{generic_type::abs(a)};
229 [[
nodiscard]]
constexpr friend simd round(array_type a)
noexcept
231 return simd{generic_type::round(a)};
234 [[
nodiscard]]
constexpr friend simd floor(array_type a)
noexcept
236 return simd{generic_type::floor(a)};
239 [[
nodiscard]]
constexpr friend simd ceil(array_type a)
noexcept
241 return simd{generic_type::ceil(a)};
244 [[
nodiscard]]
constexpr friend simd operator+(array_type a, array_type b)
noexcept
246 return simd{generic_type::add(a, b)};
249 [[
nodiscard]]
constexpr friend simd operator-(array_type a, array_type b)
noexcept
251 return simd{generic_type::sub(a, b)};
254 template<std::
size_t Mask>
255 [[
nodiscard]]
constexpr friend simd addsub_mask(array_type a, array_type b)
noexcept
260 [[
nodiscard]]
constexpr friend simd operator*(array_type a, array_type b)
noexcept
262 return simd{generic_type::mul(a, b)};
265 [[
nodiscard]]
constexpr friend simd operator/(array_type a, array_type b)
noexcept
267 return simd{generic_type::div(a, b)};
270 [[
nodiscard]]
constexpr friend simd operator%(array_type a, array_type b)
noexcept
272 return simd{generic_type::mod(a, b)};
275 [[
nodiscard]]
constexpr friend simd operator==(array_type a, array_type b)
noexcept
277 return simd{generic_type::eq(a, b)};
280 [[
nodiscard]]
constexpr friend simd operator!=(array_type a, array_type b)
noexcept
282 return simd{generic_type::ne(a, b)};
285 [[
nodiscard]]
constexpr friend simd operator<(array_type a, array_type b)
noexcept
287 return simd{generic_type::lt(a, b)};
290 [[
nodiscard]]
constexpr friend simd operator>(array_type a, array_type b)
noexcept
292 return simd{generic_type::gt(a, b)};
295 [[
nodiscard]]
constexpr friend simd operator<=(array_type a, array_type b)
noexcept
297 return simd{generic_type::le(a, b)};
300 [[
nodiscard]]
constexpr friend simd operator>=(array_type a, array_type b)
noexcept
302 return simd{generic_type::ge(a, b)};
305 [[
nodiscard]]
constexpr friend bool test(array_type a, array_type b)
noexcept
310 [[
nodiscard]]
constexpr friend bool equal(array_type a, array_type b)
noexcept
317 return simd{generic_type::max(a, b)};
322 return simd{generic_type::min(a, b)};
327 return simd{generic_type::clamp(v,
lo,
hi)};
330 [[
nodiscard]]
constexpr friend simd operator|(array_type a, array_type b)
noexcept
332 return simd{generic_type::_or(a, b)};
335 [[
nodiscard]]
constexpr friend simd operator&(array_type a, array_type b)
noexcept
337 return simd{generic_type::_and(a, b)};
340 [[
nodiscard]]
constexpr friend simd operator^(array_type a, array_type b)
noexcept
342 return simd{generic_type::_xor(a, b)};
345 [[
nodiscard]]
constexpr friend simd sll(array_type a,
unsigned int b)
noexcept
347 return simd{generic_type::sll(a, b)};
350 [[
nodiscard]]
constexpr friend simd sra(array_type a,
unsigned int b)
noexcept
352 return simd{generic_type::sra(a, b)};
355 [[
nodiscard]]
constexpr friend simd srl(array_type a,
unsigned int b)
noexcept
357 return simd{generic_type::srl(a, b)};
360 [[
nodiscard]]
constexpr friend simd operator<<(array_type a,
unsigned int b)
noexcept
362 return simd{generic_type::sll(a, b)};
365 [[
nodiscard]]
constexpr friend simd operator>>(array_type a,
unsigned int b)
noexcept
367 if constexpr (std::signed_integral<value_type>) {
368 return simd{generic_type::sra(a, b)};
370 return simd{generic_type::srl(a, b)};
374 [[
nodiscard]]
constexpr friend simd andnot(array_type a, array_type b)
noexcept
379 [[
nodiscard]]
constexpr friend simd hadd(array_type a, array_type b)
noexcept
384 [[
nodiscard]]
constexpr friend simd hsub(array_type a, array_type b)
noexcept
386 return simd{generic_type::hsub(a, b)};
390 [[
nodiscard]]
constexpr friend simd shuffle(array_type a)
noexcept
392 return simd{generic_type::template shuffle<
Indices...>(a)};
395 template<std::
size_t Mask>
396 [[
nodiscard]]
constexpr friend simd blend(array_type a, array_type b)
noexcept
402 [[
nodiscard]]
constexpr friend simd swizzle(array_type a)
noexcept
404 return simd{generic_type::template swizzle<
Indices...>(a)};
407 [[
nodiscard]]
constexpr friend simd sum(array_type a)
noexcept
409 return simd{generic_type::sum(a)};
412 template<std::
size_t Mask>
413 [[
nodiscard]]
constexpr friend simd dot(array_type a, array_type b)
noexcept
418 template<std::
size_t Mask>
419 [[
nodiscard]]
constexpr friend simd hypot(array_type a)
noexcept
424 template<std::
size_t Mask>
425 [[
nodiscard]]
constexpr friend simd rhypot(array_type a)
noexcept
430 template<std::
size_t Mask>
431 [[
nodiscard]]
constexpr friend simd normalize(array_type a)
noexcept
436 template<std::derived_from<array_type>... Columns>
439 auto const tmp = generic_type::template transpose<
Columns...>(columns...);
447 constexpr simd& operator+=(array_type a)
noexcept
449 return *
this = *
this + a;
452 constexpr simd& operator-=(array_type a)
noexcept
454 return *
this = *
this - a;
457 constexpr simd& operator*=(array_type a)
noexcept
459 return *
this = *
this * a;
462 constexpr simd& operator/=(array_type a)
noexcept
464 return *
this = *
this / a;
467 constexpr simd& operator%=(array_type a)
noexcept
469 return *
this = *
this % a;
472 constexpr simd& operator|=(array_type a)
noexcept
474 return *
this = *
this | a;
477 constexpr simd& operator&=(array_type a)
noexcept
479 return *
this = *
this & a;
482 constexpr simd& operator^=(array_type a)
noexcept
484 return *
this = *
this ^ a;
487#define X_SWIZZLE_2D(NAME, X, Y) \
488 [[nodiscard]] constexpr simd NAME() const noexcept \
491 return swizzle<X, Y>(*this); \
494#define X_SWIZZLE_2D_Y(NAME, X) \
495 X_SWIZZLE_2D(NAME##1, X, -2) \
496 X_SWIZZLE_2D(NAME##0, X, -1) \
497 X_SWIZZLE_2D(NAME##x, X, 0) \
498 X_SWIZZLE_2D(NAME##y, X, 1)
500 X_SWIZZLE_2D_Y(_1, -2)
501 X_SWIZZLE_2D_Y(_0, -1)
505#define X_SWIZZLE_4D(NAME, X, Y, Z, W) \
506 [[nodiscard]] constexpr simd NAME() const noexcept \
509 return swizzle<X, Y, Z, W>(*this); \
512#define X_SWIZZLE_4D_W(NAME, X, Y, Z) \
513 X_SWIZZLE_4D(NAME##1, X, Y, Z, -2) \
514 X_SWIZZLE_4D(NAME##0, X, Y, Z, -1) \
515 X_SWIZZLE_4D(NAME##x, X, Y, Z, 0) \
516 X_SWIZZLE_4D(NAME##y, X, Y, Z, 1) \
517 X_SWIZZLE_4D(NAME##z, X, Y, Z, 2) \
518 X_SWIZZLE_4D(NAME##w, X, Y, Z, 3)
520#define X_SWIZZLE_4D_Z(NAME, X, Y) \
521 X_SWIZZLE_4D_W(NAME##1, X, Y, -2) \
522 X_SWIZZLE_4D_W(NAME##0, X, Y, -1) \
523 X_SWIZZLE_4D_W(NAME##x, X, Y, 0) \
524 X_SWIZZLE_4D_W(NAME##y, X, Y, 1) \
525 X_SWIZZLE_4D_W(NAME##z, X, Y, 2) \
526 X_SWIZZLE_4D_W(NAME##w, X, Y, 3)
528#define X_SWIZZLE_4D_Y(NAME, X) \
529 X_SWIZZLE_4D_Z(NAME##1, X, -2) \
530 X_SWIZZLE_4D_Z(NAME##0, X, -1) \
531 X_SWIZZLE_4D_Z(NAME##x, X, 0) \
532 X_SWIZZLE_4D_Z(NAME##y, X, 1) \
533 X_SWIZZLE_4D_Z(NAME##z, X, 2) \
534 X_SWIZZLE_4D_Z(NAME##w, X, 3)
536 X_SWIZZLE_4D_Y(_1, -2)
537 X_SWIZZLE_4D_Y(_0, -1)