1
1
//! Traits related to vectors.
2
2
3
- use crate :: scalar:: { Scalar , VectorOrScalar } ;
3
+ use crate :: scalar:: Scalar ;
4
+ use core:: num:: NonZeroUsize ;
4
5
use glam:: { Vec3Swizzles , Vec4Swizzles } ;
5
6
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 ;
28
15
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 ;
37
18
}
38
19
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
+ }
47
26
}
48
27
49
28
/// Abstract trait representing a SPIR-V vector type.
@@ -53,22 +32,24 @@ unsafe impl VectorOrScalar for glam::IVec4 {
53
32
/// should not be done.
54
33
pub unsafe trait Vector < T : Scalar , const N : usize > : VectorOrScalar < Scalar = T > { }
55
34
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
+ }
68
46
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
+ }
72
53
73
54
/// Trait that implements slicing of a vector into a scalar or vector of lower dimensions, by
74
55
/// ignoring the higter dimensions
0 commit comments