feanor_math/matrix/
transpose.rs

1use super::submatrix::*;
2
3use std::ops::Range;
4
5#[stability::unstable(feature = "enable")]
6pub struct TransposableSubmatrix<'a, V: AsPointerToSlice<T>, T, const TRANSPOSED: bool> {
7    data: Submatrix<'a, V, T>
8}
9
10impl<'a, V: AsPointerToSlice<T>, T> From<Submatrix<'a, V, T>> for TransposableSubmatrix<'a, V, T, false> {
11
12    fn from(value: Submatrix<'a, V, T>) -> Self {
13        Self { data: value }
14    }
15}
16
17impl<'a, V: AsPointerToSlice<T>, T> TransposableSubmatrix<'a, V, T, false> {
18
19    #[stability::unstable(feature = "enable")]
20    pub fn transpose(self) -> TransposableSubmatrix<'a, V, T, true> {
21        TransposableSubmatrix { data: self.data }
22    }
23}
24
25impl<'a, V: AsPointerToSlice<T>, T> TransposableSubmatrix<'a, V, T, true> {
26
27    #[stability::unstable(feature = "enable")]
28    pub fn transpose(self) -> TransposableSubmatrix<'a, V, T, false> {
29        TransposableSubmatrix { data: self.data }
30    }
31}
32
33impl<'a, V: AsPointerToSlice<T>, T, const TRANSPOSED: bool> Copy for TransposableSubmatrix<'a, V, T, TRANSPOSED> {}
34
35impl<'a, V: AsPointerToSlice<T>, T, const TRANSPOSED: bool> Clone for TransposableSubmatrix<'a, V, T, TRANSPOSED> {
36
37    fn clone(&self) -> Self {
38        *self
39    }
40}
41
42impl<'a, V: AsPointerToSlice<T>, T, const TRANSPOSED: bool> TransposableSubmatrix<'a, V, T, TRANSPOSED> {
43    
44    #[stability::unstable(feature = "enable")]
45    pub fn submatrix(self, rows: Range<usize>, cols: Range<usize>) -> Self {
46        if TRANSPOSED {
47            Self { data: self.data.submatrix(cols, rows) }
48        } else {
49            Self { data: self.data.submatrix(rows, cols) }
50        }
51    }
52
53    #[stability::unstable(feature = "enable")]
54    pub fn restrict_rows(self, rows: Range<usize>) -> Self {
55        if TRANSPOSED {
56            Self { data: self.data.restrict_cols(rows) }
57        } else {
58            Self { data: self.data.restrict_rows(rows) }
59        }
60    }
61
62    #[stability::unstable(feature = "enable")]
63    pub fn into_at(self, i: usize, j: usize) -> &'a T {
64        if TRANSPOSED {
65            self.data.into_at(j, i)
66        } else {
67            self.data.into_at(i, j)
68        }
69    }
70    
71    #[stability::unstable(feature = "enable")]
72    pub fn at<'b>(&'b self, i: usize, j: usize) -> &'b T {
73        if TRANSPOSED {
74            self.data.at(j, i)
75        } else {
76            self.data.at(i, j)
77        }
78    }
79
80    #[stability::unstable(feature = "enable")]
81    pub fn restrict_cols(self, cols: Range<usize>) -> Self {
82        if TRANSPOSED {
83            Self { data: self.data.restrict_rows(cols) }
84        } else {
85            Self { data: self.data.restrict_cols(cols) }
86        }
87    }
88
89    #[stability::unstable(feature = "enable")]
90    pub fn col_count(&self) -> usize {
91        if TRANSPOSED {
92            self.data.row_count()
93        } else {
94            self.data.col_count()
95        }
96    }
97
98    #[stability::unstable(feature = "enable")]
99    pub fn row_count(&self) -> usize {
100        if TRANSPOSED {
101            self.data.col_count()
102        } else {
103            self.data.row_count()
104        }
105    }
106}
107
108#[stability::unstable(feature = "enable")]
109pub struct TransposableSubmatrixMut<'a, V: AsPointerToSlice<T>, T, const TRANSPOSED: bool> {
110    data: SubmatrixMut<'a, V, T>
111}
112
113impl<'a, V: AsPointerToSlice<T>, T> TransposableSubmatrixMut<'a, V, T, false> {
114
115    #[stability::unstable(feature = "enable")]
116    pub fn transpose(self) -> TransposableSubmatrixMut<'a, V, T, true> {
117        TransposableSubmatrixMut { data: self.data }
118    }
119}
120
121impl<'a, V: AsPointerToSlice<T>, T> TransposableSubmatrixMut<'a, V, T, true> {
122
123    #[stability::unstable(feature = "enable")]
124    pub fn transpose(self) -> TransposableSubmatrixMut<'a, V, T, false> {
125        TransposableSubmatrixMut { data: self.data }
126    }
127}
128
129impl<'a, V: AsPointerToSlice<T>, T> From<SubmatrixMut<'a, V, T>> for TransposableSubmatrixMut<'a, V, T, false> {
130
131    fn from(value: SubmatrixMut<'a, V, T>) -> Self {
132        Self { data: value }
133    }
134}
135
136impl<'a, V: AsPointerToSlice<T>, T, const TRANSPOSED: bool> TransposableSubmatrixMut<'a, V, T, TRANSPOSED> {
137
138    #[stability::unstable(feature = "enable")]
139    pub fn submatrix(self, rows: Range<usize>, cols: Range<usize>) -> Self {
140        if TRANSPOSED {
141            Self { data: self.data.submatrix(cols, rows) }
142        } else {
143            Self { data: self.data.submatrix(rows, cols) }
144        }
145    }
146
147    #[stability::unstable(feature = "enable")]
148    pub fn restrict_rows(self, rows: Range<usize>) -> Self {
149        if TRANSPOSED {
150            Self { data: self.data.restrict_cols(rows) }
151        } else {
152            Self { data: self.data.restrict_rows(rows) }
153        }
154    }
155
156    #[stability::unstable(feature = "enable")]
157    pub fn at<'b>(&'b self, i: usize, j: usize) -> &'b T {
158        if TRANSPOSED {
159            self.data.at(j, i)
160        } else {
161            self.data.at(i, j)
162        }
163    }
164
165    #[stability::unstable(feature = "enable")]
166    pub fn restrict_cols(self, cols: Range<usize>) -> Self {
167        if TRANSPOSED {
168            Self { data: self.data.restrict_rows(cols) }
169        } else {
170            Self { data: self.data.restrict_cols(cols) }
171        }
172    }
173
174    #[stability::unstable(feature = "enable")]
175    pub fn col_count(&self) -> usize {
176        if TRANSPOSED {
177            self.data.row_count()
178        } else {
179            self.data.col_count()
180        }
181    }
182
183    #[stability::unstable(feature = "enable")]
184    pub fn row_count(&self) -> usize {
185        if TRANSPOSED {
186            self.data.col_count()
187        } else {
188            self.data.row_count()
189        }
190    }
191
192    #[stability::unstable(feature = "enable")]
193    pub fn split_rows(self, fst_rows: Range<usize>, snd_rows: Range<usize>) -> (Self, Self) {
194        if TRANSPOSED {
195            let (fst, snd) = self.data.split_cols(fst_rows, snd_rows);
196            return (Self { data: fst }, Self { data: snd });
197        } else {
198            let (fst, snd) = self.data.split_rows(fst_rows, snd_rows);
199            return (Self { data: fst }, Self { data: snd });
200        }
201    }
202
203    #[stability::unstable(feature = "enable")]
204    pub fn split_cols(self, fst_cols: Range<usize>, snd_cols: Range<usize>) -> (Self, Self) {
205        if TRANSPOSED {
206            let (fst, snd) = self.data.split_rows(fst_cols, snd_cols);
207            return (Self { data: fst }, Self { data: snd });
208        } else {
209            let (fst, snd) = self.data.split_cols(fst_cols, snd_cols);
210            return (Self { data: fst }, Self { data: snd });
211        }
212    }
213
214    #[stability::unstable(feature = "enable")]
215    pub fn at_mut<'b>(&'b mut self, i: usize, j: usize) -> &'b mut T {
216        if TRANSPOSED {
217            self.data.at_mut(j, i)
218        } else {
219            self.data.at_mut(i, j)
220        }
221    }
222
223    #[stability::unstable(feature = "enable")]
224    pub fn into_at_mut(self, i: usize, j: usize) -> &'a mut T {
225        if TRANSPOSED {
226            self.data.into_at_mut(j, i)
227        } else {
228            self.data.into_at_mut(i, j)
229        }
230    }
231
232    #[stability::unstable(feature = "enable")]
233    pub fn reborrow<'b>(&'b mut self) -> TransposableSubmatrixMut<'b, V, T, TRANSPOSED> {
234        TransposableSubmatrixMut { data: self.data.reborrow() }
235    }
236
237    #[stability::unstable(feature = "enable")]
238    pub fn as_const<'b>(&'b self) -> TransposableSubmatrix<'b, V, T, TRANSPOSED> {
239        TransposableSubmatrix { data: self.data.as_const() }
240    }
241}