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<array_
generic_convertible_to<value_type>... Args>
30 constexpr simd(Args... args)
noexcept requires(
sizeof...(Args) == N)
31 : array_type(generic_type::set(
static_cast<value_type
>(args)...))
35 template<array_
generic_convertible_to<value_type> Arg>
36 constexpr explicit simd(Arg arg) noexcept : array_type(generic_type::set(
static_cast<value_type
>(arg)))
40 template<array_
generic_convertible_to<value_type> O>
45 [[nodiscard]]
constexpr static simd make_undefined()
noexcept
47 return simd{generic_type::undefined()};
50 [[nodiscard]]
constexpr static simd make_zero()
noexcept
52 return simd{generic_type::set_zero()};
55 [[nodiscard]]
constexpr static simd make_one()
noexcept
57 return simd{generic_type::set_one()};
60 [[nodiscard]]
constexpr static simd make_all_ones()
noexcept
62 return simd{generic_type::set_all_ones()};
65 template<array_
generic_convertible_to<value_type> Arg>
66 [[nodiscard]]
constexpr static simd broadcast(Arg arg)
noexcept
68 return simd{generic_type::broadcast(
static_cast<value_type
>(arg))};
71 [[nodiscard]]
constexpr static simd broadcast(array_type arg)
noexcept
73 return simd{generic_type::broadcast(arg)};
76 [[nodiscard]]
constexpr static simd make_mask(
std::size_t mask)
noexcept
86 [[nodiscard]]
constexpr value_type x()
const noexcept
88 return generic_type::template get<0>(*
this);
91 [[nodiscard]]
constexpr value_type y()
const noexcept
93 return generic_type::template get<1>(*
this);
96 [[nodiscard]]
constexpr value_type z()
const noexcept
98 return generic_type::template get<2>(*
this);
101 [[nodiscard]]
constexpr value_type w()
const noexcept
103 return generic_type::template get<3>(*
this);
106 [[nodiscard]]
constexpr value_type& x()
noexcept
108 return std::get<0>(*
this);
111 [[nodiscard]]
constexpr value_type& y()
noexcept
113 return std::get<1>(*
this);
116 [[nodiscard]]
constexpr value_type& z()
noexcept
118 return std::get<2>(*
this);
121 [[nodiscard]]
constexpr value_type& w()
noexcept
123 return std::get<3>(*
this);
126 [[nodiscard]]
constexpr value_type r()
const noexcept
128 return generic_type::template get<0>(*
this);
131 [[nodiscard]]
constexpr value_type g()
const noexcept
133 return generic_type::template get<1>(*
this);
136 [[nodiscard]]
constexpr value_type b()
const noexcept
138 return generic_type::template get<2>(*
this);
141 [[nodiscard]]
constexpr value_type a()
const noexcept
143 return generic_type::template get<3>(*
this);
146 [[nodiscard]]
constexpr value_type& r()
noexcept
148 return std::get<0>(*
this);
151 [[nodiscard]]
constexpr value_type& g()
noexcept
153 return std::get<1>(*
this);
156 [[nodiscard]]
constexpr value_type& b()
noexcept
158 return std::get<2>(*
this);
161 [[nodiscard]]
constexpr value_type& a()
noexcept
163 return std::get<3>(*
this);
166 [[nodiscard]]
constexpr value_type width()
const noexcept
168 return generic_type::template get<0>(*
this);
171 [[nodiscard]]
constexpr value_type height()
const noexcept
173 return generic_type::template get<1>(*
this);
176 [[nodiscard]]
constexpr value_type depth()
const noexcept
178 return generic_type::template get<2>(*
this);
181 [[nodiscard]]
constexpr value_type& width()
noexcept
183 return std::get<0>(*
this);
186 [[nodiscard]]
constexpr value_type& height()
noexcept
188 return std::get<1>(*
this);
191 [[nodiscard]]
constexpr value_type& depth()
noexcept
193 return std::get<2>(*
this);
196 [[nodiscard]]
constexpr friend simd operator-(array_type a)
noexcept
198 return simd{generic_type::neg(a)};
201 template<std::
size_t Mask>
202 [[nodiscard]]
constexpr friend simd neg_mask(array_type a)
noexcept
204 return simd{generic_type::template neg_mask<Mask>(a)};
207 [[nodiscard]]
constexpr friend simd operator~(array_type a)
noexcept
209 return simd{generic_type::inv(a)};
212 [[nodiscard]]
constexpr friend simd rcp(array_type a)
noexcept
214 return simd{generic_type::rcp(a)};
217 [[nodiscard]]
constexpr friend simd sqrt(array_type a)
noexcept
219 return simd{generic_type::sqrt(a)};
222 [[nodiscard]]
constexpr friend simd rsqrt(array_type a)
noexcept
224 return simd{generic_type::rsqrt(a)};
227 [[nodiscard]]
constexpr friend simd abs(array_type a)
noexcept
229 return simd{generic_type::abs(a)};
232 [[nodiscard]]
constexpr friend simd round(array_type a)
noexcept
234 return simd{generic_type::round(a)};
237 [[nodiscard]]
constexpr friend simd floor(array_type a)
noexcept
239 return simd{generic_type::floor(a)};
242 [[nodiscard]]
constexpr friend simd ceil(array_type a)
noexcept
244 return simd{generic_type::ceil(a)};
247 [[nodiscard]]
constexpr friend simd operator+(array_type a, array_type b)
noexcept
249 return simd{generic_type::add(a, b)};
252 [[nodiscard]]
constexpr friend simd operator-(array_type a, array_type b)
noexcept
254 return simd{generic_type::sub(a, b)};
257 template<std::
size_t Mask>
258 [[nodiscard]]
constexpr friend simd addsub_mask(array_type a, array_type b)
noexcept
260 return simd{generic_type::template addsub_mask<Mask>(a, b)};
263 [[nodiscard]]
constexpr friend simd operator*(array_type a, array_type b)
noexcept
265 return simd{generic_type::mul(a, b)};
268 [[nodiscard]]
constexpr friend simd operator/(array_type a, array_type b)
noexcept
270 return simd{generic_type::div(a, b)};
273 [[nodiscard]]
constexpr friend simd operator%(array_type a, array_type b)
noexcept
275 return simd{generic_type::mod(a, b)};
278 [[nodiscard]]
constexpr friend simd operator==(array_type a, array_type b)
noexcept
280 return simd{generic_type::eq(a, b)};
283 [[nodiscard]]
constexpr friend simd operator!=(array_type a, array_type b)
noexcept
285 return simd{generic_type::ne(a, b)};
288 [[nodiscard]]
constexpr friend simd operator<(array_type a, array_type b)
noexcept
290 return simd{generic_type::lt(a, b)};
293 [[nodiscard]]
constexpr friend simd operator>(array_type a, array_type b)
noexcept
295 return simd{generic_type::gt(a, b)};
298 [[nodiscard]]
constexpr friend simd operator<=(array_type a, array_type b)
noexcept
300 return simd{generic_type::le(a, b)};
303 [[nodiscard]]
constexpr friend simd operator>=(array_type a, array_type b)
noexcept
305 return simd{generic_type::ge(a, b)};
308 [[nodiscard]]
constexpr friend bool test(array_type a, array_type b)
noexcept
313 [[nodiscard]]
constexpr friend bool equal(array_type a, array_type b)
noexcept
318 [[nodiscard]]
constexpr friend simd max(
simd a,
simd b)
noexcept
320 return simd{generic_type::max(a, b)};
323 [[nodiscard]]
constexpr friend simd min(
simd a,
simd b)
noexcept
325 return simd{generic_type::min(a, b)};
330 return simd{generic_type::clamp(v, lo,
hi)};
333 [[nodiscard]]
constexpr friend simd operator|(array_type a, array_type b)
noexcept
335 return simd{generic_type::_or(a, b)};
338 [[nodiscard]]
constexpr friend simd operator&(array_type a, array_type b)
noexcept
340 return simd{generic_type::_and(a, b)};
343 [[nodiscard]]
constexpr friend simd operator^(array_type a, array_type b)
noexcept
345 return simd{generic_type::_xor(a, b)};
348 [[nodiscard]]
constexpr friend simd sll(array_type a,
unsigned int b)
noexcept
350 return simd{generic_type::sll(a, b)};
353 [[nodiscard]]
constexpr friend simd sra(array_type a,
unsigned int b)
noexcept
355 return simd{generic_type::sra(a, b)};
358 [[nodiscard]]
constexpr friend simd srl(array_type a,
unsigned int b)
noexcept
360 return simd{generic_type::srl(a, b)};
363 [[nodiscard]]
constexpr friend simd operator<<(array_type a,
unsigned int b)
noexcept
365 return simd{generic_type::sll(a, b)};
368 [[nodiscard]]
constexpr friend simd operator>>(array_type a,
unsigned int b)
noexcept
370 if constexpr (std::signed_integral<value_type>) {
371 return simd{generic_type::sra(a, b)};
373 return simd{generic_type::srl(a, b)};
377 [[nodiscard]]
constexpr friend simd andnot(array_type a, array_type b)
noexcept
382 [[nodiscard]]
constexpr friend simd hadd(array_type a, array_type b)
noexcept
387 [[nodiscard]]
constexpr friend simd hsub(array_type a, array_type b)
noexcept
389 return simd{generic_type::hsub(a, b)};
392 template<
int... Indices>
393 [[nodiscard]]
constexpr friend simd shuffle(array_type a)
noexcept
395 return simd{generic_type::template shuffle<Indices...>(a)};
398 template<std::
size_t Mask>
399 [[nodiscard]]
constexpr friend simd blend(array_type a, array_type b)
noexcept
401 return simd{generic_type::template blend<Mask>(a, b)};
404 template<
int... Indices>
405 [[nodiscard]]
constexpr friend simd swizzle(array_type a)
noexcept
407 return simd{generic_type::template swizzle<Indices...>(a)};
410 [[nodiscard]]
constexpr friend simd sum(array_type a)
noexcept
412 return simd{generic_type::sum(a)};
415 template<std::
size_t Mask>
416 [[nodiscard]]
constexpr friend simd dot(array_type a, array_type b)
noexcept
418 return simd{generic_type::template dot<Mask>(a, b)};
421 template<std::
size_t Mask>
422 [[nodiscard]]
constexpr friend simd hypot(array_type a)
noexcept
424 return simd{generic_type::template hypot<Mask>(a)};
427 template<std::
size_t Mask>
428 [[nodiscard]]
constexpr friend simd rhypot(array_type a)
noexcept
430 return simd{generic_type::template rhypot<Mask>(a)};
433 template<std::
size_t Mask>
434 [[nodiscard]]
constexpr friend simd normalize(array_type a)
noexcept
436 return simd{generic_type::template normalize<Mask>(a)};
439 template<std::derived_from<array_type>... Columns>
442 auto const tmp = generic_type::template transpose<Columns...>(columns...);
450 constexpr simd& operator+=(array_type a)
noexcept
452 return *
this = *
this + a;
455 constexpr simd& operator-=(array_type a)
noexcept
457 return *
this = *
this - a;
460 constexpr simd& operator*=(array_type a)
noexcept
462 return *
this = *
this * a;
465 constexpr simd& operator/=(array_type a)
noexcept
467 return *
this = *
this / a;
470 constexpr simd& operator%=(array_type a)
noexcept
472 return *
this = *
this % a;
475 constexpr simd& operator|=(array_type a)
noexcept
477 return *
this = *
this | a;
480 constexpr simd& operator&=(array_type a)
noexcept
482 return *
this = *
this & a;
485 constexpr simd& operator^=(array_type a)
noexcept
487 return *
this = *
this ^ a;
490#define X_SWIZZLE_2D(NAME, X, Y) \
491 [[nodiscard]] constexpr simd NAME() const noexcept requires(N == 2) \
493 return swizzle<X, Y>(*this); \
496#define X_SWIZZLE_2D_Y(NAME, X) \
497 X_SWIZZLE_2D(NAME##1, X, -2) \
498 X_SWIZZLE_2D(NAME##0, X, -1) \
499 X_SWIZZLE_2D(NAME##x, X, 0) \
500 X_SWIZZLE_2D(NAME##y, X, 1)
502 X_SWIZZLE_2D_Y(_1, -2)
503 X_SWIZZLE_2D_Y(_0, -1)
507#define X_SWIZZLE_4D(NAME, X, Y, Z, W) \
508 [[nodiscard]] constexpr simd NAME() const noexcept requires(N == 4) \
510 return swizzle<X, Y, Z, W>(*this); \
513#define X_SWIZZLE_4D_W(NAME, X, Y, Z) \
514 X_SWIZZLE_4D(NAME##1, X, Y, Z, -2) \
515 X_SWIZZLE_4D(NAME##0, X, Y, Z, -1) \
516 X_SWIZZLE_4D(NAME##x, X, Y, Z, 0) \
517 X_SWIZZLE_4D(NAME##y, X, Y, Z, 1) \
518 X_SWIZZLE_4D(NAME##z, X, Y, Z, 2) \
519 X_SWIZZLE_4D(NAME##w, X, Y, Z, 3)
521#define X_SWIZZLE_4D_Z(NAME, X, Y) \
522 X_SWIZZLE_4D_W(NAME##1, X, Y, -2) \
523 X_SWIZZLE_4D_W(NAME##0, X, Y, -1) \
524 X_SWIZZLE_4D_W(NAME##x, X, Y, 0) \
525 X_SWIZZLE_4D_W(NAME##y, X, Y, 1) \
526 X_SWIZZLE_4D_W(NAME##z, X, Y, 2) \
527 X_SWIZZLE_4D_W(NAME##w, X, Y, 3)
529#define X_SWIZZLE_4D_Y(NAME, X) \
530 X_SWIZZLE_4D_Z(NAME##1, X, -2) \
531 X_SWIZZLE_4D_Z(NAME##0, X, -1) \
532 X_SWIZZLE_4D_Z(NAME##x, X, 0) \
533 X_SWIZZLE_4D_Z(NAME##y, X, 1) \
534 X_SWIZZLE_4D_Z(NAME##z, X, 2) \
535 X_SWIZZLE_4D_Z(NAME##w, X, 3)
537 X_SWIZZLE_4D_Y(_1, -2)
538 X_SWIZZLE_4D_Y(_0, -1)