vek/
vec.rs

1//! Vector types.
2//!
3//! They do NOT derive `PartialOrd` and `Ord`, because it makes no sense for them,
4//! and functions such as `partial_min` and `partial_max` may give surprising results
5//! because of this.
6//! They do have element-wise comparison functions though.
7
8use std::borrow::{Borrow, BorrowMut};
9use std::fmt::{self, Display, Formatter};
10use std::iter::{FromIterator, Product, Sum};
11use std::mem;
12use std::ptr;
13use std::cmp;
14use std::ops::*;
15use std::slice::{self, /*SliceIndex*/}; // NOTE: Will want to use SliceIndex once it's stabilized
16use std::num::Wrapping;
17#[cfg(feature = "platform_intrinsics")]
18use std::simd::SimdElement;
19use num_traits::{Zero, One, NumCast, AsPrimitive, Signed, real::Real};
20use approx::{AbsDiffEq, RelativeEq, UlpsEq};
21use crate::ops::*;
22
23#[cfg(feature = "bytemuck")]
24use crate::bytemuck;
25
26// Macro for selecting separate implementations for repr(C) vs repr(simd), at compile time.
27macro_rules! choose {
28    (c { c => $c_impl:expr, simd_llvm => $s_impl:expr, }) => {
29        { $c_impl }
30    };
31    (simd { c => $c_impl:expr, simd_llvm => $s_impl:expr, }) => {
32        #[cfg(not(feature = "platform_intrinsics"))]
33        { $c_impl }
34
35        #[cfg(feature = "platform_intrinsics")]
36        { $s_impl }
37    };
38}
39
40macro_rules! cond_borrow {
41    (ref, $a:expr) => { &$a };
42    (move, $a:expr) => { $a };
43}
44
45macro_rules! reduce_fn {
46    ($fn:expr, $a:expr, $b:expr) => { $fn($a, $b) };
47    ($fn:expr, $a:expr, $b:expr, $($v:expr),+) => { reduce_fn!($fn, reduce_fn!($fn, $a, $b), $($v),+) };
48}
49
50// reduce_fn_mut is no different than reduce_fn, but it introduces "unnecessary" let bindings (and therefore, debug symbols or whatever).
51// It's specifically for when $fn is an FnMut.
52macro_rules! reduce_fn_mut {
53    ($fn:expr, $a:expr, $b:expr) => { $fn($a, $b) };
54    ($fn:expr, $a:expr, $b:expr, $($v:expr),+) => { { let x = reduce_fn_mut!($fn, $a, $b); reduce_fn_mut!($fn, x, $($v),+) } };
55}
56
57// NOTE: using reduce_binop!() form should be preferred instead of reduce_fn!() when possible.
58// For instance:
59// - reduce_binop!(&&, x, y, z) will yield: x && y && z.
60// - reduce_fn!(And::and, x, y, z) will yield: And::and(And::and(x, y), z).
61// Notice that when using reduce_binop!(), we benefit from short-circuit semantics and operator priority.
62macro_rules! reduce_binop {
63    ($op:tt, $a:expr, $b:expr) => { $a $op $b };
64    ($op:tt, $a:expr, $b:expr, $($v:expr),+) => { reduce_binop!($op, reduce_binop!($op, $a, $b), $($v),+) };
65}
66
67// Same semantics as "horizontal add".
68macro_rules! horizontal_binop {
69    ($op:tt, $out:expr => $a:expr, $b:expr) => { $out = $a $op $b; };
70    ($op:tt, $out:expr, $($vout:expr),+ => $a:expr, $b:expr, $($v:expr),+) => { horizontal_binop!($op, $out => $a, $b); horizontal_binop!($op, $($vout),+ => $($v),+); };
71}
72
73macro_rules! vec_impl_cmp {
74    ($(#[$attrs:meta])*, $c_or_simd:ident, $Vec:ident, $cmp:ident, $cmp_simd:ident, $simd_cmp:ident, $op:tt, $Bounds:tt, ($($get:tt)+)) => {
75        // NOTE: Rhs is taken as reference: see how std::cmp::PartialEq is implemented.
76        $(#[$attrs])*
77        #[inline]
78        pub fn $cmp<Rhs: AsRef<Self>>(&self, rhs: &Rhs) -> $Vec<bool> where T: $Bounds {
79            let rhs = rhs.as_ref();
80            choose!{$c_or_simd {
81                c => $Vec::new($(self.$get $op rhs.$get),+),
82                // Doesn't compile, vectors must be passed by value
83                // simd_llvm => unsafe { simd_llvm::$simd_cmp(self, rhs) },
84                simd_llvm => $Vec::new($(self.$get $op rhs.$get),+),
85            }}
86        }
87        $(#[$attrs])*
88        #[cfg(feature = "platform_intrinsics")]
89        #[inline]
90        pub fn $cmp_simd(self, rhs: Self) -> $Vec<T::Mask>
91            where
92                T: $Bounds + SimdElement,
93                <T as SimdElement>::Mask: num_traits::cast::FromPrimitive {
94            choose!{$c_or_simd {
95                c => $Vec::new($(<T::Mask as num_traits::cast::FromPrimitive>::from_u8((self.$get $op rhs.$get) as _).unwrap()),+),
96                simd_llvm => unsafe { std::intrinsics::simd::$simd_cmp(self, rhs) },
97            }}
98        }
99
100        $(#[$attrs])*
101        #[cfg(not(feature = "platform_intrinsics"))]
102        #[inline]
103        pub fn $cmp_simd(self, rhs: Self) -> $Vec<bool> where T: $Bounds {
104            self.$cmp(&rhs)
105        }
106    }
107}
108
109macro_rules! vec_impl_trinop_vec_vec {
110    ($op:ident, $Out:ty, $Rhs1:ty, $Rhs2:ty, ($($namedget:ident)+) ($($get:tt)+) ($lborrow:tt) ($rborrow:tt)) => {
111        type Output = $Out;
112        #[inline]
113        fn $op(self, a: $Rhs1, b: $Rhs2) -> Self::Output {
114            Self::Output::new($(self.$get.$op(cond_borrow!($lborrow, a.$get), cond_borrow!($rborrow, b.$get))),+)
115        }
116    }
117}
118
119macro_rules! vec_impl_trinop {
120    (impl $Op:ident for $Vec:ident { $op:tt } ($($namedget:tt)+) ($($get:tt)+)) => {
121        impl<            T> $Op<    $Vec<T>,     $Vec<T>> for     $Vec<T> where     T: $Op<    T,     T, Output=T> { vec_impl_trinop_vec_vec!{$op, $Vec<T>,     $Vec<T>,     $Vec<T>, ($($namedget)+) ($($get)+) (move) (move)} }
122        impl<       'c,  T> $Op<    $Vec<T>,     $Vec<T>> for &'c $Vec<T> where &'c T: $Op<    T,     T, Output=T> { vec_impl_trinop_vec_vec!{$op, $Vec<T>,     $Vec<T>,     $Vec<T>, ($($namedget)+) ($($get)+) (move) (move)} }
123        impl<   'b,      T> $Op<    $Vec<T>, &'b $Vec<T>> for     $Vec<T> where     T: $Op<    T, &'b T, Output=T> { vec_impl_trinop_vec_vec!{$op, $Vec<T>,     $Vec<T>, &'b $Vec<T>, ($($namedget)+) ($($get)+) (move) (ref)} }
124        impl<   'b, 'c,  T> $Op<    $Vec<T>, &'b $Vec<T>> for &'c $Vec<T> where &'c T: $Op<    T, &'b T, Output=T> { vec_impl_trinop_vec_vec!{$op, $Vec<T>,     $Vec<T>, &'b $Vec<T>, ($($namedget)+) ($($get)+) (move) (ref)} }
125        impl<'a,         T> $Op<&'a $Vec<T>,     $Vec<T>> for     $Vec<T> where     T: $Op<&'a T,     T, Output=T> { vec_impl_trinop_vec_vec!{$op, $Vec<T>, &'a $Vec<T>,     $Vec<T>, ($($namedget)+) ($($get)+) (ref) (move)} }
126        impl<'a,     'c, T> $Op<&'a $Vec<T>,     $Vec<T>> for &'c $Vec<T> where &'c T: $Op<&'a T,     T, Output=T> { vec_impl_trinop_vec_vec!{$op, $Vec<T>, &'a $Vec<T>,     $Vec<T>, ($($namedget)+) ($($get)+) (ref) (move)} }
127        impl<'a, 'b,     T> $Op<&'a $Vec<T>, &'b $Vec<T>> for     $Vec<T> where     T: $Op<&'a T, &'b T, Output=T> { vec_impl_trinop_vec_vec!{$op, $Vec<T>, &'a $Vec<T>, &'b $Vec<T>, ($($namedget)+) ($($get)+) (ref) (ref)} }
128        impl<'a, 'b, 'c, T> $Op<&'a $Vec<T>, &'b $Vec<T>> for &'c $Vec<T> where &'c T: $Op<&'a T, &'b T, Output=T> { vec_impl_trinop_vec_vec!{$op, $Vec<T>, &'a $Vec<T>, &'b $Vec<T>, ($($namedget)+) ($($get)+) (ref) (ref)} }
129    }
130}
131
132macro_rules! vec_impl_trinop_assign_vec_vec {
133    ($op:ident, $Rhs1:ty, $Rhs2:ty, ($($namedget:ident)+) ($($get:tt)+) ($lborrow:tt) ($rborrow:tt)) => {
134        #[inline]
135        fn $op(&mut self, a: $Rhs1, b: $Rhs2) {
136            $(self.$get.$op(cond_borrow!($lborrow, a.$get), cond_borrow!($rborrow, b.$get)));+;
137        }
138    }
139}
140
141macro_rules! vec_impl_trinop_assign {
142    (impl $Op:ident for $Vec:ident { $op:tt } ($($namedget:tt)+) ($($get:tt)+)) => {
143        impl<            T> $Op<    $Vec<T>,     $Vec<T>> for     $Vec<T> where     T: $Op<    T,     T> { vec_impl_trinop_assign_vec_vec!{$op,     $Vec<T>,     $Vec<T>, ($($namedget)+) ($($get)+) (move) (move)} }
144        impl<   'b,      T> $Op<    $Vec<T>, &'b $Vec<T>> for     $Vec<T> where     T: $Op<    T, &'b T> { vec_impl_trinop_assign_vec_vec!{$op,     $Vec<T>, &'b $Vec<T>, ($($namedget)+) ($($get)+) (move) (ref)} }
145        impl<'a,         T> $Op<&'a $Vec<T>,     $Vec<T>> for     $Vec<T> where     T: $Op<&'a T,     T> { vec_impl_trinop_assign_vec_vec!{$op, &'a $Vec<T>,     $Vec<T>, ($($namedget)+) ($($get)+) (ref) (move)} }
146        impl<'a, 'b,     T> $Op<&'a $Vec<T>, &'b $Vec<T>> for     $Vec<T> where     T: $Op<&'a T, &'b T> { vec_impl_trinop_assign_vec_vec!{$op, &'a $Vec<T>, &'b $Vec<T>, ($($namedget)+) ($($get)+) (ref) (ref)} }
147    }
148}
149
150macro_rules! vec_impl_binop_commutative {
151    ($c_or_simd:ident, impl $Op:ident<$Vec:ident> for T { $op:tt, $simd_op:ident } where T = $($lhs:ident),+) => {
152        $(
153            // Allows $lhs * $Vec<$lhs>
154            impl $Op<$Vec<$lhs>> for $lhs {
155                type Output = $Vec<$lhs>;
156
157                #[inline]
158                fn $op(self, rhs: $Vec<$lhs>) -> Self::Output {
159                    rhs.$op(self)
160                }
161            }
162        )+
163    }
164}
165
166macro_rules! vec_impl_binop {
167    // If $Op is commutative, both "a $op b" and "b $op a" produce the same results
168    ($c_or_simd:ident, commutative impl $Op:ident for $Vec:ident { $op:tt, $simd_op:ident } ($($get:tt)+)) => {
169        // Generate the remaining non-commutative impls
170        vec_impl_binop!($c_or_simd, impl $Op for $Vec { $op, $simd_op } ($($get)+));
171
172        /* This is the generic impl we'd like to write: (forbidden by the coherence rules due to
173         * the uncovered type parameter before the local type)
174        impl<T: Copy> $Op<$Vec<T>> for T where T: $Op<T, Output=$Vec<T>> {
175            type Output = $Vec<T>;
176
177            fn $op(self, rhs: $Vec<T>) -> Self::Output {
178                rhs.$op(self)
179            }
180        }
181        */
182
183        // Since the generic impl isn't possible, we'll compromise here and add impls for specific
184        // types. This isn't ideally what we would want in a generic library like this, but it is a
185        // reasonable compromise to enable a nice syntax for certain operators with certain common types.
186        vec_impl_binop_commutative!($c_or_simd, impl $Op<$Vec> for T { $op, $simd_op } where T = i8, u8, i16, u16, i32, u32, i64, u64, f32, f64);
187    };
188    ($c_or_simd:ident, impl $Op:ident for $Vec:ident { $op:tt, $simd_op:ident } ($($get:tt)+)) => {
189        // NOTE: Reminder that scalars T: Copy also implement Into<$Vec<T>>.
190        impl<V, T> $Op<V> for $Vec<T> where V: Into<$Vec<T>>, T: $Op<T, Output=T> {
191            type Output = Self;
192            #[inline]
193            fn $op(self, rhs: V) -> Self::Output {
194                let rhs = rhs.into();
195                choose!{$c_or_simd {
196                    c => $Vec::new($(self.$get.$op(rhs.$get)),+),
197                    simd_llvm => unsafe { std::intrinsics::simd::$simd_op(self, rhs) },
198                }}
199            }
200        }
201
202        impl<'a, T> $Op<&'a $Vec<T>> for $Vec<T> where T: $Op<&'a T, Output=T> {
203            type Output = $Vec<T>;
204            #[inline]
205            fn $op(self, rhs: &'a $Vec<T>) -> Self::Output {
206                $Vec::new($(self.$get.$op(&rhs.$get)),+)
207            }
208        }
209        impl<'a, T> $Op<$Vec<T>> for &'a $Vec<T> where &'a T: $Op<T, Output=T> {
210            type Output = $Vec<T>;
211            #[inline]
212            fn $op(self, rhs: $Vec<T>) -> Self::Output {
213                $Vec::new($(self.$get.$op(rhs.$get)),+)
214            }
215        }
216        impl<'a, 'b, T> $Op<&'a $Vec<T>> for &'b $Vec<T> where &'b T: $Op<&'a T, Output=T> {
217            type Output = $Vec<T>;
218            #[inline]
219            fn $op(self, rhs: &'a $Vec<T>) -> Self::Output {
220                $Vec::new($(self.$get.$op(&rhs.$get)),+)
221            }
222        }
223
224        /*
225        #[allow(incoherent_fundamental_impls)]
226        impl<'a, T> $Op<&'a T> for $Vec<T> where T: $Op<&'a T, Output=T> {
227            type Output = $Vec<T>;
228            fn $op(self, rhs: &'a T) -> Self::Output {
229                $Vec::new($(self.$get.$op(rhs)),+)
230            }
231        }
232        */
233        impl<'a, T> $Op<T> for &'a $Vec<T> where &'a T: $Op<T, Output=T>, T: Copy {
234            type Output = $Vec<T>;
235            #[inline]
236            fn $op(self, rhs: T) -> Self::Output {
237                $Vec::new($(self.$get.$op(rhs)),+)
238            }
239        }
240        impl<'a, 'b, T> $Op<&'a T> for &'b $Vec<T> where &'b T: $Op<&'a T, Output=T> {
241            type Output = $Vec<T>;
242            #[inline]
243            fn $op(self, rhs: &'a T) -> Self::Output {
244                $Vec::new($(self.$get.$op(rhs)),+)
245            }
246        }
247    };
248}
249macro_rules! vec_impl_binop_assign {
250    ($c_or_simd:ident, impl $Op:ident for $Vec:ident { $op:tt } ($($get:tt)+)) => {
251        // NOTE: Reminder that scalars T: Copy also implement Into<$Vec<T>>.
252        impl<V, T> $Op<V> for $Vec<T> where V: Into<$Vec<T>>, T: $Op<T> {
253            #[inline]
254            fn $op(&mut self, rhs: V) {
255                let rhs = rhs.into();
256                $(self.$get.$op(rhs.$get);)+
257            }
258        }
259        /*
260        #[allow(incoherent_fundamental_impls)]
261        impl<'a, T> $Op<&'a $Vec<T>> for $Vec<T> where T: $Op<&'a T> {
262            fn $op(&mut self, rhs: &'a $Vec<T>) {
263                $(self.$get.$op(&rhs.$get);)+
264            }
265        }
266        #[allow(incoherent_fundamental_impls)]
267        impl<'a, T> $Op<&'a T> for $Vec<T> where T: $Op<&'a T> {
268            fn $op(&mut self, rhs: &'a T) {
269                $(self.$get.$op(rhs);)+
270            }
271        }
272        */
273    }
274}
275macro_rules! vec_impl_unop {
276    (impl $Op:ident for $Vec:ident { $op:tt } ($($get:tt)+)) => {
277        impl<T> $Op for $Vec<T> where T: $Op<Output=T> {
278            type Output = Self;
279            #[inline]
280            fn $op(self) -> Self::Output {
281                Self::new($(self.$get.$op()),+)
282            }
283        }
284    }
285}
286
287macro_rules! vec_impl_reduce_bool_ops_for_primitive {
288    ($c_or_simd:ident, $Vec:ident, $T:ty, ($($get:tt)+)) => {
289        impl $Vec<$T> {
290            /// Returns the result of logical AND (`&&`) on all elements of this vector.
291            /// Each element is converted to `bool` as follows: zero is `false`, and any other value is `true`.
292            ///
293            /// ```
294            /// # use vek::vec::Vec4;
295            /// assert_eq!(true,  Vec4::new(true, true, true, true).reduce_and());
296            /// assert_eq!(false, Vec4::new(true, false, true, true).reduce_and());
297            /// assert_eq!(false, Vec4::new(true, true, true, false).reduce_and());
298            /// ```
299            #[inline]
300            pub fn reduce_and(self) -> bool {
301                choose!{$c_or_simd {
302                    c => reduce_binop!(&&, $(!self.$get.is_zero()),+),
303                    simd_llvm => unsafe { std::intrinsics::simd::simd_reduce_all(self) },
304                }}
305            }
306            /// Returns the result of logical OR (`||`) on all elements of this vector.
307            /// Each element is converted to `bool` as follows: zero is `false`, and any other value is `true`.
308            ///
309            /// ```
310            /// # use vek::vec::Vec4;
311            /// assert_eq!(false, Vec4::new(false, false, false, false).reduce_or());
312            /// assert_eq!(true,  Vec4::new(false, false, true, false).reduce_or());
313            /// ```
314            #[inline]
315            pub fn reduce_or(self) -> bool {
316                choose!{$c_or_simd {
317                    c => reduce_binop!(||, $(!self.$get.is_zero()),+),
318                    simd_llvm => unsafe { std::intrinsics::simd::simd_reduce_any(self) },
319                }}
320            }
321        }
322    }
323}
324
325macro_rules! vec_impl_reduce_bool_ops_for_int {
326    ($c_or_simd:ident, $Vec:ident, $T:ty, ($($get:tt)+)) => {
327        vec_impl_reduce_bool_ops_for_primitive!{$c_or_simd, $Vec, $T, ($($get)+)}
328        vec_impl_reduce_bool_ops_for_primitive!{$c_or_simd, $Vec, Wrapping<$T>, ($($get)+)}
329    }
330}
331
332/// Generates implementations specific to the given vector type.
333macro_rules! vec_impl_vec {
334
335    ($c_or_simd:ident $repr_c:ident tuple $Vec:ident $vec:ident ($dim:expr) ($fmt:expr) ($fmt_prefix:expr) ($($get:tt)+) ($($namedget:tt)+) ($($tupleget:tt)+) $Tuple:ty) => {
336
337        impl<T> $Vec<T> {
338            /// Creates a vector from elements.
339            pub const fn new($($namedget:T),+) -> Self {
340                $Vec($($namedget),+)
341            }
342        }
343
344        vec_impl_vec!{common $c_or_simd $Vec $vec ($dim) ($fmt) ($fmt_prefix) ($($get)+) ($($namedget)+) ($($tupleget)+) $Tuple}
345        vec_impl_vec!{specific $c_or_simd $repr_c $Vec $vec ($dim) ($fmt) ($fmt_prefix) ($($get)+) ($($namedget)+) ($($tupleget)+) $Tuple}
346    };
347
348    ($c_or_simd:ident $repr_c:ident struct $Vec:ident $vec:ident ($dim:expr) ($fmt:expr) ($fmt_prefix:expr) ($($get:tt)+) ($($namedget:tt)+) ($($tupleget:tt)+) $Tuple:ty) => {
349
350        impl<T> $Vec<T> {
351            /// Creates a vector from elements.
352            pub const fn new($($namedget:T),+) -> Self {
353                Self { $($namedget),+ }
354            }
355        }
356
357        vec_impl_vec!{common $c_or_simd $Vec $vec ($dim) ($fmt) ($fmt_prefix) ($($get)+) ($($namedget)+) ($($tupleget)+) $Tuple}
358        vec_impl_vec!{specific $c_or_simd $repr_c $Vec $vec ($dim) ($fmt) ($fmt_prefix) ($($get)+) ($($namedget)+) ($($tupleget)+) $Tuple}
359    };
360
361    (specific simd $repr_c:ident $Vec:ident $vec:ident ($dim:expr) ($fmt:expr) ($fmt_prefix:expr) ($($get:tt)+) ($($namedget:tt)+) ($($tupleget:tt)+) $Tuple:ty) => {
362        vec_impl_vec!{specificsimd $Vec $vec ($dim) ($fmt) ($fmt_prefix) ($($get)+) ($($namedget)+) ($($tupleget)+) $Tuple}
363    };
364    (specific c repr_simd $Vec:ident $vec:ident ($dim:expr) ($fmt:expr) ($fmt_prefix:expr) ($($get:tt)+) ($($namedget:tt)+) ($($tupleget:tt)+) $Tuple:ty) => {
365        vec_impl_vec!{specificsimd $Vec $vec ($dim) ($fmt) ($fmt_prefix) ($($get)+) ($($namedget)+) ($($tupleget)+) $Tuple}
366    };
367    (specific c repr_c $Vec:ident $vec:ident ($dim:expr) ($fmt:expr) ($fmt_prefix:expr) ($($get:tt)+) ($($namedget:tt)+) ($($tupleget:tt)+) $Tuple:ty) => {
368
369        use super::super::repr_c::$vec::$Vec as CVec;
370    };
371    (specificsimd $Vec:ident $vec:ident ($dim:expr) ($fmt:expr) ($fmt_prefix:expr) ($($get:tt)+) ($($namedget:tt)+) ($($tupleget:tt)+) $Tuple:ty) => {
372
373        use super::super::repr_c::$vec::$Vec as CVec;
374
375        impl<T> From<CVec<T>> for $Vec<T> {
376            fn from(v: CVec<T>) -> Self {
377                Self::new($(v.$get),+)
378            }
379        }
380
381        impl<T> From<$Vec<T>> for CVec<T> {
382            fn from(v: $Vec<T>) -> Self {
383                Self::new($(v.$get),+)
384            }
385        }
386
387        /* NOTE: This will never be valid: SIMD vectors have alignment requirements.
388        impl<T> AsRef<CVec<T>> for $Vec<T> {
389            fn as_ref(v: &Self) -> &CVec<T> {
390                unsafe {
391                    mem::transmute(self)
392                }
393            }
394        }
395        impl<T> AsMut<CVec<T>> for $Vec<T> {
396            fn as_ref(v: &mut Self) -> &mut CVec<T> {
397                unsafe {
398                    mem::transmute(self)
399                }
400            }
401        }
402        */
403
404        impl<T> $Vec<T> {
405            /// Converts this vector into its `#[repr(C)]` counterpart.
406            pub fn into_repr_c(self) -> CVec<T> {
407                self.into()
408            }
409        }
410        impl<T> CVec<T> {
411            /// Converts this vector into its `#[repr(simd)]` counterpart.
412            pub fn into_repr_simd(self) -> $Vec<T> {
413                self.into()
414            }
415        }
416    };
417    (common $c_or_simd:ident $Vec:ident $vec:ident ($dim:expr) ($fmt:expr) ($fmt_prefix:expr) ($($get:tt)+) ($($namedget:tt)+) ($($tupleget:tt)+) $Tuple:ty) => {
418
419        #[allow(missing_docs)]
420        /// Displays the vector, formatted as `
421        #[doc=$fmt]
422        /// ` where `...` are the actual formatting parameters.
423        impl<T: Display> Display for $Vec<T> {
424            fn fmt(&self, f: &mut Formatter) -> fmt::Result {
425                write!(f, $fmt_prefix)?;
426                write!(f, "(")?;
427                let mut elems = self.iter();
428                if let Some(elem)=elems.next(){
429                    write!(f, " ")?;
430                    elem.fmt(f)?;
431                }
432                for elem in elems {
433                    write!(f, ", ")?;
434                    elem.fmt(f)?;
435                }
436                write!(f, " )")
437            }
438        }
439
440
441        impl<T> $Vec<T> {
442
443            /// Broadcasts a single value to all elements of a new vector.
444            ///
445            /// This function is also named `splat()` in some libraries, or
446            /// `set1()` in Intel intrinsics.
447            ///
448            /// "Broadcast" was chosen as the name because it is explicit enough and is the
449            /// same wording as the description in relevant Intel intrinsics.
450            ///
451            /// ```
452            /// # use vek::vec::Vec4;
453            /// assert_eq!(Vec4::broadcast(5), Vec4::new(5,5,5,5));
454            /// assert_eq!(Vec4::broadcast(5), Vec4::from(5));
455            /// ```
456            #[inline]
457            pub const fn broadcast(val: T) -> Self where T: Copy {
458                Self::new($({let $namedget = val; $namedget}),+)
459            }
460
461            /// Creates a new vector with all elements set to zero.
462            ///
463            /// ```
464            /// # use vek::vec::Vec4;
465            /// assert_eq!(Vec4::zero(), Vec4::new(0,0,0,0));
466            /// assert_eq!(Vec4::zero(), Vec4::broadcast(0));
467            /// assert_eq!(Vec4::zero(), Vec4::from(0));
468            /// ```
469            #[inline]
470            pub fn zero() -> Self where T: Zero {
471                Self::new($({let $namedget = T::zero(); $namedget}),+)
472            }
473
474            /// Creates a new vector with all elements set to one.
475            ///
476            /// ```
477            /// # use vek::vec::Vec4;
478            /// assert_eq!(Vec4::one(), Vec4::new(1,1,1,1));
479            /// assert_eq!(Vec4::one(), Vec4::broadcast(1));
480            /// assert_eq!(Vec4::one(), Vec4::from(1));
481            /// ```
482            #[inline]
483            pub fn one() -> Self where T: One {
484                Self::new($({let $namedget = T::one(); $namedget}),+)
485            }
486
487            /// Produces a vector of the first `n` integers, starting from zero,
488            /// where `n` is the number of elements for this vector type.
489            ///
490            /// The iota (ι) function, originating from APL.
491            ///
492            /// See [this StackOverflow answer](https://stackoverflow.com/a/9244949).
493            ///
494            /// This is mostly useful for debugging purposes and tests.
495            ///
496            /// ```
497            /// # use vek::vec::Vec4;
498            /// assert_eq!(Vec4::iota(), Vec4::new(0, 1, 2, 3));
499            /// ```
500            pub fn iota() -> Self where T: Zero + One + AddAssign + Copy {
501                let mut i = T::zero();
502                $(
503                    let $namedget = i;
504                    i += T::one();
505                )+
506                Self::new($($namedget),+)
507            }
508
509            /// Convenience method which returns the number of elements of this vector.
510            ///
511            /// ```
512            /// # use vek::vec::Vec4;
513            /// let v = Vec4::new(0,1,2,3);
514            /// assert_eq!(v.elem_count(), 4);
515            /// ```
516            pub const fn elem_count(&self) -> usize {
517                $dim
518            }
519            /// Convenience constant representing the number of elements for this vector type.
520            pub const ELEM_COUNT: usize = $dim;
521
522            /// Converts this into a tuple with the same number of elements by consuming.
523            pub fn into_tuple(self) -> $Tuple {
524                ($(self.$get),+)
525            }
526            /// Converts this vector into a fixed-size array.
527            pub fn into_array(self) -> [T; $dim] {
528                [$(self.$get, )+]
529            }
530            // NOTE: Deref<[T]> provides `to_vec()`. Don't write one here!
531
532            /// Converts this into a raw pointer of read-only data.
533            #[inline]
534            fn as_ptr_priv(&self) -> *const T {
535                self as *const _ as *const T
536            }
537            /// Converts this into a raw pointer.
538            #[inline]
539            fn as_mut_ptr_priv(&mut self) -> *mut T {
540                self as *mut _ as *mut T
541            }
542
543            /// View this vector as an immutable slice.
544            #[inline]
545            pub fn as_slice(&self) -> &[T] {
546                unsafe {
547                    slice::from_raw_parts(self.as_ptr_priv(), $dim)
548                }
549            }
550            /// View this vector as a mutable slice.
551            #[inline]
552            pub fn as_mut_slice(&mut self) -> &mut [T] {
553                unsafe {
554                    slice::from_raw_parts_mut(self.as_mut_ptr_priv(), $dim)
555                }
556            }
557
558            /// Collects the content of a slice into a new vector. Elements are initialized to
559            /// their default values.
560            pub fn from_slice(slice: &[T]) -> Self where T: Default + Copy {
561                Self::from_iter(slice.into_iter().cloned())
562            }
563
564            /// Returns a memberwise-converted copy of this vector, using the given conversion
565            /// closure.
566            ///
567            /// ```
568            /// # use vek::vec::Vec4;
569            /// let v = Vec4::new(0_f32, 1., 1.8, 3.14);
570            /// let i = v.map(|x| x.round() as i32);
571            /// assert_eq!(i, Vec4::new(0, 1, 2, 3));
572            /// ```
573            ///
574            /// Performing LERP on integer vectors by concisely converting them to floats:
575            ///
576            /// ```
577            /// # use vek::Vec4;
578            /// let a = Vec4::new(0,1,2,3).map(|x| x as f32);
579            /// let b = Vec4::new(2,3,4,5).map(|x| x as f32);
580            /// let v = Vec4::lerp(a, b, 0.5_f32).map(|x| x.round() as i32);
581            /// assert_eq!(v, Vec4::new(1,2,3,4));
582            /// ```
583            #[inline]
584            pub fn map<D,F>(self, mut f: F) -> $Vec<D> where F: FnMut(T) -> D {
585                $Vec::new($(f(self.$get)),+)
586            }
587            /// Applies the function f to each element of two vectors, pairwise, and returns the result.
588            ///
589            /// ```
590            /// # use vek::vec::Vec4;
591            /// let a = Vec4::<u8>::new(255, 254, 253, 252);
592            /// let b = Vec4::<u8>::new(1, 2, 3, 4);
593            /// let v = a.map2(b, |a, b| a.wrapping_add(b));
594            /// assert_eq!(v, Vec4::zero());
595            /// let v = a.map2(b, u8::wrapping_add);
596            /// assert_eq!(v, Vec4::zero());
597            /// ```
598            #[inline]
599            pub fn map2<D,F,S>(self, other: $Vec<S>, mut f: F) -> $Vec<D> where F: FnMut(T, S) -> D {
600                $Vec::new($(f(self.$get, other.$get)),+)
601            }
602            /// Applies the function f to each element of three vectors, and returns the result.
603            ///
604            /// ```
605            /// # use vek::vec::Vec4;
606            /// let a = Vec4::<u8>::new(255, 254, 253, 252);
607            /// let b = Vec4::<u8>::new(1, 2, 3, 4);
608            /// let c = Vec4::<u8>::new(1, 2, 3, 4);
609            /// let v = a.map3(b, c, |a, b, c| a.wrapping_add(b) + c);
610            /// assert_eq!(v, c);
611            /// ```
612            #[inline]
613            pub fn map3<D,F,S1,S2>(self, a: $Vec<S1>, b: $Vec<S2>, mut f: F) -> $Vec<D> where F: FnMut(T, S1, S2) -> D {
614                $Vec::new($(f(self.$get, a.$get, b.$get)),+)
615            }
616            /// Applies the function f to each element of this vector, in-place.
617            ///
618            /// ```
619            /// # use vek::Vec4;
620            /// let mut v = Vec4::new(0_u32, 1, 2, 3);
621            /// v.apply(|x| x.count_ones());
622            /// assert_eq!(v, Vec4::new(0, 1, 1, 2));
623            /// ```
624            #[inline]
625            pub fn apply<F>(&mut self, mut f: F) where T: Copy, F: FnMut(T) -> T {
626                $(self.$get = f(self.$get);)+
627            }
628            /// Applies the function f to each element of two vectors, pairwise, in-place.
629            ///
630            /// ```
631            /// # use vek::vec::Vec4;
632            /// let mut a = Vec4::<u8>::new(255, 254, 253, 252);
633            /// let b = Vec4::<u8>::new(1, 2, 3, 4);
634            /// a.apply2(b, |a, b| a.wrapping_add(b));
635            /// assert_eq!(a, Vec4::zero());
636            /// a.apply2(b, u8::wrapping_add);
637            /// assert_eq!(a, b);
638            /// ```
639            #[inline]
640            pub fn apply2<F, S>(&mut self, other: $Vec<S>, mut f: F) where T: Copy, F: FnMut(T, S) -> T {
641                $(self.$get = f(self.$get, other.$get);)+
642            }
643            /// Applies the function f to each element of three vectors, in-place.
644            ///
645            /// ```
646            /// # use vek::vec::Vec4;
647            /// let mut a = Vec4::<u8>::new(255, 254, 253, 252);
648            /// let b = Vec4::<u8>::new(1, 2, 3, 4);
649            /// let c = Vec4::<u8>::new(1, 2, 3, 4);
650            /// a.apply3(b, c, |a, b, c| a.wrapping_add(b) + c);
651            /// assert_eq!(a, c);
652            /// ```
653            #[inline]
654            pub fn apply3<F, S1, S2>(&mut self, a: $Vec<S1>, b: $Vec<S2>, mut f: F) where T: Copy, F: FnMut(T, S1, S2) -> T {
655                $(self.$get = f(self.$get, a.$get, b.$get);)+
656            }
657            /// "Zips" two vectors together into a vector of tuples.
658            ///
659            /// ```
660            /// # use vek::vec::Vec4;
661            /// let a = Vec4::<u8>::new(255, 254, 253, 252);
662            /// let b = Vec4::<u8>::new(1, 2, 3, 4);
663            /// assert_eq!(a.zip(b), Vec4::new((255, 1), (254, 2), (253, 3), (252, 4)));
664            /// ```
665            pub fn zip<S>(self, other: $Vec<S>) -> $Vec<(T, S)> {
666                self.map2(other, |a, b| (a, b))
667            }
668            /// Returns a memberwise-converted copy of this vector, using `AsPrimitive`.
669            ///
670            /// # Examples
671            ///
672            /// ```
673            /// # use vek::vec::Vec4;
674            /// let v = Vec4::new(0_f32, 1., 2., 3.);
675            /// let i: Vec4<i32> = v.as_();
676            /// assert_eq!(i, Vec4::new(0, 1, 2, 3));
677            /// ```
678            ///
679            /// # Safety
680            ///
681            /// **In Rust versions before 1.45.0**, some uses of the `as` operator were not entirely safe.
682            /// In particular, it was undefined behavior if
683            /// a truncated floating point value could not fit in the target integer
684            /// type ([#10184](https://github.com/rust-lang/rust/issues/10184));
685            ///
686            /// ```ignore
687            /// # use num_traits::AsPrimitive;
688            /// let x: u8 = (1.04E+17).as_(); // UB
689            /// ```
690            #[inline]
691            pub fn as_<D>(self) -> $Vec<D> where T: AsPrimitive<D>, D: 'static + Copy {
692                choose!{$c_or_simd {
693                    c => $Vec::new($(self.$get.as_()),+),
694                    simd_llvm => unsafe { std::intrinsics::simd::simd_cast(self) },
695                }}
696            }
697            /// Returns a memberwise-converted copy of this vector, using `NumCast`.
698            ///
699            /// ```
700            /// # use vek::vec::Vec4;
701            /// let v = Vec4::new(0_f32, 1., 2., 3.);
702            /// let i: Vec4<i32> = v.numcast().unwrap();
703            /// assert_eq!(i, Vec4::new(0, 1, 2, 3));
704            /// ```
705            pub fn numcast<D>(self) -> Option<$Vec<D>> where T: NumCast, D: NumCast {
706                // NOTE: Should use `?` for conciseness, but docs.rs uses rustc 1.22 and doesn't seem to like that.
707                Some($Vec::new($(match D::from(self.$get) {
708                    Some(x) => x,
709                    None => return None,
710                }),+))
711            }
712
713            /// Fused multiply-add. Returns `self * mul + add`, and may be implemented
714            /// efficiently by the hardware.
715            ///
716            /// The compiler is often able to detect this kind of operation,
717            /// so generally you don't need to use it. However, it can make
718            /// your intent clear.
719            ///
720            /// The name for this method is the one used by the same operation
721            /// on primitive floating-point types.
722            ///
723            /// ```
724            /// # use vek::vec::Vec4;
725            /// let a = Vec4::new(0,1,2,3);
726            /// let b = Vec4::new(4,5,6,7);
727            /// let c = Vec4::new(8,9,0,1);
728            /// assert_eq!(a*b+c, a.mul_add(b, c));
729            /// ```
730            #[inline]
731            pub fn mul_add<V0: Into<Self>, V1: Into<Self>>(self, mul: V0, add: V1) -> Self
732                where T: MulAdd<T,T,Output=T>
733            {
734                let mul = mul.into();
735                let add = add.into();
736                choose!{$c_or_simd {
737                    c => $Vec::new($(self.$get.mul_add(mul.$get, add.$get)),+),
738                    simd_llvm => unsafe { std::intrinsics::simd::simd_fma(self, mul, add) },
739                }}
740            }
741
742            /// Is any of the elements negative ?
743            ///
744            /// This was intended for checking the validity of extent vectors, but can make
745            /// sense for other types too.
746            #[inline]
747            pub fn is_any_negative(&self) -> bool where T: Signed {
748                reduce_binop!(||, $(self.$get.is_negative()),+)
749            }
750
751            /// Are all of the elements positive ?
752            #[inline]
753            pub fn are_all_positive(&self) -> bool where T: Signed {
754                reduce_binop!(&&, $(self.$get.is_positive()),+)
755            }
756
757            /// Compares elements of `a` and `b`, and returns the minimum values into a new
758            /// vector, using total ordering.
759            ///
760            /// ```
761            /// # use vek::vec::Vec4;
762            /// let a = Vec4::new(0,1,2,3);
763            /// let b = Vec4::new(3,2,1,0);
764            /// let m = Vec4::new(0,1,1,0);
765            /// assert_eq!(m, Vec4::min(a, b));
766            /// ```
767            #[inline]
768            pub fn min<V0, V1>(a: V0, b: V1) -> Self where V0: Into<Self>, V1: Into<Self>, T: Ord {
769                let (a, b) = (a.into(), b.into());
770                Self::new($(cmp::min(a.$get, b.$get)),+)
771            }
772            /// Compares elements of `a` and `b`, and returns the maximum values into a new
773            /// vector, using total ordering.
774            ///
775            /// ```
776            /// # use vek::vec::Vec4;
777            /// let a = Vec4::new(0,1,2,3);
778            /// let b = Vec4::new(3,2,1,0);
779            /// let m = Vec4::new(3,2,2,3);
780            /// assert_eq!(m, Vec4::max(a, b));
781            /// ```
782            #[inline]
783            pub fn max<V0, V1>(a: V0, b: V1) -> Self where V0: Into<Self>, V1: Into<Self>, T: Ord {
784                let (a, b) = (a.into(), b.into());
785                Self::new($(cmp::max(a.$get, b.$get)),+)
786            }
787            /// Compares elements of `a` and `b`, and returns the minimum values into a new
788            /// vector, using partial ordering.
789            ///
790            /// ```
791            /// # use vek::vec::Vec4;
792            /// let a = Vec4::new(0,1,2,3);
793            /// let b = Vec4::new(3,2,1,0);
794            /// let m = Vec4::new(0,1,1,0);
795            /// assert_eq!(m, Vec4::partial_min(a, b));
796            /// ```
797            #[inline]
798            pub fn partial_min<V0, V1>(a: V0, b: V1) -> Self where V0: Into<Self>, V1: Into<Self>, T: PartialOrd {
799                let (a, b) = (a.into(), b.into());
800                Self::new($(partial_min(a.$get, b.$get)),+)
801            }
802            /// Compares elements of `a` and `b`, and returns the maximum values into a new
803            /// vector, using partial ordering.
804            ///
805            /// ```
806            /// # use vek::vec::Vec4;
807            /// let a = Vec4::new(0,1,2,3);
808            /// let b = Vec4::new(3,2,1,0);
809            /// let m = Vec4::new(3,2,2,3);
810            /// assert_eq!(m, Vec4::partial_max(a, b));
811            /// ```
812            #[inline]
813            pub fn partial_max<V0, V1>(a: V0, b: V1) -> Self where V0: Into<Self>, V1: Into<Self>, T: PartialOrd {
814                let (a, b) = (a.into(), b.into());
815                Self::new($(partial_max(a.$get, b.$get)),+)
816            }
817
818            /// Returns the element which has the lowest value in this vector, using total
819            /// ordering.
820            ///
821            /// ```
822            /// # use vek::vec::Vec4;
823            /// assert_eq!(-5, Vec4::new(0, 5, -5, 8).reduce_min());
824            /// ```
825            #[inline]
826            pub fn reduce_min(self) -> T where T: Ord {
827                choose!{$c_or_simd {
828                    c => reduce_fn!(cmp::min, $(self.$get),+),
829                    simd_llvm => unsafe { std::intrinsics::simd::simd_reduce_min(self) },
830                }}
831            }
832            /// Returns the element which has the highest value in this vector, using total
833            /// ordering.
834            ///
835            /// ```
836            /// # use vek::vec::Vec4;
837            /// assert_eq!(8, Vec4::new(0, 5, -5, 8).reduce_max());
838            /// ```
839            #[inline]
840            pub fn reduce_max(self) -> T where T: Ord {
841                choose!{$c_or_simd {
842                    c => reduce_fn!(cmp::max, $(self.$get),+),
843                    simd_llvm => unsafe { std::intrinsics::simd::simd_reduce_max(self) },
844                }}
845            }
846
847            /// Returns the element which has the lowest value in this vector, using partial
848            /// ordering.
849            ///
850            /// ```
851            /// # use vek::vec::Vec4;
852            /// assert_eq!(-5_f32, Vec4::new(0_f32, 5., -5., 8.).reduce_partial_min());
853            /// ```
854            #[inline]
855            pub fn reduce_partial_min(self) -> T where T: PartialOrd {
856                choose!{$c_or_simd {
857                    c => reduce_fn!(partial_min, $(self.$get),+),
858                    simd_llvm => unsafe { std::intrinsics::simd::simd_reduce_min(self) },
859                }}
860            }
861            /// Returns the element which has the highest value in this vector, using partial
862            /// ordering.
863            ///
864            /// ```
865            /// # use vek::vec::Vec4;
866            /// assert_eq!(8_f32, Vec4::new(0_f32, 5., -5., 8.).reduce_partial_max());
867            /// ```
868            #[inline]
869            pub fn reduce_partial_max(self) -> T where T: PartialOrd {
870                choose!{$c_or_simd {
871                    c => reduce_fn!(partial_max, $(self.$get),+),
872                    simd_llvm => unsafe { std::intrinsics::simd::simd_reduce_max(self) },
873                }}
874            }
875
876            /// Returns the result of bitwise-AND (`&`) on all elements of this vector.
877            ///
878            /// ```
879            /// # use vek::vec::Vec4;
880            /// assert_eq!(true,  Vec4::new(true, true, true, true).reduce_bitand());
881            /// assert_eq!(false, Vec4::new(true, false, true, true).reduce_bitand());
882            /// assert_eq!(false, Vec4::new(true, true, true, false).reduce_bitand());
883            /// ```
884            #[inline]
885            pub fn reduce_bitand(self) -> T where T: BitAnd<T, Output=T> {
886                choose!{$c_or_simd {
887                    c => reduce_binop!(&, $(self.$get),+),
888                    simd_llvm => unsafe { std::intrinsics::simd::simd_reduce_and(self) },
889                }}
890            }
891
892            /// Returns the result of bitwise-OR (`|`) on all elements of this vector.
893            ///
894            /// ```
895            /// # use vek::vec::Vec4;
896            /// assert_eq!(false, Vec4::new(false, false, false, false).reduce_bitor());
897            /// assert_eq!(true,  Vec4::new(false, false, true, false).reduce_bitor());
898            /// ```
899            #[inline]
900            pub fn reduce_bitor(self) -> T where T: BitOr<T, Output=T> {
901                choose!{$c_or_simd {
902                    c => reduce_binop!(|, $(self.$get),+),
903                    simd_llvm => unsafe { std::intrinsics::simd::simd_reduce_or(self) },
904                }}
905            }
906
907            /// Returns the result of bitwise-XOR (`^`) on all elements of this vector.
908            ///
909            /// ```
910            /// # use vek::vec::Vec4;
911            /// assert_eq!(false, Vec4::new(true, true, true, true).reduce_bitxor());
912            /// assert_eq!(true,  Vec4::new(true, false, true, true).reduce_bitxor());
913            /// ```
914            #[inline]
915            pub fn reduce_bitxor(self) -> T where T: BitXor<T, Output=T> {
916                choose!{$c_or_simd {
917                    c => reduce_binop!(^, $(self.$get),+),
918                    simd_llvm => unsafe { std::intrinsics::simd::simd_reduce_xor(self) },
919                }}
920            }
921
922            /// Reduces this vector with the given accumulator closure.
923            #[inline]
924            pub fn reduce<F>(self, mut f: F) -> T where F: FnMut(T,T) -> T {
925                reduce_fn_mut!(f, $(self.$get),+)
926            }
927
928            /// Returns the product of each of this vector's elements.
929            ///
930            /// ```
931            /// # use vek::vec::Vec4;
932            /// assert_eq!(1*2*3*4, Vec4::new(1, 2, 3, 4).product());
933            /// ```
934            #[inline]
935            pub fn product(self) -> T where T: Mul<Output=T> {
936                choose!{$c_or_simd {
937                    c => reduce_binop!(*, $(self.$get),+),
938                    simd_llvm => unsafe { std::intrinsics::simd::simd_reduce_mul_unordered(self) },
939                }}
940            }
941            /// Returns the sum of each of this vector's elements.
942            ///
943            /// ```
944            /// # use vek::vec::Vec4;
945            /// assert_eq!(1+2+3+4, Vec4::new(1, 2, 3, 4).sum());
946            /// ```
947            #[inline]
948            pub fn sum(self) -> T where T: Add<T, Output=T> {
949                choose!{$c_or_simd {
950                    c => reduce_binop!(+, $(self.$get),+),
951                    simd_llvm => unsafe { std::intrinsics::simd::simd_reduce_add_unordered(self) },
952                }}
953            }
954            /// Returns the average of this vector's elements.
955            ///
956            /// ```
957            /// # use vek::vec::Vec4;
958            /// assert_eq!(2.5_f32, Vec4::new(1_f32, 2., 3., 4.).average());
959            /// ```
960            ///
961            /// You should avoid using it on `u8` vectors, not only because integer
962            /// overflows cause panics in debug mode, but also because of integer division, the result
963            /// may not be the one you expect.
964            ///
965            /// ```should_panic
966            /// # use vek::vec::Vec4;
967            /// // This causes a panic!
968            /// let red = Vec4::new(255u8, 1, 0, 0);
969            /// let grey_level = red.average();
970            /// assert_eq!(grey_level, 128);
971            /// ```
972            ///
973            /// You may want to convert the elements to bigger integers
974            /// (or floating-point) instead:
975            ///
976            /// ```
977            /// # use vek::vec::Vec4;
978            /// let red = Vec4::new(255u8, 1, 128, 128);
979            ///
980            /// let red = red.map(|c| c as u16);
981            /// let grey_level = red.average() as u8;
982            /// assert_eq!(grey_level, 128);
983            ///
984            /// let red = red.map(|c| c as f32);
985            /// let grey_level = red.average().round() as u8;
986            /// assert_eq!(grey_level, 128);
987            /// ```
988            #[inline]
989            pub fn average(self) -> T where T: Add<T, Output=T> + Div<T, Output=T> + From<u8> {
990                self.sum() / T::from($dim as _)
991            }
992
993            /// Returns a new vector which elements are the respective square roots of this
994            /// vector's elements.
995            ///
996            /// ```
997            /// # use vek::vec::Vec4;
998            /// let v = Vec4::new(1f32, 2f32, 3f32, 4f32);
999            /// let s = Vec4::new(1f32, 4f32, 9f32, 16f32);
1000            /// assert_eq!(v, s.sqrt());
1001            /// ```
1002            #[inline]
1003            pub fn sqrt(self) -> Self where T: Real {
1004                choose!{$c_or_simd {
1005                    c => Self::new($(self.$get.sqrt()),+),
1006                    simd_llvm => unsafe { std::intrinsics::simd::simd_fsqrt(self) },
1007                }}
1008            }
1009
1010            /// Returns a new vector which elements are the respective reciprocal
1011            /// square roots of this vector's elements.
1012            ///
1013            /// ```
1014            /// # use vek::vec::Vec4;
1015            /// let v = Vec4::new(1f32, 0.5f32, 1f32/3f32, 0.25f32);
1016            /// let s = Vec4::new(1f32, 4f32, 9f32, 16f32);
1017            /// assert_eq!(v, s.rsqrt());
1018            /// ```
1019            #[inline]
1020            pub fn rsqrt(self) -> Self where T: Real {
1021                self.sqrt().recip()
1022            }
1023            /// Returns a new vector which elements are the respective reciprocal
1024            /// of this vector's elements.
1025            ///
1026            /// ```
1027            /// # use vek::vec::Vec4;
1028            /// let v = Vec4::new(1f32, 0.5f32, 0.25f32, 0.125f32);
1029            /// let s = Vec4::new(1f32, 2f32, 4f32, 8f32);
1030            /// assert_eq!(v, s.recip());
1031            /// assert_eq!(s, v.recip());
1032            /// ```
1033            #[inline]
1034            pub fn recip(self) -> Self where T: Real {
1035                Self::new($(self.$get.recip()),+)
1036            }
1037            /// Returns a new vector which elements are rounded to the nearest greater integer.
1038            ///
1039            /// ```
1040            /// # use vek::vec::Vec4;
1041            /// let v = Vec4::new(0_f32, 1., 1.8, 3.14);
1042            /// assert_eq!(v.ceil(), Vec4::new(0f32, 1f32, 2f32, 4f32));
1043            /// ```
1044            #[inline]
1045            pub fn ceil(self) -> Self where T: Real {
1046                choose!{$c_or_simd {
1047                    c => Self::new($(self.$get.ceil()),+),
1048                    simd_llvm => unsafe { std::intrinsics::simd::simd_ceil(self) },
1049                }}
1050            }
1051            /// Returns a new vector which elements are rounded down to the nearest lower integer.
1052            ///
1053            /// ```
1054            /// # use vek::vec::Vec4;
1055            /// let v = Vec4::new(0_f32, 1., 1.8, 3.14);
1056            /// assert_eq!(v.floor(), Vec4::new(0f32, 1f32, 1f32, 3f32));
1057            /// ```
1058            #[inline]
1059            pub fn floor(self) -> Self where T: Real {
1060                choose!{$c_or_simd {
1061                    c => Self::new($(self.$get.floor()),+),
1062                    simd_llvm => unsafe { std::intrinsics::simd::simd_floor(self) },
1063                }}
1064            }
1065            /// Returns a new vector which elements are rounded to the nearest integer.
1066            ///
1067            /// ```
1068            /// # use vek::vec::Vec4;
1069            /// let v = Vec4::new(0_f32, 1., 1.8, 3.14);
1070            /// assert_eq!(v.round(), Vec4::new(0f32, 1f32, 2f32, 3f32));
1071            /// ```
1072            #[inline]
1073            pub fn round(self) -> Self where T: Real {
1074                Self::new($(self.$get.round()),+)
1075            }
1076
1077            /// Horizontally adds adjacent pairs of elements in `self` and `rhs` into a new vector.
1078            ///
1079            /// ```
1080            /// # use vek::vec::Vec4;
1081            /// let a = Vec4::new(0, 1, 2, 3);
1082            /// let b = Vec4::new(4, 5, 6, 7);
1083            /// let h = Vec4::new(0+1, 2+3, 4+5, 6+7);
1084            /// assert_eq!(h, a.hadd(b));
1085            /// ```
1086            #[inline]
1087            pub fn hadd(self, rhs: Self) -> Self where T: Add<T, Output=T> {
1088                $(let $namedget;)+
1089                horizontal_binop!(+, $($namedget),+ => $(self.$get,)+ $(rhs.$get),+);
1090                Self::new($($namedget),+)
1091            }
1092
1093            vec_impl_cmp!{
1094                /// Compares each element of two vectors with the partial equality test, returning a boolean vector.
1095                /// 
1096                /// The version ending with `_simd` is best utilized with the features "repr_simd" and "platform_intrinsics" enabled; otherwise, it falls back to regular scalar code.
1097                /// Note that SIMD intrinsics do not actually distinguish partial ordering from total ordering.
1098                ///
1099                /// ```
1100                /// # use vek::vec::Vec4;
1101                /// let u = Vec4::new(0,2,2,6);
1102                /// let v = Vec4::new(0,1,2,3);
1103                /// assert_eq!(u.partial_cmpeq(&v), Vec4::new(true, false, true, false));
1104                /// ```
1105                , $c_or_simd, $Vec, partial_cmpeq, partial_cmpeq_simd, simd_eq, ==, PartialEq, ($($get)+)
1106            }
1107
1108            vec_impl_cmp!{
1109                /// Compares each element of two vectors with the partial not-equal test, returning a boolean vector.
1110                /// 
1111                /// The version ending with `_simd` is best utilized with the features "repr_simd" and "platform_intrinsics" enabled; otherwise, it falls back to regular scalar code.
1112                /// Note that SIMD intrinsics do not actually distinguish partial ordering from total ordering.
1113                ///
1114                /// ```
1115                /// # use vek::vec::Vec4;
1116                /// let u = Vec4::new(0,2,2,6);
1117                /// let v = Vec4::new(0,1,2,3);
1118                /// assert_eq!(u.partial_cmpne(&v), Vec4::new(false, true, false, true));
1119                /// ```
1120                , $c_or_simd, $Vec, partial_cmpne, partial_cmpne_simd, simd_ne, !=, PartialEq, ($($get)+)
1121            }
1122
1123            vec_impl_cmp!{
1124                /// Compares each element of two vectors with the partial greater-or-equal test, returning a boolean vector.
1125                /// 
1126                /// The version ending with `_simd` is best utilized with the features "repr_simd" and "platform_intrinsics" enabled; otherwise, it falls back to regular scalar code.
1127                /// Note that SIMD intrinsics do not actually distinguish partial ordering from total ordering.
1128                /// 
1129                /// ```
1130                /// # use vek::vec::Vec4;
1131                /// let u = Vec4::new(0,2,2,2);
1132                /// let v = Vec4::new(0,1,2,3);
1133                /// assert_eq!(u.partial_cmpge(&v), Vec4::new(true, true, true, false));
1134                /// ```
1135                , $c_or_simd, $Vec, partial_cmpge, partial_cmpge_simd, simd_ge, >=, PartialOrd, ($($get)+)
1136            }
1137
1138            vec_impl_cmp!{
1139                /// Compares each element of two vectors with the partial greater-than test, returning a boolean vector.
1140                /// 
1141                /// The version ending with `_simd` is best utilized with the features "repr_simd" and "platform_intrinsics" enabled; otherwise, it falls back to regular scalar code.
1142                /// Note that SIMD intrinsics do not actually distinguish partial ordering from total ordering.
1143                ///
1144                /// ```
1145                /// # use vek::vec::Vec4;
1146                /// let u = Vec4::new(0,2,2,6);
1147                /// let v = Vec4::new(0,1,2,3);
1148                /// assert_eq!(u.partial_cmpgt(&v), Vec4::new(false, true, false, true));
1149                /// ```
1150                , $c_or_simd, $Vec, partial_cmpgt, partial_cmpgt_simd, simd_gt, >, PartialOrd, ($($get)+)
1151            }
1152
1153            vec_impl_cmp!{
1154                /// Compares each element of two vectors with the partial less-or-equal test, returning a boolean vector.
1155                /// 
1156                /// The version ending with `_simd` is best utilized with the features "repr_simd" and "platform_intrinsics" enabled; otherwise, it falls back to regular scalar code.
1157                /// Note that SIMD intrinsics do not actually distinguish partial ordering from total ordering.
1158                ///
1159                /// ```
1160                /// # use vek::vec::Vec4;
1161                /// let u = Vec4::new(0,2,2,2);
1162                /// let v = Vec4::new(0,1,2,3);
1163                /// assert_eq!(u.partial_cmple(&v), Vec4::new(true, false, true, true));
1164                /// ```
1165                , $c_or_simd, $Vec, partial_cmple, partial_cmple_simd, simd_le, <=, PartialOrd, ($($get)+)
1166            }
1167
1168            vec_impl_cmp!{
1169                /// Compares each element of two vectors with the partial less-than test, returning a boolean vector.
1170                /// 
1171                /// The version ending with `_simd` is best utilized with the features "repr_simd" and "platform_intrinsics" enabled; otherwise, it falls back to regular scalar code.
1172                /// Note that SIMD intrinsics do not actually distinguish partial ordering from total ordering.
1173                ///
1174                /// ```
1175                /// # use vek::vec::Vec4;
1176                /// let u = Vec4::new(0,2,2,2);
1177                /// let v = Vec4::new(0,1,2,3);
1178                /// assert_eq!(u.partial_cmplt(&v), Vec4::new(false, false, false, true));
1179                /// ```
1180                , $c_or_simd, $Vec, partial_cmplt, partial_cmplt_simd, simd_lt, <, PartialOrd, ($($get)+)
1181            }
1182
1183            vec_impl_cmp!{
1184                /// Compares each element of two vectors with the partial equality test, returning a boolean vector.
1185                /// 
1186                /// The version ending with `_simd` is best utilized with the features "repr_simd" and "platform_intrinsics" enabled; otherwise, it falls back to regular scalar code.
1187                /// Note that SIMD intrinsics do not actually distinguish partial ordering from total ordering.
1188                ///
1189                /// ```
1190                /// # use vek::vec::Vec4;
1191                /// let u = Vec4::new(0,2,2,6);
1192                /// let v = Vec4::new(0,1,2,3);
1193                /// assert_eq!(u.cmpeq(&v), Vec4::new(true, false, true, false));
1194                /// ```
1195                , $c_or_simd, $Vec, cmpeq, cmpeq_simd, simd_eq, ==, Eq, ($($get)+)
1196            }
1197
1198            vec_impl_cmp!{
1199                /// Compares each element of two vectors with the total not-equal test, returning a boolean vector.
1200                /// 
1201                /// The version ending with `_simd` is best utilized with the features "repr_simd" and "platform_intrinsics" enabled; otherwise, it falls back to regular scalar code.
1202                /// Note that SIMD intrinsics do not actually distinguish partial ordering from total ordering.
1203                ///
1204                /// ```
1205                /// # use vek::vec::Vec4;
1206                /// let u = Vec4::new(0,2,2,6);
1207                /// let v = Vec4::new(0,1,2,3);
1208                /// assert_eq!(u.cmpne(&v), Vec4::new(false, true, false, true));
1209                /// ```
1210                , $c_or_simd, $Vec, cmpne, cmpne_simd, simd_ne, !=, Eq, ($($get)+)
1211            }
1212
1213            vec_impl_cmp!{
1214                /// Compares each element of two vectors with the total greater-or-equal test, returning a boolean vector.
1215                /// 
1216                /// The version ending with `_simd` is best utilized with the features "repr_simd" and "platform_intrinsics" enabled; otherwise, it falls back to regular scalar code.
1217                /// Note that SIMD intrinsics do not actually distinguish partial ordering from total ordering.
1218                ///
1219                /// ```
1220                /// # use vek::vec::Vec4;
1221                /// let u = Vec4::new(0,2,2,2);
1222                /// let v = Vec4::new(0,1,2,3);
1223                /// assert_eq!(u.cmpge(&v), Vec4::new(true, true, true, false));
1224                /// ```
1225                , $c_or_simd, $Vec, cmpge, cmpge_simd, simd_ge, >=, Ord, ($($get)+)
1226            }
1227
1228            vec_impl_cmp!{
1229                /// Compares each element of two vectors with the total greater-than test, returning a boolean vector.
1230                /// 
1231                /// The version ending with `_simd` is best utilized with the features "repr_simd" and "platform_intrinsics" enabled; otherwise, it falls back to regular scalar code.
1232                /// Note that SIMD intrinsics do not actually distinguish partial ordering from total ordering.
1233                ///
1234                /// ```
1235                /// # use vek::vec::Vec4;
1236                /// let u = Vec4::new(0,2,2,6);
1237                /// let v = Vec4::new(0,1,2,3);
1238                /// assert_eq!(u.cmpgt(&v), Vec4::new(false, true, false, true));
1239                /// ```
1240                , $c_or_simd, $Vec, cmpgt, cmpgt_simd, simd_gt, >, Ord, ($($get)+)
1241            }
1242
1243            vec_impl_cmp!{
1244                /// Compares each element of two vectors with the total less-or-equal test, returning a boolean vector.
1245                /// 
1246                /// The version ending with `_simd` is best utilized with the features "repr_simd" and "platform_intrinsics" enabled; otherwise, it falls back to regular scalar code.
1247                /// Note that SIMD intrinsics do not actually distinguish partial ordering from total ordering.
1248                ///
1249                /// ```
1250                /// # use vek::vec::Vec4;
1251                /// let u = Vec4::new(0,2,2,2);
1252                /// let v = Vec4::new(0,1,2,3);
1253                /// assert_eq!(u.cmple(&v), Vec4::new(true, false, true, true));
1254                /// ```
1255                , $c_or_simd, $Vec, cmple, cmple_simd, simd_le, <=, Ord, ($($get)+)
1256            }
1257
1258            vec_impl_cmp!{
1259                /// Compares each element of two vectors with the total less-than test, returning a boolean vector.
1260                /// 
1261                /// The version ending with `_simd` is best utilized with the features "repr_simd" and "platform_intrinsics" enabled; otherwise, it falls back to regular scalar code.
1262                /// Note that SIMD intrinsics do not actually distinguish partial ordering from total ordering.
1263                ///
1264                /// ```
1265                /// # use vek::vec::Vec4;
1266                /// let u = Vec4::new(0,2,2,2);
1267                /// let v = Vec4::new(0,1,2,3);
1268                /// assert_eq!(u.cmplt(&v), Vec4::new(false, false, false, true));
1269                /// ```
1270                , $c_or_simd, $Vec, cmplt, cmplt_simd, simd_lt, <, Ord, ($($get)+)
1271            }
1272
1273            /// Returns the linear interpolation of `from` to `to` with `factor` unconstrained.
1274            /// See the `Lerp` trait.
1275            #[inline]
1276            pub fn lerp_unclamped_precise<S: Into<Self>>(from: Self, to: Self, factor: S) -> Self
1277                where T: Copy + One + Mul<Output=T> + Sub<Output=T> + MulAdd<T,T,Output=T>
1278            {
1279                let factor = factor.into();
1280                from.mul_add(Self::one()-factor, to*factor)
1281            }
1282            /// Same as `lerp_unclamped_precise`, implemented as a possibly faster but less precise operation.
1283            /// See the `Lerp` trait.
1284            #[inline]
1285            pub fn lerp_unclamped<S: Into<Self>>(from: Self, to: Self, factor: S) -> Self
1286                where T: Copy + Sub<Output=T> + MulAdd<T,T,Output=T>
1287            {
1288                let factor = factor.into();
1289                factor.mul_add(to - from, from)
1290            }
1291            /// Returns the linear interpolation of `from` to `to` with `factor` constrained to be
1292            /// between 0 and 1.
1293            /// See the `Lerp` trait.
1294            #[inline]
1295            pub fn lerp<S: Into<Self> + Clamp + Zero + One>(from: Self, to: Self, factor: S) -> Self
1296                where T: Copy + Sub<Output=T> + MulAdd<T,T,Output=T>
1297            {
1298                Self::lerp_unclamped(from, to, factor.clamped01().into())
1299            }
1300            /// Returns the linear interpolation of `from` to `to` with `factor` constrained to be
1301            /// between 0 and 1.
1302            /// See the `Lerp` trait.
1303            #[inline]
1304            pub fn lerp_precise<S: Into<Self> + Clamp + Zero + One>(from: Self, to: Self, factor: S) -> Self
1305                where T: Copy + One + Mul<Output=T> + Sub<Output=T> + MulAdd<T,T,Output=T>
1306            {
1307                Self::lerp_unclamped_precise(from, to, factor.clamped01().into())
1308            }
1309        }
1310
1311        // Implement az conversion methods
1312        #[cfg(feature = "az")]
1313        impl<T> $Vec<T> {
1314                /// Casts the components similar to `as`.
1315                ///
1316                /// **Panics**
1317                /// - In debug mode if the value does not fit in the target type
1318                /// - If the value does not fit and can't be wrapped, for example `f32::INFINITY`
1319                pub fn az<U>(self) -> $Vec<U> where T: az::Cast<U> {
1320                    az::Cast::cast(self)
1321                }
1322                /// Casts the components, but returns `None` if the value does not fit in the target type.
1323                pub fn checked_as<U>(self) -> Option<$Vec<U>> where T: az::CheckedCast<U> {
1324                    az::CheckedCast::checked_cast(self)
1325                }
1326                /// Cast the components, uses `MIN` and `MAX` if the value does not fit in the target type.
1327                pub fn saturating_as<U>(self) -> $Vec<U> where T: az::SaturatingCast<U> {
1328                    az::SaturatingCast::saturating_cast(self)
1329                }
1330                /// Cast the components and wraps if the value does not fit in the target type.
1331                ///
1332                /// **Panics**
1333                /// - If the value does not fit and can't be wrapped, for example `f32::INFINITY`
1334                pub fn wrapping_as<U>(self) -> $Vec<U> where T: az::WrappingCast<U> {
1335                    az::WrappingCast::wrapping_cast(self)
1336                }
1337                /// Cast the components and wraps if the value does not fit in the target type.
1338                /// Returns an additional `bool` to indicate if a value has wrapped.
1339                ///
1340                /// **Panics**
1341                /// - If the value does not fit and can't be wrapped, for example `f32::INFINITY`
1342                pub fn overflowing_as<U>(self) -> ($Vec<U>, bool) where T: az::OverflowingCast<U> {
1343                    az::OverflowingCast::overflowing_cast(self)
1344                }
1345                /// Cast the components and **panics** if the value does not fit in the target type.
1346                pub fn unwrapped_as<U>(self) -> $Vec<U> where T: az::UnwrappedCast<U> {
1347                    az::UnwrappedCast::unwrapped_cast(self)
1348                }
1349            }
1350
1351        // OPS
1352
1353        impl<T, Factor> Lerp<Factor> for $Vec<T>
1354            where T: Lerp<Factor,Output=T>,
1355                  Factor: Copy
1356        {
1357            type Output = Self;
1358            fn lerp_unclamped_precise(from: Self, to: Self, factor: Factor) -> Self {
1359                Self::new($(Lerp::lerp_unclamped_precise(from.$get, to.$get, factor)),+)
1360            }
1361            fn lerp_unclamped(from: Self, to: Self, factor: Factor) -> Self {
1362                Self::new($(Lerp::lerp_unclamped(from.$get, to.$get, factor)),+)
1363            }
1364        }
1365        impl<'a, T, Factor> Lerp<Factor> for &'a $Vec<T>
1366            where &'a T: Lerp<Factor,Output=T>,
1367                  Factor: Copy
1368        {
1369            type Output = $Vec<T>;
1370            fn lerp_unclamped_precise(from: Self, to: Self, factor: Factor) -> $Vec<T> {
1371                $Vec::new($(Lerp::lerp_unclamped_precise(&from.$get, &to.$get, factor)),+)
1372            }
1373            fn lerp_unclamped(from: Self, to: Self, factor: Factor) -> $Vec<T> {
1374                $Vec::new($(Lerp::lerp_unclamped(&from.$get, &to.$get, factor)),+)
1375            }
1376        }
1377
1378
1379        impl<T: Wrap + Copy> Wrap<T> for $Vec<T> {
1380            fn wrapped(self, upper: T) -> Self {
1381                self.wrapped(Self::broadcast(upper))
1382            }
1383            fn wrapped_between(self, lower: T, upper: T) -> Self {
1384                self.wrapped_between(Self::broadcast(lower), Self::broadcast(upper))
1385            }
1386            fn pingpong(self, upper: T) -> Self {
1387                self.pingpong(Self::broadcast(upper))
1388            }
1389        }
1390        impl<T: Wrap> Wrap<$Vec<T>> for $Vec<T> {
1391            fn wrapped(self, upper: $Vec<T>) -> Self {
1392                Self::new($(self.$get.wrapped(upper.$get)),+)
1393            }
1394            fn wrapped_between(self, lower: Self, upper: Self) -> Self {
1395                Self::new($(self.$get.wrapped_between(lower.$get, upper.$get)),+)
1396            }
1397            fn pingpong(self, upper: Self) -> Self {
1398                Self::new($(self.$get.pingpong(upper.$get)),+)
1399            }
1400        }
1401
1402        impl<T: Clamp + Copy> Clamp<T> for $Vec<T> {
1403            fn clamped(self, lower: T, upper: T) -> Self {
1404                self.clamped(Self::broadcast(lower), Self::broadcast(upper))
1405            }
1406        }
1407        impl<T: IsBetween<Output=bool> + Copy> IsBetween<T> for $Vec<T> {
1408            type Output = $Vec<bool>;
1409            fn is_between(self, lower: T, upper: T) -> Self::Output {
1410                self.is_between(Self::broadcast(lower), Self::broadcast(upper))
1411            }
1412        }
1413        impl<T: Clamp> Clamp<$Vec<T>> for $Vec<T> {
1414            fn clamped(self, lower: Self, upper: Self) -> Self {
1415                $Vec::new($(self.$get.clamped(lower.$get, upper.$get)),+)
1416            }
1417        }
1418        impl<T: IsBetween<Output=bool>> IsBetween<$Vec<T>> for $Vec<T> {
1419            type Output = $Vec<bool>;
1420            fn is_between(self, lower: Self, upper: Self) -> Self::Output {
1421                $Vec::new($(self.$get.is_between(lower.$get, upper.$get)),+)
1422            }
1423        }
1424
1425
1426        // TRAITS IMPLS
1427
1428        impl<T: Zero + PartialEq> Zero for $Vec<T> {
1429            fn zero() -> Self { Self::zero() }
1430            fn is_zero(&self) -> bool { self == &Self::zero() }
1431        }
1432
1433        impl<T: One> One for $Vec<T> {
1434            fn one() -> Self { Self::one() }
1435        }
1436
1437        // WISH: impl Real for Vec<Real> ?
1438        // NOPE: Vectors can't implement these items :
1439        // - fn classify(self) -> FpCategory;
1440        // - fn integer_decode(self) -> (u64, i16, i8);
1441
1442        // Internal module to restrict the scope of the `use` directive
1443        mod impl_num_traits {
1444            use super::$Vec;
1445            use num_traits::ops::checked::{
1446                CheckedAdd,
1447                CheckedSub,
1448                CheckedMul,
1449                CheckedDiv,
1450                CheckedRem,
1451                CheckedNeg,
1452            };
1453
1454            impl<T: CheckedAdd> CheckedAdd for $Vec<T> {
1455                fn checked_add(&self, v: &Self) -> Option<Self> {
1456                    Some($Vec::new($(self.$get.checked_add(&v.$get)?),+))
1457                }
1458            }
1459            impl<T: CheckedSub> CheckedSub for $Vec<T> {
1460                fn checked_sub(&self, v: &Self) -> Option<Self> {
1461                    Some($Vec::new($(self.$get.checked_sub(&v.$get)?),+))
1462                }
1463            }
1464            impl<T: CheckedMul> CheckedMul for $Vec<T> {
1465                fn checked_mul(&self, v: &Self) -> Option<Self> {
1466                    Some($Vec::new($(self.$get.checked_mul(&v.$get)?),+))
1467                }
1468            }
1469            impl<T: CheckedDiv> CheckedDiv for $Vec<T> {
1470                fn checked_div(&self, v: &Self) -> Option<Self> {
1471                    Some($Vec::new($(self.$get.checked_div(&v.$get)?),+))
1472                }
1473            }
1474            impl<T: CheckedRem> CheckedRem for $Vec<T> {
1475                fn checked_rem(&self, v: &Self) -> Option<Self> {
1476                    Some($Vec::new($(self.$get.checked_rem(&v.$get)?),+))
1477                }
1478            }
1479            impl<T: CheckedNeg> CheckedNeg for $Vec<T> {
1480                fn checked_neg(&self) -> Option<Self> {
1481                    Some($Vec::new($(self.$get.checked_neg()?),+))
1482                }
1483            }
1484
1485            use num_traits::ops::wrapping::{
1486                WrappingAdd,
1487                WrappingSub,
1488                WrappingMul,
1489                WrappingNeg,
1490            };
1491
1492            impl<T: WrappingAdd> WrappingAdd for $Vec<T> {
1493                fn wrapping_add(&self, v: &Self) -> Self {
1494                    $Vec::new($(self.$get.wrapping_add(&v.$get)),+)
1495                }
1496            }
1497            impl<T: WrappingSub> WrappingSub for $Vec<T> {
1498                fn wrapping_sub(&self, v: &Self) -> Self {
1499                    $Vec::new($(self.$get.wrapping_sub(&v.$get)),+)
1500                }
1501            }
1502            impl<T: WrappingMul> WrappingMul for $Vec<T> {
1503                fn wrapping_mul(&self, v: &Self) -> Self {
1504                    $Vec::new($(self.$get.wrapping_mul(&v.$get)),+)
1505                }
1506            }
1507            impl<T: WrappingNeg> WrappingNeg for $Vec<T> {
1508                fn wrapping_neg(&self) -> Self {
1509                    $Vec::new($(self.$get.wrapping_neg()),+)
1510                }
1511            }
1512
1513            use num_traits::ops::saturating::{
1514                SaturatingAdd,
1515                SaturatingSub,
1516                SaturatingMul,
1517            };
1518
1519            impl<T: SaturatingAdd> SaturatingAdd for $Vec<T> {
1520                fn saturating_add(&self, v: &Self) -> Self {
1521                    $Vec::new($(self.$get.saturating_add(&v.$get)),+)
1522                }
1523            }
1524            impl<T: SaturatingSub> SaturatingSub for $Vec<T> {
1525                fn saturating_sub(&self, v: &Self) -> Self {
1526                    $Vec::new($(self.$get.saturating_sub(&v.$get)),+)
1527                }
1528            }
1529            impl<T: SaturatingMul> SaturatingMul for $Vec<T> {
1530                fn saturating_mul(&self, v: &Self) -> Self {
1531                    $Vec::new($(self.$get.saturating_mul(&v.$get)),+)
1532                }
1533            }
1534
1535            use num_traits::ops::overflowing::{
1536                OverflowingAdd,
1537                OverflowingSub,
1538                OverflowingMul,
1539            };
1540
1541            impl<T: OverflowingAdd> OverflowingAdd for $Vec<T> {
1542                fn overflowing_add(&self, v: &Self) -> (Self, bool) {
1543                    let mut any_would_overflow = false;
1544                    $(
1545                        let ($namedget, would_overflow) = self.$get.overflowing_add(&v.$get);
1546                        any_would_overflow |= would_overflow;
1547                    )+
1548                    ($Vec::new($($namedget),+), any_would_overflow)
1549                }
1550            }
1551            impl<T: OverflowingSub> OverflowingSub for $Vec<T> {
1552                fn overflowing_sub(&self, v: &Self) -> (Self, bool) {
1553                    let mut any_would_overflow = false;
1554                    $(
1555                        let ($namedget, would_overflow) = self.$get.overflowing_sub(&v.$get);
1556                        any_would_overflow |= would_overflow;
1557                    )+
1558                    ($Vec::new($($namedget),+), any_would_overflow)
1559                }
1560            }
1561            impl<T: OverflowingMul> OverflowingMul for $Vec<T> {
1562                fn overflowing_mul(&self, v: &Self) -> (Self, bool) {
1563                    let mut any_would_overflow = false;
1564                    $(
1565                        let ($namedget, would_overflow) = self.$get.overflowing_mul(&v.$get);
1566                        any_would_overflow |= would_overflow;
1567                    )+
1568                    ($Vec::new($($namedget),+), any_would_overflow)
1569                }
1570            }
1571
1572            use num_traits::ops::inv::Inv;
1573
1574            impl<T: Inv<Output = T>> Inv for $Vec<T> {
1575                type Output = Self;
1576                fn inv(self) -> Self {
1577                    $Vec::new($(self.$get.inv()),+)
1578                }
1579            }
1580
1581            use num_traits::ops::euclid::{Euclid, CheckedEuclid};
1582
1583            impl<T: Euclid> Euclid for $Vec<T> {
1584                fn div_euclid(&self, v: &Self) -> Self {
1585                    $Vec::new($(self.$get.div_euclid(&v.$get)),+)
1586                }
1587                fn rem_euclid(&self, v: &Self) -> Self {
1588                    $Vec::new($(self.$get.rem_euclid(&v.$get)),+)
1589                }
1590            }
1591
1592            impl<T: CheckedEuclid> CheckedEuclid for $Vec<T> {
1593                fn checked_div_euclid(&self, v: &Self) -> Option<Self> {
1594                    Some($Vec::new($(self.$get.checked_div_euclid(&v.$get)?),+))
1595                }
1596                fn checked_rem_euclid(&self, v: &Self) -> Option<Self> {
1597                    Some($Vec::new($(self.$get.checked_rem_euclid(&v.$get)?),+))
1598                }
1599            }
1600
1601            /*
1602            use num_traits::ops::mul_add::{MulAddAssign};
1603
1604            impl<A, B, T: MulAddAssign<A, B>> MulAddAssign<$Vec<A>, $Vec<B>> for $Vec<T> {
1605                fn mul_add(&mut self, b: &Self, c: &Self) -> Self {
1606                    $Vec::new($(self.$get.mul_add_assign(&b.$get, c.$get)),+)
1607                }
1608            }
1609            */
1610        }
1611
1612
1613        impl<T: AbsDiffEq> AbsDiffEq for $Vec<T> where T::Epsilon: Copy {
1614            type Epsilon = T::Epsilon;
1615
1616            fn default_epsilon() -> T::Epsilon {
1617                T::default_epsilon()
1618            }
1619
1620            #[inline]
1621            fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
1622                reduce_binop!(&&, $(T::abs_diff_eq(&self.$get, &other.$get, epsilon)),+)
1623            }
1624        }
1625
1626        impl<T: UlpsEq> UlpsEq for $Vec<T> where T::Epsilon: Copy {
1627            fn default_max_ulps() -> u32 {
1628                T::default_max_ulps()
1629            }
1630
1631            #[inline]
1632            fn ulps_eq(&self, other: &Self, epsilon: T::Epsilon, max_ulps: u32) -> bool {
1633                reduce_binop!(&&, $(T::ulps_eq(&self.$get, &other.$get, epsilon, max_ulps)),+)
1634            }
1635        }
1636
1637        impl<T: RelativeEq> RelativeEq for $Vec<T> where T::Epsilon: Copy {
1638            fn default_max_relative() -> T::Epsilon {
1639                T::default_max_relative()
1640            }
1641
1642            #[inline]
1643            fn relative_eq(&self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon) -> bool {
1644                reduce_binop!(&&, $(T::relative_eq(&self.$get, &other.$get, epsilon, max_relative)),+)
1645            }
1646        }
1647
1648        impl $Vec<bool> {
1649            // This method is not public because I don't want anyone to start relying on the concrete output type.
1650            // If we do make it public at some point, then we must warn that it's only intended for SIMD intrinsics.
1651            // The better route, though, is to simply avoid Vec<bool> in the first place.
1652            //
1653            // u32 is chosen because SIMD instructions commonly deal with 32-bit lanes.
1654            #[inline]
1655            #[allow(dead_code)] // Unreachable when simd_llvm is not used
1656            fn into_native_simd_integer_vector(self) -> $Vec<u32> {
1657                $Vec::new($(self.$get as _),+)
1658            }
1659            /// Returns the result of logical AND (`&&`) on all elements of this vector.
1660            ///
1661            /// ```
1662            /// # use vek::vec::Vec4;
1663            /// assert_eq!(true,  Vec4::new(true, true, true, true).reduce_and());
1664            /// assert_eq!(false, Vec4::new(true, false, true, true).reduce_and());
1665            /// assert_eq!(false, Vec4::new(true, true, true, false).reduce_and());
1666            /// ```
1667            #[inline]
1668            pub fn reduce_and(self) -> bool {
1669                choose!{$c_or_simd {
1670                    c => reduce_binop!(&&, $(self.$get),+),
1671                    simd_llvm => unsafe { std::intrinsics::simd::simd_reduce_all(self.into_native_simd_integer_vector()) },
1672                }}
1673            }
1674            /// Returns the result of logical OR (`||`) on all elements of this vector.
1675            ///
1676            /// ```
1677            /// # use vek::vec::Vec4;
1678            /// assert_eq!(false, Vec4::new(false, false, false, false).reduce_or());
1679            /// assert_eq!(true,  Vec4::new(false, false, true, false).reduce_or());
1680            /// ```
1681            #[inline]
1682            pub fn reduce_or(self) -> bool {
1683                choose!{$c_or_simd {
1684                    c => reduce_binop!(||, $(self.$get),+),
1685                    simd_llvm => unsafe { std::intrinsics::simd::simd_reduce_any(self.into_native_simd_integer_vector()) },
1686                }}
1687            }
1688            /// Reduces this vector using total inequality.
1689            /// Note that this operation doesn't actually make much sense and has no native SIMD support.
1690            #[inline]
1691            #[deprecated(since="0.15.8", note="This operation makes no sense and has no native SIMD support. As the compiler reports, comparison operators such as != cannot be chained. Chaining with booleans is allowed, but whacky.")]
1692            pub fn reduce_ne(self) -> bool {
1693                reduce_binop!(!=, $(self.$get),+)
1694            }
1695        }
1696
1697        vec_impl_reduce_bool_ops_for_int!{$c_or_simd, $Vec, i8  , ($($get)+)}
1698        vec_impl_reduce_bool_ops_for_int!{$c_or_simd, $Vec, i16 , ($($get)+)}
1699        vec_impl_reduce_bool_ops_for_int!{$c_or_simd, $Vec, i32 , ($($get)+)}
1700        vec_impl_reduce_bool_ops_for_int!{$c_or_simd, $Vec, i64 , ($($get)+)}
1701        vec_impl_reduce_bool_ops_for_int!{$c_or_simd, $Vec, u8  , ($($get)+)}
1702        vec_impl_reduce_bool_ops_for_int!{$c_or_simd, $Vec, u16 , ($($get)+)}
1703        vec_impl_reduce_bool_ops_for_int!{$c_or_simd, $Vec, u32 , ($($get)+)}
1704        vec_impl_reduce_bool_ops_for_int!{$c_or_simd, $Vec, u64 , ($($get)+)}
1705        vec_impl_reduce_bool_ops_for_primitive!{$c_or_simd, $Vec, f32 , ($($get)+)}
1706        vec_impl_reduce_bool_ops_for_primitive!{$c_or_simd, $Vec, f64 , ($($get)+)}
1707
1708        vec_impl_trinop!{impl MulAdd for $Vec { mul_add } ($($namedget)+) ($($get)+)}
1709        vec_impl_trinop_assign!{impl MulAddAssign for $Vec { mul_add_assign } ($($namedget)+) ($($get)+)}
1710        vec_impl_unop!{ impl Neg for $Vec { neg } ($($get)+)}
1711        vec_impl_binop!{$c_or_simd, commutative impl Add for $Vec { add, simd_add } ($($get)+)}
1712        vec_impl_binop!{$c_or_simd,             impl Sub for $Vec { sub, simd_sub } ($($get)+)}
1713        vec_impl_binop!{$c_or_simd, commutative impl Mul for $Vec { mul, simd_mul } ($($get)+)}
1714        vec_impl_binop!{$c_or_simd,             impl Div for $Vec { div, simd_div } ($($get)+)}
1715        vec_impl_binop!{c,                      impl Rem for $Vec { rem, simd_rem } ($($get)+)}
1716        vec_impl_binop_assign!{$c_or_simd, impl AddAssign for $Vec { add_assign } ($($get)+)}
1717        vec_impl_binop_assign!{$c_or_simd, impl SubAssign for $Vec { sub_assign } ($($get)+)}
1718        vec_impl_binop_assign!{$c_or_simd, impl MulAssign for $Vec { mul_assign } ($($get)+)}
1719        vec_impl_binop_assign!{$c_or_simd, impl DivAssign for $Vec { div_assign } ($($get)+)}
1720        vec_impl_binop_assign!{$c_or_simd, impl RemAssign for $Vec { rem_assign } ($($get)+)}
1721        vec_impl_binop!{$c_or_simd, impl Shl    for $Vec { shl, simd_shl } ($($get)+)}
1722        vec_impl_binop!{$c_or_simd, impl Shr    for $Vec { shr, simd_shr } ($($get)+)}
1723        vec_impl_binop_assign!{$c_or_simd, impl ShlAssign    for $Vec { shl_assign    } ($($get)+)}
1724        vec_impl_binop_assign!{$c_or_simd, impl ShrAssign    for $Vec { shr_assign    } ($($get)+)}
1725        vec_impl_binop!{$c_or_simd, impl BitAnd for $Vec { bitand, simd_and } ($($get)+)}
1726        vec_impl_binop!{$c_or_simd, impl BitOr  for $Vec { bitor , simd_or  } ($($get)+)}
1727        vec_impl_binop!{$c_or_simd, impl BitXor for $Vec { bitxor, simd_xor } ($($get)+)}
1728        vec_impl_binop_assign!{$c_or_simd, impl BitAndAssign for $Vec { bitand_assign } ($($get)+)}
1729        vec_impl_binop_assign!{$c_or_simd, impl BitOrAssign  for $Vec { bitor_assign  } ($($get)+)}
1730        vec_impl_binop_assign!{$c_or_simd, impl BitXorAssign for $Vec { bitxor_assign } ($($get)+)}
1731        vec_impl_unop!{ impl Not for $Vec { not } ($($get)+)}
1732
1733        impl<T> AsRef<[T]> for $Vec<T> {
1734            #[inline]
1735            fn as_ref(&self) -> &[T] {
1736                self.as_slice()
1737            }
1738        }
1739
1740        impl<T> AsMut<[T]> for $Vec<T> {
1741            #[inline]
1742            fn as_mut(&mut self) -> &mut [T] {
1743                self.as_mut_slice()
1744            }
1745        }
1746        impl<T> Borrow<[T]> for $Vec<T> {
1747            #[inline]
1748            fn borrow(&self) -> &[T] {
1749                self.as_slice()
1750            }
1751        }
1752        impl<T> BorrowMut<[T]> for $Vec<T> {
1753            #[inline]
1754            fn borrow_mut(&mut self) -> &mut [T] {
1755                self.as_mut_slice()
1756            }
1757        }
1758
1759        impl<T> AsRef<$Vec<T>> for $Vec<T> {
1760            fn as_ref(&self) -> &Self {
1761                self
1762            }
1763        }
1764
1765        impl<T> AsMut<$Vec<T>> for $Vec<T> {
1766            fn as_mut(&mut self) -> &mut Self {
1767                self
1768            }
1769        }
1770
1771        impl<'a, T> IntoIterator for &'a $Vec<T> {
1772            type Item = &'a T;
1773            type IntoIter = slice::Iter<'a, T>;
1774            #[inline]
1775            fn into_iter(self) -> Self::IntoIter {
1776                // Note to self: DO NOT return self.iter() here. Causes infinite recursion.
1777                self.as_slice().iter()
1778            }
1779        }
1780        impl<'a, T> IntoIterator for &'a mut $Vec<T> {
1781            type Item = &'a mut T;
1782            type IntoIter = slice::IterMut<'a, T>;
1783            #[inline]
1784            fn into_iter(self) -> Self::IntoIter {
1785                // Note to self: DO NOT return self.iter_mut() here. Causes infinite recursion.
1786                self.as_mut_slice().iter_mut()
1787            }
1788        }
1789
1790        impl<T> Deref for $Vec<T> {
1791            type Target = [T];
1792            #[inline]
1793            fn deref(&self) -> &[T] {
1794                self.as_slice()
1795            }
1796        }
1797        impl<T> DerefMut for $Vec<T> {
1798            #[inline]
1799            fn deref_mut(&mut self) -> &mut [T] {
1800                self.as_mut_slice()
1801            }
1802        }
1803
1804        use std::mem::ManuallyDrop;
1805
1806        /// Consuming iterator over this module's vector type.
1807        // Can't (De)Serialize a ManuallyDrop<T>
1808        //#[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
1809        #[derive(Debug, Hash, PartialEq, Eq)]
1810        pub struct IntoIter<T> {
1811            // NOTE: Use a CVec and not $Vec; repr_simd vectors can't monomorphize ManuallyDrop<T>.
1812            vector: CVec<ManuallyDrop<T>>,
1813            start: usize,
1814            end: usize,
1815        }
1816
1817        // NOTE: Be careful to only drop elements that weren't yielded.
1818        impl<T> Drop for IntoIter<T> {
1819            fn drop(&mut self) {
1820                for elem in &mut self.vector[self.start .. self.end] {
1821                    unsafe {
1822                        ManuallyDrop::drop(elem);
1823                    }
1824                }
1825            }
1826        }
1827
1828        impl<T> IntoIterator for $Vec<T> {
1829            type Item = T;
1830            type IntoIter = IntoIter<T>;
1831            fn into_iter(self) -> Self::IntoIter {
1832                Self::IntoIter {
1833                    vector: CVec::from(self).map(ManuallyDrop::new),
1834                    start: 0,
1835                    end: $dim,
1836                }
1837            }
1838        }
1839
1840        impl<T> Iterator for IntoIter<T> {
1841            type Item = T;
1842            fn next(&mut self) -> Option<Self::Item> {
1843                if self.start == self.end {
1844                    return None;
1845                }
1846                unsafe {
1847                    let result = ManuallyDrop::into_inner(ptr::read(self.vector.get_unchecked(self.start)));
1848                    self.start += 1;
1849                    Some(result)
1850                }
1851            }
1852            fn size_hint(&self) -> (usize, Option<usize>) {
1853                let rem = self.len();
1854                (rem, Some(rem))
1855            }
1856        }
1857
1858        impl<T> ExactSizeIterator for IntoIter<T> {
1859            fn len(&self) -> usize {
1860                self.end - self.start
1861            }
1862        }
1863
1864        impl<T> DoubleEndedIterator for IntoIter<T> {
1865            fn next_back(&mut self) -> Option<T> {
1866                if self.start == self.end {
1867                    return None;
1868                }
1869                unsafe {
1870                    self.end -= 1;
1871                    Some(ManuallyDrop::into_inner(ptr::read(self.vector.get_unchecked(self.end))))
1872                }
1873            }
1874        }
1875
1876        impl<T: Default> FromIterator<T> for $Vec<T> {
1877            fn from_iter<I>(iter: I) -> Self where I: IntoIterator<Item = T> {
1878                let mut out = Self::default();
1879                let mut iter = iter.into_iter();
1880                for elem in &mut out {
1881                    if let Some(value) = iter.next() {
1882                        *elem = value
1883                    } else {
1884                        break;
1885                    }
1886                }
1887                out
1888            }
1889        }
1890
1891        impl<T> Sum for $Vec<T> where T: Add<T, Output=T> + Zero {
1892            fn sum<I: Iterator<Item=$Vec<T>>>(iter: I) -> $Vec<T> {
1893                iter.fold(Self::zero(), Add::add)
1894            }
1895        }
1896
1897        impl<T> Product for $Vec<T> where T: Mul<T, Output=T> + One {
1898            fn product<I: Iterator<Item=$Vec<T>>>(iter: I) -> $Vec<T> {
1899                iter.fold(Self::one(), Mul::mul)
1900            }
1901        }
1902
1903        // CONVERSIONS
1904
1905        impl<T> From<$Tuple> for $Vec<T> {
1906            fn from(tuple: $Tuple) -> Self {
1907                Self::new($(tuple.$tupleget),+)
1908            }
1909        }
1910        impl<T> From<[T; $dim]> for $Vec<T> {
1911            fn from(array: [T; $dim]) -> Self {
1912                let array = mem::ManuallyDrop::new(array);
1913                let mut i = -1_isize;
1914                $(
1915                    i += 1;
1916                    let $namedget = unsafe {
1917                        ptr::read(array.get_unchecked(i as usize))
1918                    };
1919                )+
1920                Self::new($($namedget),+)
1921            }
1922        }
1923        /// A vector can be obtained from a single scalar by broadcasting it.
1924        ///
1925        /// This conversion is important because it allows scalars to be
1926        /// smoothly accepted as operands in most vector operations.
1927        ///
1928        /// For instance :
1929        ///
1930        /// ```
1931        /// # use vek::{Mat4, Vec3, Vec4};
1932        /// assert_eq!(Vec4::min(4, 5), Vec4::broadcast(4));
1933        /// assert_eq!(Vec4::max(4, 5), Vec4::broadcast(5));
1934        /// assert_eq!(Vec4::from(4), Vec4::broadcast(4));
1935        /// assert_eq!(Vec4::from(4).mul_add(4, 5), Vec4::broadcast(21));
1936        ///
1937        /// // scaling_3d() logically accepts a Vec3...
1938        /// let _ = Mat4::<f32>::scaling_3d(Vec3::broadcast(5.0));
1939        /// // ... but there you go; quick uniform scale, thanks to Into !
1940        /// let _ = Mat4::scaling_3d(5_f32);
1941        /// ```
1942        ///
1943        /// On the other hand, it also allows writing nonsense.
1944        /// To minimize surprises, the names of operations try to be as explicit as possible.
1945        ///
1946        /// ```
1947        /// # use vek::Mat4;
1948        /// // This creates a matrix that translates to (5,5,5), but it's probably not what you meant.
1949        /// // Hopefully the `_3d` suffix would help you catch this.
1950        /// let _ = Mat4::translation_3d(5_f32);
1951        /// // translation_3d() takes V: Into<Vec3> because it allows it to accept
1952        /// // Vec2, Vec3 and Vec4, and also with both repr(C) and repr(simd) layouts.
1953        /// ```
1954        impl<T: Copy> From<T> for $Vec<T> {
1955            #[inline]
1956            fn from(val: T) -> Self {
1957                Self::broadcast(val)
1958            }
1959        }
1960
1961        // We can't do this :(
1962        /*
1963        impl<U, T: From<U>> From<$Vec<U>> for $Vec<T> {
1964            fn from(v: $Vec<U>) -> Self {
1965                Self::new($(v.$get.into()),+)
1966            }
1967        }
1968        */
1969
1970        #[cfg(feature = "bytemuck")]
1971        unsafe impl<T> bytemuck::Zeroable for $Vec<T> where T: bytemuck::Zeroable {
1972            fn zeroed() -> Self {
1973                Self::new($({ let $namedget = T::zeroed(); $namedget }),+)
1974            }
1975        }
1976
1977        #[cfg(feature = "bytemuck")]
1978        unsafe impl<T> bytemuck::Pod for $Vec<T> where T: bytemuck::Pod {
1979            // Nothing here
1980        }
1981
1982        #[cfg(feature = "az")]
1983        mod impl_az {
1984            use super::$Vec;
1985
1986            impl<T, U> az::Cast<$Vec<U>> for $Vec<T> where T: az::Cast<U> {
1987                fn cast(self) -> $Vec<U> {
1988                    $Vec::new($( self.$get.cast() ),*)
1989                }
1990            }
1991            impl<T, U> az::CheckedCast<$Vec<U>> for $Vec<T> where T: az::CheckedCast<U> {
1992                fn checked_cast(self) -> Option<$Vec<U>> {
1993                    Some($Vec::new($( self.$get.checked_cast()? ),*))
1994                }
1995            }
1996            impl<T, U> az::SaturatingCast<$Vec<U>> for $Vec<T> where T: az::SaturatingCast<U> {
1997                fn saturating_cast(self) -> $Vec<U> {
1998                    $Vec::new($( self.$get.saturating_cast() ),*)
1999                }
2000            }
2001            impl<T, U> az::WrappingCast<$Vec<U>> for $Vec<T> where T: az::WrappingCast<U> {
2002                fn wrapping_cast(self) -> $Vec<U> {
2003                    $Vec::new($( self.$get.wrapping_cast() ),*)
2004                }
2005            }
2006            impl<T, U> az::OverflowingCast<$Vec<U>> for $Vec<T> where T: az::OverflowingCast<U> {
2007                fn overflowing_cast(self) -> ($Vec<U>, bool) {
2008                    $(let $get = self.$get.overflowing_cast();)*
2009                    ($Vec::new($( $get.0 ),*), $($get.1)||*)
2010                }
2011            }
2012            impl<T, U> az::UnwrappedCast<$Vec<U>> for $Vec<T> where T: az::UnwrappedCast<U> {
2013                fn unwrapped_cast(self) -> $Vec<U> {
2014                    $Vec::new($( self.$get.unwrapped_cast() ),*)
2015                }
2016            }
2017        }
2018    };
2019}
2020
2021macro_rules! vec_impl_spatial {
2022    ($Vec:ident) => {
2023        impl<T> $Vec<T> {
2024            /// Dot product between this vector and another.
2025            #[inline]
2026            pub fn dot(self, v: Self) -> T where T: Add<T, Output=T> + Mul<Output=T> {
2027                (self * v).sum()
2028            }
2029            /// The squared magnitude of a vector is its spatial length, squared.
2030            /// It is slightly cheaper to compute than `magnitude` because it avoids a square root.
2031            #[inline]
2032            pub fn magnitude_squared(self) -> T where T: Copy + Add<T, Output=T> + Mul<Output=T> {
2033                self.dot(self)
2034            }
2035            /// The magnitude of a vector is its spatial length.
2036            #[inline]
2037            pub fn magnitude(self) -> T where T: Add<T, Output=T> + Real {
2038                self.magnitude_squared().sqrt()
2039            }
2040            /// Squared distance between two point vectors.
2041            /// It is slightly cheaper to compute than `distance` because it avoids a square root.
2042            #[inline]
2043            pub fn distance_squared(self, v: Self) -> T where T: Copy + Add<T, Output=T> + Sub<Output=T> + Mul<Output=T> {
2044                (self - v).magnitude_squared()
2045            }
2046            /// Distance between two point vectors.
2047            #[inline]
2048            pub fn distance(self, v: Self) -> T where T: Add<T, Output=T> + Real {
2049                (self - v).magnitude()
2050            }
2051            /// Get a copy of this direction vector such that its length equals 1.
2052            #[inline]
2053            pub fn normalized(self) -> Self where T: Add<T, Output=T> + Real {
2054                self / self.magnitude()
2055            }
2056            /// Get a copy of this direction vector such that its length equals 1.
2057            /// If all components approximately zero, None is returned (uses RelativeEq).
2058            pub fn try_normalized<E>(self) -> Option<Self>
2059            where
2060                T: RelativeEq<Epsilon = E> + Add<T, Output=T> + Real,
2061                E: Add<Output = E> + Real,
2062            {
2063                if self.is_approx_zero() {
2064                    None
2065                } else {
2066                    Some(self.normalized())
2067                }
2068            }
2069            /// Divide this vector's components such that its length equals 1.
2070            #[inline]
2071            pub fn normalize(&mut self) where T: Add<T, Output=T> + Real {
2072                *self = self.normalized();
2073            }
2074            /// Divide this vector's components such that its length equals 1, and also returns the previous length.
2075            #[inline]
2076            pub fn normalize_and_get_magnitude(&mut self) -> T where T: Add<T, Output=T> + Real {
2077                let (normalized, magnitude) = self.normalized_and_get_magnitude();
2078                *self = normalized;
2079                magnitude
2080            }
2081            /// Get a copy of this direction vector such that its length equals 1, and also returns the length of the original vector.
2082            #[inline]
2083            pub fn normalized_and_get_magnitude(self) -> (Self, T) where T: Add<T, Output=T> + Real {
2084                let magnitude = self.magnitude();
2085                (self / magnitude, magnitude)
2086            }
2087            /// Is this vector normalized ? (Uses `RelativeEq`)
2088            #[inline]
2089            pub fn is_normalized<E>(self) -> bool
2090            where
2091                T: RelativeEq<Epsilon = E> + Add<T, Output=T> + Real,
2092                E: Real,
2093            {
2094                self.is_magnitude_close_to(T::one())
2095            }
2096            /// Is this vector approximately zero ? (Uses `RelativeEq`)
2097            #[inline]
2098            pub fn is_approx_zero<E>(self) -> bool
2099            where
2100                T: RelativeEq<Epsilon = E> + Add<T, Output=T> + Real,
2101                E: Real,
2102            {
2103                self.is_magnitude_close_to(T::zero())
2104            }
2105            /// Is the magnitude of the vector close to `x` ? (Uses `RelativeEq`)
2106            pub fn is_magnitude_close_to<E>(self, x: T) -> bool
2107            where
2108                T: RelativeEq<Epsilon = E> + Add<T, Output=T> + Real,
2109                E: Real,
2110            {
2111                let epsilon = T::default_epsilon();
2112                let max_rel = T::default_max_relative();
2113
2114                let four_epsilon = epsilon + epsilon + epsilon + epsilon;
2115                let four_max_rel = max_rel + max_rel + max_rel + max_rel;
2116
2117                let x_squared = x * x;
2118
2119                self.magnitude_squared()
2120                    .relative_eq(&(x_squared), four_epsilon, four_max_rel)
2121            }
2122            /// Get the smallest angle, in radians, between two direction vectors.
2123            pub fn angle_between(self, v: Self) -> T where T: Add<T, Output=T> + Real + Clamp {
2124                self.normalized().dot(v.normalized()).clamped_minus1_1().acos()
2125            }
2126            #[deprecated(note="Use `to_degrees()` on the value returned by `angle_between()` instead")]
2127            /// Get the smallest angle, in degrees, between two direction vectors.
2128            pub fn angle_between_degrees(self, v: Self) -> T
2129                where T: Add<T, Output=T> + Real + Clamp
2130            {
2131                self.angle_between(v).to_degrees()
2132            }
2133            /// The reflection direction for this vector on a surface which normal is given.
2134            pub fn reflected(self, surface_normal: Self) -> Self
2135                where T: Copy + Add<T, Output=T> + Mul<Output=T> + Sub<Output=T> + Add<Output=T>
2136            {
2137                let dot = self.dot(surface_normal);
2138                self - surface_normal * (dot + dot)
2139            }
2140            /// The refraction vector for this incident vector, a surface normal and a ratio of
2141            /// indices of refraction (`eta`).
2142            pub fn refracted(self, surface_normal: Self, eta: T) -> Self
2143                where T: Real + Add<T, Output=T> + Mul<Output=T>
2144            {
2145                let n = surface_normal;
2146                let i = self;
2147                let n_dot_i = n.dot(i);
2148                let k = T::one() - eta * eta * (T::one() - n_dot_i * n_dot_i);
2149                if k < T::zero() {
2150                    Self::zero()
2151                } else {
2152                    i * eta - n * (eta * n_dot_i + k.sqrt())
2153                }
2154            }
2155            /// Orients a vector to point away from a surface as defined by its normal.
2156            pub fn face_forward(self, incident: Self, reference: Self) -> Self
2157                where T: Add<T, Output=T> + Mul<Output=T> + Zero + PartialOrd + Neg<Output=T>
2158            {
2159                if reference.dot(incident) <= T::zero() {
2160                    self
2161                } else {
2162                    -self
2163                }
2164            }
2165        }
2166    };
2167}
2168
2169
2170#[allow(unused_macros)]
2171macro_rules! vec_impl_spatial_2d {
2172    ($Vec:ident) => {
2173        impl<T> $Vec<T> {
2174            /// A signed value which tells in which half-space of the line segment `ab` this point lies.
2175            ///
2176            /// Returns:
2177            ///
2178            /// - ` < 0`: This point lies in the half-space right of segment `ab`.
2179            /// - `== 0`: This point lies in the infinite line along segment `ab`.
2180            /// - ` > 0`: This point lies in the half-space left of segment `ab`.
2181            #[inline]
2182            pub fn determine_side(self, a: Self, b: Self) -> T
2183                where T: Copy + Sub<Output=T> + Mul<Output=T>
2184            {
2185                let (cx, cy) = self.into_tuple();
2186                let (ax, ay) = a.into_tuple();
2187                let (bx, by) = b.into_tuple();
2188                let d1 = (bx - ax) * (cy - ay);
2189                let d2 = (by - ay) * (cx - ax);
2190                d1 - d2
2191            }
2192            /// The signed area of the triangle defined by points `(a, b, c)`.
2193            pub fn signed_triangle_area(a: Self, b: Self, c: Self) -> T
2194                where T: Copy + Sub<Output=T> + Mul<Output=T> + One + Div<Output=T> + Add<Output=T>
2195            {
2196                let two = T::one() + T::one();
2197                c.determine_side(a, b)/two
2198            }
2199            /// The area of the triangle defined by points `(a, b, c)`.
2200            pub fn triangle_area(a: Self, b: Self, c: Self) -> T
2201                where T: Copy + Sub<Output=T> + Mul<Output=T> + One + Div<Output=T> + Add<Output=T> + PartialOrd + Neg<Output=T>
2202            {
2203                let s = Self::signed_triangle_area(a, b, c);
2204                partial_max(s, -s)
2205            }
2206
2207            /// Returns this vector rotated in 2D, counter-clockwise.
2208            ///
2209            /// ```
2210            /// # extern crate vek;
2211            /// # #[macro_use] extern crate approx;
2212            /// # use vek::Vec2;
2213            /// use std::f32::consts::PI;
2214            ///
2215            /// # fn main() {
2216            /// assert_relative_eq!(Vec2::unit_x().rotated_z(0_f32), Vec2::unit_x());
2217            /// assert_relative_eq!(Vec2::unit_x().rotated_z(PI/2.), Vec2::unit_y());
2218            /// assert_relative_eq!(Vec2::unit_x().rotated_z(PI), -Vec2::unit_x());
2219            /// assert_relative_eq!(Vec2::unit_x().rotated_z(PI*1.5), -Vec2::unit_y());
2220            /// assert_relative_eq!(Vec2::unit_x().rotated_z(PI*2.), Vec2::unit_x(), epsilon = 0.000001);
2221            /// # }
2222            /// ```
2223            #[inline]
2224            pub fn rotated_z(self, angle_radians: T) -> Self where T: Real {
2225                let c = angle_radians.cos();
2226                let s = angle_radians.sin();
2227                let Self { x, y } = self;
2228                Self::new(c*x - s*y, s*x + c*y)
2229            }
2230            /// Rotates this vector in 2D. See `rotated_z()`.
2231            #[inline]
2232            pub fn rotate_z(&mut self, angle_radians: T) where T: Real {
2233                *self = self.rotated_z(angle_radians);
2234            }
2235            /// Get the unit vector which has `x` set to 1.
2236            pub fn unit_x    () -> Self where T: Zero + One { Self::new(T::one(), T::zero()) }
2237            /// Get the unit vector which has `y` set to 1.
2238            pub fn unit_y    () -> Self where T: Zero + One { Self::new(T::zero(), T::one()) }
2239            /// Get the unit vector which has `x` set to -1.
2240            #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2241            pub fn left      () -> Self where T: Zero + One + Neg<Output=T> { -Self::unit_x() }
2242            /// Get the unit vector which has `x` set to 1.
2243            #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2244            pub fn right     () -> Self where T: Zero + One {  Self::unit_x() }
2245            /// Get the unit vector which has `y` set to 1.
2246            /// This is not intended for screen-space coordinates (in which case the Y axis is reversed). When in doubt, just use `unit_y()` instead.
2247            #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2248            pub fn up        () -> Self where T: Zero + One {  Self::unit_y() }
2249            /// Get the unit vector which has `y` set to -1.
2250            /// This is not intended for screen-space coordinates (in which case the Y axis is reversed). When in doubt, just use `unit_y()` instead.
2251            #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2252            pub fn down      () -> Self where T: Zero + One + Neg<Output=T> { -Self::unit_y() }
2253        }
2254    };
2255}
2256
2257
2258#[allow(unused_macros)]
2259macro_rules! vec_impl_spatial_3d {
2260    ($($Vec:ident)+) => {
2261        $(
2262            impl<T> $Vec<T> {
2263                /// Creates a 2D point vector in homogeneous coordinates (sets the last coordinate to 1).
2264                pub fn new_point_2d(x: T, y: T) -> Self where T: One {
2265                    Self::new(x, y, T::one())
2266                }
2267                /// Creates a 2D direction vector in homogeneous coordinates (sets the last coordinate to 0).
2268                pub fn new_direction_2d(x: T, y: T) -> Self where T: Zero {
2269                    Self::new(x, y, T::zero())
2270                }
2271                /// Turns a 2D vector into a point vector in homogeneous coordinates (sets the last coordinate to 1).
2272                pub fn from_point_2d<V: Into<Vec2<T>>>(v: V) -> Self where T: One {
2273                    let Vec2 { x, y } = v.into();
2274                    Self::new_point_2d(x, y)
2275                }
2276                /// Turns a 2D vector into a direction vector in homogeneous coordinates (sets the last coordinate to 0).
2277                pub fn from_direction_2d<V: Into<Vec2<T>>>(v: V) -> Self where T: Zero {
2278                    let Vec2 { x, y } = v.into();
2279                    Self::new_direction_2d(x, y)
2280                }
2281
2282                /// The cross-product of this vector with another.
2283                ///
2284                /// On two noncolinear vectors, the result is perpendicular to the plane they
2285                /// define.
2286                ///
2287                /// The result's facing direction depends on the handedness of your
2288                /// coordinate system:
2289                /// If we let `f` be a forward vector and `u` an up vector, then we have :
2290                ///
2291                /// - Right-handed: `f.cross(u)` points to the right.
2292                /// - Left-handed: `f.cross(u)` points to the left.
2293                ///
2294                /// There's a trick to remember this which involves your hand:
2295                /// spread your fingers such that your middle finger points upwards
2296                /// and your index finger points forwards, then your thumb points
2297                /// in the direction of `f.cross(u)`.
2298                ///
2299                /// The following example demonstrates an identity that is easy to remember.
2300                ///
2301                /// ```
2302                /// # extern crate vek;
2303                /// # #[macro_use] extern crate approx;
2304                /// # use vek::Vec3;
2305                /// # fn main() {
2306                /// let i = Vec3::<f32>::unit_x();
2307                /// let j = Vec3::<f32>::unit_y();
2308                /// let k = Vec3::<f32>::unit_z();
2309                /// assert_relative_eq!(i.cross(j), k);
2310                /// # }
2311                /// ```
2312                #[inline]
2313                pub fn cross(self, b: Self)
2314                    -> Self where T: Copy + Mul<Output=T> + Sub<Output=T>
2315                {
2316                    let a = self;
2317                    Self::new(
2318                        a.y*b.z - a.z*b.y,
2319                        a.z*b.x - a.x*b.z,
2320                        a.x*b.y - a.y*b.x
2321                    )
2322                }
2323                /// Performs spherical linear interpolation between this vector and another,
2324                /// without implicitly constraining `factor` to be between 0 and 1.
2325                ///
2326                /// The vectors are not required to be normalized; their length
2327                /// is also linearly interpolated in the process.
2328                ///
2329                /// ```
2330                /// # extern crate vek;
2331                /// # #[macro_use] extern crate approx;
2332                /// # use vek::Vec3;
2333                /// # fn main() {
2334                /// let u = Vec3::<f32>::unit_x();
2335                /// let v = Vec3::<f32>::unit_y() * 2.;
2336                /// let slerp = Vec3::slerp(u, v, 0.5);
2337                /// assert_relative_eq!(slerp.magnitude(), 1.5);
2338                /// assert_relative_eq!(slerp.x, slerp.y);
2339                /// # }
2340                /// ```
2341                pub fn slerp_unclamped(from: Self, to: Self, factor: T) -> Self
2342                    where T: Add<T, Output=T> + Real + Clamp + Lerp<T,Output=T>
2343                {
2344                    // From GLM, gtx/rotate_vector.inl
2345                    let (mag_from, mag_to) = (from.magnitude(), to.magnitude());
2346                    let (from, to) = (from/mag_from, to/mag_to);
2347                    let cos_alpha = from.dot(to).clamped_minus1_1();
2348                    let alpha = cos_alpha.acos();
2349                    let sin_alpha = alpha.sin();
2350                    let t1 = ((T::one() - factor) * alpha).sin() / sin_alpha;
2351                    let t2 = (factor * alpha).sin() / sin_alpha;
2352                    (from * t1 + to * t2) * Lerp::lerp_unclamped(mag_from, mag_to, factor)
2353                }
2354                /// Performs spherical linear interpolation between this vector and another,
2355                /// implicitly constraining `factor` to be between 0 and 1.
2356                ///
2357                /// The vectors are not required to be normalized; their length
2358                /// is also interpolated in the process.
2359                pub fn slerp(from: Self, to: Self, factor: T) -> Self
2360                    where T: Add<T, Output=T> + Real + Clamp + Lerp<T,Output=T>
2361                {
2362                    Slerp::slerp(from, to, factor)
2363                }
2364
2365                /// Get the unit vector which has `x` set to 1.
2366                pub fn unit_x    () -> Self where T: Zero + One { Self::new(T::one(), T::zero(), T::zero()) }
2367                /// Get the unit vector which has `y` set to 1.
2368                pub fn unit_y    () -> Self where T: Zero + One { Self::new(T::zero(), T::one(), T::zero()) }
2369                /// Get the unit vector which has `z` set to 1.
2370                pub fn unit_z    () -> Self where T: Zero + One { Self::new(T::zero(), T::zero(), T::one()) }
2371                /// Get the unit vector which has `x` set to -1.
2372                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2373                pub fn left      () -> Self where T: Zero + One + Neg<Output=T> { -Self::unit_x() }
2374                /// Get the unit vector which has `x` set to 1.
2375                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2376                pub fn right     () -> Self where T: Zero + One {  Self::unit_x() }
2377                /// Get the unit vector which has `y` set to 1.
2378                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2379                pub fn up        () -> Self where T: Zero + One {  Self::unit_y() }
2380                /// Get the unit vector which has `y` set to -1.
2381                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2382                pub fn down      () -> Self where T: Zero + One + Neg<Output=T> { -Self::unit_y() }
2383                /// Get the unit vector which has `z` set to 1 ("forward" in a left-handed coordinate system).
2384                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2385                pub fn forward_lh() -> Self where T: Zero + One {  Self::unit_z() }
2386                /// Get the unit vector which has `z` set to -1 ("forward" in a right-handed coordinate system).
2387                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2388                pub fn forward_rh() -> Self where T: Zero + One + Neg<Output=T> { -Self::unit_z() }
2389                /// Get the unit vector which has `z` set to -1 ("back" in a left-handed coordinate system).
2390                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2391                pub fn back_lh   () -> Self where T: Zero + One + Neg<Output=T> { -Self::unit_z() }
2392                /// Get the unit vector which has `z` set to 1 ("back" in a right-handed coordinate system).
2393                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2394                pub fn back_rh   () -> Self where T: Zero + One {  Self::unit_z() }
2395            }
2396            impl<T> Slerp<T> for $Vec<T>
2397                where T: Add<T, Output=T> + Real + Clamp + Lerp<T,Output=T>
2398            {
2399                type Output = Self;
2400                fn slerp_unclamped(from: Self, to: Self, factor: T) -> Self {
2401                    Self::slerp_unclamped(from, to, factor)
2402                }
2403            }
2404        )+
2405    }
2406}
2407
2408macro_rules! vec_impl_spatial_4d {
2409    ($($Vec:ident)+) => {
2410        $(
2411            impl<T> $Vec<T> {
2412                /// Creates a point vector in homogeneous coordinates (sets the last coordinate to 1).
2413                pub fn new_point(x: T, y: T, z: T) -> Self where T: One {
2414                    Self::new(x, y, z, T::one())
2415                }
2416                /// Creates a direction vector in homogeneous coordinates (sets the last coordinate to 0).
2417                pub fn new_direction(x: T, y: T, z: T) -> Self where T: Zero {
2418                    Self::new(x, y, z, T::zero())
2419                }
2420                /// Turns a vector into a point vector in homogeneous coordinates (sets the last coordinate to 1).
2421                pub fn from_point<V: Into<Vec3<T>>>(v: V) -> Self where T: One {
2422                    let Vec3 { x, y, z } = v.into();
2423                    Self::new_point(x, y, z)
2424                }
2425                /// Turns a vector into a direction vector in homogeneous coordinates (sets the last coordinate to 0).
2426                pub fn from_direction<V: Into<Vec3<T>>>(v: V) -> Self where T: Zero {
2427                    let Vec3 { x, y, z } = v.into();
2428                    Self::new_direction(x, y, z)
2429                }
2430                /// Get the unit direction vector which has `x` set to 1.
2431                pub fn unit_x    () -> Self where T: Zero + One { Self::new(T::one(), T::zero(), T::zero(), T::zero()) }
2432                /// Get the unit direction vector which has `y` set to 1.
2433                pub fn unit_y    () -> Self where T: Zero + One { Self::new(T::zero(), T::one(), T::zero(), T::zero()) }
2434                /// Get the unit direction vector which has `z` set to 1.
2435                pub fn unit_z    () -> Self where T: Zero + One { Self::new(T::zero(), T::zero(), T::one(), T::zero()) }
2436                /// Get the vector which has `w` set to 1 and all other elements to zero.
2437                pub fn unit_w    () -> Self where T: Zero + One { Self::new(T::zero(), T::zero(), T::zero(), T::one()) }
2438                /// Get the unit direction vector which has `x` set to -1.
2439                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2440                pub fn left      () -> Self where T: Zero + One + Neg<Output=T> { -Self::unit_x() }
2441                /// Get the unit direction vector which has `x` set to 1.
2442                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2443                pub fn right     () -> Self where T: Zero + One {  Self::unit_x() }
2444                /// Get the unit direction vector which has `y` set to 1.
2445                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2446                pub fn up        () -> Self where T: Zero + One {  Self::unit_y() }
2447                /// Get the unit direction vector which has `y` set to -1.
2448                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2449                pub fn down      () -> Self where T: Zero + One + Neg<Output=T> { -Self::unit_y() }
2450                /// Get the unit direction vector which has `z` set to 1 ("forward" in a left-handed coordinate system).
2451                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2452                pub fn forward_lh() -> Self where T: Zero + One {  Self::unit_z() }
2453                /// Get the unit direction vector which has `z` set to -1 ("forward" in a right-handed coordinate system).
2454                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2455                pub fn forward_rh() -> Self where T: Zero + One + Neg<Output=T> { -Self::unit_z() }
2456                /// Get the unit direction vector which has `z` set to -1 ("back" in a left-handed coordinate system).
2457                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2458                pub fn back_lh   () -> Self where T: Zero + One + Neg<Output=T> { -Self::unit_z() }
2459                /// Get the unit direction vector which has `z` set to 1 ("back" in a right-handed coordinate system).
2460                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2461                pub fn back_rh   () -> Self where T: Zero + One {  Self::unit_z() }
2462
2463                /// Get the homogeneous point vector which has `x` set to 1.
2464                pub fn unit_x_point    () -> Self where T: Zero + One { Self::new(T::one(), T::zero(), T::zero(), T::one()) }
2465                /// Get the homogeneous point vector which has `y` set to 1.
2466                pub fn unit_y_point    () -> Self where T: Zero + One { Self::new(T::zero(), T::one(), T::zero(), T::one()) }
2467                /// Get the homogeneous point vector which has `z` set to 1.
2468                pub fn unit_z_point    () -> Self where T: Zero + One { Self::new(T::zero(), T::zero(), T::one(), T::one()) }
2469                /// Get the homogeneous point vector which has `x` set to -1.
2470                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2471                pub fn left_point      () -> Self where T: Zero + One + Neg<Output=T> { Self::new(-T::one(), T::zero(), T::zero(), T::one()) }
2472                /// Get the homogeneous point vector which has `x` set to 1.
2473                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2474                pub fn right_point     () -> Self where T: Zero + One {  Self::unit_x_point() }
2475                /// Get the homogeneous point vector which has `y` set to 1.
2476                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2477                pub fn up_point        () -> Self where T: Zero + One {  Self::unit_y_point() }
2478                /// Get the homogeneous point vector which has `y` set to -1.
2479                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2480                pub fn down_point      () -> Self where T: Zero + One + Neg<Output=T> { Self::new(T::zero(), -T::one(), T::zero(), T::one()) }
2481                /// Get the homogeneous point vector which has `z` set to 1 ("forward" in a left-handed coordinate system).
2482                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2483                pub fn forward_point_lh() -> Self where T: Zero + One {  Self::unit_z_point() }
2484                /// Get the homogeneous point vector which has `z` set to -1 ("forward" in a right-handed coordinate system).
2485                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2486                pub fn forward_point_rh() -> Self where T: Zero + One + Neg<Output=T> { Self::new(T::zero(), T::zero(), -T::one(), T::one()) }
2487                /// Get the homogeneous point vector which has `z` set to -1 ("back" in a left-handed coordinate system).
2488                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2489                pub fn back_point_lh   () -> Self where T: Zero + One + Neg<Output=T> { Self::new(T::zero(), T::zero(), -T::one(), T::one()) }
2490                /// Get the homogeneous point vector which has `z` set to 1 ("back" in a right-handed coordinate system).
2491                #[deprecated(since = "0.14.0", note = "This function is opinionated about the semantics of X,Y and Z axii, and should not be used. The mapping of axii (X,Y,Z) to perceived directions (e.g right, up, forward) is not universal at all and varies between libraries, graphics APIs, content creation tools and engines. If you want such helper functions, you should write these yourself as part of the package you're working on, according to what you know about YOUR current coordinate space.")]
2492                pub fn back_point_rh   () -> Self where T: Zero + One {  Self::unit_z_point() }
2493
2494                /// Get a copy of this vector where each component has been divided in order to
2495                /// make `w = 1`.
2496                ///
2497                /// More info: A homogeneous point has `w = 1`. Some operations (e.g. projection)
2498                /// can cause this to no longer be the case. Homogenization is when you divide
2499                /// every component of the vector by `w`. This makes `w = 1` and the remaining
2500                /// components are also appropriately scaled. This process is also called
2501                /// "normalization" in some textbooks, but that name is already taken by
2502                /// other methods of this struct.
2503                ///
2504                /// If `w = 0`, this method will result in a division by zero. Be careful!
2505                pub fn homogenized(self) -> Self where T: Div<Output=T>, T: Copy {
2506                    self / self.w
2507                }
2508                /// Divide the vector's components such that `w = 1`.
2509                ///
2510                /// See the `homogenized` method for more information.
2511                pub fn homogenize(&mut self) where T: Div<Output=T>, T: Copy {
2512                    *self = self.homogenized();
2513                }
2514                /// Returns true if this vector is homogeneous (`w = 0` or `w = 1`).
2515                ///
2516                /// Uses `RelativeEq`.
2517                pub fn is_homogeneous(self) -> bool where T: RelativeEq + Zero + One + Copy {
2518                    self.is_point() || self.is_direction()
2519                }
2520                /// Returns true if this vector is a homogeneous point (`w = 1`).
2521                ///
2522                /// Uses `RelativeEq`.
2523                pub fn is_point(self) -> bool where T: RelativeEq + One {
2524                    self.w.relative_eq(&T::one(), T::default_epsilon(), T::default_max_relative())
2525                }
2526                /// Returns true if this vector is a homogeneous direction (`w = 0`).
2527                ///
2528                /// Uses `RelativeEq`.
2529                pub fn is_direction(self) -> bool where T: RelativeEq + Zero {
2530                    self.w.relative_eq(&T::zero(), T::default_epsilon(), T::default_max_relative())
2531                }
2532            }
2533        )+
2534    }
2535}
2536
2537#[cfg(feature="image")]
2538macro_rules! vec_impl_pixel_rgb {
2539    ($Vec:ident) => {
2540        extern crate image;
2541
2542        use self::image::{Primitive, Pixel, ColorType, Luma, LumaA};
2543
2544        impl<T> Pixel for $Vec<T>
2545            where T: ColorComponent + Copy + Clone + Primitive
2546        {
2547            type Subpixel = T;
2548
2549            const CHANNEL_COUNT: u8 = 3;
2550            const COLOR_MODEL: &'static str = "RGB";
2551
2552            // When I first introduced the optional dependency to the `image` crate, ColorType allowed specifying the bit depth procedurally.
2553            // Now the bit depths are fixed; the only "really" supported T are now u8 and u16...
2554            // For now, I choose to still "implement" this trait for other T (such as f32), for convenience and backwards compatibility, but you shouldn't use the COLOR_TYPE in that case.
2555            // Feel free to open an issue about that.
2556            // NOTE: this comment is duplicated in vec_impl_pixel_rgba!(), please update both instances if you change one
2557            const COLOR_TYPE: ColorType = match mem::size_of::<T>() {
2558                1 => ColorType::Rgb8,  // This is wrong if T is a signed type, but the closest we can get
2559                2 => ColorType::Rgb16, // This is wrong if T is a signed type, but the closest we can get
2560                _ => ColorType::Rgb8,  // This is wrong for literally any T
2561            };
2562
2563            fn channels(&self) -> &[Self::Subpixel] {
2564                self.as_slice()
2565            }
2566            fn channels_mut(&mut self) -> &mut [Self::Subpixel] {
2567                self.as_mut_slice()
2568            }
2569            fn channels4(&self) -> (Self::Subpixel, Self::Subpixel, Self::Subpixel, Self::Subpixel) {
2570                (self.r, self.g, self.b, T::full())
2571            }
2572            fn from_channels(a: Self::Subpixel, b: Self::Subpixel, c: Self::Subpixel, _d: Self::Subpixel) -> Self {
2573                Self::new(a, b, c)
2574            }
2575            fn from_slice(slice: &[Self::Subpixel]) -> &Self {
2576                assert!(slice.len() >= Self::CHANNEL_COUNT as _);
2577                unsafe { &*(slice.as_ptr() as *const _ as *const Self) }
2578            }
2579            fn from_slice_mut(slice: &mut [Self::Subpixel]) -> &mut Self {
2580                assert!(slice.len() >= Self::CHANNEL_COUNT as _);
2581                unsafe { &mut *(slice.as_mut_ptr() as *mut _ as *mut Self) }
2582            }
2583            fn to_rgb(&self) -> image::Rgb<Self::Subpixel> {
2584                image::Rgb([self.r, self.g, self.b])
2585            }
2586            fn to_rgba(&self) -> image::Rgba<Self::Subpixel> {
2587                image::Rgba([self.r, self.g, self.b, T::full()])
2588            }
2589            fn to_bgr(&self) -> image::Bgr<Self::Subpixel> {
2590                image::Bgr([self.b, self.g, self.r])
2591            }
2592            fn to_bgra(&self) -> image::Bgra<Self::Subpixel> {
2593                image::Bgra([self.b, self.g, self.r, T::full()])
2594            }
2595            fn to_luma(&self) -> Luma<Self::Subpixel> {
2596                let three = T::one() + T::one() + T::one();
2597                let c = (self.r + self.g + self.b) / three;
2598                Luma([c])
2599            }
2600            fn to_luma_alpha(&self) -> LumaA<Self::Subpixel> {
2601                LumaA([self.to_luma().0[0], T::full()])
2602            }
2603            fn map<F>(&self, mut f: F) -> Self where F: FnMut(Self::Subpixel) -> Self::Subpixel {
2604                Self { r: f(self.r), g: f(self.g), b: f(self.b) }
2605            }
2606            fn apply<F>(&mut self, f: F) where F: FnMut(Self::Subpixel) -> Self::Subpixel {
2607                *self = Pixel::map(self, f);
2608            }
2609            fn map_with_alpha<F, G>(&self, mut f: F, mut _g: G) -> Self
2610                where F: FnMut(Self::Subpixel) -> Self::Subpixel, G: FnMut(Self::Subpixel) -> Self::Subpixel
2611            {
2612                Self { r: f(self.r), g: f(self.g), b: f(self.b) }
2613            }
2614            fn apply_with_alpha<F, G>(&mut self, f: F, g: G)
2615                where F: FnMut(Self::Subpixel) -> Self::Subpixel, G: FnMut(Self::Subpixel) -> Self::Subpixel
2616            {
2617                *self = self.map_with_alpha(f, g);
2618            }
2619
2620            fn map2<F>(&self, other: &Self, mut f: F) -> Self
2621                where F: FnMut(Self::Subpixel, Self::Subpixel) -> Self::Subpixel
2622            {
2623                Self {
2624                    r: f(self.r, other.r),
2625                    g: f(self.g, other.g),
2626                    b: f(self.b, other.b)
2627                }
2628            }
2629            fn apply2<F>(&mut self, other: &Self, f: F)
2630                where F: FnMut(Self::Subpixel, Self::Subpixel) -> Self::Subpixel
2631            {
2632                *self = self.map2(*other, f);
2633            }
2634
2635            fn invert(&mut self) {
2636                *self = self.inverted_rgb();
2637            }
2638            fn blend(&mut self, other: &Self) {
2639                self.apply2(*other, |a, b| {
2640                    let a = <f64 as NumCast>::from(a).unwrap();
2641                    let b = <f64 as NumCast>::from(b).unwrap();
2642                    let m = (a+b)/2f64;
2643                    <T as NumCast>::from(m.round()).unwrap()
2644                });
2645            }
2646        }
2647    }
2648}
2649
2650
2651#[cfg(feature="image")]
2652macro_rules! vec_impl_pixel_rgba {
2653    ($Vec:ident) => {
2654        extern crate image;
2655
2656        use self::image::{Primitive, Pixel, ColorType, Luma, LumaA};
2657
2658        impl<T> Pixel for $Vec<T>
2659            where T: ColorComponent + Copy + Clone + Primitive
2660        {
2661            type Subpixel = T;
2662
2663            const CHANNEL_COUNT: u8 = 4;
2664            const COLOR_MODEL: &'static str = "RGBA";
2665
2666            // When I first introduced the optional dependency to the `image` crate, ColorType allowed specifying the bit depth procedurally.
2667            // Now the bit depths are fixed; the only "really" supported T are now u8 and u16...
2668            // For now, I choose to still "implement" this trait for other T (such as f32), for convenience and backwards compatibility, but you shouldn't use the COLOR_TYPE in that case.
2669            // Feel free to open an issue about that.
2670            // NOTE: this comment is duplicated in vec_impl_pixel_rgb!(), please update both instances if you change one
2671            const COLOR_TYPE: ColorType = match mem::size_of::<T>() {
2672                1 => ColorType::Rgba8,  // This is wrong if T is a signed type, but the closest we can get
2673                2 => ColorType::Rgba16, // This is wrong if T is a signed type, but the closest we can get
2674                _ => ColorType::Rgba8,  // This is wrong for literally any T
2675            };
2676
2677            fn channels(&self) -> &[Self::Subpixel] {
2678                self.as_slice()
2679            }
2680            fn channels_mut(&mut self) -> &mut [Self::Subpixel] {
2681                self.as_mut_slice()
2682            }
2683            fn channels4(&self) -> (Self::Subpixel, Self::Subpixel, Self::Subpixel, Self::Subpixel) {
2684                (self.r, self.g, self.b, self.a)
2685            }
2686            fn from_channels(a: Self::Subpixel, b: Self::Subpixel, c: Self::Subpixel, d: Self::Subpixel) -> Self {
2687                Self::new(a, b, c, d)
2688            }
2689            fn from_slice(slice: &[Self::Subpixel]) -> &Self {
2690                assert!(slice.len() >= Self::CHANNEL_COUNT as _);
2691                unsafe { &*(slice.as_ptr() as *const _ as *const Self) }
2692            }
2693            fn from_slice_mut(slice: &mut [Self::Subpixel]) -> &mut Self {
2694                assert!(slice.len() >= Self::CHANNEL_COUNT as _);
2695                unsafe { &mut *(slice.as_mut_ptr() as *mut _ as *mut Self) }
2696            }
2697            fn to_rgb(&self) -> image::Rgb<Self::Subpixel> {
2698                image::Rgb([self.r, self.g, self.b])
2699            }
2700            fn to_rgba(&self) -> image::Rgba<Self::Subpixel> {
2701                image::Rgba([self.r, self.g, self.b, self.a])
2702            }
2703            fn to_bgr(&self) -> image::Bgr<Self::Subpixel> {
2704                image::Bgr([self.b, self.g, self.r])
2705            }
2706            fn to_bgra(&self) -> image::Bgra<Self::Subpixel> {
2707                image::Bgra([self.b, self.g, self.r, self.a])
2708            }
2709            fn to_luma(&self) -> Luma<Self::Subpixel> {
2710                let three = T::one() + T::one() + T::one();
2711                let c = (self.r + self.g + self.b) / three;
2712                Luma([c])
2713            }
2714            fn to_luma_alpha(&self) -> LumaA<Self::Subpixel> {
2715                LumaA([self.to_luma().0[0], self.a])
2716            }
2717            fn map<F>(&self, mut f: F) -> Self where F: FnMut(Self::Subpixel) -> Self::Subpixel {
2718                Self { r: f(self.r), g: f(self.g), b: f(self.b), a: f(self.a) }
2719            }
2720            fn apply<F>(&mut self, f: F) where F: FnMut(Self::Subpixel) -> Self::Subpixel {
2721                *self = Pixel::map(self, f);
2722            }
2723            fn map_with_alpha<F, G>(&self, mut f: F, mut g: G) -> Self
2724                where F: FnMut(Self::Subpixel) -> Self::Subpixel, G: FnMut(Self::Subpixel) -> Self::Subpixel
2725            {
2726                Self { r: f(self.r), g: f(self.g), b: f(self.b), a: g(self.a) }
2727            }
2728            fn apply_with_alpha<F, G>(&mut self, f: F, g: G)
2729                where F: FnMut(Self::Subpixel) -> Self::Subpixel, G: FnMut(Self::Subpixel) -> Self::Subpixel
2730            {
2731                *self = self.map_with_alpha(f, g);
2732            }
2733
2734            fn map2<F>(&self, other: &Self, mut f: F) -> Self
2735                where F: FnMut(Self::Subpixel, Self::Subpixel) -> Self::Subpixel
2736            {
2737                Self {
2738                    r: f(self.r, other.r),
2739                    g: f(self.g, other.g),
2740                    b: f(self.b, other.b),
2741                    a: f(self.a, other.a)
2742                }
2743            }
2744            fn apply2<F>(&mut self, other: &Self, f: F)
2745                where F: FnMut(Self::Subpixel, Self::Subpixel) -> Self::Subpixel
2746            {
2747                *self = self.map2(*other, f);
2748            }
2749
2750            fn invert(&mut self) {
2751                *self = self.inverted_rgb();
2752            }
2753            fn blend(&mut self, other: &Self) {
2754                self.apply2(*other, |a, b| {
2755                    let a = <f64 as NumCast>::from(a).unwrap();
2756                    let b = <f64 as NumCast>::from(b).unwrap();
2757                    let m = (a+b)/2f64;
2758                    <T as NumCast>::from(m.round()).unwrap()
2759                });
2760            }
2761        }
2762    }
2763}
2764
2765#[cfg(feature="rgba")]
2766macro_rules! vec_impl_color_rgba {
2767    ($Vec:ident) => {
2768
2769        #[cfg(feature="image")]
2770        vec_impl_pixel_rgba!{$Vec}
2771
2772        impl<T: ColorComponent> Rgba<T> {
2773            /// Creates an RGBA color from RGB elements and full alpha.
2774            pub fn new_opaque(r: T, g: T, b: T) -> Self {
2775                Self::new(r, g, b, T::full())
2776            }
2777            /// Creates an RGBA color from RGB elements and zero alpha.
2778            pub fn new_transparent(r: T, g: T, b: T) -> Self {
2779                Self::new(r, g, b, T::zero())
2780            }
2781            /// Creates an RGBA color from an RGB vector and full alpha.
2782            #[cfg(feature="rgb")]
2783            pub fn from_opaque<V: Into<Rgb<T>>>(color: V) -> Self {
2784                let Rgb { r, g, b } = color.into();
2785                Self::new_opaque(r, g, b)
2786            }
2787            /// Creates an RGBA color from an RGB vector and zero alpha.
2788            #[cfg(feature="rgb")]
2789            pub fn from_transparent<V: Into<Rgb<T>>>(color: V) -> Self {
2790                let Rgb { r, g, b } = color.into();
2791                Self::new_transparent(r, g, b)
2792            }
2793        }
2794        impl<T> Rgba<T> {
2795            /// Creates an RGBA color from an RGB vector and variable alpha.
2796            #[cfg(feature="rgb")]
2797            pub fn from_translucent<V: Into<Rgb<T>>>(color: V, opacity: T) -> Self {
2798                let Rgb { r, g, b } = color.into();
2799                Self::new(r, g, b, opacity)
2800            }
2801        }
2802        #[allow(missing_docs)]
2803        impl<T: ColorComponent> $Vec<T> {
2804            pub fn black   () -> Self { Self::new_opaque(T::zero(), T::zero(), T::zero()) }
2805            pub fn white   () -> Self { Self::new_opaque(T::full(), T::full(), T::full()) }
2806            pub fn red     () -> Self { Self::new_opaque(T::full(), T::zero(), T::zero()) }
2807            pub fn green   () -> Self { Self::new_opaque(T::zero(), T::full(), T::zero()) }
2808            pub fn blue    () -> Self { Self::new_opaque(T::zero(), T::zero(), T::full()) }
2809            pub fn cyan    () -> Self { Self::new_opaque(T::zero(), T::full(), T::full()) }
2810            pub fn magenta () -> Self { Self::new_opaque(T::full(), T::zero(), T::full()) }
2811            pub fn yellow  () -> Self { Self::new_opaque(T::full(), T::full(), T::zero()) }
2812            pub fn gray(value: T) -> Self where T: Copy { Self::new_opaque(value, value, value) }
2813            pub fn grey(value: T) -> Self where T: Copy { Self::gray(value) }
2814
2815            /// Returns this color with RGB elements inverted. Alpha is preserved.
2816            ///
2817            /// ```
2818            /// # use vek::Rgba;
2819            /// let opaque_orange = Rgba::new(255_u8, 128, 0, 255_u8);
2820            /// assert_eq!(opaque_orange.inverted_rgb(), Rgba::new(0, 127, 255, 255));
2821            /// assert_eq!(Rgba::<u8>::black().inverted_rgb(), Rgba::white());
2822            /// assert_eq!(Rgba::<u8>::white().inverted_rgb(), Rgba::black());
2823            /// assert_eq!(Rgba::<u8>::red().inverted_rgb(), Rgba::cyan());
2824            /// ```
2825            pub fn inverted_rgb(mut self) -> Self where T: Sub<Output=T> {
2826                self.r = T::full() - self.r;
2827                self.g = T::full() - self.g;
2828                self.b = T::full() - self.b;
2829                self
2830            }
2831            /// Returns the average of this vector's RGB elements.
2832            ///
2833            /// This is not the same as `average` because `average` takes all elements into
2834            /// account, which includes alpha.
2835            /// Be careful when calling this on integer vectors. See the `average()` method
2836            /// of vectors for a discussion and example.
2837            pub fn average_rgb(self) -> T where T: Add<T, Output=T> + Div<T, Output=T> + From<u8> {
2838                let Self { r, g, b, .. } = self;
2839                (r+g+b) / T::from(3)
2840            }
2841        }
2842
2843        impl<T> $Vec<T> {
2844            /// Returns this vector with elements shuffled to map RGBA to ARGB.
2845            pub fn shuffled_argb(self) -> Self {
2846                let Self { r, g, b, a } = self;
2847                Self::new(a, r, g, b)
2848            }
2849            /// Returns this vector with elements shuffled to map RGBA to BGRA.
2850            pub fn shuffled_bgra(self) -> Self {
2851                let Self { r, g, b, a } = self;
2852                Self::new(b, g, r, a)
2853            }
2854        }
2855        /* WISH: FromStr for Rgba and Rgb and vectors in general
2856        impl<T> FromStr for $Vec<T> {
2857            fn from_str(s: &str) -> Option<Self> {
2858                let (mut i, c) = match s.chars().enumerate().skip_while(|c| !(c==&'#'||c==&'('||c==&'r'||c==&'R')).next() {
2859                    None => return None,
2860                    Some((i, c)) => (i, c),
2861                };
2862                i += 1;
2863                match c {
2864                    '#' => unimplemented!{},
2865                    '(' => unimplemented!{},
2866                    c if c=='r' || c=='R' => {
2867                        match s[i..].chars().enumerate().skip_while()
2868                    },
2869                    _ => return None,
2870                }
2871            }
2872        }
2873        */
2874    };
2875}
2876
2877#[cfg(feature="rgb")]
2878macro_rules! vec_impl_color_rgb {
2879    ($Vec:ident) => {
2880
2881        #[cfg(feature="image")]
2882        vec_impl_pixel_rgb!{$Vec}
2883
2884        #[allow(missing_docs)]
2885        impl<T: ColorComponent> $Vec<T> {
2886            pub fn black   () -> Self { Self::new(T::zero(), T::zero(), T::zero()) }
2887            pub fn white   () -> Self { Self::new(T::full(), T::full(), T::full()) }
2888            pub fn red     () -> Self { Self::new(T::full(), T::zero(), T::zero()) }
2889            pub fn green   () -> Self { Self::new(T::zero(), T::full(), T::zero()) }
2890            pub fn blue    () -> Self { Self::new(T::zero(), T::zero(), T::full()) }
2891            pub fn cyan    () -> Self { Self::new(T::zero(), T::full(), T::full()) }
2892            pub fn magenta () -> Self { Self::new(T::full(), T::zero(), T::full()) }
2893            pub fn yellow  () -> Self { Self::new(T::full(), T::full(), T::zero()) }
2894            pub fn gray(value: T) -> Self where T: Copy { Self::new(value, value, value) }
2895            pub fn grey(value: T) -> Self where T: Copy { Self::new(value, value, value) }
2896            /// Returns this color with RGB elements inverted.
2897            ///
2898            /// ```
2899            /// # use vek::Rgb;
2900            /// let orange = Rgb::new(255_u8, 128, 0);
2901            /// assert_eq!(orange.inverted_rgb(), Rgb::new(0, 127, 255));
2902            /// assert_eq!(Rgb::<u8>::black().inverted_rgb(), Rgb::white());
2903            /// assert_eq!(Rgb::<u8>::white().inverted_rgb(), Rgb::black());
2904            /// assert_eq!(Rgb::<u8>::red().inverted_rgb(), Rgb::cyan());
2905            /// ```
2906            pub fn inverted_rgb(mut self) -> Self where T: Sub<Output=T> {
2907                self.r = T::full() - self.r;
2908                self.g = T::full() - self.g;
2909                self.b = T::full() - self.b;
2910                self
2911            }
2912            /// Returns the average of this vector's RGB elements.
2913            ///
2914            /// For `Rgb`, this is the same as `average`, and is provided for compatibility
2915            /// with `Rgba`.
2916            /// Be careful when calling this on integer vectors. See the `average()` method
2917            /// of vectors for a discussion and example.
2918            pub fn average_rgb(self) -> T where T: Add<T, Output=T> + Div<T, Output=T> + From<u8> {
2919                let Self { r, g, b, .. } = self;
2920                (r+g+b) / T::from(3)
2921            }
2922        }
2923
2924        impl<T> $Vec<T> {
2925            /// Returns this vector with R and B elements swapped.
2926            pub fn shuffled_bgr(self) -> Self {
2927                let Self { r, g, b } = self;
2928                Self::new(b, g, r)
2929            }
2930        }
2931    }
2932}
2933
2934
2935/// Opaque type wrapping a hardware-preferred shuffle mask format for 4D vectors.
2936// NOTE: I know that _mm_shuffle_ps() needs an immediate value for the mask,
2937// which means that the mask value has to be known at compile-time, which is
2938// problematic.
2939// Later: See platorm-intrinsics for a fix, and how the x86intrin crate implements
2940// _mm_shuffle_ps().
2941#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
2942pub struct ShuffleMask4(u8);
2943
2944/// A `ShuffleMask4` can be obtained by using the same index for all elements of the result.
2945impl From<usize> for ShuffleMask4 {
2946    fn from(m: usize) -> Self {
2947        Self::new(m,m,m,m)
2948    }
2949}
2950impl From<(usize, usize, usize, usize)> for ShuffleMask4 {
2951    fn from(tuple: (usize, usize, usize, usize)) -> Self {
2952        let (a,b,c,d) = tuple;
2953        Self::new(a,b,c,d)
2954    }
2955}
2956impl From<[usize; 4]> for ShuffleMask4 {
2957    fn from(m: [usize; 4]) -> Self {
2958        Self::new(m[0], m[1], m[2], m[3])
2959    }
2960}
2961impl ShuffleMask4 {
2962    /// Creates a new shuffle mask from indices.
2963    #[inline]
2964    pub fn new(m0: usize, m1: usize, m2: usize, m3: usize) -> Self {
2965        ShuffleMask4(((m0&3) | ((m1&3)<<2) | ((m2&3)<<4) | ((m3&3)<<6)) as _)
2966    }
2967    /// Extracts indices from this shuffle mask.
2968    pub fn to_indices(&self) -> (usize, usize, usize, usize) {
2969        let m = self.0 as usize;
2970        (m&3, (m>>2)&3, (m>>4)&3, (m>>6)&3)
2971    }
2972}
2973
2974macro_rules! vec_impl_shuffle_4d {
2975    ($Vec:ident ($x:tt $y:tt $z:tt $w:tt)) => {
2976
2977        use super::super::ShuffleMask4;
2978
2979        // NOTE: Inspired by
2980        // https://lxjk.github.io/2017/09/03/Fast-4x4-Matrix-Inverse-with-SSE-SIMD-Explained.html
2981        impl<T> $Vec<T> {
2982            /// Shuffle elements from this vector, using `mask`.
2983            ///
2984            /// The relevant x86 intrinsic is `_mm_shuffle_ps(v, v, mask)`.
2985            ///
2986            /// ```
2987            /// # use vek::Vec4;
2988            /// let a = Vec4::<u32>::new(0,1,2,3);
2989            /// assert_eq!(a.shuffled((0,1,2,3)), Vec4::new(0,1,2,3));
2990            /// assert_eq!(a.shuffled((3,2,1,0)), Vec4::new(3,2,1,0));
2991            /// assert_eq!(a.shuffled((2,3,4,5)), Vec4::new(2,3,0,1));
2992            /// assert_eq!(a.shuffled(1), Vec4::new(1,1,1,1));
2993            /// assert_eq!(a.shuffled(1), Vec4::broadcast(1));
2994            /// ```
2995            pub fn shuffled<M: Into<ShuffleMask4>>(self, mask: M) -> Self where T: Copy {
2996                Self::shuffle_lo_hi(self, self, mask)
2997            }
2998            /// Moves the lower two elements of this vector to the upper two elements of the result.
2999            /// The lower two elements of this vector are passed through to the result.
3000            ///
3001            /// The relevant x86 intrinsic is `_mm_movelh_ps(v, v)`.
3002            ///
3003            /// ```
3004            /// # use vek::Vec4;
3005            /// let a = Vec4::<u32>::new(0,1,2,3);
3006            /// let b = Vec4::<u32>::new(0,1,0,1);
3007            /// assert_eq!(a.shuffled_0101(), b);
3008            /// ```
3009            pub fn shuffled_0101(self) -> Self where T: Copy {
3010                Self::shuffle_lo_hi_0101(self, self)
3011            }
3012            /// Moves the upper two elements of this vector to the lower two elements of the result.
3013            /// The upper two elements of this vector are passed through to the result.
3014            ///
3015            /// The relevant x86 intrinsic is `_mm_movehl_ps(v, v)`.
3016            ///
3017            /// ```
3018            /// # use vek::Vec4;
3019            /// let a = Vec4::<u32>::new(0,1,2,3);
3020            /// let b = Vec4::<u32>::new(2,3,2,3);
3021            /// assert_eq!(a.shuffled_2323(), b);
3022            /// ```
3023            pub fn shuffled_2323(self) -> Self where T: Copy {
3024                Self::shuffle_hi_lo_2323(self, self)
3025            }
3026            /// Shuffle elements from `lo`'s low part and `hi`'s high part using `mask`.
3027            ///
3028            /// To shuffle a single vector, you may pass it as the first two arguments,
3029            /// or use the `shuffled()` method.
3030            ///
3031            /// The relevant x86 intrinsic is `_mm_shuffle_ps(lo, hi, mask)`.
3032            ///
3033            /// ```
3034            /// # use vek::Vec4;
3035            /// let a = Vec4::<u32>::new(0,1,2,3);
3036            /// let b = Vec4::<u32>::new(4,5,6,7);
3037            /// assert_eq!(Vec4::shuffle_lo_hi(a, b, (0,1,2,3)), Vec4::new(0,1,6,7));
3038            /// assert_eq!(Vec4::shuffle_lo_hi(a, b, (3,2,1,0)), Vec4::new(3,2,5,4));
3039            /// ```
3040            pub fn shuffle_lo_hi<M: Into<ShuffleMask4>>(lo: Self, hi: Self, mask: M) -> Self where T: Copy {
3041                let (lo0, lo1, hi2, hi3) = mask.into().to_indices();
3042                Self::new(lo[lo0], lo[lo1], hi[hi2], hi[hi3])
3043            }
3044            /// Interleaves the lower two elements from `a` and `b`.
3045            ///
3046            /// The relevant x86 intrinsic is `_mm_unpacklo_ps(a, b)`.
3047            ///
3048            /// ```
3049            /// # use vek::Vec4;
3050            /// let a = Vec4::<u32>::new(0,1,2,3);
3051            /// let b = Vec4::<u32>::new(4,5,6,7);
3052            /// let c = Vec4::<u32>::new(0,4,1,5);
3053            /// assert_eq!(Vec4::interleave_0011(a, b), c);
3054            /// ```
3055            pub fn interleave_0011(a: Self, b: Self) -> Self {
3056                Self::new(a.$x, b.$x, a.$y, b.$y)
3057            }
3058            /// Interleaves the upper two elements from `a` and `b`.
3059            ///
3060            /// The relevant x86 intrinsic is `_mm_unpackhi_ps(a, b)`.
3061            ///
3062            /// ```
3063            /// # use vek::Vec4;
3064            /// let a = Vec4::<u32>::new(0,1,2,3);
3065            /// let b = Vec4::<u32>::new(4,5,6,7);
3066            /// let c = Vec4::<u32>::new(2,6,3,7);
3067            /// assert_eq!(Vec4::interleave_2233(a, b), c);
3068            /// ```
3069            pub fn interleave_2233(a: Self, b: Self) -> Self {
3070                Self::new(a.$z, b.$z, a.$w, b.$w)
3071            }
3072            /// Moves the lower two elements of `b` to the upper two elements of the result.
3073            /// The lower two elements of `a` are passed through to the result.
3074            ///
3075            /// The relevant x86 intrinsic is `_mm_movelh_ps(a, b)`.
3076            ///
3077            /// ```
3078            /// # use vek::Vec4;
3079            /// let a = Vec4::<u32>::new(0,1,2,3);
3080            /// let b = Vec4::<u32>::new(4,5,6,7);
3081            /// let c = Vec4::<u32>::new(0,1,4,5);
3082            /// assert_eq!(Vec4::shuffle_lo_hi_0101(a, b), c);
3083            /// ```
3084            pub fn shuffle_lo_hi_0101(a: Self, b: Self) -> Self {
3085                Self::new(a.$x, a.$y, b.$x, b.$y)
3086            }
3087            /// Moves the upper two elements of `b` to the lower two elements of the result.
3088            /// The upper two elements of `a` are passed through to the result.
3089            ///
3090            /// The relevant x86 intrinsic is `_mm_movehl_ps(a, b)`.
3091            ///
3092            /// ```
3093            /// # use vek::Vec4;
3094            /// let a = Vec4::<u32>::new(0,1,2,3);
3095            /// let b = Vec4::<u32>::new(4,5,6,7);
3096            /// let c = Vec4::<u32>::new(6,7,2,3);
3097            /// assert_eq!(Vec4::shuffle_hi_lo_2323(a, b), c);
3098            /// ```
3099            pub fn shuffle_hi_lo_2323(a: Self, b: Self) -> Self {
3100                Self::new(b.$z, b.$w, a.$z, a.$w)
3101            }
3102            /// Returns a copy of this vector with `v[1]` set to `v[0]` and `v[3]` set to `v[2]`.
3103            ///
3104            /// The relevant x86 intrinsic is `_mm_moveldup_ps(v)`.
3105            ///
3106            /// ```
3107            /// # use vek::Vec4;
3108            /// let a = Vec4::<u32>::new(0,1,2,3);
3109            /// let b = Vec4::<u32>::new(0,0,2,2);
3110            /// assert_eq!(a.shuffled_0022(), b);
3111            /// ```
3112            pub fn shuffled_0022(self) -> Self where T: Copy {
3113                Self::new(self.$x, self.$x, self.$z, self.$z)
3114            }
3115            /// Returns a copy of this vector with `v[0]` set to `v[1]` and `v[2]` set to `v[3]`.
3116            ///
3117            /// The relevant x86 intrinsic is `_mm_movehdup_ps(v)`.
3118            ///
3119            /// ```
3120            /// # use vek::Vec4;
3121            /// let a = Vec4::<u32>::new(0,1,2,3);
3122            /// let b = Vec4::<u32>::new(1,1,3,3);
3123            /// assert_eq!(a.shuffled_1133(), b);
3124            /// ```
3125            pub fn shuffled_1133(self) -> Self where T: Copy {
3126                Self::new(self.$y, self.$y, self.$w, self.$w)
3127            }
3128        }
3129    };
3130}
3131
3132macro_rules! vec_impl_mat2_via_vec4 {
3133    ($Vec:ident) => {
3134        // NOTE: Stolen from
3135        // https://lxjk.github.io/2017/09/03/Fast-4x4-Matrix-Inverse-with-SSE-SIMD-Explained.html#_appendix
3136        impl<T: Copy + Add<T,Output=T> + Mul<T,Output=T> + Sub<T,Output=T>> $Vec<T> {
3137            /// Performs 2x2 matrix multiplication, treating each `Vec4` as a row-major 2x2 matrix.
3138            ///
3139            /// ```
3140            /// # use vek::Vec4;
3141            /// let a = Vec4::new(
3142            ///     0,1,
3143            ///     2,3
3144            /// );
3145            /// let b = Vec4::new(
3146            ///     2,3,
3147            ///     6,11
3148            /// );
3149            /// assert_eq!(a.mat2_rows_mul(a), b)
3150            /// ```
3151            pub fn mat2_rows_mul(self, rhs: Self) -> Self {
3152                self * rhs.shuffled((0,3,0,3)) + self.shuffled((1,0,3,2)) * rhs.shuffled((2,1,2,1))
3153            }
3154            /// 2x2 row-major Matrix adjugate multiply (A#)*B
3155            pub fn mat2_rows_adj_mul(self, rhs: Self) -> Self {
3156                self.shuffled((3,3,0,0)) * rhs - self.shuffled((1,1,2,2)) * rhs.shuffled((2,3,0,1))
3157            }
3158            /// 2x2 row-major Matrix multiply adjugate A*(B#)
3159            pub fn mat2_rows_mul_adj(self, rhs: Self) -> Self {
3160                self * rhs.shuffled((3,0,3,0)) - self.shuffled((1,0,3,2)) * rhs.shuffled((2,1,2,1))
3161            }
3162            /// Performs 2x2 matrix multiplication, treating each `Vec4` as a column-major 2x2 matrix.
3163            ///
3164            /// ```
3165            /// # use vek::Vec4;
3166            /// let a = Vec4::new(
3167            ///     0,2,
3168            ///     1,3
3169            /// );
3170            /// let b = Vec4::new(
3171            ///     2,6,
3172            ///     3,11
3173            /// );
3174            /// assert_eq!(a.mat2_cols_mul(a), b)
3175            /// ```
3176            pub fn mat2_cols_mul(self, rhs: Self) -> Self {
3177                self * rhs.shuffled((0,0,3,3)) + self.shuffled((2,3,0,1)) * rhs.shuffled((1,1,2,2))
3178            }
3179            /// 2x2 column-major Matrix adjugate multiply (A#)*B
3180            pub fn mat2_cols_adj_mul(self, rhs: Self) -> Self {
3181                self.shuffled((3,0,3,0)) * rhs - self.shuffled((2,1,2,1)) * rhs.shuffled((1,0,3,2))
3182            }
3183            /// 2x2 column-major Matrix multiply adjugate A*(B#)
3184            pub fn mat2_cols_mul_adj(self, rhs: Self) -> Self {
3185                self * rhs.shuffled((3,3,0,0)) - self.shuffled((2,3,0,1)) * rhs.shuffled((1,1,2,2))
3186            }
3187        }
3188    };
3189}
3190
3191macro_rules! vec_impl_from_smaller_vec_and_scalar {
3192    ($Vec:ident, $SmallerVec:ident, ($($smaller_vec_get:ident)+)) => {
3193        impl<T> From<($SmallerVec<T>, T)> for $Vec<T> {
3194            fn from(t: ($SmallerVec<T>, T)) -> Self {
3195                Self::new($(t.0.$smaller_vec_get),+, t.1)
3196            }
3197        }
3198    };
3199}
3200
3201macro_rules! vec_impl_mint {
3202    ($Vec:ident, $mintVec:ident, ($($namedget:ident)+)) => {
3203        #[cfg(feature = "mint")]
3204        impl<T> From<mint::$mintVec<T>> for $Vec<T> {
3205            fn from(v: mint::$mintVec<T>) -> Self {
3206                Self { $($namedget : v.$namedget),+ }
3207            }
3208        }
3209
3210        #[cfg(feature = "mint")]
3211        impl<T> Into<mint::$mintVec<T>> for $Vec<T> {
3212            fn into(self) -> mint::$mintVec<T> {
3213                mint::$mintVec { $($namedget : self.$namedget),+ }
3214            }
3215        }
3216    };
3217}
3218
3219/// Calls `vec_impl_vec!{}` on each appropriate vector type.
3220macro_rules! vec_impl_all_vecs {
3221    ($c_or_simd:ident #[$repr_for_power_of_two_length:meta] $c_or_simd_non_power_of_two:ident #[$repr_for_non_power_of_two_length:meta] $repr_c_non_power_of_two:ident) => {
3222
3223        /// Vector type suited for 2D spatial coordinates.
3224        pub mod vec2 {
3225            use super::*;
3226            /// Vector type suited for 2D spatial coordinates.
3227            #[allow(missing_docs)]
3228            #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq/*, Ord, PartialOrd*/)]
3229            #[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
3230            #[$repr_for_power_of_two_length]
3231            pub struct Vec2<T> { pub x:T, pub y:T }
3232            vec_impl_vec!($c_or_simd repr_c struct Vec2   vec2      (2) ("({...}, {...})") ("") (x y) (x y) (0 1) (T,T));
3233            vec_impl_mint!(Vec2, Vector2, (x y));
3234            vec_impl_mint!(Vec2, Point2, (x y));
3235            vec_impl_spatial!(Vec2);
3236            vec_impl_spatial_2d!(Vec2);
3237
3238            impl<T> Vec2<T> {
3239                /// Returns a copy of this vector, with X and Y swapped.
3240                pub fn yx(self) -> Self {
3241                    let Self { x, y } = self;
3242                    Self { x: y, y: x }
3243                }
3244                /// Returns a copy of this vector, with a new X value.
3245                pub fn with_x(mut self, x: T) -> Self {
3246                    self.x = x;
3247                    self
3248                }
3249                /// Returns a copy of this vector, with a new Y value.
3250                pub fn with_y(mut self, y: T) -> Self {
3251                    self.y = y;
3252                    self
3253                }
3254                /// Add a Z component to this vector such that it becomes a Vec3.
3255                pub fn with_z(self, z: T) -> Vec3<T> {
3256                    Vec3::new(self.x, self.y, z)
3257                }
3258                /// Add a W component to this vector such that it becomes a Vec4.
3259                pub fn with_w(self, w: T) -> Vec4<T> where T: Zero {
3260                    Vec4::new(self.x, self.y, T::zero(), w)
3261                }
3262            }
3263
3264            impl<T> From<Vec3<T>> for Vec2<T> {
3265                fn from(v: Vec3<T>) -> Self {
3266                    Self::new(v.x, v.y)
3267                }
3268            }
3269            impl<T> From<Vec4<T>> for Vec2<T> {
3270                fn from(v: Vec4<T>) -> Self {
3271                    Self::new(v.x, v.y)
3272                }
3273            }
3274            impl<T> From<Extent2<T>> for Vec2<T> {
3275                fn from(v: Extent2<T>) -> Self {
3276                    Self::new(v.w, v.h)
3277                }
3278            }
3279        }
3280        pub use self::vec2::Vec2;
3281
3282        /// Vector type suited for 3D spatial coordinates.
3283        pub mod vec3 {
3284            use super::*;
3285            /// Vector type suited for 3D spatial coordinates.
3286            #[allow(missing_docs)]
3287            #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq/*, Ord, PartialOrd*/)]
3288            #[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
3289            #[$repr_for_non_power_of_two_length]
3290            pub struct Vec3<T> { pub x:T, pub y:T, pub z:T }
3291            vec_impl_vec!($c_or_simd_non_power_of_two $repr_c_non_power_of_two struct Vec3     vec3     (3) ("({...}, {...}, {...})") ("") (x y z) (x y z) (0 1 2) (T,T,T));
3292            vec_impl_from_smaller_vec_and_scalar!(Vec3, Vec2, (x y));
3293            vec_impl_mint!(Vec3, Vector3, (x y z));
3294            vec_impl_mint!(Vec3, Point3, (x y z));
3295            vec_impl_spatial!(Vec3);
3296            vec_impl_spatial_3d!(Vec3);
3297
3298            impl<T> Vec3<T> {
3299                /// Returns a copy of this vector, with X and Z swapped. This effectively reverses the order of the three elements.
3300                pub fn zyx(self) -> Self {
3301                    let Self { x, y, z } = self;
3302                    Self { x: z, y, z: x }
3303                }
3304                /// Same as Vec2::from(self), but shorter.
3305                pub fn xy(self) -> Vec2<T> {
3306                    self.into()
3307                }
3308                /// Returns a copy of this vector, with a new X value.
3309                pub fn with_x(mut self, x: T) -> Self {
3310                    self.x = x;
3311                    self
3312                }
3313                /// Returns a copy of this vector, with a new Y value.
3314                pub fn with_y(mut self, y: T) -> Self {
3315                    self.y = y;
3316                    self
3317                }
3318                /// Returns a copy of this vector, with a new Z value.
3319                pub fn with_z(mut self, z: T) -> Self {
3320                    self.z = z;
3321                    self
3322                }
3323                /// Add a W component to this vector such that it becomes a Vec4.
3324                pub fn with_w(self, w: T) -> Vec4<T> {
3325                    Vec4::new(self.x, self.y, self.z, w)
3326                }
3327            }
3328
3329            impl<T: Zero> From<Vec2<T>> for Vec3<T> {
3330                fn from(v: Vec2<T>) -> Self {
3331                    Self::new(v.x, v.y, T::zero())
3332                }
3333            }
3334            impl<T> From<Vec4<T>> for Vec3<T> {
3335                fn from(v: Vec4<T>) -> Self {
3336                    Self::new(v.x, v.y, v.z)
3337                }
3338            }
3339            impl<T> From<Extent3<T>> for Vec3<T> {
3340                fn from(v: Extent3<T>) -> Self {
3341                    Self::new(v.w, v.h, v.d)
3342                }
3343            }
3344            #[cfg(feature="rgb")]
3345            impl<T> From<Rgb<T>> for Vec3<T> {
3346                fn from(v: Rgb<T>) -> Self {
3347                    Self::new(v.r, v.g, v.b)
3348                }
3349            }
3350            #[cfg(feature="uvw")]
3351            impl<T> From<Uvw<T>> for Vec3<T> {
3352                fn from(v: Uvw<T>) -> Self {
3353                    Self::new(v.u, v.v, v.w)
3354                }
3355            }
3356        }
3357        pub use self::vec3::Vec3;
3358
3359        /// Vector type suited for homogeneous 3D spatial coordinates.
3360        pub mod vec4 {
3361            use super::*;
3362            /// Vector type suited for homogeneous 3D spatial coordinates.
3363            #[allow(missing_docs)]
3364            #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq/*, Ord, PartialOrd*/)]
3365            #[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
3366            #[$repr_for_power_of_two_length]
3367            pub struct Vec4<T> {
3368                pub x:T, pub y:T, pub z:T,
3369                /// In homogeneous 3D-space coordinates, `w` is often set to
3370                /// `1` for points, and `0` for directions.
3371                ///
3372                /// One reason behind this: with floating-point numbers,
3373                /// division by zero gives infinity (a direction is then
3374                /// a point stretching infinitely towards another).
3375                pub w: T
3376            }
3377            vec_impl_vec!($c_or_simd repr_c struct Vec4   vec4    (4) ("({...}, {...}, {...}, {...})") ("") (x y z w) (x y z w) (0 1 2 3) (T,T,T,T));
3378            vec_impl_from_smaller_vec_and_scalar!(Vec4, Vec3, (x y z));
3379            vec_impl_mint!(Vec4, Vector4, (x y z w));
3380            vec_impl_spatial!(Vec4);
3381            vec_impl_spatial_4d!(Vec4);
3382            vec_impl_shuffle_4d!(Vec4 (x y z w));
3383            vec_impl_mat2_via_vec4!(Vec4);
3384
3385            impl<T> Vec4<T> {
3386                /// Returns a copy of this vector, with W placed first and XYZ shifted to the right. This may be useful because some quaternion implementations store their elements in WXYZ order.
3387                pub fn wxyz(self) -> Self {
3388                    let Self { x, y, z, w } = self;
3389                    Self { x: w, y: x, z: y, w: z }
3390                }
3391                /// Returns a copy of this vector, with elements reversed.
3392                pub fn wzyx(self) -> Self {
3393                    let Self { x, y, z, w } = self;
3394                    Self { x: w, y: z, z: y, w: x }
3395                }
3396                /// Returns a copy of this vector, with X and Z swapped. This effectively reverses the order of the first three elements.
3397                pub fn zyxw(self) -> Self {
3398                    let Self { x, y, z, w } = self;
3399                    Self { x: z, y, z: x, w }
3400                }
3401                /// Same as Vec3::from(self), but shorter.
3402                pub fn xyz(self) -> Vec3<T> {
3403                    self.into()
3404                }
3405                /// Same as Vec2::from(self), but shorter.
3406                pub fn xy(self) -> Vec2<T> {
3407                    self.into()
3408                }
3409
3410                /// Returns a copy of this vector, with a new X value.
3411                pub fn with_x(mut self, x: T) -> Self {
3412                    self.x = x;
3413                    self
3414                }
3415                /// Returns a copy of this vector, with a new Y value.
3416                pub fn with_y(mut self, y: T) -> Self {
3417                    self.y = y;
3418                    self
3419                }
3420                /// Returns a copy of this vector, with a new Z value.
3421                pub fn with_z(mut self, z: T) -> Self {
3422                    self.z = z;
3423                    self
3424                }
3425                /// Returns a copy of this vector, with a new W value.
3426                pub fn with_w(mut self, w: T) -> Self {
3427                    self.w = w;
3428                    self
3429                }
3430            }
3431
3432            impl<T: Zero> From<Vec3<T>> for Vec4<T> {
3433                fn from(v: Vec3<T>) -> Self {
3434                    Self::new(v.x, v.y, v.z, T::zero())
3435                }
3436            }
3437            impl<T: Zero> From<Vec2<T>> for Vec4<T> {
3438                fn from(v: Vec2<T>) -> Self {
3439                    Self::new(v.x, v.y, T::zero(), T::zero())
3440                }
3441            }
3442            #[cfg(feature="rgba")]
3443            impl<T> From<Rgba<T>> for Vec4<T> {
3444                fn from(v: Rgba<T>) -> Self {
3445                    Self::new(v.r, v.g, v.b, v.a)
3446                }
3447            }
3448
3449        }
3450        pub use self::vec4::Vec4;
3451
3452        #[cfg(feature="vec8")]
3453        /// An eight-components generic vector type.
3454        pub mod vec8 {
3455            use super::*;
3456            /// An eight-components generic vector type.
3457            ///
3458            /// This type exists mostly for crunching arrays of values.
3459            /// For instance, on AVX2-enabled x86 CPUs, a `Vec8<i32>` makes sense.
3460            /// Otherwise, LLVM lowers it to a fixed-sized array of whichever "best" SIMD vector type is available.
3461            ///
3462            /// There's a lot of related intrinsics that are not provided as associated functions.
3463            /// If you find yourself needing them, use other crates such as `llvmint` or `x86intrin`.
3464            #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq/*, Ord, PartialOrd*/)]
3465            #[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
3466            #[$repr_for_power_of_two_length]
3467            pub struct Vec8<T>(pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T);
3468            vec_impl_vec!($c_or_simd repr_c tuple Vec8     vec8   (8) ("({...}, {...}, {...}, {...}, {...}, {...}, {...}, {...})") ("") (0 1 2 3 4 5 6 7) (m0 m1 m2 m3 m4 m5 m6 m7) (0 1 2 3 4 5 6 7) (T,T,T,T,T,T,T,T));
3469            vec_impl_spatial!(Vec8);
3470        }
3471        #[cfg(feature="vec8")]
3472        pub use self::vec8::Vec8;
3473
3474        #[cfg(feature="vec16")]
3475        /// A sixteen-components generic vector type.
3476        pub mod vec16 {
3477            use super::*;
3478            /// A sixteen-components generic vector type.
3479            ///
3480            /// This type exists mostly for crunching arrays of values.
3481            /// For instance, on AVX2-enabled x86 CPUs, a `Vec16<i16>` makes sense.
3482            /// Otherwise, LLVM lowers it to a fixed-sized array of whichever "best" SIMD vector type is available.
3483            ///
3484            /// There's a lot of related intrinsics that are not provided as associated functions.
3485            /// If you find yourself needing them, use other crates such as `llvmint` or `x86intrin`.
3486            #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq/*, Ord, PartialOrd*/)]
3487            #[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
3488            #[$repr_for_power_of_two_length]
3489            pub struct Vec16<T>(pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T);
3490            vec_impl_vec!($c_or_simd repr_c tuple Vec16   vec16   (16) ("({...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...})") ("") (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15) (m0 m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 m12 m13 m14 m15) (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15) (T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T));
3491            vec_impl_spatial!(Vec16);
3492        }
3493        #[cfg(feature="vec16")]
3494        pub use self::vec16::Vec16;
3495
3496        #[cfg(feature="vec32")]
3497        /// A thirty-two-components generic vector type.
3498        pub mod vec32 {
3499            use super::*;
3500            /// A thirty-two-components generic vector type.
3501            ///
3502            /// This type exists mostly for crunching arrays of values.
3503            /// For instance, on AVX512-enabled x86 CPUs, a `Vec32<i16>` makes sense.
3504            /// Otherwise, LLVM lowers it to a fixed-sized array of whichever "best" SIMD vector type is available.
3505            ///
3506            /// There's a lot of related intrinsics that are not provided as associated functions.
3507            /// If you find yourself needing them, use other crates such as `llvmint` or `x86intrin`.
3508            #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq/*, Ord, PartialOrd*/)]
3509            #[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
3510            #[$repr_for_power_of_two_length]
3511            pub struct Vec32<T>(pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T);
3512            vec_impl_vec!($c_or_simd repr_c tuple Vec32   vec32   (32) ("({...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...})") ("") (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31) (m0 m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 m12 m13 m14 m15 m16 m17 m18 m19 m20 m21 m22 m23 m24 m25 m26 m27 m28 m29 m30 m31) (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31) (T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T));
3513            vec_impl_spatial!(Vec32);
3514        }
3515        #[cfg(feature="vec32")]
3516        pub use self::vec32::Vec32;
3517
3518
3519        #[cfg(feature="vec64")]
3520        /// A sixty-four-components generic vector type.
3521        pub mod vec64 {
3522            use super::*;
3523            /// A sixty-four-components generic vector type.
3524            ///
3525            /// This type exists mostly for crunching arrays of values.
3526            /// For instance, on AVX512-enabled x86 CPUs, a `Vec64<i8>` makes sense.
3527            /// Otherwise, LLVM is able to process it as a fixed-sized array of whichever "best" SIMD vector type available.
3528            ///
3529            /// There's a lot of related intrinsics that are not provided as associated functions.
3530            /// If you find yourself needing them, use other crates such as `llvmint` or `x86intrin`.
3531            #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq/*, Ord, PartialOrd*/)]
3532            #[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
3533            #[$repr_for_power_of_two_length]
3534            pub struct Vec64<T>(pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T);
3535            vec_impl_vec!($c_or_simd repr_c tuple Vec64   vec64   (64) ("({...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...})") ("") (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63) (m0 m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 m12 m13 m14 m15 m16 m17 m18 m19 m20 m21 m22 m23 m24 m25 m26 m27 m28 m29 m30 m31 m32 m33 m34 m35 m36 m37 m38 m39 m40 m41 m42 m43 m44 m45 m46 m47 m48 m49 m50 m51 m52 m53 m54 m55 m56 m57 m58 m59 m60 m61 m62 m63) (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63) (T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T));
3536            vec_impl_spatial!(Vec64);
3537        }
3538        #[cfg(feature="vec64")]
3539        pub use self::vec64::Vec64;
3540
3541        /// Vector type suited for 3D extents (width, height and depth).
3542        pub mod extent3 {
3543            use super::*;
3544            /// Vector type suited for 3D extents (width, height and depth).
3545            ///
3546            /// There is no `Unsigned` trait bound because it is not practical,
3547            /// since we sometimes want to be
3548            /// able to express extents as floating-point numbers, for instance.
3549            ///
3550            /// If you want to assert unsignedness at runtime, you can use the
3551            /// `is_all_positive()` or `is_any_negative()` methods.
3552            #[allow(missing_docs)]
3553            #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq/*, Ord, PartialOrd*/)]
3554            #[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
3555            #[$repr_for_non_power_of_two_length]
3556            pub struct Extent3<T> { pub w:T, pub h:T, pub d:T }
3557            vec_impl_vec!($c_or_simd_non_power_of_two $repr_c_non_power_of_two struct Extent3 extent3 (3) ("({...}, {...}, {...})") ("") (w h d) (w h d) (0 1 2) (T,T,T));
3558            vec_impl_from_smaller_vec_and_scalar!(Extent3, Extent2, (w h));
3559            vec_impl_spatial!(Extent3);
3560
3561            impl<T> From<Vec3<T>> for Extent3<T> {
3562                fn from(v: Vec3<T>) -> Self {
3563                    Self::new(v.x, v.y, v.z)
3564                }
3565            }
3566        }
3567        pub use self::extent3::Extent3;
3568
3569        /// Vector type suited for 2D extents (width and height).
3570        pub mod extent2 {
3571            use super::*;
3572            /// Vector type suited for 2D extents (width and height).
3573            ///
3574            /// There is no `Unsigned` trait bound because it is not practical,
3575            /// since we sometimes want to be
3576            /// able to express extents as floating-point numbers, for instance.
3577            ///
3578            /// If you want to assert unsignedness at runtime, you can use the
3579            /// `is_all_positive()` or `is_any_negative()` methods.
3580            #[allow(missing_docs)]
3581            #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq/*, Ord, PartialOrd*/)]
3582            #[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
3583            #[$repr_for_power_of_two_length]
3584            pub struct Extent2<T> { pub w:T, pub h:T }
3585            vec_impl_vec!($c_or_simd repr_c struct Extent2 extent2 (2) ("({...}, {...})") ("") (w h) (w h) (0 1) (T,T));
3586            vec_impl_spatial!(Extent2);
3587
3588            impl<T> From<Vec2<T>> for Extent2<T> {
3589                fn from(v: Vec2<T>) -> Self {
3590                    Self::new(v.x, v.y)
3591                }
3592            }
3593        }
3594        pub use self::extent2::Extent2;
3595
3596        #[cfg(feature="rgba")]
3597        /// Vector type suited for RGBA color data.
3598        pub mod rgba {
3599            use super::*;
3600            /// Vector type suited for RGBA color data.
3601            ///
3602            /// There is no trait bound on `ColorComponent`, but if `T` doesn't implement it, you'll
3603            /// miss some goodies.
3604            #[allow(missing_docs)]
3605            #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq/*, Ord, PartialOrd*/)]
3606            #[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
3607            #[$repr_for_power_of_two_length]
3608            pub struct Rgba<T> { pub r:T, pub g:T, pub b:T, pub a:T }
3609            vec_impl_vec!($c_or_simd repr_c struct Rgba   rgba    (4) ("rgba({...}, {...}, {...}, {...})") ("rgba") (r g b a) (r g b a) (0 1 2 3) (T,T,T,T));
3610            vec_impl_color_rgba!{Rgba}
3611            vec_impl_shuffle_4d!(Rgba (r g b a));
3612
3613            #[cfg(feature="rgb")]
3614            vec_impl_from_smaller_vec_and_scalar!(Rgba, Rgb, (r g b));
3615
3616            #[cfg(feature="rgb")]
3617            impl<T> Rgba<T> {
3618                /// Same as Rgb::from(self), but more concise.
3619                pub fn rgb(self) -> Rgb<T> {
3620                    self.into()
3621                }
3622            }
3623            impl<T> From<Vec4<T>> for Rgba<T> {
3624                fn from(v: Vec4<T>) -> Self {
3625                    Self::new(v.x, v.y, v.z, v.w)
3626                }
3627            }
3628            #[cfg(feature="rgb")]
3629            impl<T: ColorComponent> From<Rgb<T>> for Rgba<T> {
3630                fn from(v: Rgb<T>) -> Self {
3631                    Self::from_opaque(v)
3632                }
3633            }
3634        }
3635        #[cfg(feature="rgba")]
3636        pub use self::rgba::Rgba;
3637
3638        #[cfg(feature="rgb")]
3639        /// Vector type suited for RGB color data.
3640        pub mod rgb {
3641            use super::*;
3642            /// Vector type suited for RGB color data.
3643            ///
3644            /// There is no trait bound on `ColorComponent`, but if `T` doesn't implement it, you'll
3645            /// miss some goodies.
3646            #[allow(missing_docs)]
3647            #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq/*, Ord, PartialOrd*/)]
3648            #[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
3649            #[$repr_for_non_power_of_two_length]
3650            pub struct Rgb<T> { pub r:T, pub g:T, pub b:T }
3651            vec_impl_vec!($c_or_simd_non_power_of_two $repr_c_non_power_of_two struct Rgb     rgb     (3) ("rgb({...}, {...}, {...})") ("rgb") (r g b) (r g b) (0 1 2) (T,T,T));
3652            vec_impl_color_rgb!{Rgb}
3653
3654            impl<T> From<Vec3<T>> for Rgb<T> {
3655                fn from(v: Vec3<T>) -> Self {
3656                    Self::new(v.x, v.y, v.z)
3657                }
3658            }
3659            #[cfg(feature="rgba")]
3660            impl<T> From<Rgba<T>> for Rgb<T> {
3661                fn from(v: Rgba<T>) -> Self {
3662                    Self::new(v.r, v.g, v.b)
3663                }
3664            }
3665        }
3666        #[cfg(feature="rgb")]
3667        pub use self::rgb::Rgb;
3668
3669        #[cfg(feature="uvw")]
3670        /// Vector type suited for 3D texture coordinates.
3671        pub mod uvw {
3672            use super::*;
3673            /// Vector type suited for 3D texture coordinates.
3674            #[allow(missing_docs)]
3675            #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq/*, Ord, PartialOrd*/)]
3676            #[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
3677            #[$repr_for_non_power_of_two_length]
3678            pub struct Uvw<T> { pub u:T, pub v:T, pub w:T }
3679            vec_impl_vec!($c_or_simd_non_power_of_two $repr_c_non_power_of_two struct Uvw     uvw     (3) ("({...}, {...}, {...})") ("") (u v w) (u v w) (0 1 2) (T,T,T));
3680
3681            #[cfg(feature="uv")]
3682            vec_impl_from_smaller_vec_and_scalar!(Uvw, Uv, (u v));
3683
3684            impl<T> From<Vec3<T>> for Uvw<T> {
3685                fn from(v: Vec3<T>) -> Self {
3686                    Self::new(v.x, v.y, v.z)
3687                }
3688            }
3689        }
3690        #[cfg(feature="uvw")]
3691        pub use self::uvw::Uvw;
3692
3693        #[cfg(feature="uv")]
3694        /// Vector type suited for 2D texture coordinates.
3695        pub mod uv {
3696            use super::*;
3697            /// Vector type suited for 2D texture coordinates.
3698            #[allow(missing_docs)]
3699            #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq/*, Ord, PartialOrd*/)]
3700            #[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
3701            #[$repr_for_power_of_two_length]
3702            pub struct Uv<T> { pub u:T, pub v:T }
3703            vec_impl_vec!($c_or_simd repr_c struct Uv   uv      (2) ("({...}, {...})") ("") (u v) (u v) (0 1) (T,T));
3704
3705            impl<T> From<Vec2<T>> for Uv<T> {
3706                fn from(v: Vec2<T>) -> Self {
3707                    Self::new(v.x, v.y)
3708                }
3709            }
3710        }
3711        #[cfg(feature="uv")]
3712        pub use self::uv::Uv;
3713    }
3714}
3715
3716pub mod repr_c {
3717    //! Vector types which are marked `#[repr(C)]`.
3718    //!
3719    //! See also the `repr_simd` neighbour module, which is available on Nightly
3720    //! with the `repr_simd` feature enabled.
3721
3722    use super::*;
3723    vec_impl_all_vecs!{c #[repr(C)] c #[repr(C)] repr_c}
3724}
3725
3726#[cfg(all(nightly, feature="repr_simd"))]
3727pub mod repr_simd {
3728    //! Vector types which are marked `#[repr(simd)]`.
3729
3730    use super::*;
3731    vec_impl_all_vecs!{simd #[repr(simd)] c #[repr(C)] repr_simd}
3732}
3733
3734pub use self::repr_c::*;
3735
3736#[cfg(test)]
3737mod tests {
3738    #[cfg(feature = "az")]
3739    #[test]
3740    fn test_az() {
3741        let err = crate::Vec2::new(u16::MAX as u32 + 3, 21);
3742        let ok = crate::Vec2::new(0, u16::MAX as u32);
3743        assert!(err.checked_as::<u16>().is_none());
3744        assert!(ok.checked_as::<u16>().is_some());
3745        assert_eq!(err.wrapping_as::<u16>(), crate::Vec2::new(2, 21));
3746        assert_eq!(err.saturating_as::<u16>(), crate::Vec2::new(u16::MAX, 21));
3747        assert_eq!(err.overflowing_as::<u16>(), (err.wrapping_as(), true));
3748        assert_eq!(ok.overflowing_as::<u16>(), (ok.unwrapped_as(), false));
3749    }
3750    macro_rules! test_vec_t {
3751        (repr_c $Vec:ident<$T:ident>) => {
3752
3753            test_vec_t!{common $Vec<$T>}
3754
3755            use $crate::vtest::Rc;
3756
3757            #[test]
3758            fn from_rc_array() {
3759                let v: $Vec<Rc<i32>> = Default::default();
3760                let mut a = v.into_array();
3761                assert_eq!(Rc::strong_count(&a[0]), 1);
3762                *Rc::make_mut(&mut a[0]) = 2; // Try to write. If there's a double free, this is supposed to crash.
3763                let mut v = $Vec::from(a);
3764                assert_eq!(Rc::strong_count(&v[0]), 1);
3765                *Rc::make_mut(&mut v[0]) = 1; // Try to write. If there's a double free, this is supposed to crash.
3766            }
3767            #[test]
3768            fn vec_rc_into_iter() {
3769                let v: $Vec<Rc<i32>> = Default::default();
3770                let mut rc = v.into_iter().next().unwrap();
3771                assert_eq!(Rc::strong_count(&rc), 1);
3772                *Rc::make_mut(&mut rc) = 1; // Try to write. If there's a double free, this is supposed to crash.
3773            }
3774        };
3775        (repr_simd $Vec:ident<$T:ident>) => {
3776            test_vec_t!{common $Vec<$T>}
3777        };
3778        (common $Vec:ident<$T:ident>) => {
3779            #[test] fn iterator_api() {
3780                let v = $Vec::<i32>::default();
3781                let mut v: $Vec<i32> = (0..).into_iter().take(v.elem_count()).collect();
3782                for _ in &mut v {}
3783                for _ in &v {}
3784                for _ in v {}
3785                let mut v = $Vec::<i32>::default();
3786                let _ = v.as_ptr();
3787                let _ = v.as_mut_ptr();
3788                let _ = v.iter_mut();
3789                let _ = v.iter();
3790                let _ = v.into_iter();
3791                let mut v = $Vec::<i32>::default();
3792                let _ = v.iter_mut().rev();
3793                let _ = v.iter().rev();
3794                let _ = v.into_iter().rev();
3795                let mut v = $Vec::<i32>::default();
3796                let _ = v[0];
3797                v[0] = 0;
3798                let _ = v.get(0);
3799                let _ = v.get_mut(0);
3800                unsafe {
3801                    let _ = v.get_unchecked(0);
3802                    let _ = v.get_unchecked_mut(0);
3803                }
3804            }
3805        };
3806        (repr_simd_except_bool $Vec:ident<$T:ident>) => {
3807            #[test] fn is_actually_packed() {
3808                let v = $Vec::<$T>::iota();
3809                let a = v.clone().into_array();
3810                assert_eq!(v.as_slice(), &a);
3811            }
3812        };
3813        (repr_c_except_bool $Vec:ident<$T:ident>) => {
3814            #[test] fn is_actually_packed() {
3815                let v = $Vec::<$T>::iota();
3816                let a = v.clone().into_array();
3817                assert_eq!(v.as_slice(), &a);
3818            }
3819
3820            #[test] fn is_actually_packed_refcell() {
3821                let v = $Vec::<$T>::iota().map(::std::cell::RefCell::new);
3822                let a = v.clone().into_array();
3823                assert_eq!(v.as_slice(), &a);
3824            }
3825
3826            #[test] fn commutative() {
3827                let v = $Vec::from(5 as $T);
3828                assert_eq!((2 as $T) * v, v * (2 as $T));
3829                assert_eq!((2 as $T) + v, v + (2 as $T));
3830            }
3831        };
3832        (repr_simd_padding $Vec:ident<$T:ident>) => {
3833            // This test aims to prove that types in the `repr_simd` modules have no padding/uninit bytes, which is a requirement for implementing bytemuck's Pod trait.
3834            // In the past, `#[repr(simd)] Vec3<T>` had that issue as the compiler treated it as an aligned Vec4 in memory, but since some time, the compiler stopped supporting non-power-of-two SIMD types, so we were forced to write them as `#[repr(C)]`, which means that now they don't have any padding, but they're also not true SIMD types, which is fine : users should use Vec4 instead if they want SIMD.
3835            #[test]
3836            fn test_simd_padding() {
3837                let count = $Vec::<$T>::ELEM_COUNT;
3838                let elem_size = std::mem::size_of::<$T>();
3839                assert_eq!(std::mem::size_of::<$Vec<$T>>(), count * elem_size);
3840            }
3841        };
3842    }
3843    macro_rules! for_each_type {
3844        ($vec:ident $Vec:ident $($T:ident)+) => {
3845            mod $vec {
3846                mod repr_c {
3847                    use $crate::vec::repr_c::$Vec;
3848                    $(mod $T {
3849                        use super::$Vec;
3850                        test_vec_t!{repr_c $Vec<$T>}
3851                        test_vec_t!{repr_c_except_bool $Vec<$T>}
3852                    })+
3853                    mod bool {
3854                        use super::$Vec;
3855                        test_vec_t!{repr_c $Vec<bool>}
3856                    }
3857                }
3858                #[cfg(all(nightly, feature="repr_simd"))]
3859                mod repr_simd {
3860                    $(mod $T {
3861                        use $crate::vec::repr_simd::$Vec;
3862                        test_vec_t!{repr_simd $Vec<$T>}
3863                        test_vec_t!{repr_simd_except_bool $Vec<$T>}
3864                        test_vec_t!{repr_simd_padding $Vec<$T>}
3865                    })+
3866                    mod bool {
3867                        use $crate::vec::repr_simd::$Vec;
3868                        test_vec_t!{repr_simd $Vec<bool>}
3869                    }
3870                }
3871            }
3872        };
3873    }
3874    // Vertical editing helps here :)
3875    /*#[cfg(feature="vec2")]*/   for_each_type!{vec2    Vec2    i8 u8 i16 u16 i32 u32 i64 u64 f32 f64}
3876    /*#[cfg(feature="vec3")]*/   for_each_type!{vec3    Vec3    i8 u8 i16 u16 i32 u32 i64 u64 f32 f64}
3877    /*#[cfg(feature="vec4")]*/   for_each_type!{vec4    Vec4    i8 u8 i16 u16 i32 u32 i64 u64 f32 f64}
3878    #[cfg(feature="vec8")]       for_each_type!{vec8    Vec8    i8 u8 i16 u16 i32 u32 i64 u64 f32 f64}
3879    #[cfg(feature="vec16")]      for_each_type!{vec16   Vec16   i8 u8 i16 u16 i32 u32 i64 u64 f32 f64}
3880    #[cfg(feature="vec32")]      for_each_type!{vec32   Vec32   i8 u8 i16 u16 i32 u32 i64 u64 f32 f64}
3881    // NOTE: Don't test these, because [T; 64] implements no traits and it's a pain
3882    //#[cfg(feature="vec64")]      for_each_type!{vec64   Vec64   i8 u8 i16 u16 i32 u32 i64 u64 f32 f64}
3883    #[cfg(feature="rgba")]       for_each_type!{rgba    Rgba    i8 u8 i16 u16 i32 u32 i64 u64 f32 f64}
3884    #[cfg(feature="rgb")]        for_each_type!{rgb     Rgb     i8 u8 i16 u16 i32 u32 i64 u64 f32 f64}
3885    /*#[cfg(feature="extent3")]*/for_each_type!{extent3 Extent3 i8 u8 i16 u16 i32 u32 i64 u64 f32 f64}
3886    /*#[cfg(feature="extent2")]*/for_each_type!{extent2 Extent2 i8 u8 i16 u16 i32 u32 i64 u64 f32 f64}
3887    #[cfg(feature="uv")]         for_each_type!{uv      Uv      i8 u8 i16 u16 i32 u32 i64 u64 f32 f64}
3888    #[cfg(feature="uvw")]        for_each_type!{uvw     Uvw     i8 u8 i16 u16 i32 u32 i64 u64 f32 f64}
3889}