ggmath/vector/
mod.rs

1//! Vector related items.
2
3use 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/// A generic vector type.
24///
25/// This type is parameterized over:
26/// - `N`: The number of elements in the vector.
27/// - `T`: The element type.
28/// - `S`: Whether the vector uses SIMD acceleration.
29///
30/// ## Type Aliases
31///
32/// This type provides the following convenient aliases:
33/// - `Vec{N}<T>` — shorthand for [`Vector<N, T, Simd>`], e.g. [`Vec2<f32>`] =
34///   [`Vector<2, f32, Simd>`].
35/// - `Vec{N}S<T>` — shorthand for [`Vector<N, T, NonSimd>`], e.g. [`Vec2S<f32>`] =
36///   [`Vector<2, f32, NonSimd>`].
37///
38/// ## SIMD Acceleration
39///
40/// The `S` parameter determines whether the vector uses SIMD.  
41/// It can be either [`Simd`] or [`NonSimd`].
42///
43/// You might wonder: if SIMD makes operations faster, why disable it?  
44///
45/// While SIMD provides significant performance benefits, SIMD-backed vectors also
46/// require higher memory alignment. Using [`NonSimd`] can be beneficial when
47/// minimizing memory usage is more important than maximizing performance.
48///
49/// The implementation of [`Simd`] vectors is controlled by the [`SimdBehaviour`] trait,
50/// which is implemented for `T`. Each implementation can choose how to store and
51/// operate on the vector, and may use SIMD instructions when doing so improves
52/// performance.
53#[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        /// Creates a vector from an array.
66        pub fn from_array(array: [T; N]) -> Self;
67
68        /// Creates a vector with all elements set to the same value.
69        pub fn splat(value: T) -> Self;
70
71        /// Creates a vector2 from `(self[X_SRC], self[Y_SRC])`.
72        ///
73        /// ## Examples
74        ///
75        /// ```
76        /// use ggmath::{Vec4, vec2, vec4};
77        ///
78        /// let v: Vec4<f32> = vec4!(1.0, 2.0, 3.0, 4.0);
79        ///
80        /// assert_eq!(v.swizzle2::<0, 1>(), vec2!(1.0, 2.0));
81        /// assert_eq!(v.swizzle2::<2, 3>(), vec2!(3.0, 4.0));
82        /// assert_eq!(v.swizzle2::<3, 0>(), vec2!(4.0, 1.0));
83        ///
84        /// // Elements can be repeated
85        /// assert_eq!(v.swizzle2::<1, 1>(), vec2!(2.0, 2.0));
86        /// ```
87        pub fn swizzle2<const X_SRC: usize, const Y_SRC: usize>(self) -> Vector<2, T, S>;
88
89        /// Creates a vector3 from `(self[X_SRC], self[Y_SRC], self[Z_SRC])`.
90        ///
91        /// ## Examples
92        ///
93        /// ```
94        /// use ggmath::{Vec4, vec3, vec4};
95        ///
96        /// let v: Vec4<f32> = vec4!(1.0, 2.0, 3.0, 4.0);
97        ///
98        /// assert_eq!(v.swizzle3::<0, 1, 2>(), vec3!(1.0, 2.0, 3.0));
99        /// assert_eq!(v.swizzle3::<2, 1, 0>(), vec3!(3.0, 2.0, 1.0));
100        /// assert_eq!(v.swizzle3::<3, 0, 1>(), vec3!(4.0, 1.0, 2.0));
101        ///
102        /// // Elements can be repeated
103        /// assert_eq!(v.swizzle3::<1, 1, 1>(), vec3!(2.0, 2.0, 2.0));
104        /// ```
105        pub fn swizzle3<const X_SRC: usize, const Y_SRC: usize, const Z_SRC: usize>(self) -> Vector<3, T, S>;
106
107        /// Creates a vector4 from `(self[X_SRC], self[Y_SRC], self[Z_SRC], self[W_SRC])`.
108        ///
109        /// ## Examples
110        ///
111        /// ```
112        /// use ggmath::{Vec4, vec4};
113        ///
114        /// let v: Vec4<f32> = vec4!(1.0, 2.0, 3.0, 4.0);
115        ///
116        /// assert_eq!(v.swizzle4::<0, 1, 2, 3>(), vec4!(1.0, 2.0, 3.0, 4.0));
117        /// assert_eq!(v.swizzle4::<3, 2, 1, 0>(), vec4!(4.0, 3.0, 2.0, 1.0));
118        /// assert_eq!(v.swizzle4::<3, 0, 1, 2>(), vec4!(4.0, 1.0, 2.0, 3.0));
119        ///
120        /// // Elements can be repeated
121        /// assert_eq!(v.swizzle4::<1, 1, 1, 1>(), vec4!(2.0, 2.0, 2.0, 2.0));
122        /// ```
123        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    /// Creates a vector where each element is produced by calling `f` with that
127    /// element's index.
128    ///
129    /// ## Examples
130    ///
131    /// ```
132    /// use ggmath::{Vec4, vec4};
133    ///
134    /// let v: Vec4<f32> = Vec4::from_fn(|i| i as f32);
135    /// assert_eq!(v, vec4!(0.0, 1.0, 2.0, 3.0));
136    /// ```
137    #[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    /// Creates a vector from an array, *in a const context*.
143    ///
144    /// [`Vector::from_array`] performs the same operation but cannot be used in const
145    /// contexts. This function is intended for initializing constants and should not
146    /// be used at runtime, as it is slower than [`Vector::from_array`].
147    #[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        // SAFETY: Vector<N, MaybeUninit<T>, S> is transparent to [MaybeUninit<T>; N] which allows all bit patterns
155        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        // SAFETY:
173        // Vector<N, MaybeUninit<T>, S> is guaranteed to begin with N MaybeUninit<T>'s, so it also begins with N T's,
174        // and all elements are initialized.
175        unsafe { transmute_copy::<Vector<N, MaybeUninit<T>, S>, Vector<N, T, S>>(&result) }
176    }
177
178    /// Returns the number of elements in the vector, which is a statically known
179    /// constant.
180    #[inline(always)]
181    pub const fn len(self) -> usize {
182        N
183    }
184
185    /// Returns true for [`Simd`] vectors, false for [`NonSimd`] vectors.
186    #[inline(always)]
187    pub const fn is_simd(self) -> bool {
188        S::IS_SIMD
189    }
190
191    /// Converts `self` to a vector of a different [`Simdness`].
192    #[inline(always)]
193    pub fn as_simdness<S2: Simdness>(self) -> Vector<N, T, S2> {
194        if S::IS_SIMD == S2::IS_SIMD {
195            // SAFETY: S and S2 are the same type, so we are transmuting a type to itself
196            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    /// Converts `self` to a [`Simd`] vector.
203    #[inline(always)]
204    pub fn as_simd(self) -> Vector<N, T, Simd> {
205        self.as_simdness::<Simd>()
206    }
207
208    /// Converts `self` to a [`NonSimd`] vector.
209    #[inline(always)]
210    pub fn as_nonsimd(self) -> Vector<N, T, NonSimd> {
211        self.as_simdness::<NonSimd>()
212    }
213
214    /// Converts `self` to an owned array.
215    #[inline(always)]
216    pub const fn as_array(self) -> [T; N] {
217        *self.as_array_ref()
218    }
219
220    /// Converts a vector reference to an array reference.
221    #[inline(always)]
222    pub const fn as_array_ref(&self) -> &[T; N] {
223        // SAFETY: Vector<N, T, S> is guaranteed to begin with N T's
224        unsafe { transmute::<&Vector<N, T, S>, &[T; N]>(self) }
225    }
226
227    /// Converts a mutable vector reference to an mutable array reference.
228    #[inline(always)]
229    pub const fn as_mut_array(&mut self) -> &mut [T; N] {
230        // SAFETY: Vector<N, T, S> is guaranteed to begin with N T's
231        unsafe { transmute::<&mut Vector<N, T, S>, &mut [T; N]>(self) }
232    }
233
234    /// Returns the element at the given index, or `None` if the index is out of
235    /// bounds.
236    #[inline(always)]
237    pub const fn get(self, index: usize) -> Option<T> {
238        if index < N {
239            // SAFETY: index is guaranteed to be in bounds
240            Some(unsafe { *self.as_array_ref().as_ptr().add(index) })
241        } else {
242            None
243        }
244    }
245
246    /// Returns a mutable reference to the element at the given index, or `None`
247    /// if the index is out of bounds.
248    #[inline(always)]
249    pub const fn get_mut(&mut self, index: usize) -> Option<&mut T> {
250        if index < N {
251            // SAFETY: index is guaranteed to be in bounds
252            Some(unsafe { &mut *self.as_mut_array().as_mut_ptr().add(index) })
253        } else {
254            None
255        }
256    }
257
258    /// Returns a new vector with the elements of `self` in reverse order.
259    #[inline(always)]
260    pub fn reverse(self) -> Self {
261        (const {
262            match N {
263                // SAFETY: N is guaranteed to be 2, so we are transmuting a type to itself
264                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                // SAFETY: N is guaranteed to be 3, so we are transmuting a type to itself
273                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                // SAFETY: N is guaranteed to be 4, so we are transmuting a type to itself
282                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    /// Returns an iterator over the elements of the vector.
296    #[inline(always)]
297    pub fn iter(self) -> <[T; N] as IntoIterator>::IntoIter {
298        self.as_array().into_iter()
299    }
300
301    /// Returns an iterator over mutable references to the elements of the vector.
302    #[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    /// Returns a new vector with function `f` applied to each element.
308    ///
309    /// ## Examples
310    ///
311    /// ```
312    /// use ggmath::{Vec2, vec2};
313    ///
314    /// let v: Vec2<f32> = vec2!(1.0, 2.0);
315    /// assert_eq!(v.map(|x| x * 2.0), vec2!(2.0, 4.0));
316    /// ```
317    #[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    /// Returns a vector with the same elements as `self`, but with the x component replaced with `value`.
332    #[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    /// Returns a vector with the same elements as `self`, but with the y component replaced with `value`.
341    #[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    /// Returns a vector with the same elements as `self`, but with the x component replaced with `value`.
352    #[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    /// Returns a vector with the same elements as `self`, but with the y component replaced with `value`.
361    #[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    /// Returns a vector with the same elements as `self`, but with the z component replaced with `value`.
370    #[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    /// Returns a vector with the same elements as `self`, but with the x component replaced with `value`.
381    #[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    /// Returns a vector with the same elements as `self`, but with the y component replaced with `value`.
390    #[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    /// Returns a vector with the same elements as `self`, but with the z component replaced with `value`.
399    #[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    /// Returns a vector with the same elements as `self`, but with the w component replaced with `value`.
408    #[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    /// Creates a [`Simd`] vector from its internal representation, which is
422    /// [`<T as SimdBehaviour<N>>::VectorRepr`][SimdBehaviour::VectorRepr].
423    ///
424    /// This function is useful when implementing SIMD optimizations for custom
425    /// scalar types.
426    #[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        // SAFETY: Vector<N, T, Simd> is transparent to <T as SimdBehaviour<N>>::VectorRepr
442        unsafe { transmute_copy::<<T as SimdBehaviour<N>>::VectorRepr, Vector<N, T, Simd>>(&repr) }
443    }
444
445    /// Returns the internal representation of a [`Simd`] vector, which is
446    /// [`<T as SimdBehaviour<N>>::VectorRepr`][SimdBehaviour::VectorRepr].
447    ///
448    /// This function is useful when implementing SIMD optimizations for custom
449    /// scalar types.
450    #[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        // SAFETY: Vector<N, T, Simd> is transparent to <T as SimdBehaviour<N>>::VectorRepr
466        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    /// Converts an array reference to a [`NonSimd`] vector reference.
475    #[inline(always)]
476    pub const fn from_array_ref(array: &[T; N]) -> &Self {
477        // SAFETY: Vector<N, T, NonSimd> is transparent to [T; N]
478        unsafe { transmute::<&[T; N], &Vector<N, T, NonSimd>>(array) }
479    }
480
481    /// Converts a mutable array reference to a mutable [`NonSimd`] vector reference.
482    #[inline(always)]
483    pub const fn from_mut_array(array: &mut [T; N]) -> &mut Self {
484        // SAFETY: Vector<N, T, NonSimd> is transparent to [T; N]
485        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
618////////////////////////////////////////////////////////////////////////////////
619// Type Aliases
620////////////////////////////////////////////////////////////////////////////////
621
622/// A 2D vector of `T` elements.
623///
624/// This is a type alias for [`Vector<2, T, Simd>`]. For appropriate `T`s,
625/// this type is SIMD-aligned and uses performant SIMD instructions.
626pub type Vec2<T> = Vector<2, T, Simd>;
627
628/// A 3D vector of `T` elements.
629///
630/// This is a type alias for [`Vector<3, T, Simd>`]. For appropriate `T`s,
631/// this type is SIMD-aligned and uses performant SIMD instructions.
632pub type Vec3<T> = Vector<3, T, Simd>;
633
634/// A 4D vector of `T` elements.
635///
636/// This is a type alias for [`Vector<4, T, Simd>`]. For appropriate `T`s,
637/// this type is SIMD-aligned and uses performant SIMD instructions.
638pub type Vec4<T> = Vector<4, T, Simd>;
639
640/// A 2D vector of `T` elements.
641///
642/// Unlike [`Vec2`], this type is never SIMD-aligned ("s" stands for
643/// "scalar"). This is a type alias for [`Vector<2, T, NonSimd>`].
644pub type Vec2S<T> = Vector<2, T, NonSimd>;
645
646/// A 3D vector of `T` elements.
647///
648/// Unlike [`Vec3`], this type is never SIMD-aligned ("s" stands for
649/// "scalar").
650/// This is a type alias for [`Vector<3, T, NonSimd>`].
651pub type Vec3S<T> = Vector<3, T, NonSimd>;
652
653/// A 4D vector of `T` elements.
654///
655/// Unlike [`Vec4`], this type is never SIMD-aligned ("s" stands for
656/// "scalar").
657/// This is a type alias for [`Vector<4, T, NonSimd>`].
658pub type Vec4S<T> = Vector<4, T, NonSimd>;
659
660/// Declares vector type aliases for a custom scalar type.
661///
662/// ## Example
663///
664/// ```
665/// use ggmath::declare_vector_aliases;
666///
667/// struct CustomScalar(f32);
668///
669/// declare_vector_aliases!(type C => CustomScalar);
670///
671/// // Generated aliases:
672/// // type CVec2 = Vector<2, CustomScalar, Simd>;
673/// // type CVec3 = Vector<3, CustomScalar, Simd>;
674/// // type CVec4 = Vector<4, CustomScalar, Simd>;
675/// // type CVec2S = Vector<2, CustomScalar, NonSimd>;
676/// // type CVec3S = Vector<3, CustomScalar, NonSimd>;
677/// // type CVec4S = Vector<4, CustomScalar, NonSimd>;
678/// ```
679#[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
724////////////////////////////////////////////////////////////////////////////////
725// Scalar
726////////////////////////////////////////////////////////////////////////////////
727
728/// A trait for types that can be used as elements in a [`Vector`].
729///
730/// To implement this trait, you must also implement the [`SimdBehaviour<N>`] trait
731/// for `N = 2, 3, 4`. The [`SimdBehaviour`] trait controls the implementation
732/// details of [`Vector<N, Self, Simd>`].
733///
734/// For an example of a SIMD-optimized implementation, see the
735/// `fixed_point_scalar` example.
736///
737/// ## Example
738///
739/// ```
740/// use ggmath::*;
741///
742/// #[derive(Clone, Copy)]
743/// struct CustomScalar(f32);
744///
745/// impl Scalar for CustomScalar {}
746///
747/// impl SimdBehaviour<2> for CustomScalar {
748///     type VectorRepr = [CustomScalar; 2];
749/// }
750///
751/// impl SimdBehaviour<3> for CustomScalar {
752///     type VectorRepr = [CustomScalar; 3];
753/// }
754///
755/// impl SimdBehaviour<4> for CustomScalar {
756///     type VectorRepr = [CustomScalar; 4];
757/// }
758///
759/// // Now `CustomScalar` can be used as a vector element type.
760/// ```
761pub trait Scalar: SimdBehaviour<2> + SimdBehaviour<3> + SimdBehaviour<4> {}
762
763/// Controls the implementation details of [`Vector<N, Self, Simd>`]. For
764/// example, `f32` implementing `SimdBehaviour<4>` controls
765/// `Vector<4, f32, Simd>`.
766///
767/// The goal of implementing this trait is to enable SIMD optimizations,
768/// but it's acceptable not to use SIMD if it doesn't provide a performance
769/// benefit, or if it's only a placeholder implementation.
770pub trait SimdBehaviour<const N: usize>: Construct
771where
772    VecLen<N>: SupportedVecLen,
773{
774    /// The internal representation of the vector.
775    ///
776    /// There are two ways to define the internal representation:
777    ///
778    /// 1. Array:  
779    ///    If the internal representation is `[Self; N]`, there is no SIMD alignment.  
780    ///    In this case, the behavior of [`Simd`] and [`NonSimd`] is the same, with no SIMD optimizations.
781    ///
782    /// 2. Wrapped Vector Type:  
783    ///    If `Self` is a wrapper around an existing scalar type,  
784    ///    the internal representation can be a vector of that scalar type.  
785    ///    This allows you to leverage the SIMD-optimized API of the base type.  
786    ///    To enable this, `Self` must implement [`ScalarWrapper<TInner>`].
787    ///
788    /// ## Example
789    ///
790    /// ```rust
791    /// use ggmath::*;
792    ///
793    /// #[repr(transparent)]
794    /// #[derive(Copy, Clone)]
795    /// struct CustomScalar(f32);
796    ///
797    /// impl Scalar for CustomScalar {}
798    ///
799    /// // SAFETY: CustomScalar is a direct wrapper around f32, so it's safe to
800    /// // implement ScalarWrapper<f32> for it.
801    /// unsafe impl ScalarWrapper<f32> for CustomScalar {}
802    ///
803    /// impl<const N: usize> SimdBehaviour<N> for CustomScalar
804    /// where
805    ///     VecLen<N>: SupportedVecLen,
806    /// {
807    ///     type VectorRepr = Vector<N, f32, Simd>;
808    ///
809    ///     // Now you can use f32's SIMD-optimized vector API to optimize your vector
810    ///     // implementation.
811    /// }
812    /// ```
813    #[expect(private_bounds)]
814    type VectorRepr: SoundVectorRepr<N, Self>;
815
816    /// Overridable implementation of [`Vector::from_array`].
817    #[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    /// Overridable implementation of [`Vector::splat`].
826    #[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    /// Overridable implementation of [`Vector::swizzle2`].
835    #[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    /// Overridable implementation of [`Vector::swizzle3`].
846    #[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    /// Overridable implementation of [`Vector::swizzle4`].
857    #[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    /// Overridable implementation of [`Vector::eq`].
873    #[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    /// Overridable implementation of [`Vector::ne`].
882    #[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    /// Overridable implementation of [`Vector::neg`].
891    ///
892    /// Implementations may deviate from `Self as Neg` in edge cases, but should
893    /// otherwise closely follow the behavior of `Self as Neg`.
894    #[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    /// Overridable implementation of [`Vector::not`].
903    ///
904    /// Implementations may deviate from `Self as Not` in edge cases, but should
905    /// otherwise closely follow the behavior of `Self as Not`.
906    #[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    /// Overridable implementation of [`Vector::add`].
915    ///
916    /// Implementations may deviate from `Self as Add` in edge cases, but should
917    /// otherwise closely follow the behavior of `Self as Add`.
918    #[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    /// Overridable implementation of [`Vector::sub`].
927    ///
928    /// Implementations may deviate from `Self as Sub` in edge cases, but should
929    /// otherwise closely follow the behavior of `Self as Sub`.
930    #[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    /// Overridable implementation of [`Vector::mul`].
939    ///
940    /// Implementations may deviate from `Self as Mul` in edge cases, but should
941    /// otherwise closely follow the behavior of `Self as Mul`.
942    #[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    /// Overridable implementation of [`Vector::div`].
951    ///
952    /// Implementations may deviate from `Self as Div` in edge cases, but should
953    /// otherwise closely follow the behavior of `Self as Div`.
954    #[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    /// Overridable implementation of [`Vector::rem`].
963    ///
964    /// Implementations may deviate from `Self as Rem` in edge cases, but should
965    /// otherwise closely follow the behavior of `Self as Rem`.
966    #[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    /// Overridable implementation of [`Vector::shl`].
975    ///
976    /// Implementations may deviate from `Self as Shl` in edge cases, but should
977    /// otherwise closely follow the behavior of `Self as Shl`.
978    #[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    /// Overridable implementation of [`Vector::shr`].
987    ///
988    /// Implementations may deviate from `Self as Shr` in edge cases, but should
989    /// otherwise closely follow the behavior of `Self as Shr`.
990    #[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    /// Overridable implementation of [`Vector::bitand`].
999    ///
1000    /// Implementations may deviate from `Self as BitAnd` in edge cases, but should
1001    /// otherwise closely follow the behavior of `Self as BitAnd`.
1002    #[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    /// Overridable implementation of [`Vector::bitor`].
1011    ///
1012    /// Implementations may deviate from `Self as BitOr` in edge cases, but should
1013    /// otherwise closely follow the behavior of `Self as BitOr`.
1014    #[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    /// Overridable implementation of [`Vector::bitxor`].
1023    ///
1024    /// Implementations may deviate from `Self as BitXor` in edge cases, but should
1025    /// otherwise closely follow the behavior of `Self as BitXor`.
1026    #[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
1035/// Unsafe trait for scalar types that are direct wrappers around another scalar type.
1036///
1037/// This trait is used by [`SimdBehaviour::VectorRepr`].
1038///
1039/// ## Example
1040///
1041/// ```
1042/// use ggmath::*;
1043///
1044/// #[repr(transparent)]
1045/// #[derive(Copy, Clone)]
1046/// struct CustomScalar(f32);
1047///
1048/// // SAFETY: CustomScalar is a direct wrapper around f32, so it's safe to
1049/// // implement ScalarWrapper<f32> for it.
1050/// unsafe impl ScalarWrapper<f32> for CustomScalar {}
1051/// ```
1052pub unsafe trait ScalarWrapper<T: Scalar> {}
1053
1054////////////////////////////////////////////////////////////////////////////////
1055// Length
1056////////////////////////////////////////////////////////////////////////////////
1057
1058/// A type that represents the length of a vector, and allows for this pattern:
1059///
1060/// ```ignore
1061/// impl<const N: usize, T: Scalar, S: Simdness> Vector<N, T, S>
1062/// where
1063///     VecLen<N>: SupportedVecLen,
1064/// {
1065/// }
1066/// ```
1067pub struct VecLen<const N: usize>;
1068
1069/// A trait that marks supported [`Vector`] lengths.
1070pub 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
1089////////////////////////////////////////////////////////////////////////////////
1090// Simdness
1091////////////////////////////////////////////////////////////////////////////////
1092
1093/// A type that marks a [`Vector`] as SIMD-backed.
1094pub struct Simd;
1095
1096/// A type that marks a [`Vector`] as not SIMD-backed.
1097pub struct NonSimd;
1098
1099/// A trait that is implemented for [`Simd`] and [`NonSimd`].
1100pub trait Simdness: Sealed + 'static {
1101    #[doc(hidden)]
1102    type Pick<TSimd: Construct, TNonSimd: Construct>: Construct;
1103
1104    /// Is true for [`Simd`], and false for [`NonSimd`].
1105    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
1122////////////////////////////////////////////////////////////////////////////////
1123// Vector Representation
1124////////////////////////////////////////////////////////////////////////////////
1125
1126trait 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
1146// SAFETY: [T; N] begins with N T's
1147unsafe impl<const N: usize, T: Scalar> SoundVectorRepr<N, T> for [T; N] {}
1148
1149// SAFETY: Vector<N, InsideT, InsideS> begins with N InsideT's, so it also begins with N T's
1150unsafe 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
1158////////////////////////////////////////////////////////////////////////////////
1159// Specialization
1160////////////////////////////////////////////////////////////////////////////////
1161
1162trait 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        // SAFETY: it is guaranteed that X_SRC and Y_SRC are in bounds
1268        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        // SAFETY: it is guaranteed that X_SRC, Y_SRC, and Z_SRC are in bounds
1282        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        // SAFETY: it is guaranteed that X_SRC, Y_SRC, Z_SRC, and W_SRC are in bounds
1302        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;