naga_rust_rt/
vector.rs

1use core::{cmp, ops};
2use num_traits::ConstZero;
3
4// Provides float math functions without std.
5// TODO: Be more rigorous and explicitly call libm depending on the feature flag
6// instead of using the trait.
7#[cfg(not(feature = "std"))]
8#[cfg_attr(test, allow(unused_imports))]
9use num_traits::float::Float as _;
10
11// -------------------------------------------------------------------------------------------------
12// Vector type declarations.
13//
14// Note that these vectors are *not* prepared to become implemented as SIMD vectors.
15// This is because, when SIMD happens, our SIMD story is going to be making the
16// application-level vectors’ *components* into SIMD vectors, like:
17//     Vec2<std::simd::Simd<f32, 4>>
18// This will allow us to have a constant SIMD lane count across the entire execution, even while
19// the shader code works with vectors of all sizes and scalars.
20
21/// This type wraps an underlying Rust-native scalar (or someday SIMD) type
22/// to provide *only* methods and operators which are compatible with shader
23/// function behaviors. That is, they act like `Vec*` even where `T` might not.
24/// This allows the code generator to not worry as much about mismatches
25/// between Rust and shader semantics.
26///
27/// TODO: This isn't actually used yet.
28#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd)]
29#[repr(transparent)]
30pub struct Scalar<T>(pub T);
31
32#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
33#[repr(C)]
34pub struct Vec2<T> {
35    pub x: T,
36    pub y: T,
37}
38
39#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
40#[repr(C)]
41pub struct Vec3<T> {
42    pub x: T,
43    pub y: T,
44    pub z: T,
45}
46
47#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
48#[repr(C)]
49pub struct Vec4<T> {
50    pub x: T,
51    pub y: T,
52    pub z: T,
53    pub w: T,
54}
55
56// -------------------------------------------------------------------------------------------------
57// Most general helper macros
58
59macro_rules! delegate_unary_method_elementwise {
60    (const $name:ident ($($component:tt)*)) => {
61        #[inline]
62        pub const fn $name(self) -> Self {
63            Self { $( $component: self.$component.$name() ),* }
64        }
65    };
66    ($name:ident ($($component:tt)*)) => {
67        #[inline]
68        pub fn $name(self) -> Self {
69            Self { $( $component: self.$component.$name() ),* }
70        }
71    };
72}
73
74macro_rules! delegate_unary_methods_elementwise {
75    (const { $($name:ident),* } $components:tt) => {
76        $( delegate_unary_method_elementwise!(const $name $components ); )*
77    };
78    ({ $($name:ident),* } $components:tt) => {
79        $( delegate_unary_method_elementwise!($name $components ); )*
80    };
81}
82
83macro_rules! delegate_binary_method_elementwise {
84    (const $name:ident ($($component:tt)*)) => {
85        #[inline]
86        pub const fn $name(self, rhs: Self) -> Self {
87            Self { $( $component: self.$component.$name(rhs.$component) ),* }
88        }
89    };
90    ($name:ident ($($component:tt)*)) => {
91        #[inline]
92        pub fn $name(self, rhs: Self) -> Self {
93            Self { $( $component: self.$component.$name(rhs.$component) ),* }
94        }
95    };
96}
97
98macro_rules! delegate_binary_methods_elementwise {
99    (const { $($name:ident),* } $components:tt) => {
100        $( delegate_binary_method_elementwise!(const $name $components ); )*
101    };
102    ({ $($name:ident),* } $components:tt) => {
103        $( delegate_binary_method_elementwise!($name $components ); )*
104    };
105}
106
107// -------------------------------------------------------------------------------------------------
108// Vector operations
109
110/// Generate arithmetic operators and functions for cases where the element type is a
111/// Rust primitive *integer*. (In these cases we must ask for wrapping operations.)
112macro_rules! impl_vector_integer_arithmetic {
113    ($vec:ident, $int:ty, $( $component:tt )*) => {
114        impl ops::Add for $vec<$int> {
115            type Output = Self;
116            /// Wrapping addition.
117            #[inline]
118            fn add(self, rhs: Self) -> Self::Output {
119                $vec { $( $component: self.$component.wrapping_add(rhs.$component), )* }
120            }
121        }
122        impl ops::Sub for $vec<$int> {
123            type Output = Self;
124            /// Wrapping subtraction.
125            #[inline]
126            fn sub(self, rhs: Self) -> Self::Output {
127                $vec { $( $component: self.$component.wrapping_sub(rhs.$component), )* }
128            }
129        }
130        impl ops::Mul for $vec<$int> {
131            type Output = Self;
132            /// Wrapping multiplication.
133            #[inline]
134            fn mul(self, rhs: Self) -> Self::Output {
135                $vec { $( $component: self.$component.wrapping_mul(rhs.$component), )* }
136            }
137        }
138        impl ops::Div for $vec<$int> {
139            type Output = Self;
140            /// On division by zero or overflow, returns the component of `self`,
141            /// per [WGSL](https://www.w3.org/TR/2025/CRD-WGSL-20250322/#arithmetic-expr).
142            #[inline]
143            fn div(self, rhs: Self) -> Self::Output {
144                // wrapping_div() panics on division by zero, which is not what we need
145                $vec { $(
146                    $component:
147                        self.$component.checked_div(rhs.$component)
148                            .unwrap_or(self.$component),
149                )* }
150            }
151        }
152        impl ops::Rem for $vec<$int> {
153            type Output = Self;
154            #[inline]
155            fn rem(self, rhs: Self) -> Self::Output {
156                $vec { $( $component: self.$component.wrapping_rem(rhs.$component), )* }
157            }
158        }
159
160        // Vector-scalar operations
161        impl ops::Add<$int> for $vec<$int> {
162            type Output = Self;
163            /// Wrapping addition.
164            #[inline]
165            fn add(self, rhs: $int) -> Self::Output {
166                $vec { $( $component: self.$component.wrapping_add(rhs), )* }
167            }
168        }
169        impl ops::Sub<$int> for $vec<$int> {
170            type Output = Self;
171            /// Wrapping subtraction.
172            #[inline]
173            fn sub(self, rhs: $int) -> Self::Output {
174                $vec { $( $component: self.$component.wrapping_sub(rhs), )* }
175            }
176        }
177        impl ops::Mul<$int> for $vec<$int> {
178            type Output = Self;
179            /// Wrapping multiplication.
180            #[inline]
181            fn mul(self, rhs: $int) -> Self::Output {
182                $vec { $( $component: self.$component.wrapping_mul(rhs), )* }
183            }
184        }
185        impl ops::Div<$int> for $vec<$int> {
186            type Output = Self;
187            #[inline]
188            /// On division by zero or overflow, returns `self`,
189            /// per [WGSL](https://www.w3.org/TR/2025/CRD-WGSL-20250322/#arithmetic-expr).
190            fn div(self, rhs: $int) -> Self::Output {
191                // wrapping_div() panics on division by zero, which is not what we need
192                $vec { $(
193                    $component:
194                        self.$component.checked_div(rhs)
195                            .unwrap_or(self.$component),
196                )* }
197            }
198        }
199        impl ops::Rem<$int> for $vec<$int> {
200            type Output = Self;
201            #[inline]
202            fn rem(self, rhs: $int) -> Self::Output {
203                $vec { $( $component: self.$component.wrapping_rem(rhs), )* }
204            }
205        }
206
207        impl $vec<$int> {
208            delegate_binary_methods_elementwise!({
209                max, min
210            } ($($component)*));
211        }
212    }
213}
214
215/// Generate arithmetic operators and functions for cases where the element type is a
216/// Rust primitive *float*.
217macro_rules! impl_vector_float_arithmetic {
218    ($vec:ident, $float:ty, $( $component:tt )*) => {
219        // Vector-vector operations
220        impl ops::Add for $vec<$float> {
221            type Output = Self;
222            #[inline]
223            fn add(self, rhs: Self) -> Self::Output {
224                $vec { $( $component: self.$component + rhs.$component, )* }
225            }
226        }
227        impl ops::Sub for $vec<$float> {
228            type Output = Self;
229            #[inline]
230            fn sub(self, rhs: Self) -> Self::Output {
231                $vec { $( $component: self.$component - rhs.$component, )* }
232            }
233        }
234        impl ops::Mul for $vec<$float> {
235            type Output = Self;
236            #[inline]
237            fn mul(self, rhs: Self) -> Self::Output {
238                $vec { $( $component: self.$component * rhs.$component, )* }
239            }
240        }
241        impl ops::Div for $vec<$float> {
242            type Output = Self;
243            #[inline]
244            fn div(self, rhs: Self) -> Self::Output {
245                $vec { $( $component: self.$component / rhs.$component, )* }
246            }
247        }
248        impl ops::Rem for $vec<$float> {
249            type Output = Self;
250            #[inline]
251            fn rem(self, rhs: Self) -> Self::Output {
252                $vec { $( $component: self.$component % rhs.$component, )* }
253            }
254        }
255
256        // Vector-scalar operations
257        impl ops::Add<$float> for $vec<$float> {
258            type Output = Self;
259            #[inline]
260            fn add(self, rhs: $float) -> Self::Output {
261                $vec { $( $component: self.$component + rhs, )* }
262            }
263        }
264        impl ops::Sub<$float> for $vec<$float> {
265            type Output = Self;
266            #[inline]
267            fn sub(self, rhs: $float) -> Self::Output {
268                $vec { $( $component: self.$component - rhs, )* }
269            }
270        }
271        impl ops::Mul<$float> for $vec<$float> {
272            type Output = Self;
273            #[inline]
274            fn mul(self, rhs: $float) -> Self::Output {
275                $vec { $( $component: self.$component * rhs, )* }
276            }
277        }
278        impl ops::Div<$float> for $vec<$float> {
279            type Output = Self;
280            #[inline]
281            fn div(self, rhs: $float) -> Self::Output {
282                $vec { $( $component: self.$component / rhs, )* }
283            }
284        }
285        impl ops::Rem<$float> for $vec<$float> {
286            type Output = Self;
287            #[inline]
288            fn rem(self, rhs: $float) -> Self::Output {
289                $vec { $( $component: self.$component % rhs, )* }
290            }
291        }
292
293        // Float math functions (mostly elementwise, but not exclusively)
294        impl $vec<$float> {
295            /// As per WGSL [`clamp()`](https://www.w3.org/TR/2025/CRD-WGSL-20250322/#clamp).
296            #[inline]
297            pub const fn clamp(self, low: Self, high: Self) -> Self {
298                // TODO: std clamp() panics if low > high, which isn’t conformant
299                // (but maybe a better debugging tool? )
300                $vec { $( $component: self.$component.clamp(low.$component, high.$component) ),*  }
301            }
302            /// As per WGSL [`distance()`](https://www.w3.org/TR/2025/CRD-WGSL-20250322/#distance-builtin).
303            #[inline]
304            pub fn distance(self, rhs: Self) -> $float {
305                (self - rhs).length()
306            }
307            /// As per WGSL [`dot()`](https://www.w3.org/TR/2025/CRD-WGSL-20250322/#dot-builtin).
308            #[inline]
309            pub const fn dot(self, rhs: Self) -> $float {
310                $( self.$component * rhs.$component + )* 0.0
311            }
312            /// As per WGSL [`faceForward()`](https://www.w3.org/TR/2025/CRD-WGSL-20250322/#faceForward-builtin).
313            #[inline]
314            pub fn face_forward(self, e2: Self, e3: Self) -> Self {
315                // note this is Rust's definition of signum
316                self * -e2.dot(e3).signum()
317            }
318            /// As per WGSL [`length()`](https://www.w3.org/TR/2025/CRD-WGSL-20250322/#length-builtin).
319            #[inline]
320            pub fn length(self) -> $float {
321                self.dot(self).sqrt()
322            }
323            /// As per WGSL [`mix()`](https://www.w3.org/TR/2025/CRD-WGSL-20250322/#mix-builtin).
324            #[inline]
325            pub const fn mix(self, rhs: Self, blend: $float) -> Self {
326                $vec { $( $component: self.$component * (1.0 - blend) + rhs.$component * blend ),*  }
327            }
328            /// As per WGSL [`fma()`](https://www.w3.org/TR/2025/CRD-WGSL-20250322/#fma-builtin).
329            #[inline]
330            pub fn mul_add(self, b: Self, c: Self) -> Self {
331                $vec { $( $component: self.$component.mul_add(b.$component, c.$component) ),*  }
332            }
333            /// As per WGSL [`normalize()`](https://www.w3.org/TR/2025/CRD-WGSL-20250322/#normalize-builtin).
334            #[inline]
335            pub fn normalize(self) -> Self {
336                self * self.length().recip()
337            }
338            /// As per WGSL [`reflect()`](https://www.w3.org/TR/2025/CRD-WGSL-20250322/#reflect-builtin).
339            #[inline]
340            pub fn reflect(self, rhs: Self) -> Self {
341                self - rhs * (2.0 * rhs.dot(self))
342            }
343            /// As per WGSL [`saturate()`](https://www.w3.org/TR/2025/CRD-WGSL-20250322/#saturate-float-builtin).
344            #[inline]
345            pub const fn saturate(self) -> Self {
346                $vec { $( $component: self.$component.clamp(0.0, 1.0) ),* }
347            }
348            /// As per WGSL [`sign()`](https://www.w3.org/TR/2025/CRD-WGSL-20250322/#sign-builtin).
349            #[inline]
350            pub const fn sign(self) -> Self {
351                $vec { $(
352                    // TODO: branchless form of this?
353                    $component: if self.$component == 0.0 {
354                        0.0
355                    } else {
356                        self.$component.signum()
357                    }
358                ),* }
359            }
360
361            // TODO: some more of these can be const
362            delegate_unary_methods_elementwise!(const {
363                abs
364            } ($($component)*));
365            delegate_unary_methods_elementwise!({
366                acos, acosh, asin, asinh, atan, atanh, ceil, cos, cosh, exp, exp2, floor, fract, log2, round,
367                sin, sinh, tan, tanh, trunc, to_degrees, to_radians
368            } ($($component)*));
369            delegate_binary_methods_elementwise!({
370                atan2, max, min, powf
371            } ($($component)*));
372
373            // TODO: modf, frexp, ldexp, cross, refract, step, smoothstep, inverse_sqrt,
374            // quantizeToF16, pack*,
375        }
376    }
377}
378
379macro_rules! impl_vector_bitwise {
380    ($vec:ident, $int:ty, $( $component:tt )*) => {
381        impl ops::BitAnd for $vec<$int> {
382            type Output = Self;
383            fn bitand(self, rhs: Self) -> Self::Output {
384                $vec { $( $component: self.$component & rhs.$component, )* }
385            }
386        }
387        impl ops::BitOr for $vec<$int> {
388            type Output = Self;
389            fn bitor(self, rhs: Self) -> Self::Output {
390                $vec { $( $component: self.$component | rhs.$component, )* }
391            }
392        }
393        impl ops::BitXor for $vec<$int> {
394            type Output = Self;
395            fn bitxor(self, rhs: Self) -> Self::Output {
396                $vec { $( $component: self.$component ^ rhs.$component, )* }
397            }
398        }
399        impl ops::Not for $vec<$int> {
400            type Output = Self;
401            fn not(self) -> Self::Output {
402                $vec { $( $component: !self.$component, )* }
403            }
404        }
405
406    }
407}
408
409macro_rules! impl_element_casts {
410    ($ty:ident) => {
411        // TODO: These do not have the right cast semantics, but what *are* the right cast
412        // semantics? Naga IR docs are cryptic for `Expression::As`.
413        pub fn cast_elem_as_u32(self) -> $ty<u32> {
414            self.map(|component| component as u32)
415        }
416        pub fn cast_elem_as_i32(self) -> $ty<i32> {
417            self.map(|component| component as i32)
418        }
419        pub fn cast_elem_as_f32(self) -> $ty<f32> {
420            self.map(|component| component as f32)
421        }
422        pub fn cast_elem_as_f64(self) -> $ty<f64> {
423            self.map(|component| component as f64)
424        }
425    };
426}
427
428macro_rules! impl_vector_regular_fns {
429    ( $ty:ident $component_count:literal : $( $component:tt )* ) => {
430        impl<T> $ty<T> {
431            pub fn splat(value: T) -> Self
432            where
433                T: Copy
434            {
435                Self { $( $component: value, )* }
436            }
437            pub fn splat_from_scalar(value: Scalar<T>) -> Self
438            where
439                T: Copy
440            {
441                Self { $( $component: value.0, )* }
442            }
443
444            /// Replaces the elements of `self` with the elements of `trues` wherever
445            /// `mask` contains [`true`].
446            pub const fn select(self, trues: Self, mask: $ty<bool>) -> Self
447            where
448                T: Copy
449            {
450                Self {
451                    $(
452                        $component: if mask.$component {
453                            trues.$component
454                        } else {
455                            self.$component
456                        },
457                    )*
458                }
459            }
460
461            pub fn map<U, F>(self, mut f: F) -> $ty<U>
462            where
463                F: FnMut(T) -> U,
464            {
465                $ty {
466                    $(
467                        $component: f(self.$component),
468                    )*
469                }
470            }
471        }
472
473        impl_vector_integer_arithmetic!($ty, i32, $($component)*);
474        impl_vector_integer_arithmetic!($ty, u32, $($component)*);
475        impl_vector_float_arithmetic!($ty, f32, $($component)*);
476        impl_vector_float_arithmetic!($ty, f64, $($component)*);
477
478        impl_vector_bitwise!($ty, bool, $($component)*);
479        impl_vector_bitwise!($ty, i32, $($component)*);
480        impl_vector_bitwise!($ty, u32, $($component)*);
481
482        impl $ty<i32> {
483            impl_element_casts!($ty);
484        }
485        impl $ty<u32> {
486            impl_element_casts!($ty);
487        }
488        impl $ty<f32> {
489            impl_element_casts!($ty);
490        }
491        impl $ty<f64> {
492            impl_element_casts!($ty);
493        }
494
495        // Zero constant and traits.
496        impl<T: ConstZero> $ty<T> {
497            // inherent so that traits are not needed in scope
498            pub const ZERO: Self = Self { $( $component: T::ZERO, )* };
499        }
500        impl<T: ConstZero> ConstZero for $ty<T>
501        where
502            Self: ops::Add<Output = Self>
503        {
504            const ZERO: Self = Self { $( $component: T::ZERO, )* };
505        }
506        impl<T: ConstZero> num_traits::Zero for $ty<T>
507        where
508            Self: ops::Add<Output = Self>
509        {
510            fn zero() -> Self {
511                Self::ZERO
512            }
513            fn is_zero(&self) -> bool {
514                $(T::is_zero(&self.$component) & )* true
515            }
516        }
517
518        // Elementwise comparison
519        impl<T: PartialOrd> $ty<T> {
520            pub fn elementwise_eq(self, rhs: Self) -> $ty<bool> {
521                self.partial_cmp(rhs).map(|cmp| matches!(cmp, Some(cmp::Ordering::Equal)))
522            }
523            pub fn elementwise_ne(self, rhs: Self) -> $ty<bool> {
524                self.partial_cmp(rhs).map(|cmp| !matches!(cmp, Some(cmp::Ordering::Equal)))
525            }
526            pub fn elementwise_lt(self, rhs: Self) -> $ty<bool> {
527                self.partial_cmp(rhs).map(|cmp| matches!(cmp, Some(cmp::Ordering::Less)))
528            }
529            pub fn elementwise_le(self, rhs: Self) -> $ty<bool> {
530                self.partial_cmp(rhs).map(|cmp| {
531                    matches!(cmp, Some(cmp::Ordering::Less | cmp::Ordering::Equal))
532                })
533            }
534            pub fn elementwise_gt(self, rhs: Self) -> $ty<bool> {
535                self.partial_cmp(rhs).map(|cmp| matches!(cmp, Some(cmp::Ordering::Greater)))
536            }
537            pub fn elementwise_ge(self, rhs: Self) -> $ty<bool> {
538                self.partial_cmp(rhs).map(|cmp| {
539                    matches!(cmp, Some(cmp::Ordering::Greater | cmp::Ordering::Equal))
540                })
541            }
542
543            /// Helper for comparison operations
544            fn partial_cmp(self, rhs: Self) -> $ty<Option<cmp::Ordering>> {
545                $ty {
546                    $(
547                        $component: self.$component.partial_cmp(&rhs.$component),
548                    )*
549                }
550            }
551        }
552
553        // Conversion in and out
554        impl<T> From<$ty<T>> for [T; $component_count] {
555            fn from(value: $ty<T>) -> Self {
556                [$( value.$component ),*]
557            }
558        }
559
560        // Irregular integer math: `$vec<u32>.abs()` exists even though it is the identity,
561        // but Rust doesn't have it.
562        impl $ty<i32> {
563            delegate_unary_methods_elementwise!(const { abs } ($($component)*));
564        }
565        impl $ty<u32> {
566            pub fn abs(self) -> Self { self }
567        }
568    }
569}
570
571impl_vector_regular_fns!(Scalar 1 : 0);
572impl_vector_regular_fns!(Vec2 2 : x y);
573impl_vector_regular_fns!(Vec3 3 : x y z);
574impl_vector_regular_fns!(Vec4 4 : x y z w);
575
576// -------------------------------------------------------------------------------------------------
577// Impls that differ between `Vec*` and `Scalar`
578
579/// Applied to every `Vec` type but not `Scalar`
580macro_rules! impl_vector_not_scalar_fns {
581    ( $ty:ident $component_count:literal : $( $component:tt )* ) => {
582        impl<T> $ty<T> {
583            // User-friendly constructor, not used by translated code.
584            pub const fn new($( $component: T, )*) -> Self {
585                Self { $( $component, )* }
586            }
587
588            pub const fn from_scalars($( $component: Scalar<T>, )*) -> Self
589            where
590                T: Copy
591            {
592                Self { $( $component: $component.0, )* }
593            }
594        }
595
596        impl<T> From<[T; $component_count]> for $ty<T> {
597            fn from(value: [T; $component_count]) -> Self {
598                let [$( $component ),*] = value;
599                Self::new($( $component ),*)
600            }
601        }
602
603        // Commutative scalar-vector operators are derived from vector-scalar operators
604        impl<T> ops::Add<$ty<T>> for Scalar<T>
605        where
606            $ty<T>: ops::Add<Scalar<T>>
607        {
608            type Output = <$ty<T> as ops::Add<Scalar<T>>>::Output;
609            fn add(self, rhs: $ty<T>) -> Self::Output {
610                rhs + self
611            }
612        }
613        impl<T> ops::Mul<$ty<T>> for Scalar<T>
614        where
615            $ty<T>: ops::Mul<Scalar<T>>
616        {
617            type Output = <$ty<T> as ops::Mul<Scalar<T>>>::Output;
618            fn mul(self, rhs: $ty<T>) -> Self::Output {
619                rhs * self
620            }
621        }
622
623    }
624}
625
626impl_vector_not_scalar_fns!(Vec2 2 : x y);
627impl_vector_not_scalar_fns!(Vec3 3 : x y z);
628impl_vector_not_scalar_fns!(Vec4 4 : x y z w);
629
630impl<T> Scalar<T> {
631    pub fn new(value: T) -> Self {
632        Self(value)
633    }
634}
635impl<T> From<[T; 1]> for Scalar<T> {
636    fn from([value]: [T; 1]) -> Self {
637        Self(value)
638    }
639}
640
641// -------------------------------------------------------------------------------------------------
642// Irregular functions and impls
643
644impl<T> From<T> for Scalar<T> {
645    fn from(value: T) -> Self {
646        Self(value)
647    }
648}
649
650impl<T: Default> Default for Scalar<T> {
651    fn default() -> Self {
652        Self(Default::default())
653    }
654}
655
656// Constructor functions that take a mix of scalars and vectors.
657// These names must match those generated by `Writer::write_constructor_expression()`.
658macro_rules! impl_flattening_ctor {
659    (fn $fn_name:ident ( $($param:tt)* ) => ( $($arg:tt)* )) => {
660        pub const fn $fn_name ($($param)*) -> Self {
661            Self::new($($arg)*)
662        }
663    }
664}
665// Note: Copy bound is solely due to otherwise needing `feature(const_precise_live_drops)`.
666impl<T: Copy> Vec3<T> {
667    impl_flattening_ctor!(fn new_12(x: T, yz: Vec2<T>) => (x, yz.x, yz.y));
668    impl_flattening_ctor!(fn new_21(xy: Vec2<T>, z: T) => (xy.x, xy.y, z));
669}
670impl<T: Copy> Vec4<T> {
671    impl_flattening_ctor!(fn new_112(x: T, y: T, zw: Vec2<T>) => (x, y, zw.x, zw.y));
672    impl_flattening_ctor!(fn new_121(x: T, yz: Vec2<T>, w: T) => (x, yz.x, yz.y, w));
673    impl_flattening_ctor!(fn new_211(xy: Vec2<T>, z: T, w: T) => (xy.x, xy.y, z, w));
674    impl_flattening_ctor!(fn new_22(xy: Vec2<T>, zw: Vec2<T>) => (xy.x, xy.y, zw.x, zw.y));
675    impl_flattening_ctor!(fn new_13(x: T, yzw: Vec3<T>) => (x, yzw.x, yzw.y, yzw.z));
676    impl_flattening_ctor!(fn new_31(xyz: Vec3<T>, w: T) => (xyz.x, xyz.y, xyz.z, w));
677}
678
679// -------------------------------------------------------------------------------------------------
680// Swizzles
681
682macro_rules! swizzle_fn {
683    ($name:ident $output:ident ($($cin:ident)*) ) => {
684        /// Takes the
685        #[doc = stringify!($($cin),*)]
686        /// elements of `self` and returns them in that order.
687        pub fn $name(self) -> $output<T> {
688            $output::new($(self.$cin,)*)
689        }
690    }
691}
692
693impl<T: Copy> Vec2<T> {
694    swizzle_fn!(xy Vec2(x y));
695    swizzle_fn!(yx Vec2(y x));
696}
697impl<T: Copy> Vec3<T> {
698    swizzle_fn!(xy Vec2(x y));
699    swizzle_fn!(yx Vec2(y x));
700    swizzle_fn!(xyz Vec3(x y z));
701    swizzle_fn!(xzy Vec3(x z y));
702    swizzle_fn!(yxz Vec3(y x z));
703    swizzle_fn!(yzx Vec3(y z x));
704    swizzle_fn!(zxy Vec3(z x y));
705    swizzle_fn!(zyx Vec3(z y x));
706}
707impl<T: Copy> Vec4<T> {
708    swizzle_fn!(xy Vec2(x y));
709    swizzle_fn!(yx Vec2(y x));
710    swizzle_fn!(xyz Vec3(x y z));
711    swizzle_fn!(xzy Vec3(x z y));
712    swizzle_fn!(yxz Vec3(y x z));
713    swizzle_fn!(yzx Vec3(y z x));
714    swizzle_fn!(zxy Vec3(z x y));
715    swizzle_fn!(zyx Vec3(z y x));
716    swizzle_fn!(xyzw Vec4(x y z w));
717    swizzle_fn!(xywz Vec4(x y w z));
718    swizzle_fn!(xzwy Vec4(x z w y));
719    swizzle_fn!(xzyw Vec4(x z y w));
720    swizzle_fn!(xwyz Vec4(x w y z));
721    swizzle_fn!(xwzy Vec4(x w z y));
722    swizzle_fn!(yxzw Vec4(y x z w));
723    swizzle_fn!(yxwz Vec4(y x w z));
724    swizzle_fn!(yzxw Vec4(y z x w));
725    swizzle_fn!(yzwx Vec4(y z w x));
726    swizzle_fn!(ywzx Vec4(y w z x));
727    swizzle_fn!(ywxz Vec4(y w x z));
728    swizzle_fn!(zxyw Vec4(z x y w));
729    swizzle_fn!(zxwy Vec4(z x w y));
730    swizzle_fn!(zyxw Vec4(z y x w));
731    swizzle_fn!(zywx Vec4(z y w x));
732    swizzle_fn!(zwxy Vec4(z w x y));
733    swizzle_fn!(zwyx Vec4(z w y x));
734    swizzle_fn!(wxyz Vec4(w x y z));
735    swizzle_fn!(wxzy Vec4(w x z y));
736    swizzle_fn!(wyxz Vec4(w y x z));
737    swizzle_fn!(wyzx Vec4(w y z x));
738    swizzle_fn!(wzxy Vec4(w z x y));
739    swizzle_fn!(wzyx Vec4(w z y x));
740}