1use 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, }; use 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
26macro_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
50macro_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
57macro_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
67macro_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 $(#[$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 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 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 ($c_or_simd:ident, commutative impl $Op:ident for $Vec:ident { $op:tt, $simd_op:ident } ($($get:tt)+)) => {
169 vec_impl_binop!($c_or_simd, impl $Op for $Vec { $op, $simd_op } ($($get)+));
171
172 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 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 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 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 }
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 #[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 #[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
332macro_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 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 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 impl<T> $Vec<T> {
405 pub fn into_repr_c(self) -> CVec<T> {
407 self.into()
408 }
409 }
410 impl<T> CVec<T> {
411 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 #[doc=$fmt]
422 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 #[inline]
457 pub const fn broadcast(val: T) -> Self where T: Copy {
458 Self::new($({let $namedget = val; $namedget}),+)
459 }
460
461 #[inline]
470 pub fn zero() -> Self where T: Zero {
471 Self::new($({let $namedget = T::zero(); $namedget}),+)
472 }
473
474 #[inline]
483 pub fn one() -> Self where T: One {
484 Self::new($({let $namedget = T::one(); $namedget}),+)
485 }
486
487 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 pub const fn elem_count(&self) -> usize {
517 $dim
518 }
519 pub const ELEM_COUNT: usize = $dim;
521
522 pub fn into_tuple(self) -> $Tuple {
524 ($(self.$get),+)
525 }
526 pub fn into_array(self) -> [T; $dim] {
528 [$(self.$get, )+]
529 }
530 #[inline]
534 fn as_ptr_priv(&self) -> *const T {
535 self as *const _ as *const T
536 }
537 #[inline]
539 fn as_mut_ptr_priv(&mut self) -> *mut T {
540 self as *mut _ as *mut T
541 }
542
543 #[inline]
545 pub fn as_slice(&self) -> &[T] {
546 unsafe {
547 slice::from_raw_parts(self.as_ptr_priv(), $dim)
548 }
549 }
550 #[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 pub fn from_slice(slice: &[T]) -> Self where T: Default + Copy {
561 Self::from_iter(slice.into_iter().cloned())
562 }
563
564 #[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 #[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 #[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 #[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 #[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 #[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 pub fn zip<S>(self, other: $Vec<S>) -> $Vec<(T, S)> {
666 self.map2(other, |a, b| (a, b))
667 }
668 #[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 pub fn numcast<D>(self) -> Option<$Vec<D>> where T: NumCast, D: NumCast {
706 Some($Vec::new($(match D::from(self.$get) {
708 Some(x) => x,
709 None => return None,
710 }),+))
711 }
712
713 #[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 #[inline]
747 pub fn is_any_negative(&self) -> bool where T: Signed {
748 reduce_binop!(||, $(self.$get.is_negative()),+)
749 }
750
751 #[inline]
753 pub fn are_all_positive(&self) -> bool where T: Signed {
754 reduce_binop!(&&, $(self.$get.is_positive()),+)
755 }
756
757 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline]
1020 pub fn rsqrt(self) -> Self where T: Real {
1021 self.sqrt().recip()
1022 }
1023 #[inline]
1034 pub fn recip(self) -> Self where T: Real {
1035 Self::new($(self.$get.recip()),+)
1036 }
1037 #[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 #[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 #[inline]
1073 pub fn round(self) -> Self where T: Real {
1074 Self::new($(self.$get.round()),+)
1075 }
1076
1077 #[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 , $c_or_simd, $Vec, partial_cmpeq, partial_cmpeq_simd, simd_eq, ==, PartialEq, ($($get)+)
1106 }
1107
1108 vec_impl_cmp!{
1109 , $c_or_simd, $Vec, partial_cmpne, partial_cmpne_simd, simd_ne, !=, PartialEq, ($($get)+)
1121 }
1122
1123 vec_impl_cmp!{
1124 , $c_or_simd, $Vec, partial_cmpge, partial_cmpge_simd, simd_ge, >=, PartialOrd, ($($get)+)
1136 }
1137
1138 vec_impl_cmp!{
1139 , $c_or_simd, $Vec, partial_cmpgt, partial_cmpgt_simd, simd_gt, >, PartialOrd, ($($get)+)
1151 }
1152
1153 vec_impl_cmp!{
1154 , $c_or_simd, $Vec, partial_cmple, partial_cmple_simd, simd_le, <=, PartialOrd, ($($get)+)
1166 }
1167
1168 vec_impl_cmp!{
1169 , $c_or_simd, $Vec, partial_cmplt, partial_cmplt_simd, simd_lt, <, PartialOrd, ($($get)+)
1181 }
1182
1183 vec_impl_cmp!{
1184 , $c_or_simd, $Vec, cmpeq, cmpeq_simd, simd_eq, ==, Eq, ($($get)+)
1196 }
1197
1198 vec_impl_cmp!{
1199 , $c_or_simd, $Vec, cmpne, cmpne_simd, simd_ne, !=, Eq, ($($get)+)
1211 }
1212
1213 vec_impl_cmp!{
1214 , $c_or_simd, $Vec, cmpge, cmpge_simd, simd_ge, >=, Ord, ($($get)+)
1226 }
1227
1228 vec_impl_cmp!{
1229 , $c_or_simd, $Vec, cmpgt, cmpgt_simd, simd_gt, >, Ord, ($($get)+)
1241 }
1242
1243 vec_impl_cmp!{
1244 , $c_or_simd, $Vec, cmple, cmple_simd, simd_le, <=, Ord, ($($get)+)
1256 }
1257
1258 vec_impl_cmp!{
1259 , $c_or_simd, $Vec, cmplt, cmplt_simd, simd_lt, <, Ord, ($($get)+)
1271 }
1272
1273 #[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 #[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 #[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 #[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 #[cfg(feature = "az")]
1313 impl<T> $Vec<T> {
1314 pub fn az<U>(self) -> $Vec<U> where T: az::Cast<U> {
1320 az::Cast::cast(self)
1321 }
1322 pub fn checked_as<U>(self) -> Option<$Vec<U>> where T: az::CheckedCast<U> {
1324 az::CheckedCast::checked_cast(self)
1325 }
1326 pub fn saturating_as<U>(self) -> $Vec<U> where T: az::SaturatingCast<U> {
1328 az::SaturatingCast::saturating_cast(self)
1329 }
1330 pub fn wrapping_as<U>(self) -> $Vec<U> where T: az::WrappingCast<U> {
1335 az::WrappingCast::wrapping_cast(self)
1336 }
1337 pub fn overflowing_as<U>(self) -> ($Vec<U>, bool) where T: az::OverflowingCast<U> {
1343 az::OverflowingCast::overflowing_cast(self)
1344 }
1345 pub fn unwrapped_as<U>(self) -> $Vec<U> where T: az::UnwrappedCast<U> {
1347 az::UnwrappedCast::unwrapped_cast(self)
1348 }
1349 }
1350
1351 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 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 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 }
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 #[inline]
1655 #[allow(dead_code)] fn into_native_simd_integer_vector(self) -> $Vec<u32> {
1657 $Vec::new($(self.$get as _),+)
1658 }
1659 #[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 #[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 #[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 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 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 #[derive(Debug, Hash, PartialEq, Eq)]
1810 pub struct IntoIter<T> {
1811 vector: CVec<ManuallyDrop<T>>,
1813 start: usize,
1814 end: usize,
1815 }
1816
1817 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 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 impl<T: Copy> From<T> for $Vec<T> {
1955 #[inline]
1956 fn from(val: T) -> Self {
1957 Self::broadcast(val)
1958 }
1959 }
1960
1961 #[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 }
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 #[inline]
2026 pub fn dot(self, v: Self) -> T where T: Add<T, Output=T> + Mul<Output=T> {
2027 (self * v).sum()
2028 }
2029 #[inline]
2032 pub fn magnitude_squared(self) -> T where T: Copy + Add<T, Output=T> + Mul<Output=T> {
2033 self.dot(self)
2034 }
2035 #[inline]
2037 pub fn magnitude(self) -> T where T: Add<T, Output=T> + Real {
2038 self.magnitude_squared().sqrt()
2039 }
2040 #[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 #[inline]
2048 pub fn distance(self, v: Self) -> T where T: Add<T, Output=T> + Real {
2049 (self - v).magnitude()
2050 }
2051 #[inline]
2053 pub fn normalized(self) -> Self where T: Add<T, Output=T> + Real {
2054 self / self.magnitude()
2055 }
2056 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 #[inline]
2071 pub fn normalize(&mut self) where T: Add<T, Output=T> + Real {
2072 *self = self.normalized();
2073 }
2074 #[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 #[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 #[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 #[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 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 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 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 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 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 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 #[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 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 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 #[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 #[inline]
2232 pub fn rotate_z(&mut self, angle_radians: T) where T: Real {
2233 *self = self.rotated_z(angle_radians);
2234 }
2235 pub fn unit_x () -> Self where T: Zero + One { Self::new(T::one(), T::zero()) }
2237 pub fn unit_y () -> Self where T: Zero + One { Self::new(T::zero(), T::one()) }
2239 #[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 #[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 #[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 #[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 pub fn new_point_2d(x: T, y: T) -> Self where T: One {
2265 Self::new(x, y, T::one())
2266 }
2267 pub fn new_direction_2d(x: T, y: T) -> Self where T: Zero {
2269 Self::new(x, y, T::zero())
2270 }
2271 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 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 #[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 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 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 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 pub fn unit_x () -> Self where T: Zero + One { Self::new(T::one(), T::zero(), T::zero()) }
2367 pub fn unit_y () -> Self where T: Zero + One { Self::new(T::zero(), T::one(), T::zero()) }
2369 pub fn unit_z () -> Self where T: Zero + One { Self::new(T::zero(), T::zero(), T::one()) }
2371 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 pub fn new_point(x: T, y: T, z: T) -> Self where T: One {
2414 Self::new(x, y, z, T::one())
2415 }
2416 pub fn new_direction(x: T, y: T, z: T) -> Self where T: Zero {
2418 Self::new(x, y, z, T::zero())
2419 }
2420 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 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 pub fn unit_x () -> Self where T: Zero + One { Self::new(T::one(), T::zero(), T::zero(), T::zero()) }
2432 pub fn unit_y () -> Self where T: Zero + One { Self::new(T::zero(), T::one(), T::zero(), T::zero()) }
2434 pub fn unit_z () -> Self where T: Zero + One { Self::new(T::zero(), T::zero(), T::one(), T::zero()) }
2436 pub fn unit_w () -> Self where T: Zero + One { Self::new(T::zero(), T::zero(), T::zero(), T::one()) }
2438 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 pub fn unit_x_point () -> Self where T: Zero + One { Self::new(T::one(), T::zero(), T::zero(), T::one()) }
2465 pub fn unit_y_point () -> Self where T: Zero + One { Self::new(T::zero(), T::one(), T::zero(), T::one()) }
2467 pub fn unit_z_point () -> Self where T: Zero + One { Self::new(T::zero(), T::zero(), T::one(), T::one()) }
2469 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 pub fn homogenized(self) -> Self where T: Div<Output=T>, T: Copy {
2506 self / self.w
2507 }
2508 pub fn homogenize(&mut self) where T: Div<Output=T>, T: Copy {
2512 *self = self.homogenized();
2513 }
2514 pub fn is_homogeneous(self) -> bool where T: RelativeEq + Zero + One + Copy {
2518 self.is_point() || self.is_direction()
2519 }
2520 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 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 const COLOR_TYPE: ColorType = match mem::size_of::<T>() {
2558 1 => ColorType::Rgb8, 2 => ColorType::Rgb16, _ => ColorType::Rgb8, };
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 const COLOR_TYPE: ColorType = match mem::size_of::<T>() {
2672 1 => ColorType::Rgba8, 2 => ColorType::Rgba16, _ => ColorType::Rgba8, };
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 pub fn new_opaque(r: T, g: T, b: T) -> Self {
2775 Self::new(r, g, b, T::full())
2776 }
2777 pub fn new_transparent(r: T, g: T, b: T) -> Self {
2779 Self::new(r, g, b, T::zero())
2780 }
2781 #[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 #[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 #[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 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 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 pub fn shuffled_argb(self) -> Self {
2846 let Self { r, g, b, a } = self;
2847 Self::new(a, r, g, b)
2848 }
2849 pub fn shuffled_bgra(self) -> Self {
2851 let Self { r, g, b, a } = self;
2852 Self::new(b, g, r, a)
2853 }
2854 }
2855 };
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 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 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 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#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
2942pub struct ShuffleMask4(u8);
2943
2944impl 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 #[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 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 impl<T> $Vec<T> {
2982 pub fn shuffled<M: Into<ShuffleMask4>>(self, mask: M) -> Self where T: Copy {
2996 Self::shuffle_lo_hi(self, self, mask)
2997 }
2998 pub fn shuffled_0101(self) -> Self where T: Copy {
3010 Self::shuffle_lo_hi_0101(self, self)
3011 }
3012 pub fn shuffled_2323(self) -> Self where T: Copy {
3024 Self::shuffle_hi_lo_2323(self, self)
3025 }
3026 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 pub fn interleave_0011(a: Self, b: Self) -> Self {
3056 Self::new(a.$x, b.$x, a.$y, b.$y)
3057 }
3058 pub fn interleave_2233(a: Self, b: Self) -> Self {
3070 Self::new(a.$z, b.$z, a.$w, b.$w)
3071 }
3072 pub fn shuffle_lo_hi_0101(a: Self, b: Self) -> Self {
3085 Self::new(a.$x, a.$y, b.$x, b.$y)
3086 }
3087 pub fn shuffle_hi_lo_2323(a: Self, b: Self) -> Self {
3100 Self::new(b.$z, b.$w, a.$z, a.$w)
3101 }
3102 pub fn shuffled_0022(self) -> Self where T: Copy {
3113 Self::new(self.$x, self.$x, self.$z, self.$z)
3114 }
3115 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 impl<T: Copy + Add<T,Output=T> + Mul<T,Output=T> + Sub<T,Output=T>> $Vec<T> {
3137 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 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 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 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 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 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
3219macro_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 pub mod vec2 {
3225 use super::*;
3226 #[allow(missing_docs)]
3228 #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq)]
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 pub fn yx(self) -> Self {
3241 let Self { x, y } = self;
3242 Self { x: y, y: x }
3243 }
3244 pub fn with_x(mut self, x: T) -> Self {
3246 self.x = x;
3247 self
3248 }
3249 pub fn with_y(mut self, y: T) -> Self {
3251 self.y = y;
3252 self
3253 }
3254 pub fn with_z(self, z: T) -> Vec3<T> {
3256 Vec3::new(self.x, self.y, z)
3257 }
3258 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 pub mod vec3 {
3284 use super::*;
3285 #[allow(missing_docs)]
3287 #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq)]
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 pub fn zyx(self) -> Self {
3301 let Self { x, y, z } = self;
3302 Self { x: z, y, z: x }
3303 }
3304 pub fn xy(self) -> Vec2<T> {
3306 self.into()
3307 }
3308 pub fn with_x(mut self, x: T) -> Self {
3310 self.x = x;
3311 self
3312 }
3313 pub fn with_y(mut self, y: T) -> Self {
3315 self.y = y;
3316 self
3317 }
3318 pub fn with_z(mut self, z: T) -> Self {
3320 self.z = z;
3321 self
3322 }
3323 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 pub mod vec4 {
3361 use super::*;
3362 #[allow(missing_docs)]
3364 #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq)]
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 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 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 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 pub fn zyxw(self) -> Self {
3398 let Self { x, y, z, w } = self;
3399 Self { x: z, y, z: x, w }
3400 }
3401 pub fn xyz(self) -> Vec3<T> {
3403 self.into()
3404 }
3405 pub fn xy(self) -> Vec2<T> {
3407 self.into()
3408 }
3409
3410 pub fn with_x(mut self, x: T) -> Self {
3412 self.x = x;
3413 self
3414 }
3415 pub fn with_y(mut self, y: T) -> Self {
3417 self.y = y;
3418 self
3419 }
3420 pub fn with_z(mut self, z: T) -> Self {
3422 self.z = z;
3423 self
3424 }
3425 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 pub mod vec8 {
3455 use super::*;
3456 #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq)]
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 pub mod vec16 {
3477 use super::*;
3478 #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq)]
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 pub mod vec32 {
3499 use super::*;
3500 #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq)]
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 pub mod vec64 {
3522 use super::*;
3523 #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq)]
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 pub mod extent3 {
3543 use super::*;
3544 #[allow(missing_docs)]
3553 #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq)]
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 pub mod extent2 {
3571 use super::*;
3572 #[allow(missing_docs)]
3581 #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq)]
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 pub mod rgba {
3599 use super::*;
3600 #[allow(missing_docs)]
3605 #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq)]
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 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 pub mod rgb {
3641 use super::*;
3642 #[allow(missing_docs)]
3647 #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq)]
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 pub mod uvw {
3672 use super::*;
3673 #[allow(missing_docs)]
3675 #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq)]
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 pub mod uv {
3696 use super::*;
3697 #[allow(missing_docs)]
3699 #[derive(Debug, Default, Clone, Copy, Hash, Eq, PartialEq)]
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 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 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; let mut v = $Vec::from(a);
3764 assert_eq!(Rc::strong_count(&v[0]), 1);
3765 *Rc::make_mut(&mut v[0]) = 1; }
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; }
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 #[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 for_each_type!{vec2 Vec2 i8 u8 i16 u16 i32 u32 i64 u64 f32 f64}
3876 for_each_type!{vec3 Vec3 i8 u8 i16 u16 i32 u32 i64 u64 f32 f64}
3877 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 #[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 for_each_type!{extent3 Extent3 i8 u8 i16 u16 i32 u32 i64 u64 f32 f64}
3886 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}