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>
30 constexpr simd(Args... args)
noexcept
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)) {}
43 [[nodiscard]]
constexpr static simd make_undefined()
noexcept
45 return simd{generic_type::undefined()};
48 [[nodiscard]]
constexpr static simd make_zero()
noexcept
50 return simd{generic_type::set_zero()};
53 [[nodiscard]]
constexpr static simd make_one()
noexcept
55 return simd{generic_type::set_one()};
58 [[nodiscard]]
constexpr static simd make_all_ones()
noexcept
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)};
73 [[nodiscard]]
constexpr static simd make_mask(
std::size_t mask)
noexcept
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
201 return simd{generic_type::template neg_mask<Mask>(a)};
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
257 return simd{generic_type::template addsub_mask<Mask>(a, b)};
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
315 [[nodiscard]]
constexpr friend simd max(
simd a,
simd b)
noexcept
317 return simd{generic_type::max(a, b)};
320 [[nodiscard]]
constexpr friend simd min(
simd a,
simd b)
noexcept
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)};
389 template<
int... Indices>
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
398 return simd{generic_type::template blend<Mask>(a, b)};
401 template<
int... Indices>
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
415 return simd{generic_type::template dot<Mask>(a, b)};
418 template<std::
size_t Mask>
419 [[nodiscard]]
constexpr friend simd hypot(array_type a)
noexcept
421 return simd{generic_type::template hypot<Mask>(a)};
424 template<std::
size_t Mask>
425 [[nodiscard]]
constexpr friend simd rhypot(array_type a)
noexcept
427 return simd{generic_type::template rhypot<Mask>(a)};
430 template<std::
size_t Mask>
431 [[nodiscard]]
constexpr friend simd normalize(array_type a)
noexcept
433 return simd{generic_type::template normalize<Mask>(a)};
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;
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)