mat/traits.rs
1//! Traits
2
3use generic_array::typenum::Unsigned;
4
5/// The transpose operation
6pub trait Transpose: Copy {
7 /// Transposes the matrix
8 fn t(self) -> super::Transpose<Self> {
9 super::Transpose { m: self }
10 }
11}
12
13/// A matrix
14pub trait Matrix: UnsafeGet {
15 /// Number of rows
16 type NROWS: Unsigned;
17 /// Number of columns
18 type NCOLS: Unsigned;
19
20 /// Returns the element at row `r` and column `c`
21 ///
22 /// # Panics
23 ///
24 /// This operation panics if `r` or `c` exceed the matrix dimensions
25 fn get(self, r: usize, c: usize) -> Self::Elem {
26 assert!(r < self.nrows() && c < self.ncols());
27
28 unsafe { self.unsafe_get(r, c) }
29 }
30
31 /// Returns the size of the matrix
32 fn size(self) -> (usize, usize) {
33 (Self::NROWS::to_usize(), Self::NCOLS::to_usize())
34 }
35
36 /// Returns the number of rows of the matrix
37 fn nrows(self) -> usize {
38 self.size().0
39 }
40
41 /// Returns the number of columns of the matrix
42 fn ncols(self) -> usize {
43 self.size().1
44 }
45}
46
47/// Unsafe indexing
48// NOTE(`: Copy`) this bound is a lint against expression trees that take ownership of `Mat`
49pub trait UnsafeGet: Copy {
50 /// The matrix element type
51 // NOTE(`: Copy`) let's narrow down the problem to matrices that contain only primitive types
52 type Elem: Copy;
53
54 /// Returns the element at row `r` and column `c` with performing bounds checks
55 unsafe fn unsafe_get(self, r: usize, c: usize) -> Self::Elem;
56}
57
58/// Types that have a "zero" value
59pub trait Zero {
60 /// Returns the value of this type that represents the number zero
61 fn zero() -> Self;
62}
63
64macro_rules! zero {
65 ($($ty:ty),+) => {
66 $(
67 impl Zero for $ty {
68 fn zero() -> Self {
69 0
70 }
71 }
72 )+
73 }
74}
75
76zero!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize);
77
78impl Zero for f32 {
79 fn zero() -> f32 {
80 0.
81 }
82}
83
84impl Zero for f64 {
85 fn zero() -> f64 {
86 0.
87 }
88}