1use core::{
4 fmt::{Debug, Display},
5 mem::{MaybeUninit, transmute, transmute_copy},
6 ops::{Add, BitAnd, BitOr, BitXor, Div, Index, IndexMut, Mul, Neg, Not, Rem, Shl, Shr, Sub},
7};
8
9use crate::{Construct, sealed::Sealed};
10
11mod constructor;
12mod deref;
13mod dir;
14mod ops;
15mod primitive_api;
16mod primitive_impls;
17pub use constructor::*;
18pub use dir::*;
19
20#[cfg(feature = "swizzle")]
21mod swizzle;
22
23#[repr(transparent)]
54pub struct Vector<const N: usize, T: Scalar, S: Simdness>(<Self as VectorReprExt>::Repr)
55where
56 VecLen<N>: SupportedVecLen;
57
58impl<const N: usize, T: Scalar, S: Simdness> Vector<N, T, S>
59where
60 VecLen<N>: SupportedVecLen,
61{
62 specialized_vector_api! {
63 VectorApi for <N, T, S>:
64
65 pub fn from_array(array: [T; N]) -> Self;
67
68 pub fn splat(value: T) -> Self;
70
71 pub fn swizzle2<const X_SRC: usize, const Y_SRC: usize>(self) -> Vector<2, T, S>;
88
89 pub fn swizzle3<const X_SRC: usize, const Y_SRC: usize, const Z_SRC: usize>(self) -> Vector<3, T, S>;
106
107 pub fn swizzle4<const X_SRC: usize, const Y_SRC: usize, const Z_SRC: usize, const W_SRC: usize>(self) -> Vector<4, T, S>;
124 }
125
126 #[inline(always)]
138 pub fn from_fn(f: impl FnMut(usize) -> T) -> Self {
139 Vector::from_array(core::array::from_fn(f))
140 }
141
142 #[inline(always)]
148 pub const fn const_from_array(array: [T; N]) -> Self {
149 const {
150 assert!(size_of::<Vector<N, T, S>>() % size_of::<T>() == 0);
151 assert!(size_of::<Vector<N, T, S>>() / size_of::<T>() >= N);
152 }
153
154 let mut result =
156 unsafe { MaybeUninit::<Vector<N, MaybeUninit<T>, S>>::uninit().assume_init() };
157
158 let mut i = 0;
159 while i < N {
160 result.as_mut_array()[i] = MaybeUninit::new(array[i]);
161 i += 1;
162 }
163
164 let mut i = N;
165 while i < size_of::<Vector<N, T, S>>() / size_of::<T>() {
166 unsafe {
167 *result.as_mut_array().as_mut_ptr().add(i) = MaybeUninit::new(array[N - 1]);
168 }
169 i += 1;
170 }
171
172 unsafe { transmute_copy::<Vector<N, MaybeUninit<T>, S>, Vector<N, T, S>>(&result) }
176 }
177
178 #[inline(always)]
181 pub const fn len(self) -> usize {
182 N
183 }
184
185 #[inline(always)]
187 pub const fn is_simd(self) -> bool {
188 S::IS_SIMD
189 }
190
191 #[inline(always)]
193 pub fn as_simdness<S2: Simdness>(self) -> Vector<N, T, S2> {
194 if S::IS_SIMD == S2::IS_SIMD {
195 unsafe { transmute_copy::<Vector<N, T, S>, Vector<N, T, S2>>(&self) }
197 } else {
198 Vector::from_array(self.as_array())
199 }
200 }
201
202 #[inline(always)]
204 pub fn as_simd(self) -> Vector<N, T, Simd> {
205 self.as_simdness::<Simd>()
206 }
207
208 #[inline(always)]
210 pub fn as_nonsimd(self) -> Vector<N, T, NonSimd> {
211 self.as_simdness::<NonSimd>()
212 }
213
214 #[inline(always)]
216 pub const fn as_array(self) -> [T; N] {
217 *self.as_array_ref()
218 }
219
220 #[inline(always)]
222 pub const fn as_array_ref(&self) -> &[T; N] {
223 unsafe { transmute::<&Vector<N, T, S>, &[T; N]>(self) }
225 }
226
227 #[inline(always)]
229 pub const fn as_mut_array(&mut self) -> &mut [T; N] {
230 unsafe { transmute::<&mut Vector<N, T, S>, &mut [T; N]>(self) }
232 }
233
234 #[inline(always)]
237 pub const fn get(self, index: usize) -> Option<T> {
238 if index < N {
239 Some(unsafe { *self.as_array_ref().as_ptr().add(index) })
241 } else {
242 None
243 }
244 }
245
246 #[inline(always)]
249 pub const fn get_mut(&mut self, index: usize) -> Option<&mut T> {
250 if index < N {
251 Some(unsafe { &mut *self.as_mut_array().as_mut_ptr().add(index) })
253 } else {
254 None
255 }
256 }
257
258 #[inline(always)]
260 pub fn reverse(self) -> Self {
261 (const {
262 match N {
263 2 => unsafe {
265 let func: fn(_) -> _ = Vector::<2, T, S>::swizzle2::<1, 0>;
266
267 transmute_copy::<
268 fn(Vector<2, T, S>) -> Vector<2, T, S>,
269 fn(Vector<N, T, S>) -> Vector<N, T, S>,
270 >(&func)
271 },
272 3 => unsafe {
274 let func: fn(_) -> _ = Vector::<3, T, S>::swizzle3::<2, 1, 0>;
275
276 transmute_copy::<
277 fn(Vector<3, T, S>) -> Vector<3, T, S>,
278 fn(Vector<N, T, S>) -> Vector<N, T, S>,
279 >(&func)
280 },
281 4 => unsafe {
283 let func: fn(_) -> _ = Vector::<4, T, S>::swizzle4::<3, 2, 1, 0>;
284
285 transmute_copy::<
286 fn(Vector<4, T, S>) -> Vector<4, T, S>,
287 fn(Vector<N, T, S>) -> Vector<N, T, S>,
288 >(&func)
289 },
290 ..2 | 5.. => panic!("N must be 2, 3, or 4"),
291 }
292 })(self)
293 }
294
295 #[inline(always)]
297 pub fn iter(self) -> <[T; N] as IntoIterator>::IntoIter {
298 self.as_array().into_iter()
299 }
300
301 #[inline(always)]
303 pub fn iter_mut(&mut self) -> <&mut [T; N] as IntoIterator>::IntoIter {
304 self.as_mut_array().iter_mut()
305 }
306
307 #[inline(always)]
318 pub fn map<U: Scalar>(self, f: impl Fn(T) -> U) -> Vector<N, U, S> {
319 Vector::from_array(self.as_array().map(f))
320 }
321
322 specialized_vector_api! {
323 VectorApi for <N, T, S>:
324
325 fn eq(self, other: Self) -> bool where T: PartialEq;
326 fn ne(self, other: Self) -> bool where T: PartialEq;
327 }
328}
329
330impl<T: Scalar, S: Simdness> Vector<2, T, S> {
331 #[inline(always)]
333 pub fn with_x(self, value: T) -> Self {
334 let mut result = self;
335 result.x = value;
336
337 result
338 }
339
340 #[inline(always)]
342 pub fn with_y(self, value: T) -> Self {
343 let mut result = self;
344 result.y = value;
345
346 result
347 }
348}
349
350impl<T: Scalar, S: Simdness> Vector<3, T, S> {
351 #[inline(always)]
353 pub fn with_x(self, value: T) -> Self {
354 let mut result = self;
355 result.x = value;
356
357 result
358 }
359
360 #[inline(always)]
362 pub fn with_y(self, value: T) -> Self {
363 let mut result = self;
364 result.y = value;
365
366 result
367 }
368
369 #[inline(always)]
371 pub fn with_z(self, value: T) -> Self {
372 let mut result = self;
373 result.z = value;
374
375 result
376 }
377}
378
379impl<T: Scalar, S: Simdness> Vector<4, T, S> {
380 #[inline(always)]
382 pub fn with_x(self, value: T) -> Self {
383 let mut result = self;
384 result.x = value;
385
386 result
387 }
388
389 #[inline(always)]
391 pub fn with_y(self, value: T) -> Self {
392 let mut result = self;
393 result.y = value;
394
395 result
396 }
397
398 #[inline(always)]
400 pub fn with_z(self, value: T) -> Self {
401 let mut result = self;
402 result.z = value;
403
404 result
405 }
406
407 #[inline(always)]
409 pub fn with_w(self, value: T) -> Self {
410 let mut result = self;
411 result.w = value;
412
413 result
414 }
415}
416
417impl<const N: usize, T: Scalar> Vector<N, T, Simd>
418where
419 VecLen<N>: SupportedVecLen,
420{
421 #[inline(always)]
427 pub const fn from_repr(repr: <T as SimdBehaviour<N>>::VectorRepr) -> Self
428 where
429 T: SimdBehaviour<N>,
430 {
431 const {
432 assert!(
433 size_of::<Vector<N, T, Simd>>() == size_of::<<T as SimdBehaviour<N>>::VectorRepr>()
434 );
435 assert!(
436 align_of::<Vector<N, T, Simd>>()
437 == align_of::<<T as SimdBehaviour<N>>::VectorRepr>()
438 );
439 }
440
441 unsafe { transmute_copy::<<T as SimdBehaviour<N>>::VectorRepr, Vector<N, T, Simd>>(&repr) }
443 }
444
445 #[inline(always)]
451 pub const fn repr(self) -> <T as SimdBehaviour<N>>::VectorRepr
452 where
453 T: SimdBehaviour<N>,
454 {
455 const {
456 assert!(
457 size_of::<Vector<N, T, Simd>>() == size_of::<<T as SimdBehaviour<N>>::VectorRepr>()
458 );
459 assert!(
460 align_of::<Vector<N, T, Simd>>()
461 == align_of::<<T as SimdBehaviour<N>>::VectorRepr>()
462 );
463 }
464
465 unsafe { transmute_copy::<Vector<N, T, Simd>, <T as SimdBehaviour<N>>::VectorRepr>(&self) }
467 }
468}
469
470impl<const N: usize, T: Scalar> Vector<N, T, NonSimd>
471where
472 VecLen<N>: SupportedVecLen,
473{
474 #[inline(always)]
476 pub const fn from_array_ref(array: &[T; N]) -> &Self {
477 unsafe { transmute::<&[T; N], &Vector<N, T, NonSimd>>(array) }
479 }
480
481 #[inline(always)]
483 pub const fn from_mut_array(array: &mut [T; N]) -> &mut Self {
484 unsafe { transmute::<&mut [T; N], &mut Vector<N, T, NonSimd>>(array) }
486 }
487}
488
489impl<const N: usize, T: Scalar, S: Simdness> Clone for Vector<N, T, S>
490where
491 VecLen<N>: SupportedVecLen,
492{
493 #[inline(always)]
494 fn clone(&self) -> Self {
495 *self
496 }
497}
498
499impl<const N: usize, T: Scalar, S: Simdness> Copy for Vector<N, T, S> where
500 VecLen<N>: SupportedVecLen
501{
502}
503
504impl<const N: usize, T: Scalar, S: Simdness> Index<usize> for Vector<N, T, S>
505where
506 VecLen<N>: SupportedVecLen,
507{
508 type Output = T;
509
510 #[inline(always)]
511 fn index(&self, index: usize) -> &Self::Output {
512 self.as_array_ref().index(index)
513 }
514}
515
516impl<const N: usize, T: Scalar, S: Simdness> IndexMut<usize> for Vector<N, T, S>
517where
518 VecLen<N>: SupportedVecLen,
519{
520 #[inline(always)]
521 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
522 self.as_mut_array().index_mut(index)
523 }
524}
525
526impl<const N: usize, T: Scalar, S: Simdness> IntoIterator for Vector<N, T, S>
527where
528 VecLen<N>: SupportedVecLen,
529{
530 type Item = T;
531 type IntoIter = <[T; N] as IntoIterator>::IntoIter;
532
533 #[inline(always)]
534 fn into_iter(self) -> Self::IntoIter {
535 self.iter()
536 }
537}
538
539impl<'a, const N: usize, T: Scalar, S: Simdness> IntoIterator for &'a Vector<N, T, S>
540where
541 VecLen<N>: SupportedVecLen,
542{
543 type Item = &'a T;
544 type IntoIter = <&'a [T; N] as IntoIterator>::IntoIter;
545
546 #[inline(always)]
547 fn into_iter(self) -> Self::IntoIter {
548 self.as_array_ref().iter()
549 }
550}
551
552impl<'a, const N: usize, T: Scalar, S: Simdness> IntoIterator for &'a mut Vector<N, T, S>
553where
554 VecLen<N>: SupportedVecLen,
555{
556 type Item = &'a mut T;
557 type IntoIter = <&'a mut [T; N] as IntoIterator>::IntoIter;
558
559 #[inline(always)]
560 fn into_iter(self) -> Self::IntoIter {
561 self.iter_mut()
562 }
563}
564
565impl<const N: usize, T: Scalar + PartialEq, S: Simdness> PartialEq for Vector<N, T, S>
566where
567 VecLen<N>: SupportedVecLen,
568{
569 #[inline(always)]
570 fn eq(&self, other: &Self) -> bool {
571 (*self).eq(*other)
572 }
573
574 #[inline(always)]
575 fn ne(&self, other: &Self) -> bool {
576 (*self).ne(*other)
577 }
578}
579
580impl<const N: usize, T: Scalar + Debug, S: Simdness> Debug for Vector<N, T, S>
581where
582 VecLen<N>: SupportedVecLen,
583{
584 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
585 write!(f, "(")?;
586
587 for i in 0..N {
588 write!(f, "{:?}", self[i])?;
589
590 if i < N - 1 {
591 write!(f, ", ")?;
592 }
593 }
594
595 write!(f, ")")
596 }
597}
598
599impl<const N: usize, T: Scalar + Display, S: Simdness> Display for Vector<N, T, S>
600where
601 VecLen<N>: SupportedVecLen,
602{
603 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
604 write!(f, "(")?;
605
606 for i in 0..N {
607 write!(f, "{}", self[i])?;
608
609 if i < N - 1 {
610 write!(f, ", ")?;
611 }
612 }
613
614 write!(f, ")")
615 }
616}
617
618pub type Vec2<T> = Vector<2, T, Simd>;
627
628pub type Vec3<T> = Vector<3, T, Simd>;
633
634pub type Vec4<T> = Vector<4, T, Simd>;
639
640pub type Vec2S<T> = Vector<2, T, NonSimd>;
645
646pub type Vec3S<T> = Vector<3, T, NonSimd>;
652
653pub type Vec4S<T> = Vector<4, T, NonSimd>;
659
660#[macro_export]
680macro_rules! declare_vector_aliases {
681 ($vis:vis type $prefix:ident => $T:ty) => {
682 $crate::hidden::paste! {
683 #[doc = "A 2D vector of `" $T "` elements."]
684 #[doc = ""]
685 #[doc = "This is a type alias for `Vector<2, " $T ", Simd>`."]
686 #[doc = "This type may be SIMD-aligned to use performant SIMD instructions."]
687 $vis type [<$prefix Vec2>] = $crate::Vector<2, $T, $crate::Simd>;
688
689 #[doc = "A 3D vector of `" $T "` elements."]
690 #[doc = ""]
691 #[doc = "This is a type alias for `Vector<3, " $T ", Simd>`."]
692 #[doc = "This type may be SIMD-aligned to use performant SIMD instructions."]
693 $vis type [<$prefix Vec3>] = $crate::Vector<3, $T, $crate::Simd>;
694
695 #[doc = "A 4D vector of `" $T "` elements."]
696 #[doc = ""]
697 #[doc = "This is a type alias for `Vector<4, " $T ", Simd>`."]
698 #[doc = "This type may be SIMD-aligned to use performant SIMD instructions."]
699 $vis type [<$prefix Vec4>] = $crate::Vector<4, $T, $crate::Simd>;
700
701 #[doc = "A 2D vector of `" $T "` elements."]
702 #[doc = ""]
703 #[doc = "Unlike [`" $prefix "Vec2`], this type is never SIMD-aligned (\"s\" stands for \"scalar\")."]
704 #[doc = "This is a type alias for `Vector<2, " $T ", NonSimd>`."]
705 $vis type [<$prefix Vec2S>] = $crate::Vector<2, $T, $crate::NonSimd>;
706
707 #[doc = "A 3D vector of `" $T "` elements."]
708 #[doc = ""]
709 #[doc = "Unlike [`" $prefix "Vec3`], this type is never SIMD-aligned (\"s\" stands for \"scalar\")."]
710 #[doc = "This is a type alias for `Vector<3, " $T ", NonSimd>`."]
711 $vis type [<$prefix Vec3S>] = $crate::Vector<3, $T, $crate::NonSimd>;
712
713 #[doc = "A 4D vector of `" $T "` elements."]
714 #[doc = ""]
715 #[doc = "Unlike [`" $prefix "Vec4`], this type is never SIMD-aligned (\"s\" stands for \"scalar\")."]
716 #[doc = "This is a type alias for `Vector<4, " $T ", NonSimd>`."]
717 $vis type [<$prefix Vec4S>] = $crate::Vector<4, $T, $crate::NonSimd>;
718 }
719 };
720}
721
722pub use declare_vector_aliases;
723
724pub trait Scalar: SimdBehaviour<2> + SimdBehaviour<3> + SimdBehaviour<4> {}
762
763pub trait SimdBehaviour<const N: usize>: Construct
771where
772 VecLen<N>: SupportedVecLen,
773{
774 #[expect(private_bounds)]
814 type VectorRepr: SoundVectorRepr<N, Self>;
815
816 #[inline(always)]
818 fn vec_from_array(array: [Self; N]) -> Vector<N, Self, Simd>
819 where
820 Self: Scalar,
821 {
822 Vector::const_from_array(array)
823 }
824
825 #[inline(always)]
827 fn vec_splat(value: Self) -> Vector<N, Self, Simd>
828 where
829 Self: Scalar,
830 {
831 Vector::from_array([value; N])
832 }
833
834 #[inline(always)]
836 unsafe fn vec_swizzle2<const X_SRC: usize, const Y_SRC: usize>(
837 vec: Vector<N, Self, Simd>,
838 ) -> Vector<2, Self, Simd>
839 where
840 Self: Scalar,
841 {
842 Vector::<2, _, _>::from_array([vec[X_SRC], vec[Y_SRC]])
843 }
844
845 #[inline(always)]
847 unsafe fn vec_swizzle3<const X_SRC: usize, const Y_SRC: usize, const Z_SRC: usize>(
848 vec: Vector<N, Self, Simd>,
849 ) -> Vector<3, Self, Simd>
850 where
851 Self: Scalar,
852 {
853 Vector::<3, _, _>::from_array([vec[X_SRC], vec[Y_SRC], vec[Z_SRC]])
854 }
855
856 #[inline(always)]
858 unsafe fn vec_swizzle4<
859 const X_SRC: usize,
860 const Y_SRC: usize,
861 const Z_SRC: usize,
862 const W_SRC: usize,
863 >(
864 vec: Vector<N, Self, Simd>,
865 ) -> Vector<4, Self, Simd>
866 where
867 Self: Scalar,
868 {
869 Vector::<4, _, _>::from_array([vec[X_SRC], vec[Y_SRC], vec[Z_SRC], vec[W_SRC]])
870 }
871
872 #[inline(always)]
874 fn vec_eq(vec: Vector<N, Self, Simd>, other: Vector<N, Self, Simd>) -> bool
875 where
876 Self: Scalar + PartialEq,
877 {
878 vec.iter().zip(other).all(|(a, b)| a == b)
879 }
880
881 #[inline(always)]
883 fn vec_ne(vec: Vector<N, Self, Simd>, other: Vector<N, Self, Simd>) -> bool
884 where
885 Self: Scalar + PartialEq,
886 {
887 vec.iter().zip(other).any(|(a, b)| a != b)
888 }
889
890 #[inline(always)]
895 fn vec_neg(vec: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
896 where
897 Self: Scalar + Neg<Output = Self>,
898 {
899 vec.map(Self::neg)
900 }
901
902 #[inline(always)]
907 fn vec_not(vec: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
908 where
909 Self: Scalar + Not<Output = Self>,
910 {
911 vec.map(Self::not)
912 }
913
914 #[inline(always)]
919 fn vec_add(vec: Vector<N, Self, Simd>, rhs: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
920 where
921 Self: Scalar + Add<Output = Self>,
922 {
923 Vector::from_fn(|i| vec[i] + rhs[i])
924 }
925
926 #[inline(always)]
931 fn vec_sub(vec: Vector<N, Self, Simd>, rhs: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
932 where
933 Self: Scalar + Sub<Output = Self>,
934 {
935 Vector::from_fn(|i| vec[i] - rhs[i])
936 }
937
938 #[inline(always)]
943 fn vec_mul(vec: Vector<N, Self, Simd>, rhs: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
944 where
945 Self: Scalar + Mul<Output = Self>,
946 {
947 Vector::from_fn(|i| vec[i] * rhs[i])
948 }
949
950 #[inline(always)]
955 fn vec_div(vec: Vector<N, Self, Simd>, rhs: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
956 where
957 Self: Scalar + Div<Output = Self>,
958 {
959 Vector::from_fn(|i| vec[i] / rhs[i])
960 }
961
962 #[inline(always)]
967 fn vec_rem(vec: Vector<N, Self, Simd>, rhs: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
968 where
969 Self: Scalar + Rem<Output = Self>,
970 {
971 Vector::from_fn(|i| vec[i] % rhs[i])
972 }
973
974 #[inline(always)]
979 fn vec_shl(vec: Vector<N, Self, Simd>, rhs: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
980 where
981 Self: Scalar + Shl<Output = Self>,
982 {
983 Vector::from_fn(|i| vec[i] << rhs[i])
984 }
985
986 #[inline(always)]
991 fn vec_shr(vec: Vector<N, Self, Simd>, rhs: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
992 where
993 Self: Scalar + Shr<Output = Self>,
994 {
995 Vector::from_fn(|i| vec[i] >> rhs[i])
996 }
997
998 #[inline(always)]
1003 fn vec_bitand(vec: Vector<N, Self, Simd>, rhs: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
1004 where
1005 Self: Scalar + BitAnd<Output = Self>,
1006 {
1007 Vector::from_fn(|i| vec[i] & rhs[i])
1008 }
1009
1010 #[inline(always)]
1015 fn vec_bitor(vec: Vector<N, Self, Simd>, rhs: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
1016 where
1017 Self: Scalar + BitOr<Output = Self>,
1018 {
1019 Vector::from_fn(|i| vec[i] | rhs[i])
1020 }
1021
1022 #[inline(always)]
1027 fn vec_bitxor(vec: Vector<N, Self, Simd>, rhs: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
1028 where
1029 Self: Scalar + BitXor<Output = Self>,
1030 {
1031 Vector::from_fn(|i| vec[i] ^ rhs[i])
1032 }
1033}
1034
1035pub unsafe trait ScalarWrapper<T: Scalar> {}
1053
1054pub struct VecLen<const N: usize>;
1068
1069pub trait SupportedVecLen: Sealed {
1071 #[doc(hidden)]
1072 type Pick<T2: Construct, T3: Construct, T4: Construct>: Construct;
1073}
1074
1075impl SupportedVecLen for VecLen<2> {
1076 type Pick<T2: Construct, T3: Construct, T4: Construct> = T2;
1077}
1078impl SupportedVecLen for VecLen<3> {
1079 type Pick<T2: Construct, T3: Construct, T4: Construct> = T3;
1080}
1081impl SupportedVecLen for VecLen<4> {
1082 type Pick<T2: Construct, T3: Construct, T4: Construct> = T4;
1083}
1084
1085impl Sealed for VecLen<2> {}
1086impl Sealed for VecLen<3> {}
1087impl Sealed for VecLen<4> {}
1088
1089pub struct Simd;
1095
1096pub struct NonSimd;
1098
1099pub trait Simdness: Sealed + 'static {
1101 #[doc(hidden)]
1102 type Pick<TSimd: Construct, TNonSimd: Construct>: Construct;
1103
1104 const IS_SIMD: bool;
1106}
1107
1108impl Simdness for Simd {
1109 type Pick<TSimd: Construct, TNonSimd: Construct> = TSimd;
1110
1111 const IS_SIMD: bool = true;
1112}
1113impl Simdness for NonSimd {
1114 type Pick<TSimd: Construct, TNonSimd: Construct> = TNonSimd;
1115
1116 const IS_SIMD: bool = false;
1117}
1118
1119impl Sealed for Simd {}
1120impl Sealed for NonSimd {}
1121
1122trait VectorReprExt {
1127 type Repr: Construct;
1128}
1129
1130impl<const N: usize, T: Scalar, S: Simdness> VectorReprExt for Vector<N, T, S>
1131where
1132 VecLen<N>: SupportedVecLen,
1133{
1134 type Repr = <S as Simdness>::Pick<
1135 <VecLen<N> as SupportedVecLen>::Pick<
1136 <T as SimdBehaviour<2>>::VectorRepr,
1137 <T as SimdBehaviour<3>>::VectorRepr,
1138 <T as SimdBehaviour<4>>::VectorRepr,
1139 >,
1140 [T; N],
1141 >;
1142}
1143
1144unsafe trait SoundVectorRepr<const N: usize, T: Construct>: Construct {}
1145
1146unsafe impl<const N: usize, T: Scalar> SoundVectorRepr<N, T> for [T; N] {}
1148
1149unsafe impl<const N: usize, T: Scalar, InsideT: Scalar, InsideS: Simdness> SoundVectorRepr<N, T>
1151 for Vector<N, InsideT, InsideS>
1152where
1153 T: ScalarWrapper<InsideT>,
1154 VecLen<N>: SupportedVecLen,
1155{
1156}
1157
1158trait VectorApi<const N: usize, S: Simdness>: Scalar
1163where
1164 VecLen<N>: SupportedVecLen,
1165{
1166 fn vec_from_array(array: [Self; N]) -> Vector<N, Self, S>;
1167
1168 fn vec_splat(value: Self) -> Vector<N, Self, S>;
1169
1170 fn vec_swizzle2<const X_SRC: usize, const Y_SRC: usize>(
1171 vec: Vector<N, Self, S>,
1172 ) -> Vector<2, Self, S>;
1173
1174 fn vec_swizzle3<const X_SRC: usize, const Y_SRC: usize, const Z_SRC: usize>(
1175 vec: Vector<N, Self, S>,
1176 ) -> Vector<3, Self, S>;
1177
1178 fn vec_swizzle4<
1179 const X_SRC: usize,
1180 const Y_SRC: usize,
1181 const Z_SRC: usize,
1182 const W_SRC: usize,
1183 >(
1184 vec: Vector<N, Self, S>,
1185 ) -> Vector<4, Self, S>;
1186
1187 fn vec_eq(vec: Vector<N, Self, S>, other: Vector<N, Self, S>) -> bool
1188 where
1189 Self: PartialEq;
1190
1191 fn vec_ne(vec: Vector<N, Self, S>, other: Vector<N, Self, S>) -> bool
1192 where
1193 Self: PartialEq;
1194
1195 fn vec_neg(vec: Vector<N, Self, S>) -> Vector<N, Self, S>
1196 where
1197 Self: Neg<Output = Self>;
1198
1199 fn vec_not(vec: Vector<N, Self, S>) -> Vector<N, Self, S>
1200 where
1201 Self: Not<Output = Self>;
1202
1203 fn vec_add(vec: Vector<N, Self, S>, rhs: Vector<N, Self, S>) -> Vector<N, Self, S>
1204 where
1205 Self: Add<Output = Self>;
1206
1207 fn vec_sub(vec: Vector<N, Self, S>, rhs: Vector<N, Self, S>) -> Vector<N, Self, S>
1208 where
1209 Self: Sub<Output = Self>;
1210
1211 fn vec_mul(vec: Vector<N, Self, S>, rhs: Vector<N, Self, S>) -> Vector<N, Self, S>
1212 where
1213 Self: Mul<Output = Self>;
1214
1215 fn vec_div(vec: Vector<N, Self, S>, rhs: Vector<N, Self, S>) -> Vector<N, Self, S>
1216 where
1217 Self: Div<Output = Self>;
1218
1219 fn vec_rem(vec: Vector<N, Self, S>, rhs: Vector<N, Self, S>) -> Vector<N, Self, S>
1220 where
1221 Self: Rem<Output = Self>;
1222
1223 fn vec_shl(vec: Vector<N, Self, S>, rhs: Vector<N, Self, S>) -> Vector<N, Self, S>
1224 where
1225 Self: Shl<Output = Self>;
1226
1227 fn vec_shr(vec: Vector<N, Self, S>, rhs: Vector<N, Self, S>) -> Vector<N, Self, S>
1228 where
1229 Self: Shr<Output = Self>;
1230
1231 fn vec_bitand(vec: Vector<N, Self, S>, rhs: Vector<N, Self, S>) -> Vector<N, Self, S>
1232 where
1233 Self: BitAnd<Output = Self>;
1234
1235 fn vec_bitor(vec: Vector<N, Self, S>, rhs: Vector<N, Self, S>) -> Vector<N, Self, S>
1236 where
1237 Self: BitOr<Output = Self>;
1238
1239 fn vec_bitxor(vec: Vector<N, Self, S>, rhs: Vector<N, Self, S>) -> Vector<N, Self, S>
1240 where
1241 Self: BitXor<Output = Self>;
1242}
1243
1244impl<const N: usize, T: Scalar + SimdBehaviour<N>> VectorApi<N, Simd> for T
1245where
1246 VecLen<N>: SupportedVecLen,
1247{
1248 #[inline(always)]
1249 fn vec_from_array(array: [Self; N]) -> Vector<N, Self, Simd> {
1250 <T as SimdBehaviour<N>>::vec_from_array(array)
1251 }
1252
1253 #[inline(always)]
1254 fn vec_splat(value: Self) -> Vector<N, Self, Simd> {
1255 <T as SimdBehaviour<N>>::vec_splat(value)
1256 }
1257
1258 #[inline(always)]
1259 fn vec_swizzle2<const X_SRC: usize, const Y_SRC: usize>(
1260 vec: Vector<N, Self, Simd>,
1261 ) -> Vector<2, Self, Simd> {
1262 const {
1263 assert!(X_SRC < N);
1264 assert!(Y_SRC < N);
1265 }
1266
1267 unsafe { <T as SimdBehaviour<N>>::vec_swizzle2::<X_SRC, Y_SRC>(vec) }
1269 }
1270
1271 #[inline(always)]
1272 fn vec_swizzle3<const X_SRC: usize, const Y_SRC: usize, const Z_SRC: usize>(
1273 vec: Vector<N, Self, Simd>,
1274 ) -> Vector<3, Self, Simd> {
1275 const {
1276 assert!(X_SRC < N);
1277 assert!(Y_SRC < N);
1278 assert!(Z_SRC < N);
1279 }
1280
1281 unsafe { <T as SimdBehaviour<N>>::vec_swizzle3::<X_SRC, Y_SRC, Z_SRC>(vec) }
1283 }
1284
1285 #[inline(always)]
1286 fn vec_swizzle4<
1287 const X_SRC: usize,
1288 const Y_SRC: usize,
1289 const Z_SRC: usize,
1290 const W_SRC: usize,
1291 >(
1292 vec: Vector<N, Self, Simd>,
1293 ) -> Vector<4, Self, Simd> {
1294 const {
1295 assert!(X_SRC < N);
1296 assert!(Y_SRC < N);
1297 assert!(Z_SRC < N);
1298 assert!(W_SRC < N);
1299 }
1300
1301 unsafe { <T as SimdBehaviour<N>>::vec_swizzle4::<X_SRC, Y_SRC, Z_SRC, W_SRC>(vec) }
1303 }
1304
1305 #[inline(always)]
1306 fn vec_eq(vec: Vector<N, Self, Simd>, other: Vector<N, Self, Simd>) -> bool
1307 where
1308 Self: PartialEq,
1309 {
1310 <T as SimdBehaviour<N>>::vec_eq(vec, other)
1311 }
1312
1313 #[inline(always)]
1314 fn vec_ne(vec: Vector<N, Self, Simd>, other: Vector<N, Self, Simd>) -> bool
1315 where
1316 Self: PartialEq,
1317 {
1318 <T as SimdBehaviour<N>>::vec_ne(vec, other)
1319 }
1320
1321 #[inline(always)]
1322 fn vec_neg(vec: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
1323 where
1324 Self: Neg<Output = Self>,
1325 {
1326 <T as SimdBehaviour<N>>::vec_neg(vec)
1327 }
1328
1329 #[inline(always)]
1330 fn vec_not(vec: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
1331 where
1332 Self: Not<Output = Self>,
1333 {
1334 <T as SimdBehaviour<N>>::vec_not(vec)
1335 }
1336
1337 #[inline(always)]
1338 fn vec_add(vec: Vector<N, Self, Simd>, rhs: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
1339 where
1340 Self: Add<Output = Self>,
1341 {
1342 <T as SimdBehaviour<N>>::vec_add(vec, rhs)
1343 }
1344
1345 #[inline(always)]
1346 fn vec_sub(vec: Vector<N, Self, Simd>, rhs: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
1347 where
1348 Self: Sub<Output = Self>,
1349 {
1350 <T as SimdBehaviour<N>>::vec_sub(vec, rhs)
1351 }
1352
1353 #[inline(always)]
1354 fn vec_mul(vec: Vector<N, Self, Simd>, rhs: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
1355 where
1356 Self: Mul<Output = Self>,
1357 {
1358 <T as SimdBehaviour<N>>::vec_mul(vec, rhs)
1359 }
1360
1361 #[inline(always)]
1362 fn vec_div(vec: Vector<N, Self, Simd>, rhs: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
1363 where
1364 Self: Div<Output = Self>,
1365 {
1366 <T as SimdBehaviour<N>>::vec_div(vec, rhs)
1367 }
1368
1369 #[inline(always)]
1370 fn vec_rem(vec: Vector<N, Self, Simd>, rhs: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
1371 where
1372 Self: Rem<Output = Self>,
1373 {
1374 <T as SimdBehaviour<N>>::vec_rem(vec, rhs)
1375 }
1376
1377 #[inline(always)]
1378 fn vec_shl(vec: Vector<N, Self, Simd>, rhs: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
1379 where
1380 Self: Shl<Output = Self>,
1381 {
1382 <T as SimdBehaviour<N>>::vec_shl(vec, rhs)
1383 }
1384
1385 #[inline(always)]
1386 fn vec_shr(vec: Vector<N, Self, Simd>, rhs: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
1387 where
1388 Self: Shr<Output = Self>,
1389 {
1390 <T as SimdBehaviour<N>>::vec_shr(vec, rhs)
1391 }
1392
1393 #[inline(always)]
1394 fn vec_bitand(vec: Vector<N, Self, Simd>, rhs: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
1395 where
1396 Self: BitAnd<Output = Self>,
1397 {
1398 <T as SimdBehaviour<N>>::vec_bitand(vec, rhs)
1399 }
1400
1401 #[inline(always)]
1402 fn vec_bitor(vec: Vector<N, Self, Simd>, rhs: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
1403 where
1404 Self: BitOr<Output = Self>,
1405 {
1406 <T as SimdBehaviour<N>>::vec_bitor(vec, rhs)
1407 }
1408
1409 #[inline(always)]
1410 fn vec_bitxor(vec: Vector<N, Self, Simd>, rhs: Vector<N, Self, Simd>) -> Vector<N, Self, Simd>
1411 where
1412 Self: BitXor<Output = Self>,
1413 {
1414 <T as SimdBehaviour<N>>::vec_bitxor(vec, rhs)
1415 }
1416}
1417
1418impl<const N: usize, T: Scalar> VectorApi<N, NonSimd> for T
1419where
1420 VecLen<N>: SupportedVecLen,
1421{
1422 #[inline(always)]
1423 fn vec_from_array(array: [Self; N]) -> Vector<N, Self, NonSimd> {
1424 Vector(array)
1425 }
1426
1427 #[inline(always)]
1428 fn vec_splat(value: Self) -> Vector<N, Self, NonSimd> {
1429 Vector([value; N])
1430 }
1431
1432 #[inline(always)]
1433 fn vec_swizzle2<const X_SRC: usize, const Y_SRC: usize>(
1434 vec: Vector<N, Self, NonSimd>,
1435 ) -> Vector<2, Self, NonSimd> {
1436 const {
1437 assert!(X_SRC < N);
1438 assert!(Y_SRC < N);
1439 }
1440
1441 Vector::<2, _, _>([vec[X_SRC], vec[Y_SRC]])
1442 }
1443
1444 #[inline(always)]
1445 fn vec_swizzle3<const X_SRC: usize, const Y_SRC: usize, const Z_SRC: usize>(
1446 vec: Vector<N, Self, NonSimd>,
1447 ) -> Vector<3, Self, NonSimd> {
1448 const {
1449 assert!(X_SRC < N);
1450 assert!(Y_SRC < N);
1451 assert!(Z_SRC < N);
1452 }
1453
1454 Vector::<3, _, _>([vec[X_SRC], vec[Y_SRC], vec[Z_SRC]])
1455 }
1456
1457 #[inline(always)]
1458 fn vec_swizzle4<
1459 const X_SRC: usize,
1460 const Y_SRC: usize,
1461 const Z_SRC: usize,
1462 const W_SRC: usize,
1463 >(
1464 vec: Vector<N, Self, NonSimd>,
1465 ) -> Vector<4, Self, NonSimd> {
1466 const {
1467 assert!(X_SRC < N);
1468 assert!(Y_SRC < N);
1469 assert!(Z_SRC < N);
1470 assert!(W_SRC < N);
1471 }
1472
1473 Vector::<4, _, _>([vec[X_SRC], vec[Y_SRC], vec[Z_SRC], vec[W_SRC]])
1474 }
1475
1476 #[inline(always)]
1477 fn vec_eq(vec: Vector<N, Self, NonSimd>, other: Vector<N, Self, NonSimd>) -> bool
1478 where
1479 Self: PartialEq,
1480 {
1481 vec.iter().zip(other).all(|(a, b)| a == b)
1482 }
1483
1484 #[inline(always)]
1485 fn vec_ne(vec: Vector<N, Self, NonSimd>, other: Vector<N, Self, NonSimd>) -> bool
1486 where
1487 Self: PartialEq,
1488 {
1489 vec.iter().zip(other).any(|(a, b)| a != b)
1490 }
1491
1492 #[inline(always)]
1493 fn vec_neg(vec: Vector<N, Self, NonSimd>) -> Vector<N, Self, NonSimd>
1494 where
1495 Self: Neg<Output = Self>,
1496 {
1497 vec.map(Self::neg)
1498 }
1499
1500 #[inline(always)]
1501 fn vec_not(vec: Vector<N, Self, NonSimd>) -> Vector<N, Self, NonSimd>
1502 where
1503 Self: Not<Output = Self>,
1504 {
1505 vec.map(Self::not)
1506 }
1507
1508 #[inline(always)]
1509 fn vec_add(
1510 vec: Vector<N, Self, NonSimd>,
1511 rhs: Vector<N, Self, NonSimd>,
1512 ) -> Vector<N, Self, NonSimd>
1513 where
1514 Self: Add<Output = Self>,
1515 {
1516 Vector::from_fn(|i| vec[i] + rhs[i])
1517 }
1518
1519 #[inline(always)]
1520 fn vec_sub(
1521 vec: Vector<N, Self, NonSimd>,
1522 rhs: Vector<N, Self, NonSimd>,
1523 ) -> Vector<N, Self, NonSimd>
1524 where
1525 Self: Sub<Output = Self>,
1526 {
1527 Vector::from_fn(|i| vec[i] - rhs[i])
1528 }
1529
1530 #[inline(always)]
1531 fn vec_mul(
1532 vec: Vector<N, Self, NonSimd>,
1533 rhs: Vector<N, Self, NonSimd>,
1534 ) -> Vector<N, Self, NonSimd>
1535 where
1536 Self: Mul<Output = Self>,
1537 {
1538 Vector::from_fn(|i| vec[i] * rhs[i])
1539 }
1540
1541 #[inline(always)]
1542 fn vec_div(
1543 vec: Vector<N, Self, NonSimd>,
1544 rhs: Vector<N, Self, NonSimd>,
1545 ) -> Vector<N, Self, NonSimd>
1546 where
1547 Self: Div<Output = Self>,
1548 {
1549 Vector::from_fn(|i| vec[i] / rhs[i])
1550 }
1551
1552 #[inline(always)]
1553 fn vec_rem(
1554 vec: Vector<N, Self, NonSimd>,
1555 rhs: Vector<N, Self, NonSimd>,
1556 ) -> Vector<N, Self, NonSimd>
1557 where
1558 Self: Rem<Output = Self>,
1559 {
1560 Vector::from_fn(|i| vec[i] % rhs[i])
1561 }
1562
1563 #[inline(always)]
1564 fn vec_shl(
1565 vec: Vector<N, Self, NonSimd>,
1566 rhs: Vector<N, Self, NonSimd>,
1567 ) -> Vector<N, Self, NonSimd>
1568 where
1569 Self: Shl<Output = Self>,
1570 {
1571 Vector::from_fn(|i| vec[i] << rhs[i])
1572 }
1573
1574 #[inline(always)]
1575 fn vec_shr(
1576 vec: Vector<N, Self, NonSimd>,
1577 rhs: Vector<N, Self, NonSimd>,
1578 ) -> Vector<N, Self, NonSimd>
1579 where
1580 Self: Shr<Output = Self>,
1581 {
1582 Vector::from_fn(|i| vec[i] >> rhs[i])
1583 }
1584
1585 #[inline(always)]
1586 fn vec_bitand(
1587 vec: Vector<N, Self, NonSimd>,
1588 rhs: Vector<N, Self, NonSimd>,
1589 ) -> Vector<N, Self, NonSimd>
1590 where
1591 Self: BitAnd<Output = Self>,
1592 {
1593 Vector::from_fn(|i| vec[i] & rhs[i])
1594 }
1595
1596 #[inline(always)]
1597 fn vec_bitor(
1598 vec: Vector<N, Self, NonSimd>,
1599 rhs: Vector<N, Self, NonSimd>,
1600 ) -> Vector<N, Self, NonSimd>
1601 where
1602 Self: BitOr<Output = Self>,
1603 {
1604 Vector::from_fn(|i| vec[i] | rhs[i])
1605 }
1606
1607 #[inline(always)]
1608 fn vec_bitxor(
1609 vec: Vector<N, Self, NonSimd>,
1610 rhs: Vector<N, Self, NonSimd>,
1611 ) -> Vector<N, Self, NonSimd>
1612 where
1613 Self: BitXor<Output = Self>,
1614 {
1615 Vector::from_fn(|i| vec[i] ^ rhs[i])
1616 }
1617}
1618
1619macro_rules! specialized_vector_api {
1620 {
1621 $Api:ident for <$N:expr, $T:ty, $S:ty>:
1622
1623 $(
1624 $(#[$meta:meta])*
1625 $vis:vis fn $fn_name:ident$(<$(const $CONST_PARAM:ident: $ConstParam:ty),* $(,)?>)?(
1626 $($param:ident$(: $Param:ty)?),* $(,)?
1627 ) -> $return_tt:ty
1628 $(where
1629 $($BoundType:ty: $BoundTrait:path),*)?;
1630 )*
1631 } => {
1632 $(
1633 $(#[$meta])*
1634 $vis fn $fn_name$(<$(const $CONST_PARAM: $ConstParam),*>)?(
1635 $($param $(: $Param)?),*
1636 ) -> $return_tt
1637 $(where
1638 $($BoundType: $BoundTrait),*)?
1639 {
1640 (const {
1641 match <$S>::IS_SIMD {
1642 true => match $N {
1643 2 => specialized_vector_api!(@transmute_fnptr($($param),*) <$T as $Api<2, crate::Simd>>::vec_$fn_name$(::<$($CONST_PARAM),*>)?),
1644 3 => specialized_vector_api!(@transmute_fnptr($($param),*) <$T as $Api<3, crate::Simd>>::vec_$fn_name$(::<$($CONST_PARAM),*>)?),
1645 4 => specialized_vector_api!(@transmute_fnptr($($param),*) <$T as $Api<4, crate::Simd>>::vec_$fn_name$(::<$($CONST_PARAM),*>)?),
1646 ..2 | 5.. => panic!("N must be 2, 3, or 4"),
1647 }
1648 false => specialized_vector_api!(@transmute_fnptr($($param),*) <$T as $Api<N, crate::NonSimd>>::vec_$fn_name$(::<$($CONST_PARAM),*>)?),
1649 }
1650 })($($param),*)
1651 }
1652 )*
1653 };
1654
1655 { @transmute_fnptr($($param:ident),*) <$T:ty as $VectorApi:ident<$N:expr, $S:ty>>::vec_$fn_name:ident$(::<$($CONST_PARAM:ident),*>)? } => {
1656 crate::hidden::paste! {
1657 unsafe {
1658 let fnptr: fn($(specialized_vector_api!(@_ $param)),*) -> _ = <$T as $VectorApi<$N, $S>>::[<vec_$fn_name>]$(::<$($CONST_PARAM),*>)?;
1659
1660 core::mem::transmute_copy::<
1661 fn($(specialized_vector_api!(@_ $param)),*) -> _,
1662 fn($(specialized_vector_api!(@_ $param)),*) -> _,
1663 >(&fnptr)
1664 }
1665 }
1666 };
1667
1668 { @_ $_:tt } => { _ }
1669}
1670
1671use specialized_vector_api;