11//! Traits related to vectors.
22
3- use crate :: scalar:: { Scalar , VectorOrScalar } ;
3+ use crate :: scalar:: Scalar ;
4+ use core:: num:: NonZeroUsize ;
45use glam:: { Vec3Swizzles , Vec4Swizzles } ;
56
6- unsafe impl VectorOrScalar for glam:: Vec2 {
7- type Scalar = f32 ;
8- }
9- unsafe impl VectorOrScalar for glam:: Vec3 {
10- type Scalar = f32 ;
11- }
12- unsafe impl VectorOrScalar for glam:: Vec3A {
13- type Scalar = f32 ;
14- }
15- unsafe impl VectorOrScalar for glam:: Vec4 {
16- type Scalar = f32 ;
17- }
18-
19- unsafe impl VectorOrScalar for glam:: DVec2 {
20- type Scalar = f64 ;
21- }
22- unsafe impl VectorOrScalar for glam:: DVec3 {
23- type Scalar = f64 ;
24- }
25- unsafe impl VectorOrScalar for glam:: DVec4 {
26- type Scalar = f64 ;
27- }
7+ /// Abstract trait representing either a vector or a scalar type.
8+ ///
9+ /// # Safety
10+ /// Implementing this trait on non-scalar or non-vector types may break assumptions about other
11+ /// unsafe code, and should not be done.
12+ pub unsafe trait VectorOrScalar : Default {
13+ /// Either the scalar component type of the vector or the scalar itself.
14+ type Scalar : Scalar ;
2815
29- unsafe impl VectorOrScalar for glam:: UVec2 {
30- type Scalar = u32 ;
31- }
32- unsafe impl VectorOrScalar for glam:: UVec3 {
33- type Scalar = u32 ;
34- }
35- unsafe impl VectorOrScalar for glam:: UVec4 {
36- type Scalar = u32 ;
16+ /// The dimension of the vector, or 1 if it is a scalar
17+ const DIM : NonZeroUsize ;
3718}
3819
39- unsafe impl VectorOrScalar for glam:: IVec2 {
40- type Scalar = i32 ;
41- }
42- unsafe impl VectorOrScalar for glam:: IVec3 {
43- type Scalar = i32 ;
44- }
45- unsafe impl VectorOrScalar for glam:: IVec4 {
46- type Scalar = i32 ;
20+ /// replace with `NonZeroUsize::new(n).unwrap()` once `unwrap()` is const stabilized
21+ pub ( crate ) const fn create_dim ( n : usize ) -> NonZeroUsize {
22+ match NonZeroUsize :: new ( n) {
23+ None => panic ! ( "dim must not be 0" ) ,
24+ Some ( n) => n,
25+ }
4726}
4827
4928/// Abstract trait representing a SPIR-V vector type.
@@ -53,22 +32,24 @@ unsafe impl VectorOrScalar for glam::IVec4 {
5332/// should not be done.
5433pub unsafe trait Vector < T : Scalar , const N : usize > : VectorOrScalar < Scalar = T > { }
5534
56- unsafe impl Vector < f32 , 2 > for glam:: Vec2 { }
57- unsafe impl Vector < f32 , 3 > for glam:: Vec3 { }
58- unsafe impl Vector < f32 , 3 > for glam:: Vec3A { }
59- unsafe impl Vector < f32 , 4 > for glam:: Vec4 { }
60-
61- unsafe impl Vector < f64 , 2 > for glam:: DVec2 { }
62- unsafe impl Vector < f64 , 3 > for glam:: DVec3 { }
63- unsafe impl Vector < f64 , 4 > for glam:: DVec4 { }
64-
65- unsafe impl Vector < u32 , 2 > for glam:: UVec2 { }
66- unsafe impl Vector < u32 , 3 > for glam:: UVec3 { }
67- unsafe impl Vector < u32 , 4 > for glam:: UVec4 { }
35+ macro_rules! impl_vector {
36+ ( $( $scalar: ty: $( $vec: ty => $dim: literal) ,+; ) +) => {
37+ $( $(
38+ unsafe impl VectorOrScalar for $vec {
39+ type Scalar = $scalar;
40+ const DIM : NonZeroUsize = create_dim( $dim) ;
41+ }
42+ unsafe impl Vector <$scalar, $dim> for $vec { }
43+ ) +) +
44+ } ;
45+ }
6846
69- unsafe impl Vector < i32 , 2 > for glam:: IVec2 { }
70- unsafe impl Vector < i32 , 3 > for glam:: IVec3 { }
71- unsafe impl Vector < i32 , 4 > for glam:: IVec4 { }
47+ impl_vector ! {
48+ f32 : glam:: Vec2 => 2 , glam:: Vec3 => 3 , glam:: Vec3A => 3 , glam:: Vec4 => 4 ;
49+ f64 : glam:: DVec2 => 2 , glam:: DVec3 => 3 , glam:: DVec4 => 4 ;
50+ u32 : glam:: UVec2 => 2 , glam:: UVec3 => 3 , glam:: UVec4 => 4 ;
51+ i32 : glam:: IVec2 => 2 , glam:: IVec3 => 3 , glam:: IVec4 => 4 ;
52+ }
7253
7354/// Trait that implements slicing of a vector into a scalar or vector of lower dimensions, by
7455/// ignoring the higter dimensions
0 commit comments