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