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}