1use crate::matrix::Matrix;
2use crate::matrix_transpose_view_mut::MatrixTransposeViewMut;
3use crate::matrix_view::MatrixView;
4use crate::matrix_view_mut::MatrixViewMut;
5use std::fmt;
6use std::ops::Index;
7
8#[derive(Debug)]
10pub struct MatrixTransposeView<
11 'a,
12 T,
13 const R: usize,
14 const C: usize,
15 const VR: usize,
16 const VC: usize,
17> {
18 data: &'a Matrix<T, R, C>,
19 start: (usize, usize), }
21
22impl<'a, T, const R: usize, const C: usize, const VR: usize, const VC: usize>
23 MatrixTransposeView<'a, T, R, C, VR, VC>
24{
25 pub(super) fn new(data: &'a Matrix<T, R, C>, start: (usize, usize)) -> Self {
26 if start.0 + VR > C || start.1 + VC > R {
27 panic!("View size out of bounds");
28 }
29 Self { data, start }
30 }
31}
32
33impl<'a, T, const R: usize, const C: usize, const VR: usize, const VC: usize>
34 MatrixTransposeView<'a, T, R, C, VR, VC>
35{
36 #[inline]
50 pub fn shape(&self) -> (usize, usize) {
51 (VR, VC)
52 }
53
54 #[inline]
68 pub fn capacity(&self) -> usize {
69 VR * VC
70 }
71
72 #[inline]
86 pub fn rows(&self) -> usize {
87 VR
88 }
89
90 #[inline]
104 pub fn cols(&self) -> usize {
105 VC
106 }
107
108 pub fn t(&self) -> MatrixView<T, R, C, VC, VR> {
123 MatrixView::new(self.data, (self.start.1, self.start.0))
124 }
125}
126
127impl<'a, T: PartialEq, const R: usize, const C: usize, const VR: usize, const VC: usize>
133 PartialEq<Matrix<T, VR, VC>> for MatrixTransposeView<'a, T, R, C, VR, VC>
134{
135 fn eq(&self, other: &Matrix<T, VR, VC>) -> bool {
136 (0..VR).all(|i| (0..VC).all(|j| self[(i, j)] == other[(i, j)]))
137 }
138}
139
140impl<
142 'a,
143 T: PartialEq,
144 const A: usize,
145 const B: usize,
146 const R: usize,
147 const C: usize,
148 const VR: usize,
149 const VC: usize,
150 > PartialEq<MatrixView<'a, T, A, B, VR, VC>> for MatrixTransposeView<'a, T, R, C, VR, VC>
151{
152 fn eq(&self, other: &MatrixView<'a, T, A, B, VR, VC>) -> bool {
153 (0..VR).all(|i| (0..VC).all(|j| self[(i, j)] == other[(i, j)]))
154 }
155}
156
157impl<
159 'a,
160 T: PartialEq,
161 const A: usize,
162 const B: usize,
163 const R: usize,
164 const C: usize,
165 const VR: usize,
166 const VC: usize,
167 > PartialEq<MatrixViewMut<'a, T, A, B, VR, VC>> for MatrixTransposeView<'a, T, R, C, VR, VC>
168{
169 fn eq(&self, other: &MatrixViewMut<'a, T, A, B, VR, VC>) -> bool {
170 (0..VR).all(|i| (0..VC).all(|j| self[(i, j)] == other[(i, j)]))
171 }
172}
173
174impl<
176 'a,
177 T: PartialEq,
178 const A: usize,
179 const B: usize,
180 const R: usize,
181 const C: usize,
182 const VR: usize,
183 const VC: usize,
184 > PartialEq<MatrixTransposeView<'a, T, A, B, VR, VC>>
185 for MatrixTransposeView<'a, T, R, C, VR, VC>
186{
187 fn eq(&self, other: &MatrixTransposeView<'a, T, A, B, VR, VC>) -> bool {
188 (0..VR).all(|i| (0..VC).all(|j| self[(i, j)] == other[(i, j)]))
189 }
190}
191
192impl<
194 'a,
195 T: PartialEq,
196 const A: usize,
197 const B: usize,
198 const R: usize,
199 const C: usize,
200 const VR: usize,
201 const VC: usize,
202 > PartialEq<MatrixTransposeViewMut<'a, T, A, B, VR, VC>>
203 for MatrixTransposeView<'a, T, R, C, VR, VC>
204{
205 fn eq(&self, other: &MatrixTransposeViewMut<'a, T, A, B, VR, VC>) -> bool {
206 (0..VR).all(|i| (0..VC).all(|j| self[(i, j)] == other[(i, j)]))
207 }
208}
209
210impl<'a, T: Eq, const R: usize, const C: usize, const VR: usize, const VC: usize> Eq
211 for MatrixTransposeView<'a, T, R, C, VR, VC>
212{
213}
214
215impl<T: fmt::Display, const R: usize, const C: usize, const VR: usize, const VC: usize> fmt::Display
220 for MatrixTransposeView<'_, T, R, C, VR, VC>
221{
222 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
223 if f.alternate() {
224 write!(f, "MatrixTransposeView(")?;
225 }
226
227 write!(f, "[")?;
228 for i in 0..VR {
229 if i > 0 {
230 write!(f, " ")?;
231 if f.alternate() {
232 write!(f, " ")?;
233 }
234 }
235 write!(f, "[")?;
236 for j in 0..VC {
237 write!(f, "{}", self[(i, j)])?;
238 if j < VC - 1 {
239 write!(f, ", ")?;
240 }
241 }
242 write!(f, "]")?;
243 if i < VR - 1 {
244 writeln!(f)?;
245 }
246 }
247 write!(f, "]")?;
248
249 if f.alternate() {
250 write!(f, ", dtype={})", std::any::type_name::<T>())?;
251 }
252
253 Ok(())
254 }
255}
256
257impl<'a, T, const R: usize, const C: usize, const VR: usize, const VC: usize>
262 MatrixTransposeView<'a, T, R, C, VR, VC>
263{
264 #[inline]
265 fn flip(&self, index: (usize, usize)) -> (usize, usize) {
266 (index.1, index.0)
267 }
268
269 #[inline]
270 fn offset(&self, index: (usize, usize)) -> (usize, usize) {
271 (index.0 + self.start.0, index.1 + self.start.1)
272 }
273
274 #[inline]
275 fn validate_index(&self, index: (usize, usize)) -> bool {
276 index.0 < VR && index.1 < VC
277 }
278}
279
280impl<T, const R: usize, const C: usize, const VR: usize, const VC: usize> Index<usize>
281 for MatrixTransposeView<'_, T, R, C, VR, VC>
282{
283 type Output = T;
284 fn index(&self, index: usize) -> &Self::Output {
285 if index >= R * C {
286 panic!("Index out of bounds");
287 }
288
289 let row_idx = index / VC;
290 let col_idx = index % VC;
291 &self.data[self.flip(self.offset((row_idx, col_idx)))]
292 }
293}
294
295impl<T, const R: usize, const C: usize, const VR: usize, const VC: usize> Index<(usize, usize)>
296 for MatrixTransposeView<'_, T, R, C, VR, VC>
297{
298 type Output = T;
299 fn index(&self, index: (usize, usize)) -> &Self::Output {
300 if !self.validate_index(index) {
301 panic!("Index out of bounds");
302 }
303 &self.data[self.flip(self.offset(index))]
304 }
305}