54 tt_force_inline
vec() noexcept :
vec(_mm_setzero_ps()) {}
55 tt_force_inline
vec(
vec const &rhs)
noexcept =
default;
56 tt_force_inline
vec &operator=(
vec const &rhs)
noexcept =
default;
57 tt_force_inline
vec(
vec &&rhs)
noexcept =
default;
58 tt_force_inline
vec &operator=(
vec &&rhs)
noexcept =
default;
60 tt_force_inline
vec(__m128 rhs) noexcept :
63 tt_force_inline
vec &operator=(__m128 rhs)
noexcept {
68 tt_force_inline
operator __m128 ()
const noexcept {
73 v(_mm_loadu_ps(rhs.data())) {}
76 v = _mm_loadu_ps(rhs.data());
82 _mm_storeu_ps(r.
data(), v);
87 v(_mm_loadl_pi(_mm_setzero_ps(),
reinterpret_cast<__m64
const *
>(rhs.data()))) {}
90 v = _mm_loadl_pi(_mm_setzero_ps(),
reinterpret_cast<__m64
const *
>(rhs.data()));
96 _mm_storel_pi(
reinterpret_cast<__m64 *
>(r.
data()), v);
101 v(_mm_cvtph_ps(_mm_loadu_si64(rhs.data()))) {}
104 v = _mm_cvtph_ps(_mm_loadu_si64(rhs.data()));
110 _mm_storeu_si64(r.
data(), _mm_cvtps_ph(v, _MM_FROUND_CUR_DIRECTION));
118 template<
typename T, std::enable_if_t<std::is_arithmetic_v<T>,
int> = 0>
119 explicit tt_force_inline
vec(T rhs)
noexcept:
120 vec(_mm_set_ps1(numeric_cast<float>(rhs))) {}
127 return *
this = _mm_set_ps1(rhs);
139 tt_force_inline
vec(
float x,
float y,
float z=0.0f,
float w=0.0f) noexcept :
140 v(_mm_set_ps(w, z, y, x)) {}
142 tt_force_inline
vec(
double x,
double y) noexcept :
143 v(_mm_cvtpd_ps(_mm_set_pd(y, x))) {}
145 tt_force_inline vec(
double x,
double y,
double z,
double w=0.0f) noexcept :
146 v(_mm256_cvtpd_ps(_mm256_set_pd(w, z, y, x))) {}
148 tt_force_inline vec(
int x,
int y,
int z=0,
int w=0) noexcept :
149 v(_mm_cvtepi32_ps(_mm_set_epi32(w, z, y, x))) {}
151 template<
typename T, std::enable_if_t<std::is_arithmetic_v<T>,
int> = 0>
152 tt_force_inline
static vec make_x(T x)
noexcept {
153 return vec{_mm_set_ss(numeric_cast<float>(x))};
156 template<
typename T, std::enable_if_t<std::is_arithmetic_v<T>,
int> = 0>
157 tt_force_inline
static vec make_y(T y)
noexcept {
158 return vec{_mm_permute_ps(_mm_set_ss(numeric_cast<float>(y)), _MM_SHUFFLE(1,1,0,1))};
161 template<
typename T, std::enable_if_t<std::is_arithmetic_v<T>,
int> = 0>
162 tt_force_inline
static vec make_z(T z)
noexcept {
163 return vec{_mm_permute_ps(_mm_set_ss(numeric_cast<float>(z)), _MM_SHUFFLE(1,0,1,1))};
166 template<
typename T, std::enable_if_t<std::is_arithmetic_v<T>,
int> = 0>
167 tt_force_inline
static vec make_w(T w)
noexcept {
168 return vec{_mm_permute_ps(_mm_set_ss(numeric_cast<float>(w)), _MM_SHUFFLE(0,1,1,1))};
180 [[nodiscard]] tt_force_inline
static vec point(
float x=0.0f,
float y=0.0f,
float z=0.0f) noexcept {
181 return vec{x, y, z, 1.0f};
184 [[nodiscard]] tt_force_inline
static vec point(
int x=0.0f,
int y=0.0f,
int z=0.0f) noexcept {
185 return vec{x, y, z, 1};
198 [[nodiscard]] tt_force_inline
static vec point(
vec rhs)
noexcept {
209 [[nodiscard]] tt_force_inline
static vec origin() noexcept {
210 return vec{_mm_permute_ps(_mm_set_ss(1.0f), 0b00'01'10'11)};
226 [[nodiscard]] tt_force_inline
static vec color(
float r,
float g,
float b,
float a=1.0f) noexcept {
227 return vec{r, g, b, a};
230 [[nodiscard]]
static vec colorFromSRGB(
float r,
float g,
float b,
float a=1.0f) noexcept;
232 [[nodiscard]] static
vec colorFromSRGB(uint8_t r, uint8_t g, uint8_t b, uint8_t a=255) noexcept;
234 [[nodiscard]] static
vec colorFromSRGB(
std::string_view str);
237 tt_force_inline
vec &set(
float rhs) noexcept {
238 static_assert(I <= 3);
239 ttlet tmp = _mm_set_ss(rhs);
240 return *
this = _mm_insert_ps(*
this, tmp, I << 4);
244 tt_force_inline
float get() const noexcept {
245 static_assert(I <= 3);
246 ttlet tmp = _mm_permute_ps(*
this, I);
247 return _mm_cvtss_f32(tmp);
250 tt_force_inline
bool is_point() const noexcept {
254 tt_force_inline
bool is_vector() const noexcept {
258 tt_force_inline
bool is_opaque() const noexcept {
262 tt_force_inline
bool is_transparent() const noexcept {
266 constexpr size_t size() const noexcept {
270 tt_force_inline
float operator[](
size_t i)
const noexcept {
272 ttlet i_ = _mm_set1_epi32(
static_cast<uint32_t
>(i));
273 ttlet tmp = _mm_permutevar_ps(*
this, i_);
274 return _mm_cvtss_f32(tmp);
277 tt_force_inline vec &x(
float rhs)
noexcept {
return set<0>(rhs); }
278 tt_force_inline vec &y(
float rhs)
noexcept {
return set<1>(rhs); }
279 tt_force_inline vec &z(
float rhs)
noexcept {
return set<2>(rhs); }
280 tt_force_inline vec &w(
float rhs)
noexcept {
return set<3>(rhs); }
281 tt_force_inline vec &r(
float rhs)
noexcept {
return set<0>(rhs); }
282 tt_force_inline vec &g(
float rhs)
noexcept {
return set<1>(rhs); }
283 tt_force_inline vec &b(
float rhs)
noexcept {
return set<2>(rhs); }
284 tt_force_inline vec &a(
float rhs)
noexcept {
return set<3>(rhs); }
285 tt_force_inline vec &width(
float rhs)
noexcept {
return set<0>(rhs); }
286 tt_force_inline vec &height(
float rhs)
noexcept {
return set<1>(rhs); }
287 tt_force_inline vec &depth(
float rhs)
noexcept {
return set<2>(rhs); }
288 tt_force_inline
float x() const noexcept {
return get<0>(); }
289 tt_force_inline
float y() const noexcept {
return get<1>(); }
290 tt_force_inline
float z() const noexcept {
return get<2>(); }
291 tt_force_inline
float w() const noexcept {
return get<3>(); }
292 tt_force_inline
float r() const noexcept {
return get<0>(); }
293 tt_force_inline
float g() const noexcept {
return get<1>(); }
294 tt_force_inline
float b() const noexcept {
return get<2>(); }
295 tt_force_inline
float a() const noexcept {
return get<3>(); }
296 tt_force_inline
float width() const noexcept {
return get<0>(); }
297 tt_force_inline
float height() const noexcept {
return get<1>(); }
298 tt_force_inline
float depth() const noexcept {
return get<2>(); }
301 tt_force_inline vec &operator+=(vec
const &rhs)
noexcept {
302 return *
this = _mm_add_ps(*
this, rhs);
305 tt_force_inline vec &operator-=(vec
const &rhs)
noexcept {
306 return *
this = _mm_sub_ps(*
this, rhs);
309 tt_force_inline vec &operator*=(vec
const &rhs)
noexcept {
310 return *
this = _mm_mul_ps(*
this, rhs);
313 tt_force_inline vec &operator/=(vec
const &rhs)
noexcept {
314 return *
this = _mm_div_ps(*
this, rhs);
317 [[nodiscard]] tt_force_inline
friend vec operator-(vec
const &rhs)
noexcept {
318 return _mm_sub_ps(_mm_setzero_ps(), rhs);
321 [[nodiscard]] tt_force_inline
friend vec operator+(vec
const &lhs, vec
const &rhs)
noexcept {
322 return _mm_add_ps(lhs, rhs);
325 [[nodiscard]] tt_force_inline
friend vec operator-(vec
const &lhs, vec
const &rhs)
noexcept {
326 return _mm_sub_ps(lhs, rhs);
329 [[nodiscard]] tt_force_inline
friend vec operator*(vec
const &lhs, vec
const &rhs)
noexcept {
330 return _mm_mul_ps(lhs, rhs);
333 template<
typename T, std::enable_if_t<std::is_arithmetic_v<T>,
int> = 0>
334 [[nodiscard]] tt_force_inline
friend vec operator*(vec
const &lhs, T
const &rhs)
noexcept {
335 return lhs * vec{rhs};
338 template<
typename T, std::enable_if_t<std::is_arithmetic_v<T>,
int> = 0>
339 [[nodiscard]] tt_force_inline
friend vec operator*(T
const &lhs, vec
const &rhs)
noexcept {
340 return vec{lhs} * rhs;
343 [[nodiscard]] tt_force_inline
friend vec operator/(vec
const &lhs, vec
const &rhs)
noexcept {
344 return _mm_div_ps(lhs, rhs);
347 [[nodiscard]] tt_force_inline
friend vec max(vec
const &lhs, vec
const &rhs)
noexcept {
348 return _mm_max_ps(lhs, rhs);
351 [[nodiscard]] tt_force_inline
friend vec min(vec
const &lhs, vec
const &rhs)
noexcept {
352 return _mm_min_ps(lhs, rhs);
355 [[nodiscard]] tt_force_inline
friend vec abs(vec
const &rhs)
noexcept {
356 return max(rhs, -rhs);
362 [[nodiscard]] tt_force_inline
friend int eq(
vec const &lhs,
vec const &rhs)
noexcept {
363 return _mm_movemask_ps(_mm_cmpeq_ps(lhs, rhs));
369 [[nodiscard]] tt_force_inline
friend int ne(
vec const &lhs,
vec const &rhs)
noexcept {
370 return _mm_movemask_ps(_mm_cmpneq_ps(lhs, rhs));
373 [[nodiscard]] tt_force_inline
friend bool operator==(
vec const &lhs,
vec const &rhs)
noexcept {
374 return !
ne(lhs, rhs);
377 [[nodiscard]] tt_force_inline
friend bool operator!=(vec
const &lhs, vec
const &rhs)
noexcept {
378 return !(lhs == rhs);
384 [[nodiscard]] tt_force_inline
friend int operator<(
vec const &lhs,
vec const &rhs)
noexcept {
385 return _mm_movemask_ps(_mm_cmplt_ps(lhs, rhs));
391 [[nodiscard]] tt_force_inline
friend int operator<=(
vec const &lhs,
vec const &rhs)
noexcept {
392 return _mm_movemask_ps(_mm_cmple_ps(lhs, rhs));
398 [[nodiscard]] tt_force_inline
friend int operator>(
vec const &lhs,
vec const &rhs)
noexcept {
399 return _mm_movemask_ps(_mm_cmpgt_ps(lhs, rhs));
405 [[nodiscard]] tt_force_inline
friend int operator>=(
vec const &lhs,
vec const &rhs)
noexcept {
406 return _mm_movemask_ps(_mm_cmpge_ps(lhs, rhs));
409 [[nodiscard]] tt_force_inline
friend __m128 _length_squared(
vec const &rhs)
noexcept {
410 ttlet tmp1 = _mm_mul_ps(rhs, rhs);
411 ttlet tmp2 = _mm_hadd_ps(tmp1, tmp1);
412 return _mm_hadd_ps(tmp2, tmp2);
415 [[nodiscard]] tt_force_inline
friend float length_squared(vec
const &rhs)
noexcept {
416 return _mm_cvtss_f32(_length_squared(rhs));
419 [[nodiscard]] tt_force_inline
friend float length(vec
const &rhs)
noexcept {
420 ttlet tmp = _mm_sqrt_ps(_length_squared(rhs));
421 return _mm_cvtss_f32(tmp);
424 [[nodiscard]] tt_force_inline
friend vec normalize(vec
const &rhs)
noexcept {
425 auto ___l = _length_squared(rhs);
426 auto llll = _mm_permute_ps(___l, _MM_SHUFFLE(0,0,0,0));
427 auto iiii = _mm_rsqrt_ps(llll);
428 return _mm_mul_ps(rhs, iiii);
436 ttlet ratio2D = rhs / *
this;
437 ttlet ratio =
std::min(ratio2D.x(), ratio2D.y());
438 return *
this * ratio;
441 [[nodiscard]] tt_force_inline
friend vec homogeneous_divide(
vec const &rhs)
noexcept {
442 auto wwww = _mm_permute_ps(rhs, _MM_SHUFFLE(3,3,3,3));
443 auto rcp_wwww = _mm_rcp_ps(wwww);
444 return _mm_mul_ps(rhs, rcp_wwww);
447 [[nodiscard]] tt_force_inline
friend float dot(vec
const &lhs, vec
const &rhs)
noexcept {
448 ttlet tmp1 = _mm_mul_ps(lhs, rhs);
449 ttlet tmp2 = _mm_hadd_ps(tmp1, tmp1);
450 ttlet tmp3 = _mm_hadd_ps(tmp2, tmp2);
451 return _mm_cvtss_f32(tmp3);
454 [[nodiscard]] tt_force_inline
friend vec reciprocal(vec
const &rhs)
noexcept {
455 return _mm_rcp_ps(rhs);
458 template<
bool nx,
bool ny,
bool nz,
bool nw>
459 friend vec neg(vec
const &rhs)
noexcept;
461 [[nodiscard]] tt_force_inline
friend vec hadd(vec
const &lhs, vec
const &rhs)
noexcept {
462 return _mm_hadd_ps(lhs, rhs);
465 [[nodiscard]] tt_force_inline
friend vec hsub(vec
const &lhs, vec
const &rhs)
noexcept {
466 return _mm_hsub_ps(lhs, rhs);
469 [[nodiscard]] tt_force_inline
friend float viktor_cross(vec
const &lhs, vec
const &rhs)
noexcept {
471 ttlet tmp1 = _mm_permute_ps(rhs, _MM_SHUFFLE(2,3,0,1));
472 ttlet tmp2 = _mm_mul_ps(lhs, tmp1);
473 ttlet tmp3 = _mm_hsub_ps(tmp2, tmp2);
474 return _mm_cvtss_f32(tmp3);
481 [[nodiscard]]
friend vec cross(vec
const &lhs, vec
const &rhs)
noexcept {
482 ttlet a_left = _mm_permute_ps(lhs, _MM_SHUFFLE(3,0,2,1));
483 ttlet b_left = _mm_permute_ps(rhs, _MM_SHUFFLE(3,1,0,2));
484 ttlet
left = _mm_mul_ps(a_left, b_left);
486 ttlet a_right = _mm_permute_ps(lhs, _MM_SHUFFLE(3,1,0,2));
487 ttlet b_right = _mm_permute_ps(rhs, _MM_SHUFFLE(3,0,2,1));
488 ttlet
right = _mm_mul_ps(a_right, b_right);
489 return _mm_sub_ps(left, right);
494 [[nodiscard]] tt_force_inline
friend vec normal(
vec const &rhs)
noexcept {
495 tt_assume(rhs.z() == 0.0f && rhs.w() == 0.0f);
496 return normalize(
vec{-rhs.y(), rhs.x()});
499 [[nodiscard]]
friend vec ceil(
vec const &rhs)
noexcept {
500 return _mm_ceil_ps(rhs);
503 [[nodiscard]]
friend vec floor(vec
const &rhs)
noexcept {
504 return _mm_floor_ps(rhs);
507 [[nodiscard]]
friend vec round(vec
const &rhs)
noexcept {
508 return _mm_round_ps(rhs, _MM_FROUND_CUR_DIRECTION);
511 [[nodiscard]]
friend std::array<vec,4> transpose(vec col0, vec col1, vec col2, vec col3)
noexcept {
512 _MM_TRANSPOSE4_PS(col0, col1, col2, col3);
513 return { col0, col1, col2, col3 };
519 return (p1 + p2) *
vec{0.5};
522 [[nodiscard]]
friend vec desaturate(
vec const &
color,
float brightness)
noexcept {
525 ttlet _0BGR =
color *
vec{0.2126, 0.7152, 0.0722} * vec{brightness};
526 ttlet __SS = _mm_hadd_ps(_0BGR, _0BGR);
527 ttlet ___L = _mm_hadd_ps(__SS, __SS);
528 ttlet LLLL = _mm_permute_ps(___L, _MM_SHUFFLE(0,0,0,0));
530 return _mm_blend_ps(LLLL,
color, 0b1000);
533 [[nodiscard]]
friend vec composit(vec
const &under, vec
const &over)
noexcept {
534 if (over.is_transparent()) {
537 if (over.is_opaque()) {
541 ttlet over_alpha = over.wwww();
542 ttlet under_alpha = under.wwww();
544 ttlet over_color = over.xyz1();
545 ttlet under_color = under.xyz1();
548 over_color * over_alpha +
549 under_color * under_alpha * (vec{1.0} - over_alpha);
551 return output_color / output_color.www1();
557 return anchor - (p - anchor);
560 [[nodiscard]]
friend std::string to_string(
vec const &rhs)
noexcept {
561 return fmt::format(
"({}, {}, {}, {})", rhs.x(), rhs.y(), rhs.z(), rhs.w());
565 return lhs << to_string(rhs);
568 template<std::
size_t I>
569 [[nodiscard]] tt_force_inline
friend float get(vec
const &rhs)
noexcept {
573 template<
char a,
char b,
char c,
char d>
574 [[nodiscard]]
constexpr static int swizzle_permute_mask() noexcept {
577 case 'x': r |= 0b00'00'00'00;
break;
578 case 'y': r |= 0b00'00'00'01;
break;
579 case 'z': r |= 0b00'00'00'10;
break;
580 case 'w': r |= 0b00'00'00'11;
break;
581 case '0': r |= 0b00'00'00'00;
break;
582 case '1': r |= 0b00'00'00'00;
break;
585 case 'x': r |= 0b00'00'00'00;
break;
586 case 'y': r |= 0b00'00'01'00;
break;
587 case 'z': r |= 0b00'00'10'00;
break;
588 case 'w': r |= 0b00'00'11'00;
break;
589 case '0': r |= 0b00'00'01'00;
break;
590 case '1': r |= 0b00'00'01'00;
break;
593 case 'x': r |= 0b00'00'00'00;
break;
594 case 'y': r |= 0b00'01'00'00;
break;
595 case 'z': r |= 0b00'10'00'00;
break;
596 case 'w': r |= 0b00'11'00'00;
break;
597 case '0': r |= 0b00'10'00'00;
break;
598 case '1': r |= 0b00'10'00'00;
break;
601 case 'x': r |= 0b00'00'00'00;
break;
602 case 'y': r |= 0b01'00'00'00;
break;
603 case 'z': r |= 0b10'00'00'00;
break;
604 case 'w': r |= 0b11'00'00'00;
break;
605 case '0': r |= 0b11'00'00'00;
break;
606 case '1': r |= 0b11'00'00'00;
break;
611 template<
char a,
char b,
char c,
char d>
612 [[nodiscard]]
constexpr static int swizzle_zero_mask() noexcept {
614 r |= (a ==
'1') ? 0 : 0b0001;
615 r |= (b ==
'1') ? 0 : 0b0010;
616 r |= (c ==
'1') ? 0 : 0b0100;
617 r |= (d ==
'1') ? 0 : 0b1000;
621 template<
char a,
char b,
char c,
char d>
622 [[nodiscard]]
constexpr static int swizzle_number_mask() noexcept {
624 r |= (a ==
'0' || a ==
'1') ? 0b0001 : 0;
625 r |= (b ==
'0' || b ==
'1') ? 0b0010 : 0;
626 r |= (c ==
'0' || c ==
'1') ? 0b0100 : 0;
627 r |= (d ==
'0' || d ==
'1') ? 0b1000 : 0;
631 template<
char a,
char b,
char c,
char d>
632 [[nodiscard]] tt_force_inline vec swizzle() const noexcept {
633 constexpr int permute_mask = vec::swizzle_permute_mask<a,b,c,d>();
634 constexpr int zero_mask = vec::swizzle_zero_mask<a,b,c,d>();
635 constexpr int number_mask = vec::swizzle_number_mask<a,b,c,d>();
639 if constexpr (permute_mask != 0b11'10'01'00) {
640 swizzled = _mm_permute_ps(*
this, permute_mask);
646 if constexpr (zero_mask == 0b0000) {
647 numbers = _mm_set_ps1(1.0f);
648 }
else if constexpr (zero_mask == 0b1111) {
649 numbers = _mm_setzero_ps();
650 }
else if constexpr (zero_mask == 0b1110) {
651 numbers = _mm_set_ss(1.0f);
653 ttlet _1111 = _mm_set_ps1(1.0f);
654 numbers = _mm_insert_ps(_1111, _1111, zero_mask);
658 if constexpr (number_mask == 0b0000) {
660 }
else if constexpr (number_mask == 0b1111) {
662 }
else if constexpr (((zero_mask | ~number_mask) & 0b1111) == 0b1111) {
663 result = _mm_insert_ps(swizzled, swizzled, number_mask);
665 result = _mm_blend_ps(swizzled, numbers, number_mask);
670#define SWIZZLE4(name, A, B, C, D)\
671 [[nodiscard]] vec name() const noexcept {\
672 return swizzle<A, B, C, D>();\
675#define SWIZZLE4_GEN3(name, A, B, C)\
676 SWIZZLE4(name ## 0, A, B, C, '0')\
677 SWIZZLE4(name ## 1, A, B, C, '1')\
678 SWIZZLE4(name ## x, A, B, C, 'x')\
679 SWIZZLE4(name ## y, A, B, C, 'y')\
680 SWIZZLE4(name ## z, A, B, C, 'z')\
681 SWIZZLE4(name ## w, A, B, C, 'w')
683#define SWIZZLE4_GEN2(name, A, B)\
684 SWIZZLE4_GEN3(name ## 0, A, B, '0')\
685 SWIZZLE4_GEN3(name ## 1, A, B, '1')\
686 SWIZZLE4_GEN3(name ## x, A, B, 'x')\
687 SWIZZLE4_GEN3(name ## y, A, B, 'y')\
688 SWIZZLE4_GEN3(name ## z, A, B, 'z')\
689 SWIZZLE4_GEN3(name ## w, A, B, 'w')
691#define SWIZZLE4_GEN1(name, A)\
692 SWIZZLE4_GEN2(name ## 0, A, '0')\
693 SWIZZLE4_GEN2(name ## 1, A, '1')\
694 SWIZZLE4_GEN2(name ## x, A, 'x')\
695 SWIZZLE4_GEN2(name ## y, A, 'y')\
696 SWIZZLE4_GEN2(name ## z, A, 'z')\
697 SWIZZLE4_GEN2(name ## w, A, 'w')
699 SWIZZLE4_GEN1(_0,
'0')
700 SWIZZLE4_GEN1(_1, '1')
701 SWIZZLE4_GEN1(x, 'x')
702 SWIZZLE4_GEN1(y, 'y')
703 SWIZZLE4_GEN1(z, 'z')
704 SWIZZLE4_GEN1(w, 'w')
706#define SWIZZLE3(name, A, B, C)\
707 [[nodiscard]] vec name() const noexcept {\
708 return swizzle<A,B,C,'w'>();\
711#define SWIZZLE3_GEN2(name, A, B)\
712 SWIZZLE3(name ## 0, A, B, '0')\
713 SWIZZLE3(name ## 1, A, B, '1')\
714 SWIZZLE3(name ## x, A, B, 'x')\
715 SWIZZLE3(name ## y, A, B, 'y')\
716 SWIZZLE3(name ## z, A, B, 'z')\
717 SWIZZLE3(name ## w, A, B, 'w')
719#define SWIZZLE3_GEN1(name, A)\
720 SWIZZLE3_GEN2(name ## 0, A, '0')\
721 SWIZZLE3_GEN2(name ## 1, A, '1')\
722 SWIZZLE3_GEN2(name ## x, A, 'x')\
723 SWIZZLE3_GEN2(name ## y, A, 'y')\
724 SWIZZLE3_GEN2(name ## z, A, 'z')\
725 SWIZZLE3_GEN2(name ## w, A, 'w')
727 SWIZZLE3_GEN1(_0,
'0')
728 SWIZZLE3_GEN1(_1, '1')
729 SWIZZLE3_GEN1(x, 'x')
730 SWIZZLE3_GEN1(y, 'y')
731 SWIZZLE3_GEN1(z, 'z')
732 SWIZZLE3_GEN1(w, 'w')
734#define SWIZZLE2(name, A, B)\
735 [[nodiscard]] vec name() const noexcept {\
736 return swizzle<A,B,'0','w'>();\
739#define SWIZZLE2_GEN1(name, A)\
740 SWIZZLE2(name ## 0, A, '0')\
741 SWIZZLE2(name ## 1, A, '1')\
742 SWIZZLE2(name ## x, A, 'x')\
743 SWIZZLE2(name ## y, A, 'y')\
744 SWIZZLE2(name ## z, A, 'z')\
745 SWIZZLE2(name ## w, A, 'w')
747 SWIZZLE2_GEN1(_0,
'0')
748 SWIZZLE2_GEN1(_1, '1')
749 SWIZZLE2_GEN1(x, 'x')
750 SWIZZLE2_GEN1(y, 'y')
751 SWIZZLE2_GEN1(z, 'z')
752 SWIZZLE2_GEN1(w, 'w')