1#![allow(missing_docs)]
2use crate::col::{Col, ColMut, ColRef};
3use crate::mat::{Mat, MatMut, MatRef};
4use crate::row::{Row, RowMut, RowRef};
5use crate::{ContiguousFwd, Idx, Shape, Stride, Unbind, diag};
6use core::marker::PhantomData;
7use equator::{assert, debug_assert};
8use reborrow::*;
9pub trait IntoView {
10 type Target;
11 fn into_view(self) -> Self::Target;
12}
13impl<'a, T, Rows: Shape, Cols: Shape> IntoView for &'a mut Mat<T, Rows, Cols> {
14 type Target = MatMut<'a, T, Rows, Cols, ContiguousFwd>;
15
16 #[inline]
17 fn into_view(self) -> Self::Target {
18 self.as_mut().try_as_col_major_mut().unwrap()
19 }
20}
21impl<'a, T, Rows: Shape, Cols: Shape> IntoView for &'a Mat<T, Rows, Cols> {
22 type Target = MatRef<'a, T, Rows, Cols, ContiguousFwd>;
23
24 #[inline]
25 fn into_view(self) -> Self::Target {
26 self.as_ref().try_as_col_major().unwrap()
27 }
28}
29impl<'a, T, Len: Shape> IntoView for &'a mut Col<T, Len> {
30 type Target = ColMut<'a, T, Len, ContiguousFwd>;
31
32 #[inline]
33 fn into_view(self) -> Self::Target {
34 self.as_mut().try_as_col_major_mut().unwrap()
35 }
36}
37impl<'a, T, Len: Shape> IntoView for &'a Col<T, Len> {
38 type Target = ColRef<'a, T, Len, ContiguousFwd>;
39
40 #[inline]
41 fn into_view(self) -> Self::Target {
42 self.as_ref().try_as_col_major().unwrap()
43 }
44}
45impl<'a, T, Len: Shape> IntoView for &'a mut Row<T, Len> {
46 type Target = RowMut<'a, T, Len, ContiguousFwd>;
47
48 #[inline]
49 fn into_view(self) -> Self::Target {
50 self.as_mut().try_as_row_major_mut().unwrap()
51 }
52}
53impl<'a, T, Len: Shape> IntoView for &'a Row<T, Len> {
54 type Target = RowRef<'a, T, Len, ContiguousFwd>;
55
56 #[inline]
57 fn into_view(self) -> Self::Target {
58 self.as_ref().try_as_row_major().unwrap()
59 }
60}
61impl<'a, T, Len: Shape> IntoView for &'a mut diag::Diag<T, Len> {
62 type Target = diag::DiagMut<'a, T, Len, ContiguousFwd>;
63
64 #[inline]
65 fn into_view(self) -> Self::Target {
66 self.as_mut()
67 .column_vector_mut()
68 .try_as_col_major_mut()
69 .unwrap()
70 .as_diagonal_mut()
71 }
72}
73impl<'a, T, Len: Shape> IntoView for &'a diag::Diag<T, Len> {
74 type Target = diag::DiagRef<'a, T, Len, ContiguousFwd>;
75
76 #[inline]
77 fn into_view(self) -> Self::Target {
78 self.as_ref()
79 .column_vector()
80 .try_as_col_major()
81 .unwrap()
82 .as_diagonal()
83 }
84}
85impl<'a, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> IntoView
86 for MatMut<'a, T, Rows, Cols, RStride, CStride>
87{
88 type Target = Self;
89
90 #[inline]
91 fn into_view(self) -> Self::Target {
92 self
93 }
94}
95impl<'a, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> IntoView
96 for MatRef<'a, T, Rows, Cols, RStride, CStride>
97{
98 type Target = Self;
99
100 #[inline]
101 fn into_view(self) -> Self::Target {
102 self
103 }
104}
105impl<'a, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> IntoView
106 for &'a MatMut<'_, T, Rows, Cols, RStride, CStride>
107{
108 type Target = MatRef<'a, T, Rows, Cols, RStride, CStride>;
109
110 #[inline]
111 fn into_view(self) -> Self::Target {
112 self.rb()
113 }
114}
115impl<'a, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> IntoView
116 for &'a MatRef<'_, T, Rows, Cols, RStride, CStride>
117{
118 type Target = MatRef<'a, T, Rows, Cols, RStride, CStride>;
119
120 #[inline]
121 fn into_view(self) -> Self::Target {
122 *self
123 }
124}
125impl<'a, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> IntoView
126 for &'a mut MatMut<'_, T, Rows, Cols, RStride, CStride>
127{
128 type Target = MatMut<'a, T, Rows, Cols, RStride, CStride>;
129
130 #[inline]
131 fn into_view(self) -> Self::Target {
132 self.rb_mut()
133 }
134}
135impl<'a, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> IntoView
136 for &'a mut MatRef<'_, T, Rows, Cols, RStride, CStride>
137{
138 type Target = MatRef<'a, T, Rows, Cols, RStride, CStride>;
139
140 #[inline]
141 fn into_view(self) -> Self::Target {
142 *self
143 }
144}
145impl<'a, T, Rows: Shape, RStride: Stride> IntoView
146 for ColMut<'a, T, Rows, RStride>
147{
148 type Target = Self;
149
150 #[inline]
151 fn into_view(self) -> Self::Target {
152 self
153 }
154}
155impl<'a, T, Rows: Shape, RStride: Stride> IntoView
156 for ColRef<'a, T, Rows, RStride>
157{
158 type Target = Self;
159
160 #[inline]
161 fn into_view(self) -> Self::Target {
162 self
163 }
164}
165impl<'a, T, Rows: Shape, RStride: Stride> IntoView
166 for &'a ColMut<'_, T, Rows, RStride>
167{
168 type Target = ColRef<'a, T, Rows, RStride>;
169
170 #[inline]
171 fn into_view(self) -> Self::Target {
172 self.rb()
173 }
174}
175impl<'a, T, Rows: Shape, RStride: Stride> IntoView
176 for &'a ColRef<'_, T, Rows, RStride>
177{
178 type Target = ColRef<'a, T, Rows, RStride>;
179
180 #[inline]
181 fn into_view(self) -> Self::Target {
182 *self
183 }
184}
185impl<'a, T, Rows: Shape, RStride: Stride> IntoView
186 for &'a mut ColMut<'_, T, Rows, RStride>
187{
188 type Target = ColMut<'a, T, Rows, RStride>;
189
190 #[inline]
191 fn into_view(self) -> Self::Target {
192 self.rb_mut()
193 }
194}
195impl<'a, T, Rows: Shape, RStride: Stride> IntoView
196 for &'a mut ColRef<'_, T, Rows, RStride>
197{
198 type Target = ColRef<'a, T, Rows, RStride>;
199
200 #[inline]
201 fn into_view(self) -> Self::Target {
202 *self
203 }
204}
205impl<'a, T, Rows: Shape, DStride: Stride> IntoView
206 for diag::DiagMut<'a, T, Rows, DStride>
207{
208 type Target = Self;
209
210 #[inline]
211 fn into_view(self) -> Self::Target {
212 self
213 }
214}
215impl<'a, T, Rows: Shape, DStride: Stride> IntoView
216 for diag::DiagRef<'a, T, Rows, DStride>
217{
218 type Target = Self;
219
220 #[inline]
221 fn into_view(self) -> Self::Target {
222 self
223 }
224}
225impl<'a, T, Rows: Shape, DStride: Stride> IntoView
226 for &'a diag::DiagMut<'_, T, Rows, DStride>
227{
228 type Target = diag::DiagRef<'a, T, Rows, DStride>;
229
230 #[inline]
231 fn into_view(self) -> Self::Target {
232 self.rb()
233 }
234}
235impl<'a, T, Rows: Shape, DStride: Stride> IntoView
236 for &'a diag::DiagRef<'_, T, Rows, DStride>
237{
238 type Target = diag::DiagRef<'a, T, Rows, DStride>;
239
240 #[inline]
241 fn into_view(self) -> Self::Target {
242 *self
243 }
244}
245impl<'a, T, Rows: Shape, DStride: Stride> IntoView
246 for &'a mut diag::DiagMut<'_, T, Rows, DStride>
247{
248 type Target = diag::DiagMut<'a, T, Rows, DStride>;
249
250 #[inline]
251 fn into_view(self) -> Self::Target {
252 self.rb_mut()
253 }
254}
255impl<'a, T, Rows: Shape, DStride: Stride> IntoView
256 for &'a mut diag::DiagRef<'_, T, Rows, DStride>
257{
258 type Target = diag::DiagRef<'a, T, Rows, DStride>;
259
260 #[inline]
261 fn into_view(self) -> Self::Target {
262 *self
263 }
264}
265impl<'a, T, Cols: Shape, CStride: Stride> IntoView
266 for RowMut<'a, T, Cols, CStride>
267{
268 type Target = Self;
269
270 #[inline]
271 fn into_view(self) -> Self::Target {
272 self
273 }
274}
275impl<'a, T, Cols: Shape, CStride: Stride> IntoView
276 for RowRef<'a, T, Cols, CStride>
277{
278 type Target = Self;
279
280 #[inline]
281 fn into_view(self) -> Self::Target {
282 self
283 }
284}
285impl<'a, T, Cols: Shape, CStride: Stride> IntoView
286 for &'a RowMut<'_, T, Cols, CStride>
287{
288 type Target = RowRef<'a, T, Cols, CStride>;
289
290 #[inline]
291 fn into_view(self) -> Self::Target {
292 self.rb()
293 }
294}
295impl<'a, T, Cols: Shape, CStride: Stride> IntoView
296 for &'a RowRef<'_, T, Cols, CStride>
297{
298 type Target = RowRef<'a, T, Cols, CStride>;
299
300 #[inline]
301 fn into_view(self) -> Self::Target {
302 *self
303 }
304}
305impl<'a, T, Cols: Shape, CStride: Stride> IntoView
306 for &'a mut RowMut<'_, T, Cols, CStride>
307{
308 type Target = RowMut<'a, T, Cols, CStride>;
309
310 #[inline]
311 fn into_view(self) -> Self::Target {
312 self.rb_mut()
313 }
314}
315impl<'a, T, Cols: Shape, CStride: Stride> IntoView
316 for &'a mut RowRef<'_, T, Cols, CStride>
317{
318 type Target = RowRef<'a, T, Cols, CStride>;
319
320 #[inline]
321 fn into_view(self) -> Self::Target {
322 *self
323 }
324}
325#[derive(Copy, Clone, Debug, PartialEq, Eq)]
326pub enum Diag {
327 Skip,
328 Include,
329}
330#[derive(Copy, Clone)]
332pub enum MatLayoutTransform {
333 None,
335 ReverseRows,
337 Transpose,
339 TransposeReverseRows,
341}
342#[derive(Copy, Clone)]
344pub enum VecLayoutTransform {
345 None,
347 Reverse,
349}
350pub trait MatIndex {
352 type Kind;
353 type Rows: Copy + Eq + core::fmt::Debug;
355 type Cols: Copy + Eq + core::fmt::Debug;
357 fn nrows(this: &Self) -> Self::Rows;
359 fn ncols(this: &Self) -> Self::Cols;
361 type Index: Copy;
363 type LayoutTransform: Copy;
365 type Item;
367 type Dyn: MatIndex<
369 Kind = Self::Kind,
370 Dyn = Self::Dyn,
371 LayoutTransform = Self::LayoutTransform,
372 Item = Self::Item,
373 Slice = Self::Slice,
374 >;
375 type Slice: for<'a> SliceFamily<'a, Self::Item>;
376 unsafe fn get_slice_unchecked<'a>(
378 this: &'a mut Self,
379 idx: Self::Index,
380 n_elems: usize,
381 ) -> <Self::Slice as SliceFamily<'a, Self::Item>>::Slice;
382 unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index;
384 unsafe fn get_unchecked(this: &mut Self, index: Self::Index) -> Self::Item;
386 unsafe fn next_unchecked<'a>(
388 slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice,
389 ) -> Self::Item;
390 fn is_contiguous(this: &Self) -> bool;
392 fn preferred_layout(this: &Self) -> Self::LayoutTransform;
394 fn with_layout(this: Self, layout: Self::LayoutTransform) -> Self::Dyn;
396}
397pub trait SliceFamily<'a, T, Outlives = &'a Self> {
398 type Slice;
399}
400pub struct Slice<T>(pub T);
401pub struct SliceRef<'b, T>(pub &'b T);
402pub struct SliceMut<'b, T>(pub &'b mut T);
403impl<'a, T> SliceFamily<'a, T> for Slice<T> {
404 type Slice = &'a [T];
405}
406impl<'a, 'b, T> SliceFamily<'a, &'b T> for SliceRef<'b, T> {
407 type Slice = &'b [T];
408}
409impl<'a, 'b, T> SliceFamily<'a, &'b mut T> for SliceMut<'b, T> {
410 type Slice = &'b mut [T];
411}
412impl<'a, T, F: SliceFamily<'a, T>> SliceFamily<'a, Last<T>> for Last<F> {
413 type Slice = Last<F::Slice>;
414}
415impl<'a, T, U, F: SliceFamily<'a, T>, G: SliceFamily<'a, U>>
416 SliceFamily<'a, Zip<T, U>> for Zip<F, G>
417{
418 type Slice = Zip<F::Slice, G::Slice>;
419}
420#[derive(Copy, Clone, Debug)]
422pub struct LastEq<Kind, Mat>(pub Mat, pub PhantomData<Kind>);
423#[derive(Copy, Clone, Debug)]
425pub struct Last<Mat>(pub Mat);
426#[derive(Copy, Clone, Debug)]
428pub struct ZipEq<Kind, Head, Tail>(pub Head, pub Tail, PhantomData<Kind>);
429#[derive(Copy, Clone, Debug)]
431pub struct Zip<Head, Tail>(pub Head, pub Tail);
432impl<
434 Kind,
435 Rows: Copy + Eq + core::fmt::Debug,
436 Cols: Copy + Eq + core::fmt::Debug,
437 Head: MatIndex<Kind = Kind, Rows = Rows, Cols = Cols>,
438 Tail: MatIndex<Kind = Kind, Rows = Rows, Cols = Cols>,
439> ZipEq<Kind, Head, Tail>
440{
441 #[inline(always)]
443 #[track_caller]
444 pub fn new(head: Head, tail: Tail) -> Self {
445 assert!(all(
446 Head::nrows(&head) == Tail::nrows(&tail),
447 Head::ncols(&head) == Tail::ncols(&tail),
448 ));
449 Self(head, tail, PhantomData)
450 }
451
452 #[inline(always)]
454 #[track_caller]
455 pub fn new_unchecked(head: Head, tail: Tail) -> Self {
456 debug_assert!(all(
457 Head::nrows(&head) == Tail::nrows(&tail),
458 Head::ncols(&head) == Tail::ncols(&tail),
459 ));
460 Self(head, tail, PhantomData)
461 }
462}
463impl<
464 Kind,
465 Rows: Copy + Eq + core::fmt::Debug,
466 Cols: Copy + Eq + core::fmt::Debug,
467 Mat: MatIndex<Rows = Rows, Cols = Cols, Kind = Kind>,
468> MatIndex for LastEq<Kind, Mat>
469{
470 type Cols = Mat::Cols;
471 type Dyn = LastEq<<Mat::Dyn as MatIndex>::Kind, Mat::Dyn>;
472 type Index = Mat::Index;
473 type Item = Last<Mat::Item>;
474 type Kind = Mat::Kind;
475 type LayoutTransform = Mat::LayoutTransform;
476 type Rows = Mat::Rows;
477 type Slice = Last<Mat::Slice>;
478
479 #[inline(always)]
480 fn nrows(this: &Self) -> Self::Rows {
481 Mat::nrows(&this.0)
482 }
483
484 #[inline(always)]
485 fn ncols(this: &Self) -> Self::Cols {
486 Mat::ncols(&this.0)
487 }
488
489 #[inline]
490 unsafe fn get_slice_unchecked<'a>(
491 this: &'a mut Self,
492 idx: Self::Index,
493 n_elems: usize,
494 ) -> <Self::Slice as SliceFamily<'a, Self::Item>>::Slice {
495 Last(Mat::get_slice_unchecked(&mut this.0, idx, n_elems))
496 }
497
498 #[inline]
499 unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index {
500 Mat::from_dyn_idx(idx)
501 }
502
503 #[inline]
504 unsafe fn get_unchecked(this: &mut Self, index: Self::Index) -> Self::Item {
505 Last(Mat::get_unchecked(&mut this.0, index))
506 }
507
508 #[inline]
509 unsafe fn next_unchecked<'a>(
510 slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice,
511 ) -> Self::Item {
512 Last(Mat::next_unchecked(&mut slice.0))
513 }
514
515 #[inline]
516 fn is_contiguous(this: &Self) -> bool {
517 Mat::is_contiguous(&this.0)
518 }
519
520 #[inline]
521 fn preferred_layout(this: &Self) -> Self::LayoutTransform {
522 Mat::preferred_layout(&this.0)
523 }
524
525 #[inline]
526 fn with_layout(this: Self, layout: Self::LayoutTransform) -> Self::Dyn {
527 LastEq(Mat::with_layout(this.0, layout), PhantomData)
528 }
529}
530impl<
531 Kind,
532 Rows: Copy + Eq + core::fmt::Debug,
533 Cols: Copy + Eq + core::fmt::Debug,
534 L: MatIndex<Kind = Kind, Rows = Rows, Cols = Cols>,
535 R: MatIndex<
536 Kind = Kind,
537 Rows = Rows,
538 Cols = Cols,
539 Index = L::Index,
540 LayoutTransform = L::LayoutTransform,
541 >,
542> MatIndex for ZipEq<Kind, L, R>
543where
544 R::Dyn: MatIndex<
545 Rows = <L::Dyn as MatIndex>::Rows,
546 Cols = <L::Dyn as MatIndex>::Cols,
547 Index = <L::Dyn as MatIndex>::Index,
548 >,
549{
550 type Cols = L::Cols;
551 type Dyn = ZipEq<<L::Dyn as MatIndex>::Kind, L::Dyn, R::Dyn>;
552 type Index = L::Index;
553 type Item = Zip<L::Item, R::Item>;
554 type Kind = L::Kind;
555 type LayoutTransform = L::LayoutTransform;
556 type Rows = L::Rows;
557 type Slice = Zip<L::Slice, R::Slice>;
558
559 #[inline(always)]
560 fn nrows(this: &Self) -> Self::Rows {
561 L::nrows(&this.0)
562 }
563
564 #[inline(always)]
565 fn ncols(this: &Self) -> Self::Cols {
566 L::ncols(&this.0)
567 }
568
569 #[inline]
570 unsafe fn get_slice_unchecked<'a>(
571 this: &'a mut Self,
572 idx: Self::Index,
573 n_elems: usize,
574 ) -> <Self::Slice as SliceFamily<'a, Self::Item>>::Slice {
575 Zip(
576 L::get_slice_unchecked(&mut this.0, idx, n_elems),
577 R::get_slice_unchecked(&mut this.1, idx, n_elems),
578 )
579 }
580
581 #[inline]
582 unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index {
583 L::from_dyn_idx(idx)
584 }
585
586 #[inline]
587 unsafe fn get_unchecked(this: &mut Self, index: Self::Index) -> Self::Item {
588 Zip(
589 L::get_unchecked(&mut this.0, index),
590 R::get_unchecked(&mut this.1, index),
591 )
592 }
593
594 #[inline]
595 unsafe fn next_unchecked<'a>(
596 slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice,
597 ) -> Self::Item {
598 Zip(
599 L::next_unchecked(&mut slice.0),
600 R::next_unchecked(&mut slice.1),
601 )
602 }
603
604 #[inline]
605 fn is_contiguous(this: &Self) -> bool {
606 L::is_contiguous(&this.0) && R::is_contiguous(&this.1)
607 }
608
609 #[inline]
610 fn preferred_layout(this: &Self) -> Self::LayoutTransform {
611 L::preferred_layout(&this.0)
612 }
613
614 #[inline]
615 fn with_layout(this: Self, layout: Self::LayoutTransform) -> Self::Dyn {
616 ZipEq(
617 L::with_layout(this.0, layout),
618 R::with_layout(this.1, layout),
619 PhantomData,
620 )
621 }
622}
623impl<'b, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> MatIndex
624 for MatMut<'b, T, Rows, Cols, RStride, CStride>
625{
626 type Cols = Cols;
627 type Dyn = MatMut<'b, T, usize, usize, isize, isize>;
628 type Index = (Idx<Rows>, Idx<Cols>);
629 type Item = &'b mut T;
630 type Kind = kind::Mat;
631 type LayoutTransform = MatLayoutTransform;
632 type Rows = Rows;
633 type Slice = SliceMut<'b, T>;
634
635 #[inline]
636 fn nrows(this: &Self) -> Self::Rows {
637 this.nrows()
638 }
639
640 #[inline]
641 fn ncols(this: &Self) -> Self::Cols {
642 this.ncols()
643 }
644
645 #[inline]
646 unsafe fn get_slice_unchecked<'a>(
647 this: &'a mut Self,
648 idx: Self::Index,
649 n_elems: usize,
650 ) -> <Self::Slice as SliceFamily<'a, Self::Item>>::Slice {
651 let ptr = this.ptr_inbounds_at_mut(idx.0, idx.1);
652 core::slice::from_raw_parts_mut(ptr, n_elems)
653 }
654
655 #[inline]
656 unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index {
657 (
658 Idx::<Rows>::new_unbound(idx.0),
659 Idx::<Cols>::new_unbound(idx.1),
660 )
661 }
662
663 #[inline]
664 unsafe fn get_unchecked(
665 this: &mut Self,
666 (i, j): Self::Index,
667 ) -> Self::Item {
668 let ptr = this.rb().ptr_inbounds_at_mut(i, j);
669 &mut *ptr
670 }
671
672 #[inline(always)]
673 unsafe fn next_unchecked<'a>(
674 slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice,
675 ) -> Self::Item {
676 let (head, tail) =
677 core::mem::take(slice).split_first_mut().unwrap_unchecked();
678 *slice = tail;
679 head
680 }
681
682 #[inline(always)]
683 fn is_contiguous(this: &Self) -> bool {
684 this.row_stride().element_stride() == 1
685 }
686
687 #[inline(always)]
688 fn preferred_layout(this: &Self) -> Self::LayoutTransform {
689 let rs = this.row_stride().element_stride();
690 let cs = this.col_stride().element_stride();
691 let nrows = this.nrows().unbound();
692 let ncols = this.ncols().unbound();
693 if nrows > 1 && rs == 1 {
694 MatLayoutTransform::None
695 } else if nrows > 1 && rs == -1 {
696 MatLayoutTransform::ReverseRows
697 } else if ncols > 1 && cs == 1 {
698 MatLayoutTransform::Transpose
699 } else if ncols > 1 && cs == -1 {
700 MatLayoutTransform::TransposeReverseRows
701 } else {
702 MatLayoutTransform::None
703 }
704 }
705
706 #[inline(always)]
707 fn with_layout(this: Self, layout: Self::LayoutTransform) -> Self::Dyn {
708 use MatLayoutTransform::*;
709 let this = this.as_dyn_mut().as_dyn_stride_mut();
710 match layout {
711 None => this,
712 ReverseRows => this.reverse_rows_mut(),
713 Transpose => this.transpose_mut(),
714 TransposeReverseRows => this.transpose_mut().reverse_rows_mut(),
715 }
716 }
717}
718impl<'b, T, Rows: Shape, Cols: Shape, RStride: Stride, CStride: Stride> MatIndex
719 for MatRef<'b, T, Rows, Cols, RStride, CStride>
720{
721 type Cols = Cols;
722 type Dyn = MatRef<'b, T, usize, usize, isize, isize>;
723 type Index = (Idx<Rows>, Idx<Cols>);
724 type Item = &'b T;
725 type Kind = kind::Mat;
726 type LayoutTransform = MatLayoutTransform;
727 type Rows = Rows;
728 type Slice = SliceRef<'b, T>;
729
730 #[inline]
731 fn nrows(this: &Self) -> Self::Rows {
732 this.nrows()
733 }
734
735 #[inline]
736 fn ncols(this: &Self) -> Self::Cols {
737 this.ncols()
738 }
739
740 #[inline]
741 unsafe fn get_slice_unchecked<'a>(
742 this: &'a mut Self,
743 idx: Self::Index,
744 n_elems: usize,
745 ) -> <Self::Slice as SliceFamily<'a, Self::Item>>::Slice {
746 let ptr = this.ptr_inbounds_at(idx.0, idx.1);
747 core::slice::from_raw_parts(ptr, n_elems)
748 }
749
750 #[inline]
751 unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index {
752 (
753 Idx::<Rows>::new_unbound(idx.0),
754 Idx::<Cols>::new_unbound(idx.1),
755 )
756 }
757
758 #[inline]
759 unsafe fn get_unchecked(
760 this: &mut Self,
761 (i, j): Self::Index,
762 ) -> Self::Item {
763 let ptr = this.rb().ptr_inbounds_at(i, j);
764 &*ptr
765 }
766
767 #[inline(always)]
768 unsafe fn next_unchecked<'a>(
769 slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice,
770 ) -> Self::Item {
771 let (head, tail) =
772 core::mem::take(slice).split_first().unwrap_unchecked();
773 *slice = tail;
774 head
775 }
776
777 #[inline(always)]
778 fn is_contiguous(this: &Self) -> bool {
779 this.row_stride().element_stride() == 1
780 }
781
782 #[inline(always)]
783 fn preferred_layout(this: &Self) -> Self::LayoutTransform {
784 let rs = this.row_stride().element_stride();
785 let cs = this.col_stride().element_stride();
786 let nrows = this.nrows().unbound();
787 let ncols = this.ncols().unbound();
788 if nrows > 1 && rs == 1 {
789 MatLayoutTransform::None
790 } else if nrows > 1 && rs == -1 {
791 MatLayoutTransform::ReverseRows
792 } else if ncols > 1 && cs == 1 {
793 MatLayoutTransform::Transpose
794 } else if ncols > 1 && cs == -1 {
795 MatLayoutTransform::TransposeReverseRows
796 } else {
797 MatLayoutTransform::None
798 }
799 }
800
801 #[inline(always)]
802 fn with_layout(this: Self, layout: Self::LayoutTransform) -> Self::Dyn {
803 use MatLayoutTransform::*;
804 let this = this.as_dyn().as_dyn_stride();
805 match layout {
806 None => this,
807 ReverseRows => this.reverse_rows(),
808 Transpose => this.transpose(),
809 TransposeReverseRows => this.transpose().reverse_rows(),
810 }
811 }
812}
813impl<'b, T, Len: Shape, Strd: Stride> MatIndex for ColMut<'b, T, Len, Strd> {
814 type Cols = ();
815 type Dyn = ColMut<'b, T, usize, isize>;
816 type Index = Idx<Len>;
817 type Item = &'b mut T;
818 type Kind = kind::Col;
819 type LayoutTransform = VecLayoutTransform;
820 type Rows = Len;
821 type Slice = SliceMut<'b, T>;
822
823 #[inline]
824 fn nrows(this: &Self) -> Self::Rows {
825 this.nrows()
826 }
827
828 #[inline]
829 fn ncols(_: &Self) -> Self::Cols {
830 ()
831 }
832
833 #[inline]
834 unsafe fn get_slice_unchecked<'a>(
835 this: &'a mut Self,
836 idx: Self::Index,
837 n_elems: usize,
838 ) -> <Self::Slice as SliceFamily<'a, Self::Item>>::Slice {
839 let ptr = this.ptr_inbounds_at_mut(idx);
840 core::slice::from_raw_parts_mut(ptr, n_elems)
841 }
842
843 #[inline]
844 unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index {
845 Idx::<Len>::new_unbound(idx)
846 }
847
848 #[inline]
849 unsafe fn get_unchecked(this: &mut Self, i: Self::Index) -> Self::Item {
850 let ptr = this.ptr_inbounds_at_mut(i);
851 &mut *ptr
852 }
853
854 #[inline(always)]
855 unsafe fn next_unchecked<'a>(
856 slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice,
857 ) -> Self::Item {
858 let (head, tail) =
859 core::mem::take(slice).split_first_mut().unwrap_unchecked();
860 *slice = tail;
861 head
862 }
863
864 #[inline(always)]
865 fn is_contiguous(this: &Self) -> bool {
866 this.row_stride().element_stride() == 1
867 }
868
869 #[inline(always)]
870 fn preferred_layout(this: &Self) -> Self::LayoutTransform {
871 let strd = this.row_stride().element_stride();
872 let len = this.nrows().unbound();
873 if len > 1 && strd == 1 {
874 VecLayoutTransform::None
875 } else if len > 1 && strd == -1 {
876 VecLayoutTransform::Reverse
877 } else {
878 VecLayoutTransform::None
879 }
880 }
881
882 #[inline(always)]
883 fn with_layout(this: Self, layout: Self::LayoutTransform) -> Self::Dyn {
884 use VecLayoutTransform::*;
885 let this = this.as_dyn_rows_mut().as_dyn_stride_mut();
886 match layout {
887 None => this,
888 Reverse => this.reverse_rows_mut(),
889 }
890 }
891}
892impl<'b, T, Len: Shape, Strd: Stride> MatIndex
893 for diag::DiagMut<'b, T, Len, Strd>
894{
895 type Cols = Len;
896 type Dyn = diag::DiagMut<'b, T, usize, isize>;
897 type Index = Idx<Len>;
898 type Item = &'b mut T;
899 type Kind = kind::Diag;
900 type LayoutTransform = VecLayoutTransform;
901 type Rows = Len;
902 type Slice = SliceMut<'b, T>;
903
904 #[inline]
905 fn nrows(this: &Self) -> Self::Rows {
906 this.dim()
907 }
908
909 #[inline]
910 fn ncols(this: &Self) -> Self::Cols {
911 this.dim()
912 }
913
914 #[inline]
915 unsafe fn get_slice_unchecked<'a>(
916 this: &'a mut Self,
917 idx: Self::Index,
918 n_elems: usize,
919 ) -> <Self::Slice as SliceFamily<'a, Self::Item>>::Slice {
920 let ptr = this.rb_mut().column_vector_mut().ptr_inbounds_at_mut(idx);
921 core::slice::from_raw_parts_mut(ptr, n_elems)
922 }
923
924 #[inline]
925 unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index {
926 Idx::<Len>::new_unbound(idx)
927 }
928
929 #[inline]
930 unsafe fn get_unchecked(this: &mut Self, i: Self::Index) -> Self::Item {
931 let ptr = this.rb_mut().column_vector_mut().ptr_inbounds_at_mut(i);
932 &mut *ptr
933 }
934
935 #[inline(always)]
936 unsafe fn next_unchecked<'a>(
937 slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice,
938 ) -> Self::Item {
939 let (head, tail) =
940 core::mem::take(slice).split_first_mut().unwrap_unchecked();
941 *slice = tail;
942 head
943 }
944
945 #[inline(always)]
946 fn is_contiguous(this: &Self) -> bool {
947 this.stride().element_stride() == 1
948 }
949
950 #[inline(always)]
951 fn preferred_layout(this: &Self) -> Self::LayoutTransform {
952 let strd = this.stride().element_stride();
953 let len = this.dim().unbound();
954 if len > 1 && strd == 1 {
955 VecLayoutTransform::None
956 } else if len > 1 && strd == -1 {
957 VecLayoutTransform::Reverse
958 } else {
959 VecLayoutTransform::None
960 }
961 }
962
963 #[inline(always)]
964 fn with_layout(this: Self, layout: Self::LayoutTransform) -> Self::Dyn {
965 use VecLayoutTransform::*;
966 let this = this.as_dyn_mut().as_dyn_stride_mut();
967 match layout {
968 None => this,
969 Reverse => this
970 .column_vector_mut()
971 .reverse_rows_mut()
972 .as_diagonal_mut(),
973 }
974 }
975}
976impl<'b, T, Len: Shape, Strd: Stride> MatIndex for RowMut<'b, T, Len, Strd> {
977 type Cols = Len;
978 type Dyn = RowMut<'b, T, usize, isize>;
979 type Index = Idx<Len>;
980 type Item = &'b mut T;
981 type Kind = kind::Row;
982 type LayoutTransform = VecLayoutTransform;
983 type Rows = ();
984 type Slice = SliceMut<'b, T>;
985
986 #[inline]
987 fn nrows(_: &Self) -> Self::Rows {
988 ()
989 }
990
991 #[inline]
992 fn ncols(this: &Self) -> Self::Cols {
993 this.ncols()
994 }
995
996 #[inline]
997 unsafe fn get_slice_unchecked<'a>(
998 this: &'a mut Self,
999 idx: Self::Index,
1000 n_elems: usize,
1001 ) -> <Self::Slice as SliceFamily<'a, Self::Item>>::Slice {
1002 let ptr = this.ptr_inbounds_at_mut(idx);
1003 core::slice::from_raw_parts_mut(ptr, n_elems)
1004 }
1005
1006 #[inline]
1007 unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index {
1008 Idx::<Len>::new_unbound(idx)
1009 }
1010
1011 #[inline]
1012 unsafe fn get_unchecked(this: &mut Self, i: Self::Index) -> Self::Item {
1013 let ptr = this.rb().ptr_inbounds_at_mut(i);
1014 &mut *ptr
1015 }
1016
1017 #[inline(always)]
1018 unsafe fn next_unchecked<'a>(
1019 slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice,
1020 ) -> Self::Item {
1021 let (head, tail) =
1022 core::mem::take(slice).split_first_mut().unwrap_unchecked();
1023 *slice = tail;
1024 head
1025 }
1026
1027 #[inline(always)]
1028 fn is_contiguous(this: &Self) -> bool {
1029 this.col_stride().element_stride() == 1
1030 }
1031
1032 #[inline(always)]
1033 fn preferred_layout(this: &Self) -> Self::LayoutTransform {
1034 let strd = this.col_stride().element_stride();
1035 let len = this.ncols().unbound();
1036 if len > 1 && strd == 1 {
1037 VecLayoutTransform::None
1038 } else if len > 1 && strd == -1 {
1039 VecLayoutTransform::Reverse
1040 } else {
1041 VecLayoutTransform::None
1042 }
1043 }
1044
1045 #[inline(always)]
1046 fn with_layout(this: Self, layout: Self::LayoutTransform) -> Self::Dyn {
1047 use VecLayoutTransform::*;
1048 let this = this.as_dyn_cols_mut().as_dyn_stride_mut();
1049 match layout {
1050 None => this,
1051 Reverse => this.reverse_cols_mut(),
1052 }
1053 }
1054}
1055impl<'b, T, Len: Shape, Strd: Stride> MatIndex for ColRef<'b, T, Len, Strd> {
1056 type Cols = ();
1057 type Dyn = ColRef<'b, T, usize, isize>;
1058 type Index = Idx<Len>;
1059 type Item = &'b T;
1060 type Kind = kind::Col;
1061 type LayoutTransform = VecLayoutTransform;
1062 type Rows = Len;
1063 type Slice = SliceRef<'b, T>;
1064
1065 #[inline]
1066 fn nrows(this: &Self) -> Self::Rows {
1067 this.nrows()
1068 }
1069
1070 #[inline]
1071 fn ncols(_: &Self) -> Self::Cols {
1072 ()
1073 }
1074
1075 #[inline]
1076 unsafe fn get_slice_unchecked<'a>(
1077 this: &'a mut Self,
1078 idx: Self::Index,
1079 n_elems: usize,
1080 ) -> <Self::Slice as SliceFamily<'a, Self::Item>>::Slice {
1081 let ptr = this.ptr_inbounds_at(idx);
1082 core::slice::from_raw_parts(ptr, n_elems)
1083 }
1084
1085 #[inline]
1086 unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index {
1087 Idx::<Len>::new_unbound(idx)
1088 }
1089
1090 #[inline]
1091 unsafe fn get_unchecked(this: &mut Self, i: Self::Index) -> Self::Item {
1092 let ptr = this.rb().ptr_inbounds_at(i);
1093 &*ptr
1094 }
1095
1096 #[inline(always)]
1097 unsafe fn next_unchecked<'a>(
1098 slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice,
1099 ) -> Self::Item {
1100 let (head, tail) =
1101 core::mem::take(slice).split_first().unwrap_unchecked();
1102 *slice = tail;
1103 head
1104 }
1105
1106 #[inline(always)]
1107 fn is_contiguous(this: &Self) -> bool {
1108 this.row_stride().element_stride() == 1
1109 }
1110
1111 #[inline(always)]
1112 fn preferred_layout(this: &Self) -> Self::LayoutTransform {
1113 let strd = this.row_stride().element_stride();
1114 let len = this.nrows().unbound();
1115 if len > 1 && strd == 1 {
1116 VecLayoutTransform::None
1117 } else if len > 1 && strd == -1 {
1118 VecLayoutTransform::Reverse
1119 } else {
1120 VecLayoutTransform::None
1121 }
1122 }
1123
1124 #[inline(always)]
1125 fn with_layout(this: Self, layout: Self::LayoutTransform) -> Self::Dyn {
1126 use VecLayoutTransform::*;
1127 let this = this.as_dyn_rows().as_dyn_stride();
1128 match layout {
1129 None => this,
1130 Reverse => this.reverse_rows(),
1131 }
1132 }
1133}
1134impl<'b, T, Len: Shape, Strd: Stride> MatIndex
1135 for diag::DiagRef<'b, T, Len, Strd>
1136{
1137 type Cols = Len;
1138 type Dyn = diag::DiagRef<'b, T, usize, isize>;
1139 type Index = Idx<Len>;
1140 type Item = &'b T;
1141 type Kind = kind::Diag;
1142 type LayoutTransform = VecLayoutTransform;
1143 type Rows = Len;
1144 type Slice = SliceRef<'b, T>;
1145
1146 #[inline]
1147 fn nrows(this: &Self) -> Self::Rows {
1148 this.dim()
1149 }
1150
1151 #[inline]
1152 fn ncols(this: &Self) -> Self::Cols {
1153 this.dim()
1154 }
1155
1156 #[inline]
1157 unsafe fn get_slice_unchecked<'a>(
1158 this: &'a mut Self,
1159 idx: Self::Index,
1160 n_elems: usize,
1161 ) -> <Self::Slice as SliceFamily<'a, Self::Item>>::Slice {
1162 let ptr = this.column_vector().ptr_inbounds_at(idx);
1163 core::slice::from_raw_parts(ptr, n_elems)
1164 }
1165
1166 #[inline]
1167 unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index {
1168 Idx::<Len>::new_unbound(idx)
1169 }
1170
1171 #[inline]
1172 unsafe fn get_unchecked(this: &mut Self, i: Self::Index) -> Self::Item {
1173 let ptr = this.column_vector().ptr_inbounds_at(i);
1174 &*ptr
1175 }
1176
1177 #[inline(always)]
1178 unsafe fn next_unchecked<'a>(
1179 slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice,
1180 ) -> Self::Item {
1181 let (head, tail) =
1182 core::mem::take(slice).split_first().unwrap_unchecked();
1183 *slice = tail;
1184 head
1185 }
1186
1187 #[inline(always)]
1188 fn is_contiguous(this: &Self) -> bool {
1189 this.stride().element_stride() == 1
1190 }
1191
1192 #[inline(always)]
1193 fn preferred_layout(this: &Self) -> Self::LayoutTransform {
1194 let strd = this.stride().element_stride();
1195 let len = this.dim().unbound();
1196 if len > 1 && strd == 1 {
1197 VecLayoutTransform::None
1198 } else if len > 1 && strd == -1 {
1199 VecLayoutTransform::Reverse
1200 } else {
1201 VecLayoutTransform::None
1202 }
1203 }
1204
1205 #[inline(always)]
1206 fn with_layout(this: Self, layout: Self::LayoutTransform) -> Self::Dyn {
1207 use VecLayoutTransform::*;
1208 let this = this.as_dyn().as_dyn_stride();
1209 match layout {
1210 None => this,
1211 Reverse => this.column_vector().reverse_rows().as_diagonal(),
1212 }
1213 }
1214}
1215impl<'b, T, Len: Shape, Strd: Stride> MatIndex for RowRef<'b, T, Len, Strd> {
1216 type Cols = Len;
1217 type Dyn = RowRef<'b, T, usize, isize>;
1218 type Index = Idx<Len>;
1219 type Item = &'b T;
1220 type Kind = kind::Row;
1221 type LayoutTransform = VecLayoutTransform;
1222 type Rows = ();
1223 type Slice = SliceRef<'b, T>;
1224
1225 #[inline]
1226 fn nrows(_: &Self) -> Self::Rows {
1227 ()
1228 }
1229
1230 #[inline]
1231 fn ncols(this: &Self) -> Self::Cols {
1232 this.ncols()
1233 }
1234
1235 #[inline]
1236 unsafe fn get_slice_unchecked<'a>(
1237 this: &'a mut Self,
1238 idx: Self::Index,
1239 n_elems: usize,
1240 ) -> <Self::Slice as SliceFamily<'a, Self::Item>>::Slice {
1241 let ptr = this.ptr_inbounds_at(idx);
1242 core::slice::from_raw_parts(ptr, n_elems)
1243 }
1244
1245 #[inline]
1246 unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index {
1247 Idx::<Len>::new_unbound(idx)
1248 }
1249
1250 #[inline]
1251 unsafe fn get_unchecked(this: &mut Self, i: Self::Index) -> Self::Item {
1252 let ptr = this.rb().ptr_inbounds_at(i);
1253 &*ptr
1254 }
1255
1256 #[inline(always)]
1257 unsafe fn next_unchecked<'a>(
1258 slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice,
1259 ) -> Self::Item {
1260 let (head, tail) =
1261 core::mem::take(slice).split_first().unwrap_unchecked();
1262 *slice = tail;
1263 head
1264 }
1265
1266 #[inline(always)]
1267 fn is_contiguous(this: &Self) -> bool {
1268 this.col_stride().element_stride() == 1
1269 }
1270
1271 #[inline(always)]
1272 fn preferred_layout(this: &Self) -> Self::LayoutTransform {
1273 let strd = this.col_stride().element_stride();
1274 let len = this.ncols().unbound();
1275 if len > 1 && strd == 1 {
1276 VecLayoutTransform::None
1277 } else if len > 1 && strd == -1 {
1278 VecLayoutTransform::Reverse
1279 } else {
1280 VecLayoutTransform::None
1281 }
1282 }
1283
1284 #[inline(always)]
1285 fn with_layout(this: Self, layout: Self::LayoutTransform) -> Self::Dyn {
1286 use VecLayoutTransform::*;
1287 let this = this.as_dyn_cols().as_dyn_stride();
1288 match layout {
1289 None => this,
1290 Reverse => this.reverse_cols(),
1291 }
1292 }
1293}
1294#[inline(always)]
1295fn annotate_noalias_mat<Z: MatIndex>(
1296 f: &mut impl FnMut(<Z as MatIndex>::Item),
1297 mut slice: <Z::Slice as SliceFamily<'_, Z::Item>>::Slice,
1298 i_begin: usize,
1299 i_end: usize,
1300 _j: usize,
1301) {
1302 for _ in i_begin..i_end {
1303 unsafe { f(Z::next_unchecked(&mut slice)) };
1304 }
1305}
1306#[inline(always)]
1307fn annotate_noalias_mat_with_index<
1308 const TRANSPOSE: bool,
1309 const REVERSE_ROWS: bool,
1310 Z: MatIndex<Index = (RowIdx, ColIdx)>,
1311 RowIdx,
1312 ColIdx,
1313>(
1314 f: &mut impl FnMut(RowIdx, ColIdx, <Z as MatIndex>::Item),
1315 mut slice: <Z::Slice as SliceFamily<'_, Z::Item>>::Slice,
1316 i_begin: usize,
1317 i_end: usize,
1318 j: usize,
1319) where
1320 Z::Dyn: MatIndex<Index = (usize, usize)>,
1321{
1322 if const { !TRANSPOSE } {
1323 if const { !REVERSE_ROWS } {
1324 for i in i_begin..i_end {
1325 unsafe {
1326 let (ii, jj) = Z::from_dyn_idx((i, j));
1327 f(ii, jj, Z::next_unchecked(&mut slice))
1328 };
1329 }
1330 } else {
1331 for i in i_begin..i_end {
1332 unsafe {
1333 let (ii, jj) =
1334 Z::from_dyn_idx((i_begin + (i_end - i - 1), j));
1335 f(ii, jj, Z::next_unchecked(&mut slice))
1336 };
1337 }
1338 }
1339 } else {
1340 if const { !REVERSE_ROWS } {
1341 for i in i_begin..i_end {
1342 unsafe {
1343 let (ii, jj) = Z::from_dyn_idx((j, i));
1344 f(ii, jj, Z::next_unchecked(&mut slice))
1345 };
1346 }
1347 } else {
1348 for i in i_begin..i_end {
1349 unsafe {
1350 let (ii, jj) =
1351 Z::from_dyn_idx((j, i_begin + (i_end - i - 1)));
1352 f(ii, jj, Z::next_unchecked(&mut slice))
1353 };
1354 }
1355 }
1356 }
1357}
1358#[inline(always)]
1359fn annotate_noalias_col<Z: MatIndex>(
1360 f: &mut impl FnMut(<Z as MatIndex>::Item),
1361 mut slice: <Z::Slice as SliceFamily<'_, Z::Item>>::Slice,
1362 i_begin: usize,
1363 i_end: usize,
1364) {
1365 for _ in i_begin..i_end {
1366 unsafe { f(Z::next_unchecked(&mut slice)) };
1367 }
1368}
1369#[inline(always)]
1370fn annotate_noalias_col_with_index<Z: MatIndex<Index = Idx>, Idx>(
1371 f: &mut impl FnMut(Idx, <Z as MatIndex>::Item),
1372 mut slice: <Z::Slice as SliceFamily<'_, Z::Item>>::Slice,
1373 i_begin: usize,
1374 i_end: usize,
1375 reverse: bool,
1376) where
1377 Z::Dyn: MatIndex<Item = Z::Item, Index = usize>,
1378{
1379 if !reverse {
1380 for i in i_begin..i_end {
1381 unsafe {
1382 let ii = Z::from_dyn_idx(i);
1383 f(ii, Z::next_unchecked(&mut slice))
1384 };
1385 }
1386 } else {
1387 for i in i_begin..i_end {
1388 unsafe {
1389 let ii = Z::from_dyn_idx(i_begin + (i_end - i - 1));
1390 f(ii, Z::next_unchecked(&mut slice))
1391 };
1392 }
1393 }
1394}
1395#[inline(always)]
1396fn for_each_mat<Z: MatIndex>(z: Z, mut f: impl FnMut(<Z as MatIndex>::Item))
1397where
1398 Z::Dyn: MatIndex<
1399 Item = Z::Item,
1400 Slice = Z::Slice,
1401 Rows = usize,
1402 Cols = usize,
1403 Index = (usize, usize),
1404 >,
1405{
1406 let layout = Z::preferred_layout(&z);
1407 let mut z = Z::with_layout(z, layout);
1408 let m = Z::Dyn::nrows(&z);
1409 let n = Z::Dyn::ncols(&z);
1410 if m == 0 || n == 0 {
1411 return;
1412 }
1413 unsafe {
1414 if Z::Dyn::is_contiguous(&z) {
1415 for j in 0..n {
1416 annotate_noalias_mat::<Z::Dyn>(
1417 &mut f,
1418 Z::Dyn::get_slice_unchecked(&mut z, (0, j), m),
1419 0,
1420 m,
1421 j,
1422 );
1423 }
1424 } else {
1425 for j in 0..n {
1426 for i in 0..m {
1427 f(Z::Dyn::get_unchecked(&mut z, (i, j)))
1428 }
1429 }
1430 }
1431 }
1432}
1433#[inline(always)]
1434fn for_each_mat_with_index<
1435 RowIdx,
1436 ColIdx,
1437 Z: MatIndex<Index = (RowIdx, ColIdx), LayoutTransform = MatLayoutTransform>,
1438>(
1439 z: Z,
1440 mut f: impl FnMut(RowIdx, ColIdx, <Z as MatIndex>::Item),
1441) where
1442 Z::Dyn: MatIndex<
1443 Rows = usize,
1444 Cols = usize,
1445 Index = (usize, usize),
1446 Slice = Z::Slice,
1447 Item = Z::Item,
1448 >,
1449{
1450 let layout = Z::preferred_layout(&z);
1451 let mut z = Z::with_layout(z, layout);
1452 let m = Z::Dyn::nrows(&z);
1453 let n = Z::Dyn::ncols(&z);
1454 if m == 0 || n == 0 {
1455 return;
1456 }
1457 match layout {
1458 MatLayoutTransform::None => unsafe {
1459 if Z::Dyn::is_contiguous(&z) {
1460 for j in 0..n {
1461 annotate_noalias_mat_with_index::<false, false, Z, _, _>(
1462 &mut f,
1463 Z::Dyn::get_slice_unchecked(&mut z, (0, j), m),
1464 0,
1465 m,
1466 j,
1467 );
1468 }
1469 } else {
1470 for j in 0..n {
1471 for i in 0..m {
1472 let (ii, jj) = Z::from_dyn_idx((i, j));
1473 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1474 }
1475 }
1476 }
1477 },
1478 MatLayoutTransform::ReverseRows => unsafe {
1479 if Z::Dyn::is_contiguous(&z) {
1480 for j in 0..n {
1481 annotate_noalias_mat_with_index::<false, true, Z, _, _>(
1482 &mut f,
1483 Z::Dyn::get_slice_unchecked(&mut z, (0, j), m),
1484 0,
1485 m,
1486 j,
1487 );
1488 }
1489 } else {
1490 for j in 0..n {
1491 for i in 0..m {
1492 let (ii, jj) = Z::from_dyn_idx((m - i - 1, j));
1493 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1494 }
1495 }
1496 }
1497 },
1498 MatLayoutTransform::Transpose => unsafe {
1499 if Z::Dyn::is_contiguous(&z) {
1500 for j in 0..n {
1501 annotate_noalias_mat_with_index::<true, false, Z, _, _>(
1502 &mut f,
1503 Z::Dyn::get_slice_unchecked(&mut z, (0, j), m),
1504 0,
1505 m,
1506 j,
1507 );
1508 }
1509 } else {
1510 for j in 0..n {
1511 for i in 0..m {
1512 let (ii, jj) = Z::from_dyn_idx((j, i));
1513 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1514 }
1515 }
1516 }
1517 },
1518 MatLayoutTransform::TransposeReverseRows => unsafe {
1519 if Z::Dyn::is_contiguous(&z) {
1520 for j in 0..n {
1521 annotate_noalias_mat_with_index::<true, true, Z, _, _>(
1522 &mut f,
1523 Z::Dyn::get_slice_unchecked(&mut z, (0, j), m),
1524 0,
1525 m,
1526 j,
1527 );
1528 }
1529 } else {
1530 for j in 0..n {
1531 for i in 0..m {
1532 let (ii, jj) = Z::from_dyn_idx((j, m - i - 1));
1533 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1534 }
1535 }
1536 }
1537 },
1538 }
1539}
1540#[inline(always)]
1541fn for_each_mat_triangular_lower_with_index<
1542 RowIdx,
1543 ColIdx,
1544 Z: MatIndex<Index = (RowIdx, ColIdx), LayoutTransform = MatLayoutTransform>,
1545>(
1546 z: Z,
1547 diag: Diag,
1548 mut f: impl FnMut(RowIdx, ColIdx, <Z as MatIndex>::Item),
1549) where
1550 Z::Dyn: MatIndex<
1551 Rows = usize,
1552 Cols = usize,
1553 Index = (usize, usize),
1554 Item = Z::Item,
1555 Slice = Z::Slice,
1556 >,
1557{
1558 let layout = Z::preferred_layout(&z);
1559 let mut z = Z::with_layout(z, layout);
1560 let m = Z::Dyn::nrows(&z);
1561 let n = Z::Dyn::ncols(&z);
1562 let strict = match diag {
1563 Diag::Skip => true,
1564 Diag::Include => false,
1565 };
1566 let strict = strict as usize;
1567 if m == 0 || n == 0 {
1568 return;
1569 }
1570 match layout {
1571 MatLayoutTransform::None => unsafe {
1572 if Z::Dyn::is_contiguous(&z) {
1573 for j in 0..n {
1574 let start = j + strict;
1575 let end = m;
1576 if start == end {
1577 continue;
1578 }
1579 annotate_noalias_mat_with_index::<false, false, Z, _, _>(
1580 &mut f,
1581 Z::Dyn::get_slice_unchecked(
1582 &mut z,
1583 (start, j),
1584 end - start,
1585 ),
1586 start,
1587 end,
1588 j,
1589 );
1590 }
1591 } else {
1592 for j in 0..n {
1593 let start = j + strict;
1594 let end = m;
1595 if start == end {
1596 continue;
1597 }
1598 for i in start..end {
1599 let (ii, jj) = Z::from_dyn_idx((i, j));
1600 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1601 }
1602 }
1603 }
1604 },
1605 MatLayoutTransform::ReverseRows => unsafe {
1606 if Z::Dyn::is_contiguous(&z) {
1607 for j in 0..Ord::min(m, n) {
1608 let start = 0;
1609 let end = m - j - strict;
1610 if start == end {
1611 continue;
1612 }
1613 annotate_noalias_mat_with_index::<false, true, Z, _, _>(
1614 &mut f,
1615 Z::Dyn::get_slice_unchecked(
1616 &mut z,
1617 (start, j),
1618 end - start,
1619 ),
1620 j + strict + start,
1621 j + strict + end,
1622 j,
1623 );
1624 }
1625 } else {
1626 for j in 0..Ord::min(m, n) {
1627 let start = 0;
1628 let end = m - j - strict;
1629 if start == end {
1630 continue;
1631 }
1632 for i in start..end {
1633 let (ii, jj) = Z::from_dyn_idx((m - i - 1, j));
1634 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1635 }
1636 }
1637 }
1638 },
1639 MatLayoutTransform::Transpose => unsafe {
1640 if Z::Dyn::is_contiguous(&z) {
1641 for j in 0..n {
1642 let start = 0;
1643 let end = Ord::min(m, j + (1 - strict));
1644 if start == end {
1645 continue;
1646 }
1647 annotate_noalias_mat_with_index::<true, false, Z, _, _>(
1648 &mut f,
1649 Z::Dyn::get_slice_unchecked(
1650 &mut z,
1651 (0, j),
1652 end - start,
1653 ),
1654 start,
1655 end,
1656 j,
1657 );
1658 }
1659 } else {
1660 for j in 0..n {
1661 let start = 0;
1662 let end = Ord::min(m, j + (1 - strict));
1663 if start == end {
1664 continue;
1665 }
1666 for i in start..end {
1667 let (ii, jj) = Z::from_dyn_idx((j, i));
1668 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1669 }
1670 }
1671 }
1672 },
1673 MatLayoutTransform::TransposeReverseRows => unsafe {
1674 if Z::Dyn::is_contiguous(&z) {
1675 for j in 0..n {
1676 let start = m - Ord::min(j + (1 - strict) as usize, m);
1677 let end = m;
1678 if start == end {
1679 continue;
1680 }
1681 annotate_noalias_mat_with_index::<true, true, Z, _, _>(
1682 &mut f,
1683 Z::Dyn::get_slice_unchecked(
1684 &mut z,
1685 (start, j),
1686 end - start,
1687 ),
1688 0,
1689 end - start,
1690 j,
1691 );
1692 }
1693 } else {
1694 for j in 0..n {
1695 let start = m - Ord::min(j + (1 - strict) as usize, m);
1696 let end = m;
1697 if start == end {
1698 continue;
1699 }
1700 for i in start..end {
1701 let (ii, jj) = Z::from_dyn_idx((j, m - i - 1));
1702 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1703 }
1704 }
1705 }
1706 },
1707 }
1708}
1709#[inline(always)]
1710fn for_each_mat_triangular_upper_with_index<
1711 RowIdx,
1712 ColIdx,
1713 Z: MatIndex<Index = (RowIdx, ColIdx), LayoutTransform = MatLayoutTransform>,
1714>(
1715 z: Z,
1716 diag: Diag,
1717 mut f: impl FnMut(RowIdx, ColIdx, <Z as MatIndex>::Item),
1718) where
1719 Z::Dyn: MatIndex<
1720 Rows = usize,
1721 Cols = usize,
1722 Index = (usize, usize),
1723 Item = Z::Item,
1724 Slice = Z::Slice,
1725 >,
1726{
1727 let layout = Z::preferred_layout(&z);
1728 let mut z = Z::with_layout(z, layout);
1729 let m = Z::Dyn::nrows(&z);
1730 let n = Z::Dyn::ncols(&z);
1731 let strict = match diag {
1732 Diag::Skip => true,
1733 Diag::Include => false,
1734 };
1735 let strict = strict as usize;
1736 if m == 0 || n == 0 {
1737 return;
1738 }
1739 match layout {
1740 MatLayoutTransform::None => unsafe {
1741 if Z::Dyn::is_contiguous(&z) {
1742 for j in 0..n {
1743 let start = 0;
1744 let end = Ord::min(m, j + (1 - strict));
1745 if start == end {
1746 continue;
1747 }
1748 annotate_noalias_mat_with_index::<false, false, Z, _, _>(
1749 &mut f,
1750 Z::Dyn::get_slice_unchecked(
1751 &mut z,
1752 (start, j),
1753 end - start,
1754 ),
1755 start,
1756 end,
1757 j,
1758 );
1759 }
1760 } else {
1761 for j in 0..n {
1762 let start = 0;
1763 let end = Ord::min(m, j + (1 - strict));
1764 if start == end {
1765 continue;
1766 }
1767 for i in start..end {
1768 let (ii, jj) = Z::from_dyn_idx((i, j));
1769 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1770 }
1771 }
1772 }
1773 },
1774 MatLayoutTransform::ReverseRows => unsafe {
1775 if Z::Dyn::is_contiguous(&z) {
1776 for j in 0..Ord::min(m, n) {
1777 let start = m - Ord::min(j + (1 - strict) as usize, m);
1778 let end = m;
1779 if start == end {
1780 continue;
1781 }
1782 annotate_noalias_mat_with_index::<false, true, Z, _, _>(
1783 &mut f,
1784 Z::Dyn::get_slice_unchecked(
1785 &mut z,
1786 (start, j),
1787 end - start,
1788 ),
1789 0,
1790 end - start,
1791 j,
1792 );
1793 }
1794 } else {
1795 for j in 0..Ord::min(m, n) {
1796 let start = m - Ord::min(j + (1 - strict) as usize, m);
1797 let end = m;
1798 if start == end {
1799 continue;
1800 }
1801 for i in start..end {
1802 let (ii, jj) = Z::from_dyn_idx((m - i - 1, j));
1803 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1804 }
1805 }
1806 }
1807 },
1808 MatLayoutTransform::Transpose => unsafe {
1809 if Z::Dyn::is_contiguous(&z) {
1810 for j in 0..n {
1811 let start = j + strict;
1812 let end = m;
1813 if start == end {
1814 continue;
1815 }
1816 annotate_noalias_mat_with_index::<true, false, Z, _, _>(
1817 &mut f,
1818 Z::Dyn::get_slice_unchecked(
1819 &mut z,
1820 (start, j),
1821 end - start,
1822 ),
1823 start,
1824 end,
1825 j,
1826 );
1827 }
1828 } else {
1829 for j in 0..n {
1830 let start = j + strict;
1831 let end = m;
1832 if start == end {
1833 continue;
1834 }
1835 for i in start..end {
1836 let (ii, jj) = Z::from_dyn_idx((j, i));
1837 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1838 }
1839 }
1840 }
1841 },
1842 MatLayoutTransform::TransposeReverseRows => unsafe {
1843 if Z::Dyn::is_contiguous(&z) {
1844 for j in 0..n {
1845 let start = 0;
1846 let end = m - j - strict;
1847 if start == end {
1848 continue;
1849 }
1850 annotate_noalias_mat_with_index::<true, true, Z, _, _>(
1851 &mut f,
1852 Z::Dyn::get_slice_unchecked(
1853 &mut z,
1854 (start, j),
1855 end - start,
1856 ),
1857 j + strict,
1858 j + strict + end - start,
1859 j,
1860 );
1861 }
1862 } else {
1863 for j in 0..n {
1864 let start = 0;
1865 let end = m - j - strict;
1866 if start == end {
1867 continue;
1868 }
1869 for i in start..end {
1870 let (ii, jj) = Z::from_dyn_idx((j, m - i - 1));
1871 f(ii, jj, Z::Dyn::get_unchecked(&mut z, (i, j)))
1872 }
1873 }
1874 }
1875 },
1876 }
1877}
1878#[inline(always)]
1879fn for_each_mat_triangular_lower<
1880 Z: MatIndex<LayoutTransform = MatLayoutTransform>,
1881>(
1882 z: Z,
1883 diag: Diag,
1884 transpose: bool,
1885 mut f: impl FnMut(<Z as MatIndex>::Item),
1886) where
1887 Z::Dyn: MatIndex<
1888 LayoutTransform = MatLayoutTransform,
1889 Item = Z::Item,
1890 Slice = Z::Slice,
1891 Rows = usize,
1892 Cols = usize,
1893 Index = (usize, usize),
1894 Dyn = Z::Dyn,
1895 >,
1896{
1897 use MatLayoutTransform::*;
1898 let z = if transpose {
1899 Z::with_layout(z, MatLayoutTransform::Transpose)
1900 } else {
1901 Z::with_layout(z, MatLayoutTransform::None)
1902 };
1903 let layout = Z::Dyn::preferred_layout(&z);
1904 let mut z = Z::Dyn::with_layout(z, layout);
1905 let m = Z::Dyn::nrows(&z);
1906 let n = Z::Dyn::ncols(&z);
1907 let n = match layout {
1908 None | ReverseRows => Ord::min(m, n),
1909 Transpose | TransposeReverseRows => n,
1910 };
1911 if m == 0 || n == 0 {
1912 return;
1913 }
1914 let strict = match diag {
1915 Diag::Skip => true,
1916 Diag::Include => false,
1917 };
1918 unsafe {
1919 if Z::Dyn::is_contiguous(&z) {
1920 for j in 0..n {
1921 let (start, end) = match layout {
1922 None => (j + strict as usize, m),
1923 ReverseRows => (0, (m - (j + strict as usize))),
1924 Transpose => (0, (j + !strict as usize).min(m)),
1925 TransposeReverseRows => {
1926 (m - (j + !strict as usize).min(m), m)
1927 },
1928 };
1929 let len = end - start;
1930 if start == end {
1931 continue;
1932 }
1933 annotate_noalias_mat::<Z::Dyn>(
1934 &mut f,
1935 Z::Dyn::get_slice_unchecked(&mut z, (start, j), len),
1936 start,
1937 end,
1938 j,
1939 );
1940 }
1941 } else {
1942 for j in 0..n {
1943 let (start, end) = match layout {
1944 None => (j + strict as usize, m),
1945 ReverseRows => (0, (m - (j + strict as usize))),
1946 Transpose => (0, (j + !strict as usize).min(m)),
1947 TransposeReverseRows => {
1948 (m - (j + !strict as usize).min(m), m)
1949 },
1950 };
1951 if start == end {
1952 continue;
1953 }
1954 for i in start..end {
1955 f(Z::Dyn::get_unchecked(&mut z, (i, j)))
1956 }
1957 }
1958 }
1959 }
1960}
1961#[inline(always)]
1962fn for_each_diag<Z: MatIndex>(z: Z, mut f: impl FnMut(<Z as MatIndex>::Item))
1963where
1964 Z::Dyn: MatIndex<
1965 Rows = usize,
1966 Cols = usize,
1967 Index = usize,
1968 Item = Z::Item,
1969 Slice = Z::Slice,
1970 >,
1971{
1972 let layout = Z::preferred_layout(&z);
1973 let mut z = Z::with_layout(z, layout);
1974 let m = Z::Dyn::nrows(&z);
1975 if m == 0 {
1976 return;
1977 }
1978 unsafe {
1979 if Z::Dyn::is_contiguous(&z) {
1980 annotate_noalias_col::<Z::Dyn>(
1981 &mut f,
1982 Z::Dyn::get_slice_unchecked(&mut z, 0, m),
1983 0,
1984 m,
1985 );
1986 } else {
1987 for i in 0..m {
1988 f(Z::Dyn::get_unchecked(&mut z, i))
1989 }
1990 }
1991 }
1992}
1993#[inline(always)]
1994fn for_each_diag_with_index<
1995 Idx,
1996 Z: MatIndex<LayoutTransform = VecLayoutTransform, Index = Idx>,
1997>(
1998 z: Z,
1999 mut f: impl FnMut(Idx, <Z as MatIndex>::Item),
2000) where
2001 Z::Dyn: MatIndex<
2002 Rows = usize,
2003 Cols = usize,
2004 Index = usize,
2005 Item = Z::Item,
2006 Slice = Z::Slice,
2007 >,
2008{
2009 let layout = Z::preferred_layout(&z);
2010 let mut z = Z::with_layout(z, layout);
2011 let m = Z::Dyn::nrows(&z);
2012 if m == 0 {
2013 return;
2014 }
2015 unsafe {
2016 match layout {
2017 VecLayoutTransform::None => {
2018 if Z::Dyn::is_contiguous(&z) {
2019 annotate_noalias_col_with_index::<Z, _>(
2020 &mut f,
2021 Z::Dyn::get_slice_unchecked(&mut z, 0, m),
2022 0,
2023 m,
2024 false,
2025 );
2026 } else {
2027 for i in 0..m {
2028 f(Z::from_dyn_idx(i), Z::Dyn::get_unchecked(&mut z, i))
2029 }
2030 }
2031 },
2032 VecLayoutTransform::Reverse => {
2033 if Z::Dyn::is_contiguous(&z) {
2034 annotate_noalias_col_with_index::<Z, _>(
2035 &mut f,
2036 Z::Dyn::get_slice_unchecked(&mut z, 0, m),
2037 0,
2038 m,
2039 true,
2040 );
2041 } else {
2042 for i in 0..m {
2043 f(
2044 Z::from_dyn_idx(m - i - 1),
2045 Z::Dyn::get_unchecked(&mut z, i),
2046 )
2047 }
2048 }
2049 },
2050 }
2051 }
2052}
2053#[inline(always)]
2054fn for_each_col<Z: MatIndex<LayoutTransform = VecLayoutTransform>>(
2055 z: Z,
2056 mut f: impl FnMut(<Z as MatIndex>::Item),
2057) where
2058 Z::Dyn: MatIndex<
2059 Rows = usize,
2060 Cols = (),
2061 Index = usize,
2062 Item = Z::Item,
2063 Slice = Z::Slice,
2064 >,
2065{
2066 let layout = Z::preferred_layout(&z);
2067 let mut z = Z::with_layout(z, layout);
2068 let m = Z::Dyn::nrows(&z);
2069 if m == 0 {
2070 return;
2071 }
2072 unsafe {
2073 if Z::Dyn::is_contiguous(&z) {
2074 annotate_noalias_col::<Z::Dyn>(
2075 &mut f,
2076 Z::Dyn::get_slice_unchecked(&mut z, 0, m),
2077 0,
2078 m,
2079 );
2080 } else {
2081 for i in 0..m {
2082 f(Z::Dyn::get_unchecked(&mut z, i))
2083 }
2084 }
2085 }
2086}
2087#[inline(always)]
2088fn for_each_col_with_index<
2089 Idx,
2090 Z: MatIndex<LayoutTransform = VecLayoutTransform, Index = Idx>,
2091>(
2092 z: Z,
2093 mut f: impl FnMut(Idx, <Z as MatIndex>::Item),
2094) where
2095 Z::Dyn: MatIndex<
2096 Rows = usize,
2097 Cols = (),
2098 Index = usize,
2099 Item = Z::Item,
2100 Slice = Z::Slice,
2101 >,
2102{
2103 let layout = Z::preferred_layout(&z);
2104 let mut z = Z::with_layout(z, layout);
2105 let m = Z::Dyn::nrows(&z);
2106 if m == 0 {
2107 return;
2108 }
2109 unsafe {
2110 match layout {
2111 VecLayoutTransform::None => {
2112 if Z::Dyn::is_contiguous(&z) {
2113 annotate_noalias_col_with_index::<Z, _>(
2114 &mut f,
2115 Z::Dyn::get_slice_unchecked(&mut z, 0, m),
2116 0,
2117 m,
2118 false,
2119 );
2120 } else {
2121 for i in 0..m {
2122 f(Z::from_dyn_idx(i), Z::Dyn::get_unchecked(&mut z, i))
2123 }
2124 }
2125 },
2126 VecLayoutTransform::Reverse => {
2127 if Z::Dyn::is_contiguous(&z) {
2128 annotate_noalias_col_with_index::<Z, _>(
2129 &mut f,
2130 Z::Dyn::get_slice_unchecked(&mut z, 0, m),
2131 0,
2132 m,
2133 true,
2134 );
2135 } else {
2136 for i in 0..m {
2137 f(
2138 Z::from_dyn_idx(m - i - 1),
2139 Z::Dyn::get_unchecked(&mut z, i),
2140 )
2141 }
2142 }
2143 },
2144 }
2145 }
2146}
2147#[inline(always)]
2148fn for_each_row_with_index<
2149 Idx,
2150 Z: MatIndex<LayoutTransform = VecLayoutTransform, Index = Idx>,
2151>(
2152 z: Z,
2153 mut f: impl FnMut(Idx, <Z as MatIndex>::Item),
2154) where
2155 Z::Dyn: MatIndex<
2156 Rows = (),
2157 Cols = usize,
2158 Index = usize,
2159 Item = Z::Item,
2160 Slice = Z::Slice,
2161 >,
2162{
2163 let layout = Z::preferred_layout(&z);
2164 let mut z = Z::with_layout(z, layout);
2165 let n = Z::Dyn::ncols(&z);
2166 if n == 0 {
2167 return;
2168 }
2169 unsafe {
2170 match layout {
2171 VecLayoutTransform::None => {
2172 if Z::Dyn::is_contiguous(&z) {
2173 annotate_noalias_col_with_index::<Z, _>(
2174 &mut f,
2175 Z::Dyn::get_slice_unchecked(&mut z, 0, n),
2176 0,
2177 n,
2178 false,
2179 );
2180 } else {
2181 for i in 0..n {
2182 f(Z::from_dyn_idx(i), Z::Dyn::get_unchecked(&mut z, i))
2183 }
2184 }
2185 },
2186 VecLayoutTransform::Reverse => {
2187 if Z::Dyn::is_contiguous(&z) {
2188 annotate_noalias_col_with_index::<Z, _>(
2189 &mut f,
2190 Z::Dyn::get_slice_unchecked(&mut z, 0, n),
2191 0,
2192 n,
2193 true,
2194 );
2195 } else {
2196 for i in 0..n {
2197 f(
2198 Z::from_dyn_idx(n - i - 1),
2199 Z::Dyn::get_unchecked(&mut z, i),
2200 )
2201 }
2202 }
2203 },
2204 }
2205 }
2206}
2207#[inline(always)]
2208fn for_each_row<Z: MatIndex>(z: Z, mut f: impl FnMut(<Z as MatIndex>::Item))
2209where
2210 Z::Dyn: MatIndex<
2211 Rows = (),
2212 Cols = usize,
2213 Index = usize,
2214 Item = Z::Item,
2215 Slice = Z::Slice,
2216 >,
2217{
2218 let layout = Z::preferred_layout(&z);
2219 let mut z = Z::with_layout(z, layout);
2220 let n = Z::Dyn::ncols(&z);
2221 if n == 0 {
2222 return;
2223 }
2224 unsafe {
2225 if Z::Dyn::is_contiguous(&z) {
2226 annotate_noalias_col::<Z::Dyn>(
2227 &mut f,
2228 Z::Dyn::get_slice_unchecked(&mut z, 0, n),
2229 0,
2230 n,
2231 );
2232 } else {
2233 for j in 0..n {
2234 f(Z::Dyn::get_unchecked(&mut z, j))
2235 }
2236 }
2237 }
2238}
2239impl<
2240 Rows: Shape,
2241 Cols: Shape,
2242 M: MatIndex<
2243 Kind = kind::Mat,
2244 LayoutTransform = MatLayoutTransform,
2245 Rows = Rows,
2246 Cols = Cols,
2247 Index = (Idx<Rows>, Idx<Cols>),
2248 >,
2249> LastEq<kind::Mat, M>
2250where
2251 M::Dyn: MatIndex<Rows = usize, Cols = usize, Index = (usize, usize)>,
2252{
2253 #[inline(always)]
2255 pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2256 for_each_mat(self, f);
2257 }
2258
2259 #[inline(always)]
2262 pub fn for_each_with_index(
2263 self,
2264 f: impl FnMut(Idx<Rows>, Idx<Cols>, <Self as MatIndex>::Item),
2265 ) {
2266 for_each_mat_with_index(self, f);
2267 }
2268
2269 #[inline(always)]
2274 pub fn for_each_triangular_lower_with_index(
2275 self,
2276 diag: Diag,
2277 f: impl FnMut(Idx<Rows>, Idx<Cols>, <Self as MatIndex>::Item),
2278 ) {
2279 for_each_mat_triangular_lower_with_index(self, diag, f);
2280 }
2281
2282 #[inline(always)]
2287 pub fn for_each_triangular_upper_with_index(
2288 self,
2289 diag: Diag,
2290 f: impl FnMut(Idx<Rows>, Idx<Cols>, <Self as MatIndex>::Item),
2291 ) {
2292 for_each_mat_triangular_upper_with_index(self, diag, f);
2293 }
2294
2295 #[inline(always)]
2299 pub fn for_each_triangular_lower(
2300 self,
2301 diag: Diag,
2302 f: impl FnMut(<Self as MatIndex>::Item),
2303 ) {
2304 for_each_mat_triangular_lower(self, diag, false, f);
2305 }
2306
2307 #[inline(always)]
2311 pub fn for_each_triangular_upper(
2312 self,
2313 diag: Diag,
2314 f: impl FnMut(<Self as MatIndex>::Item),
2315 ) {
2316 for_each_mat_triangular_lower(self, diag, true, f);
2317 }
2318
2319 #[inline(always)]
2322 pub fn map<T>(
2323 self,
2324 f: impl FnMut(<Self as MatIndex>::Item) -> T,
2325 ) -> Mat<T, Rows, Cols> {
2326 let (m, n) = (Self::nrows(&self), Self::ncols(&self));
2327 let mut f = f;
2328 let mut this = self;
2329 Mat::from_fn(
2330 m,
2331 n,
2332 #[inline(always)]
2333 |i, j| f(unsafe { Self::get_unchecked(&mut this, (i, j)) }),
2334 )
2335 }
2336
2337 #[inline(always)]
2340 pub fn map_with_index<T>(
2341 self,
2342 f: impl FnMut(Idx<Rows>, Idx<Cols>, <Self as MatIndex>::Item) -> T,
2343 ) -> Mat<T, Rows, Cols> {
2344 let (m, n) = (Self::nrows(&self), Self::ncols(&self));
2345 let mut f = f;
2346 let mut this = self;
2347 Mat::from_fn(
2348 m,
2349 n,
2350 #[inline(always)]
2351 |i, j| f(i, j, unsafe { Self::get_unchecked(&mut this, (i, j)) }),
2352 )
2353 }
2354}
2355impl<
2356 Rows: Shape,
2357 Cols: Shape,
2358 L: MatIndex<
2359 Kind = kind::Mat,
2360 LayoutTransform = MatLayoutTransform,
2361 Rows = Rows,
2362 Cols = Cols,
2363 Index = (Idx<Rows>, Idx<Cols>),
2364 >,
2365 R: MatIndex<
2366 Kind = kind::Mat,
2367 LayoutTransform = MatLayoutTransform,
2368 Rows = Rows,
2369 Cols = Cols,
2370 Index = (Idx<Rows>, Idx<Cols>),
2371 >,
2372> ZipEq<kind::Mat, L, R>
2373where
2374 L::Dyn: MatIndex<Rows = usize, Cols = usize, Index = (usize, usize)>,
2375 R::Dyn: MatIndex<Rows = usize, Cols = usize, Index = (usize, usize)>,
2376{
2377 #[inline(always)]
2379 pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2380 for_each_mat(self, f);
2381 }
2382
2383 #[inline(always)]
2386 pub fn for_each_with_index(
2387 self,
2388 f: impl FnMut(Idx<Rows>, Idx<Cols>, <Self as MatIndex>::Item),
2389 ) {
2390 for_each_mat_with_index(self, f);
2391 }
2392
2393 #[inline(always)]
2398 pub fn for_each_triangular_lower_with_index(
2399 self,
2400 diag: Diag,
2401 f: impl FnMut(Idx<Rows>, Idx<Cols>, <Self as MatIndex>::Item),
2402 ) {
2403 for_each_mat_triangular_lower_with_index(self, diag, f);
2404 }
2405
2406 #[inline(always)]
2411 pub fn for_each_triangular_upper_with_index(
2412 self,
2413 diag: Diag,
2414 f: impl FnMut(Idx<Rows>, Idx<Cols>, <Self as MatIndex>::Item),
2415 ) {
2416 for_each_mat_triangular_upper_with_index(self, diag, f);
2417 }
2418
2419 #[inline(always)]
2423 pub fn for_each_triangular_lower(
2424 self,
2425 diag: Diag,
2426 f: impl FnMut(<Self as MatIndex>::Item),
2427 ) {
2428 for_each_mat_triangular_lower(self, diag, false, f);
2429 }
2430
2431 #[inline(always)]
2435 pub fn for_each_triangular_upper(
2436 self,
2437 diag: Diag,
2438 f: impl FnMut(<Self as MatIndex>::Item),
2439 ) {
2440 for_each_mat_triangular_lower(self, diag, true, f);
2441 }
2442
2443 #[inline(always)]
2446 pub fn map<T>(
2447 self,
2448 f: impl FnMut(<Self as MatIndex>::Item) -> T,
2449 ) -> Mat<T, Rows, Cols> {
2450 let (m, n) = (Self::nrows(&self), Self::ncols(&self));
2451 let mut f = f;
2452 let mut this = self;
2453 Mat::from_fn(
2454 m,
2455 n,
2456 #[inline(always)]
2457 |i, j| f(unsafe { Self::get_unchecked(&mut this, (i, j)) }),
2458 )
2459 }
2460
2461 #[inline(always)]
2464 pub fn map_with_index<T>(
2465 self,
2466 f: impl FnMut(Idx<Rows>, Idx<Cols>, <Self as MatIndex>::Item) -> T,
2467 ) -> Mat<T, Rows, Cols> {
2468 let (m, n) = (Self::nrows(&self), Self::ncols(&self));
2469 let mut f = f;
2470 let mut this = self;
2471 Mat::from_fn(
2472 m,
2473 n,
2474 #[inline(always)]
2475 |i, j| f(i, j, unsafe { Self::get_unchecked(&mut this, (i, j)) }),
2476 )
2477 }
2478}
2479impl<
2480 Rows: Shape,
2481 M: MatIndex<
2482 Kind = kind::Col,
2483 LayoutTransform = VecLayoutTransform,
2484 Rows = Rows,
2485 Cols = (),
2486 Index = Idx<Rows>,
2487 >,
2488> LastEq<kind::Col, M>
2489where
2490 M::Dyn: MatIndex<Rows = usize, Cols = (), Index = usize>,
2491{
2492 #[inline(always)]
2494 pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2495 for_each_col(self, f);
2496 }
2497
2498 #[inline(always)]
2501 pub fn for_each_with_index(
2502 self,
2503 f: impl FnMut(Idx<Rows>, <Self as MatIndex>::Item),
2504 ) {
2505 for_each_col_with_index(self, f);
2506 }
2507
2508 #[inline(always)]
2511 pub fn map<T>(
2512 self,
2513 f: impl FnMut(<Self as MatIndex>::Item) -> T,
2514 ) -> Col<T, Rows> {
2515 let (m, _) = (Self::nrows(&self), Self::ncols(&self));
2516 let mut f = f;
2517 let mut this = self;
2518 Col::from_fn(
2519 m,
2520 #[inline(always)]
2521 |i| f(unsafe { Self::get_unchecked(&mut this, i) }),
2522 )
2523 }
2524
2525 #[inline(always)]
2528 pub fn map_with_index<T>(
2529 self,
2530 f: impl FnMut(Idx<Rows>, <Self as MatIndex>::Item) -> T,
2531 ) -> Col<T, Rows> {
2532 let (m, _) = (Self::nrows(&self), Self::ncols(&self));
2533 let mut f = f;
2534 let mut this = self;
2535 Col::from_fn(
2536 m,
2537 #[inline(always)]
2538 |i| f(i, unsafe { Self::get_unchecked(&mut this, i) }),
2539 )
2540 }
2541}
2542impl<
2543 Rows: Shape,
2544 L: MatIndex<
2545 Kind = kind::Col,
2546 LayoutTransform = VecLayoutTransform,
2547 Rows = Rows,
2548 Cols = (),
2549 Index = Idx<Rows>,
2550 >,
2551 R: MatIndex<
2552 Kind = kind::Col,
2553 LayoutTransform = VecLayoutTransform,
2554 Rows = Rows,
2555 Cols = (),
2556 Index = Idx<Rows>,
2557 >,
2558> ZipEq<kind::Col, L, R>
2559where
2560 L::Dyn: MatIndex<Rows = usize, Cols = (), Index = usize>,
2561 R::Dyn: MatIndex<Rows = usize, Cols = (), Index = usize>,
2562{
2563 #[inline(always)]
2565 pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2566 for_each_col(self, f);
2567 }
2568
2569 #[inline(always)]
2572 pub fn for_each_with_index(
2573 self,
2574 f: impl FnMut(Idx<Rows>, <Self as MatIndex>::Item),
2575 ) {
2576 for_each_col_with_index(self, f);
2577 }
2578
2579 #[inline(always)]
2582 pub fn map<T>(
2583 self,
2584 f: impl FnMut(<Self as MatIndex>::Item) -> T,
2585 ) -> Col<T, Rows> {
2586 let (m, _) = (Self::nrows(&self), Self::ncols(&self));
2587 let mut f = f;
2588 let mut this = self;
2589 Col::from_fn(
2590 m,
2591 #[inline(always)]
2592 |i| f(unsafe { Self::get_unchecked(&mut this, i) }),
2593 )
2594 }
2595
2596 #[inline(always)]
2599 pub fn map_with_index<T>(
2600 self,
2601 f: impl FnMut(Idx<Rows>, <Self as MatIndex>::Item) -> T,
2602 ) -> Col<T, Rows> {
2603 let (m, _) = (Self::nrows(&self), Self::ncols(&self));
2604 let mut f = f;
2605 let mut this = self;
2606 Col::from_fn(
2607 m,
2608 #[inline(always)]
2609 |i| f(i, unsafe { Self::get_unchecked(&mut this, i) }),
2610 )
2611 }
2612}
2613impl<
2614 Dim: Shape,
2615 M: MatIndex<
2616 Kind = kind::Diag,
2617 LayoutTransform = VecLayoutTransform,
2618 Rows = Dim,
2619 Cols = Dim,
2620 Index = Idx<Dim>,
2621 >,
2622> LastEq<kind::Diag, M>
2623where
2624 M::Dyn: MatIndex<Rows = usize, Cols = usize, Index = usize>,
2625{
2626 #[inline(always)]
2628 pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2629 for_each_diag(self, f);
2630 }
2631
2632 #[inline(always)]
2635 pub fn for_each_with_index(
2636 self,
2637 f: impl FnMut(Idx<Dim>, <Self as MatIndex>::Item),
2638 ) {
2639 for_each_diag_with_index(self, f);
2640 }
2641
2642 #[inline(always)]
2645 pub fn map<T>(
2646 self,
2647 f: impl FnMut(<Self as MatIndex>::Item) -> T,
2648 ) -> diag::Diag<T, Dim> {
2649 let (m, _) = (Self::nrows(&self), Self::ncols(&self));
2650 let mut f = f;
2651 let mut this = self;
2652 Col::from_fn(
2653 m,
2654 #[inline(always)]
2655 |i| f(unsafe { Self::get_unchecked(&mut this, i) }),
2656 )
2657 .into_diagonal()
2658 }
2659
2660 #[inline(always)]
2663 pub fn map_with_index<T>(
2664 self,
2665 f: impl FnMut(Idx<Dim>, <Self as MatIndex>::Item) -> T,
2666 ) -> diag::Diag<T, Dim> {
2667 let (m, _) = (Self::nrows(&self), Self::ncols(&self));
2668 let mut f = f;
2669 let mut this = self;
2670 Col::from_fn(
2671 m,
2672 #[inline(always)]
2673 |i| f(i, unsafe { Self::get_unchecked(&mut this, i) }),
2674 )
2675 .into_diagonal()
2676 }
2677}
2678impl<
2679 Dim: Shape,
2680 L: MatIndex<
2681 Kind = kind::Diag,
2682 LayoutTransform = VecLayoutTransform,
2683 Rows = Dim,
2684 Cols = Dim,
2685 Index = Idx<Dim>,
2686 >,
2687 R: MatIndex<
2688 Kind = kind::Diag,
2689 LayoutTransform = VecLayoutTransform,
2690 Rows = Dim,
2691 Cols = Dim,
2692 Index = Idx<Dim>,
2693 >,
2694> ZipEq<kind::Diag, L, R>
2695where
2696 L::Dyn: MatIndex<Rows = usize, Cols = usize, Index = usize>,
2697 R::Dyn: MatIndex<Rows = usize, Cols = usize, Index = usize>,
2698{
2699 #[inline(always)]
2701 pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2702 for_each_diag(self, f);
2703 }
2704
2705 #[inline(always)]
2708 pub fn for_each_with_index(
2709 self,
2710 f: impl FnMut(Idx<Dim>, <Self as MatIndex>::Item),
2711 ) {
2712 for_each_diag_with_index(self, f);
2713 }
2714
2715 #[inline(always)]
2718 pub fn map<T>(
2719 self,
2720 f: impl FnMut(<Self as MatIndex>::Item) -> T,
2721 ) -> diag::Diag<T, Dim> {
2722 let (m, _) = (Self::nrows(&self), Self::ncols(&self));
2723 let mut f = f;
2724 let mut this = self;
2725 Col::from_fn(
2726 m,
2727 #[inline(always)]
2728 |i| f(unsafe { Self::get_unchecked(&mut this, i) }),
2729 )
2730 .into_diagonal()
2731 }
2732
2733 #[inline(always)]
2736 pub fn map_with_index<T>(
2737 self,
2738 f: impl FnMut(Idx<Dim>, <Self as MatIndex>::Item) -> T,
2739 ) -> diag::Diag<T, Dim> {
2740 let (m, _) = (Self::nrows(&self), Self::ncols(&self));
2741 let mut f = f;
2742 let mut this = self;
2743 Col::from_fn(
2744 m,
2745 #[inline(always)]
2746 |i| f(i, unsafe { Self::get_unchecked(&mut this, i) }),
2747 )
2748 .into_diagonal()
2749 }
2750}
2751impl<
2752 Cols: Shape,
2753 M: MatIndex<
2754 Kind = kind::Row,
2755 LayoutTransform = VecLayoutTransform,
2756 Rows = (),
2757 Cols = Cols,
2758 Index = Idx<Cols>,
2759 >,
2760> LastEq<kind::Row, M>
2761where
2762 M::Dyn: MatIndex<Rows = (), Cols = usize, Index = usize>,
2763{
2764 #[inline(always)]
2766 pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2767 for_each_row(self, f);
2768 }
2769
2770 #[inline(always)]
2773 pub fn for_each_with_index(
2774 self,
2775 f: impl FnMut(Idx<Cols>, <Self as MatIndex>::Item),
2776 ) {
2777 for_each_row_with_index(self, f);
2778 }
2779
2780 #[inline(always)]
2783 pub fn map<T>(
2784 self,
2785 f: impl FnMut(<Self as MatIndex>::Item) -> T,
2786 ) -> Row<T, Cols> {
2787 let (_, n) = (Self::nrows(&self), Self::ncols(&self));
2788 let mut f = f;
2789 let mut this = self;
2790 Row::from_fn(
2791 n,
2792 #[inline(always)]
2793 |i| f(unsafe { Self::get_unchecked(&mut this, i) }),
2794 )
2795 }
2796
2797 #[inline(always)]
2800 pub fn map_with_index<T>(
2801 self,
2802 f: impl FnMut(Idx<Cols>, <Self as MatIndex>::Item) -> T,
2803 ) -> Row<T, Cols> {
2804 let (_, n) = (Self::nrows(&self), Self::ncols(&self));
2805 let mut f = f;
2806 let mut this = self;
2807 Row::from_fn(
2808 n,
2809 #[inline(always)]
2810 |i| f(i, unsafe { Self::get_unchecked(&mut this, i) }),
2811 )
2812 }
2813}
2814impl<
2815 Cols: Shape,
2816 L: MatIndex<
2817 Kind = kind::Row,
2818 LayoutTransform = VecLayoutTransform,
2819 Rows = (),
2820 Cols = Cols,
2821 Index = Idx<Cols>,
2822 >,
2823 R: MatIndex<
2824 Kind = kind::Row,
2825 LayoutTransform = VecLayoutTransform,
2826 Rows = (),
2827 Cols = Cols,
2828 Index = Idx<Cols>,
2829 >,
2830> ZipEq<kind::Row, L, R>
2831where
2832 L::Dyn: MatIndex<Rows = (), Cols = usize, Index = usize>,
2833 R::Dyn: MatIndex<Rows = (), Cols = usize, Index = usize>,
2834{
2835 #[inline(always)]
2837 pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2838 for_each_row(self, f);
2839 }
2840
2841 #[inline(always)]
2844 pub fn for_each_with_index(
2845 self,
2846 f: impl FnMut(Idx<Cols>, <Self as MatIndex>::Item),
2847 ) {
2848 for_each_row_with_index(self, f);
2849 }
2850
2851 #[inline(always)]
2854 pub fn map<T>(
2855 self,
2856 f: impl FnMut(<Self as MatIndex>::Item) -> T,
2857 ) -> Row<T, Cols> {
2858 let (_, n) = (Self::nrows(&self), Self::ncols(&self));
2859 let mut f = f;
2860 let mut this = self;
2861 Row::from_fn(
2862 n,
2863 #[inline(always)]
2864 |i| f(unsafe { Self::get_unchecked(&mut this, i) }),
2865 )
2866 }
2867
2868 #[inline(always)]
2871 pub fn map_with_index<T>(
2872 self,
2873 f: impl FnMut(Idx<Cols>, <Self as MatIndex>::Item) -> T,
2874 ) -> Row<T, Cols> {
2875 let (_, n) = (Self::nrows(&self), Self::ncols(&self));
2876 let mut f = f;
2877 let mut this = self;
2878 Row::from_fn(
2879 n,
2880 #[inline(always)]
2881 |i| f(i, unsafe { Self::get_unchecked(&mut this, i) }),
2882 )
2883 }
2884}
2885
2886#[doc(hidden)]
2887pub mod kind {
2888 pub struct Col;
2889 pub struct Row;
2890 pub struct Mat;
2891 pub struct Diag;
2892}