Skip to main content

feanor_math/matrix/
transpose.rs

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