glam/features/
impl_rand.rs

1macro_rules! impl_vec_types {
2    (
3        $t:ty,
4        $vec2:ident,
5        $vec3:ident,
6        $vec4:ident,
7        $uniform:ident,
8        $upper_range_multiplier:expr
9    ) => {
10        use super::{UniformVec2, UniformVec3, UniformVec4};
11        use rand::{
12            distr::{
13                uniform::{Error as UniformError, SampleBorrow, SampleUniform, UniformSampler},
14                Distribution, StandardUniform,
15            },
16            Rng,
17        };
18
19        impl Distribution<$vec2> for StandardUniform {
20            #[inline]
21            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $vec2 {
22                rng.random::<[$t; 2]>().into()
23            }
24        }
25
26        impl SampleUniform for $vec2 {
27            type Sampler = UniformVec2<$uniform<$t>>;
28        }
29
30        impl UniformSampler for UniformVec2<$uniform<$t>> {
31            type X = $vec2;
32
33            fn new<B1, B2>(low_b: B1, high_b: B2) -> Result<Self, UniformError>
34            where
35                B1: SampleBorrow<Self::X> + Sized,
36                B2: SampleBorrow<Self::X> + Sized,
37            {
38                let low = *low_b.borrow();
39                let high = *high_b.borrow();
40
41                if low.x >= high.x || low.y >= high.y {
42                    return Err(UniformError::EmptyRange);
43                }
44
45                Ok(Self {
46                    x_gen: $uniform::new(low.x, high.x)?,
47                    y_gen: $uniform::new(low.y, high.y)?,
48                })
49            }
50
51            fn new_inclusive<B1, B2>(low_b: B1, high_b: B2) -> Result<Self, UniformError>
52            where
53                B1: SampleBorrow<Self::X> + Sized,
54                B2: SampleBorrow<Self::X> + Sized,
55            {
56                let low = *low_b.borrow();
57                let high = *high_b.borrow();
58
59                if low.x >= high.x || low.y >= high.y {
60                    return Err(UniformError::EmptyRange);
61                }
62
63                Ok(Self {
64                    x_gen: $uniform::new_inclusive(low.x, high.x)?,
65                    y_gen: $uniform::new_inclusive(low.y, high.y)?,
66                })
67            }
68
69            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
70                Self::X::from([self.x_gen.sample(rng), self.y_gen.sample(rng)])
71            }
72
73            fn sample_single<R: Rng + ?Sized, B1, B2>(
74                low_b: B1,
75                high_b: B2,
76                rng: &mut R,
77            ) -> Result<Self::X, UniformError>
78            where
79                B1: SampleBorrow<Self::X> + Sized,
80                B2: SampleBorrow<Self::X> + Sized,
81            {
82                let low = *low_b.borrow();
83                let high = *high_b.borrow();
84
85                if low.x >= high.x || low.y >= high.y {
86                    return Err(UniformError::EmptyRange);
87                }
88
89                Ok(Self::X::from([
90                    $uniform::<$t>::sample_single(low.x, high.x, rng)?,
91                    $uniform::<$t>::sample_single(low.y, high.y, rng)?,
92                ]))
93            }
94
95            fn sample_single_inclusive<R: Rng + ?Sized, B1, B2>(
96                low_b: B1,
97                high_b: B2,
98                rng: &mut R,
99            ) -> Result<Self::X, UniformError>
100            where
101                B1: SampleBorrow<Self::X> + Sized,
102                B2: SampleBorrow<Self::X> + Sized,
103            {
104                let low = *low_b.borrow();
105                let high = *high_b.borrow();
106
107                if low.x >= high.x || low.y >= high.y {
108                    return Err(UniformError::EmptyRange);
109                }
110
111                Ok(Self::X::from([
112                    $uniform::<$t>::sample_single_inclusive(low.x, high.x, rng)?,
113                    $uniform::<$t>::sample_single_inclusive(low.y, high.y, rng)?,
114                ]))
115            }
116        }
117
118        impl Distribution<$vec3> for StandardUniform {
119            #[inline]
120            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $vec3 {
121                rng.random::<[$t; 3]>().into()
122            }
123        }
124
125        impl SampleUniform for $vec3 {
126            type Sampler = UniformVec3<$uniform<$t>>;
127        }
128
129        impl UniformSampler for UniformVec3<$uniform<$t>> {
130            type X = $vec3;
131
132            fn new<B1, B2>(low_b: B1, high_b: B2) -> Result<Self, UniformError>
133            where
134                B1: SampleBorrow<Self::X> + Sized,
135                B2: SampleBorrow<Self::X> + Sized,
136            {
137                let low = *low_b.borrow();
138                let high = *high_b.borrow();
139
140                if low.x >= high.x || low.y >= high.y || low.z >= high.z {
141                    return Err(UniformError::EmptyRange);
142                }
143
144                Ok(Self {
145                    x_gen: $uniform::new(low.x, high.x)?,
146                    y_gen: $uniform::new(low.y, high.y)?,
147                    z_gen: $uniform::new(low.z, high.z)?,
148                })
149            }
150
151            fn new_inclusive<B1, B2>(low_b: B1, high_b: B2) -> Result<Self, UniformError>
152            where
153                B1: SampleBorrow<Self::X> + Sized,
154                B2: SampleBorrow<Self::X> + Sized,
155            {
156                let low = *low_b.borrow();
157                let high = *high_b.borrow();
158
159                if low.x >= high.x || low.y >= high.y || low.z >= high.z {
160                    return Err(UniformError::EmptyRange);
161                }
162
163                Ok(Self {
164                    x_gen: $uniform::new_inclusive(low.x, high.x)?,
165                    y_gen: $uniform::new_inclusive(low.y, high.y)?,
166                    z_gen: $uniform::new_inclusive(low.z, high.z)?,
167                })
168            }
169
170            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
171                Self::X::from([
172                    self.x_gen.sample(rng),
173                    self.y_gen.sample(rng),
174                    self.z_gen.sample(rng),
175                ])
176            }
177
178            fn sample_single<R: Rng + ?Sized, B1, B2>(
179                low_b: B1,
180                high_b: B2,
181                rng: &mut R,
182            ) -> Result<Self::X, UniformError>
183            where
184                B1: SampleBorrow<Self::X> + Sized,
185                B2: SampleBorrow<Self::X> + Sized,
186            {
187                let low = *low_b.borrow();
188                let high = *high_b.borrow();
189
190                if low.x >= high.x || low.y >= high.y || low.z >= high.z {
191                    return Err(UniformError::EmptyRange);
192                }
193
194                Ok(Self::X::from([
195                    $uniform::<$t>::sample_single(low.x, high.x, rng)?,
196                    $uniform::<$t>::sample_single(low.y, high.y, rng)?,
197                    $uniform::<$t>::sample_single(low.z, high.z, rng)?,
198                ]))
199            }
200
201            fn sample_single_inclusive<R: Rng + ?Sized, B1, B2>(
202                low_b: B1,
203                high_b: B2,
204                rng: &mut R,
205            ) -> Result<Self::X, UniformError>
206            where
207                B1: SampleBorrow<Self::X> + Sized,
208                B2: SampleBorrow<Self::X> + Sized,
209            {
210                let low = *low_b.borrow();
211                let high = *high_b.borrow();
212
213                if low.x >= high.x || low.y >= high.y || low.z >= high.z {
214                    return Err(UniformError::EmptyRange);
215                }
216
217                Ok(Self::X::from([
218                    $uniform::<$t>::sample_single_inclusive(low.x, high.x, rng)?,
219                    $uniform::<$t>::sample_single_inclusive(low.y, high.y, rng)?,
220                    $uniform::<$t>::sample_single_inclusive(low.z, high.z, rng)?,
221                ]))
222            }
223        }
224
225        impl Distribution<$vec4> for StandardUniform {
226            #[inline]
227            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $vec4 {
228                rng.random::<[$t; 4]>().into()
229            }
230        }
231
232        impl SampleUniform for $vec4 {
233            type Sampler = UniformVec4<$uniform<$t>>;
234        }
235
236        impl UniformSampler for UniformVec4<$uniform<$t>> {
237            type X = $vec4;
238
239            fn new<B1, B2>(low_b: B1, high_b: B2) -> Result<Self, UniformError>
240            where
241                B1: SampleBorrow<Self::X> + Sized,
242                B2: SampleBorrow<Self::X> + Sized,
243            {
244                let low = *low_b.borrow();
245                let high = *high_b.borrow();
246
247                if low.x >= high.x || low.y >= high.y || low.z >= high.z || low.w >= high.w {
248                    return Err(UniformError::EmptyRange);
249                }
250
251                Ok(Self {
252                    x_gen: $uniform::new(low.x, high.x)?,
253                    y_gen: $uniform::new(low.y, high.y)?,
254                    z_gen: $uniform::new(low.z, high.z)?,
255                    w_gen: $uniform::new(low.w, high.w)?,
256                })
257            }
258
259            fn new_inclusive<B1, B2>(low_b: B1, high_b: B2) -> Result<Self, UniformError>
260            where
261                B1: SampleBorrow<Self::X> + Sized,
262                B2: SampleBorrow<Self::X> + Sized,
263            {
264                let low = *low_b.borrow();
265                let high = *high_b.borrow();
266
267                if low.x >= high.x || low.y >= high.y || low.z >= high.z || low.w >= high.w {
268                    return Err(UniformError::EmptyRange);
269                }
270
271                Ok(Self {
272                    x_gen: $uniform::new_inclusive(low.x, high.x)?,
273                    y_gen: $uniform::new_inclusive(low.y, high.y)?,
274                    z_gen: $uniform::new_inclusive(low.z, high.z)?,
275                    w_gen: $uniform::new_inclusive(low.w, high.w)?,
276                })
277            }
278
279            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
280                Self::X::from([
281                    self.x_gen.sample(rng),
282                    self.y_gen.sample(rng),
283                    self.z_gen.sample(rng),
284                    self.w_gen.sample(rng),
285                ])
286            }
287
288            fn sample_single<R: Rng + ?Sized, B1, B2>(
289                low_b: B1,
290                high_b: B2,
291                rng: &mut R,
292            ) -> Result<Self::X, UniformError>
293            where
294                B1: SampleBorrow<Self::X> + Sized,
295                B2: SampleBorrow<Self::X> + Sized,
296            {
297                let low = *low_b.borrow();
298                let high = *high_b.borrow();
299
300                if low.x >= high.x || low.y >= high.y || low.z >= high.z || low.w >= high.w {
301                    return Err(UniformError::EmptyRange);
302                }
303
304                Ok(Self::X::from([
305                    $uniform::<$t>::sample_single(low.x, high.x, rng)?,
306                    $uniform::<$t>::sample_single(low.y, high.y, rng)?,
307                    $uniform::<$t>::sample_single(low.z, high.z, rng)?,
308                    $uniform::<$t>::sample_single(low.w, high.w, rng)?,
309                ]))
310            }
311
312            fn sample_single_inclusive<R: Rng + ?Sized, B1, B2>(
313                low_b: B1,
314                high_b: B2,
315                rng: &mut R,
316            ) -> Result<Self::X, UniformError>
317            where
318                B1: SampleBorrow<Self::X> + Sized,
319                B2: SampleBorrow<Self::X> + Sized,
320            {
321                let low = *low_b.borrow();
322                let high = *high_b.borrow();
323
324                if low.x >= high.x || low.y >= high.y || low.z >= high.z || low.w >= high.w {
325                    return Err(UniformError::EmptyRange);
326                }
327
328                Ok(Self::X::from([
329                    $uniform::<$t>::sample_single_inclusive(low.x, high.x, rng)?,
330                    $uniform::<$t>::sample_single_inclusive(low.y, high.y, rng)?,
331                    $uniform::<$t>::sample_single_inclusive(low.z, high.z, rng)?,
332                    $uniform::<$t>::sample_single_inclusive(low.w, high.w, rng)?,
333                ]))
334            }
335        }
336
337        #[test]
338        fn test_vec2_rand_standard() {
339            use rand::{Rng, SeedableRng};
340            use rand_xoshiro::Xoshiro256Plus;
341            let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
342            let a: ($t, $t) = rng1.random();
343            let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
344            let b: $vec2 = rng2.random();
345            assert_eq!(a, b.into());
346        }
347
348        #[test]
349        fn test_vec3_rand_standard() {
350            use rand::{Rng, SeedableRng};
351            use rand_xoshiro::Xoshiro256Plus;
352            let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
353            let a: ($t, $t, $t) = rng1.random();
354            let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
355            let b: $vec3 = rng2.random();
356            assert_eq!(a, b.into());
357        }
358
359        #[test]
360        fn test_vec4_rand_standard() {
361            use rand::{Rng, SeedableRng};
362            use rand_xoshiro::Xoshiro256Plus;
363            let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
364            let a: ($t, $t, $t, $t) = rng1.random();
365            let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
366            let b: $vec4 = rng2.random();
367            assert_eq!(a, b.into());
368        }
369
370        test_vec_type_uniform!(
371            test_vec2_rand_uniform_equality,
372            $vec2,
373            $t,
374            2,
375            $upper_range_multiplier
376        );
377
378        test_vec_type_uniform!(
379            test_vec3_rand_uniform_equality,
380            $vec3,
381            $t,
382            3,
383            $upper_range_multiplier
384        );
385
386        test_vec_type_uniform!(
387            test_vec4_rand_uniform_equality,
388            $vec4,
389            $t,
390            4,
391            $upper_range_multiplier
392        );
393    };
394}
395
396macro_rules! test_vec_type_uniform {
397    // NOTE: These were intended to be placed in a `macro_rules!` statement in
398    // the main rule below, but rustc wants to complain about unused macros if I
399    // try to do that... even if I do use the macros.
400    (__repeat_code 2, $code:expr) => {
401        ($code, $code)
402    };
403    (__repeat_code 3, $code:expr) => {
404        ($code, $code, $code)
405    };
406    (__repeat_code 4, $code:expr) => {
407        ($code, $code, $code, $code)
408    };
409    (
410        $equality_test_name:ident,
411        $vec:ident,
412        $t:ty,
413        $t_count:tt,
414        $upper_range_divisor:expr
415    ) => {
416        /// Tests that we reach the same result, whether we generate the vector
417        /// type directly, or generate its internal values $t_count times and
418        /// convert the result into the vector type.
419        #[test]
420        fn $equality_test_name() {
421            use rand::{distr::Uniform, Rng, SeedableRng};
422            use rand_xoshiro::Xoshiro256Plus;
423
424            let mut int_rng = Xoshiro256Plus::seed_from_u64(0);
425            let mut vec_rng = Xoshiro256Plus::seed_from_u64(0);
426
427            macro_rules! test_uniform {
428                (
429                    __single_test,
430                    $uniform_function_name:ident,
431                    $t_low:expr,
432                    $t_high:expr,
433                    $vec_low:expr,
434                    $vec_high:expr
435                ) => {
436                    let int_u = Uniform::$uniform_function_name($t_low, $t_high).unwrap();
437                    let vec_u = Uniform::$uniform_function_name($vec_low, $vec_high).unwrap();
438
439                    let v_int = test_vec_type_uniform!(
440                        __repeat_code $t_count,
441                        int_rng.sample(int_u)
442                    );
443                    let v_vec: $vec = vec_rng.sample(vec_u);
444                    assert_eq!(v_int, v_vec.into());
445                };
446                (
447                    $uniform_function_name:ident,
448                    $t_low:expr,
449                    $t_high:expr,
450                    $vec_low:expr,
451                    $vec_high:expr
452                ) => {
453                    test_uniform!(
454                        __single_test,
455                        $uniform_function_name,
456                        $t_low, $t_high,
457                        $vec_low, $vec_high
458                    );
459
460                    test_uniform!(
461                        __single_test,
462                        $uniform_function_name,
463                        &$t_low, &$t_high,
464                        &$vec_low, &$vec_high
465                    );
466                };
467            }
468
469            test_uniform!(
470                new,
471                <$t>::default(),
472                <$t>::MAX / $upper_range_divisor,
473                $vec::default(),
474                $vec::MAX / $upper_range_divisor
475            );
476
477            test_uniform!(
478                new_inclusive,
479                <$t>::default(),
480                <$t>::MAX / $upper_range_divisor,
481                $vec::default(),
482                $vec::MAX / $upper_range_divisor
483            );
484
485            macro_rules! test_sample_uniform_sampler {
486                ($sampler_function_name:ident) => {
487                    let v_int = test_vec_type_uniform!(
488                        __repeat_code $t_count,
489                        <$t as SampleUniform>::Sampler::$sampler_function_name(
490                            <$t>::default(),
491                            <$t>::MAX / $upper_range_divisor,
492                            &mut int_rng,
493                        ).unwrap()
494                    );
495
496                    let v_vec: $vec = <$vec as SampleUniform>::Sampler::$sampler_function_name(
497                        $vec::default(),
498                        $vec::MAX / $upper_range_divisor,
499                        &mut vec_rng,
500                    ).unwrap();
501                    assert_eq!(v_int, v_vec.into());
502                };
503            }
504
505            test_sample_uniform_sampler!(sample_single);
506            test_sample_uniform_sampler!(sample_single_inclusive);
507        }
508    };
509}
510
511macro_rules! impl_int_types {
512    ($t:ty, $vec2:ident, $vec3:ident, $vec4:ident) => {
513        use rand::distr::uniform::UniformInt;
514
515        impl_vec_types!($t, $vec2, $vec3, $vec4, UniformInt, 1);
516    };
517}
518
519macro_rules! impl_float_types {
520    ($t:ident, $mat2:ident, $mat3:ident, $mat4:ident, $quat:ident, $vec2:ident, $vec3:ident, $vec4:ident) => {
521        use rand::distr::uniform::UniformFloat;
522
523        impl_vec_types!($t, $vec2, $vec3, $vec4, UniformFloat, 10.0);
524
525        impl Distribution<$mat2> for StandardUniform {
526            #[inline]
527            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $mat2 {
528                $mat2::from_cols_array(&rng.random())
529            }
530        }
531
532        impl Distribution<$mat3> for StandardUniform {
533            #[inline]
534            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $mat3 {
535                $mat3::from_cols_array(&rng.random())
536            }
537        }
538
539        impl Distribution<$mat4> for StandardUniform {
540            #[inline]
541            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $mat4 {
542                $mat4::from_cols_array(&rng.random())
543            }
544        }
545
546        impl Distribution<$quat> for StandardUniform {
547            #[inline]
548            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $quat {
549                let z = rng.random_range::<$t, _>(-1.0..=1.0);
550                let (y, x) = math::sin_cos(rng.random_range::<$t, _>(0.0..TAU));
551                let r = math::sqrt(1.0 - z * z);
552                let axis = $vec3::new(r * x, r * y, z);
553                let angle = rng.random_range::<$t, _>(0.0..TAU);
554                $quat::from_axis_angle(axis, angle)
555            }
556        }
557
558        #[test]
559        fn test_mat2_rand_standard() {
560            use rand::{Rng, SeedableRng};
561            use rand_xoshiro::Xoshiro256Plus;
562            let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
563            let a = $mat2::from_cols_array(&rng1.random::<[$t; 4]>());
564            let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
565            let b = rng2.random::<$mat2>();
566            assert_eq!(a, b);
567        }
568
569        #[test]
570        fn test_mat3_rand_standard() {
571            use rand::{Rng, SeedableRng};
572            use rand_xoshiro::Xoshiro256Plus;
573            let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
574            let a = $mat3::from_cols_array(&rng1.random::<[$t; 9]>());
575            let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
576            let b = rng2.random::<$mat3>();
577            assert_eq!(a, b);
578        }
579
580        #[test]
581        fn test_mat4_rand_standard() {
582            use rand::{Rng, SeedableRng};
583            use rand_xoshiro::Xoshiro256Plus;
584            let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
585            let a = $mat4::from_cols_array(&rng1.random::<[$t; 16]>());
586            let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
587            let b = rng2.random::<$mat4>();
588            assert_eq!(a, b);
589        }
590
591        #[test]
592        fn test_quat_rand_standard() {
593            use rand::{Rng, SeedableRng};
594            use rand_xoshiro::Xoshiro256Plus;
595            let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
596            let a: $quat = rng1.random();
597            assert!(a.is_normalized());
598            let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
599            let b: $quat = rng2.random();
600            assert_eq!(a, b);
601        }
602    };
603}
604
605#[derive(Clone, Copy, Debug, PartialEq)]
606pub struct UniformVec2<G> {
607    x_gen: G,
608    y_gen: G,
609}
610
611#[derive(Clone, Copy, Debug, PartialEq)]
612pub struct UniformVec3<G> {
613    x_gen: G,
614    y_gen: G,
615    z_gen: G,
616}
617
618#[derive(Clone, Copy, Debug, PartialEq)]
619pub struct UniformVec4<G> {
620    x_gen: G,
621    y_gen: G,
622    z_gen: G,
623    w_gen: G,
624}
625
626mod f32 {
627    use crate::f32::math;
628    use crate::{Mat2, Mat3, Mat4, Quat, Vec2, Vec3, Vec3A, Vec4};
629    use core::f32::consts::TAU;
630
631    impl_float_types!(f32, Mat2, Mat3, Mat4, Quat, Vec2, Vec3, Vec4);
632
633    impl Distribution<Vec3A> for StandardUniform {
634        #[inline]
635        fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Vec3A {
636            rng.random::<[f32; 3]>().into()
637        }
638    }
639
640    #[test]
641    fn test_vec3a_rand_standard() {
642        use rand::{Rng, SeedableRng};
643        use rand_xoshiro::Xoshiro256Plus;
644        let mut rng1 = Xoshiro256Plus::seed_from_u64(0);
645        let a: (f32, f32, f32) = rng1.random();
646        let mut rng2 = Xoshiro256Plus::seed_from_u64(0);
647        let b: Vec3A = rng2.random();
648        assert_eq!(a, b.into());
649    }
650}
651
652mod f64 {
653    use crate::f64::math;
654    use crate::{DMat2, DMat3, DMat4, DQuat, DVec2, DVec3, DVec4};
655    use core::f64::consts::TAU;
656
657    impl_float_types!(f64, DMat2, DMat3, DMat4, DQuat, DVec2, DVec3, DVec4);
658}
659
660mod i8 {
661    use crate::{I8Vec2, I8Vec3, I8Vec4};
662
663    impl_int_types!(i8, I8Vec2, I8Vec3, I8Vec4);
664}
665
666mod i16 {
667    use crate::{I16Vec2, I16Vec3, I16Vec4};
668
669    impl_int_types!(i16, I16Vec2, I16Vec3, I16Vec4);
670}
671
672mod i32 {
673    use crate::{IVec2, IVec3, IVec4};
674
675    impl_int_types!(i32, IVec2, IVec3, IVec4);
676}
677
678mod i64 {
679    use crate::{I64Vec2, I64Vec3, I64Vec4};
680
681    impl_int_types!(i64, I64Vec2, I64Vec3, I64Vec4);
682}
683
684mod u8 {
685    use crate::{U8Vec2, U8Vec3, U8Vec4};
686
687    impl_int_types!(u8, U8Vec2, U8Vec3, U8Vec4);
688}
689
690mod u16 {
691    use crate::{U16Vec2, U16Vec3, U16Vec4};
692
693    impl_int_types!(u16, U16Vec2, U16Vec3, U16Vec4);
694}
695
696mod u32 {
697    use crate::{UVec2, UVec3, UVec4};
698
699    impl_int_types!(u32, UVec2, UVec3, UVec4);
700}
701
702mod u64 {
703    use crate::{U64Vec2, U64Vec3, U64Vec4};
704
705    impl_int_types!(u64, U64Vec2, U64Vec3, U64Vec4);
706}