Skip to main content

faer/linalg/
zip.rs

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/// matrix layout transformation. used for zipping optimizations
331#[derive(Copy, Clone)]
332pub enum MatLayoutTransform {
333	/// matrix is used as-is
334	None,
335	/// matrix rows are reversed
336	ReverseRows,
337	/// matrix is transposed
338	Transpose,
339	/// matrix is transposed, then rows are reversed
340	TransposeReverseRows,
341}
342/// vector layout transformation. used for zipping optimizations
343#[derive(Copy, Clone)]
344pub enum VecLayoutTransform {
345	/// vector is used as-is
346	None,
347	/// vector is reversed
348	Reverse,
349}
350/// type with a given matrix shape
351pub trait MatIndex {
352	type Kind;
353	/// type of rows
354	type Rows: Copy + Eq + core::fmt::Debug;
355	/// type of columns
356	type Cols: Copy + Eq + core::fmt::Debug;
357	/// returns the number of rows
358	fn nrows(this: &Self) -> Self::Rows;
359	/// returns the number of columns
360	fn ncols(this: &Self) -> Self::Cols;
361	/// indexing type
362	type Index: Copy;
363	/// layout transformation type
364	type LayoutTransform: Copy;
365	/// item produced by the zip views
366	type Item;
367	/// matrix type with type erased dimensions
368	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	/// returns slice at index of length `n_elems`
377	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	/// converts a type erased index back to its original representation
383	unsafe fn from_dyn_idx(idx: <Self::Dyn as MatIndex>::Index) -> Self::Index;
384	/// get the item at the given index, skipping bound checks
385	unsafe fn get_unchecked(this: &mut Self, index: Self::Index) -> Self::Item;
386	/// get the item at the given slice position, skipping bound checks
387	unsafe fn next_unchecked<'a>(
388		slice: &mut <Self::Slice as SliceFamily<'a, Self::Item>>::Slice,
389	) -> Self::Item;
390	/// checks if the zip matrices are contiguous
391	fn is_contiguous(this: &Self) -> bool;
392	/// computes the preferred iteration layout of the matrices
393	fn preferred_layout(this: &Self) -> Self::LayoutTransform;
394	/// applies the layout transformation to the matrices
395	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/// single matrix
421#[derive(Copy, Clone, Debug)]
422pub struct LastEq<Kind, Mat>(pub Mat, pub PhantomData<Kind>);
423/// single element
424#[derive(Copy, Clone, Debug)]
425pub struct Last<Mat>(pub Mat);
426/// zipped matrices
427#[derive(Copy, Clone, Debug)]
428pub struct ZipEq<Kind, Head, Tail>(pub Head, pub Tail, PhantomData<Kind>);
429/// zipped elements
430#[derive(Copy, Clone, Debug)]
431pub struct Zip<Head, Tail>(pub Head, pub Tail);
432/// single matrix view
433impl<
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	/// creates a zip matrix, after asserting that the dimensions match
442	#[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	/// creates a zip matrix, assuming that the dimensions match
453	#[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	/// applies `f` to each element of `self`
2254	#[inline(always)]
2255	pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2256		for_each_mat(self, f);
2257	}
2258
2259	/// applies `f` to each element of `self`, while passing the indices of the
2260	/// position of the current element
2261	#[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	/// applies `f` to each element of the lower triangular half of `self`,
2270	/// while passing the indices of the position of the current element
2271	///
2272	/// `diag` specifies whether the diagonal should be included or excluded
2273	#[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	/// applies `f` to each element of the upper triangular half of `self`,
2283	/// while passing the indices of the position of the current element
2284	///
2285	/// `diag` specifies whether the diagonal should be included or excluded
2286	#[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	/// applies `f` to each element of the lower triangular half of `self`
2296	///
2297	/// `diag` specifies whether the diagonal should be included or excluded
2298	#[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	/// applies `f` to each element of the upper triangular half of `self`
2308	///
2309	/// `diag` specifies whether the diagonal should be included or excluded
2310	#[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	/// applies `f` to each element of `self` and collect its result into a new
2320	/// matrix
2321	#[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	/// applies `f` to each element of `self` and collect its result into a new
2338	/// matrix
2339	#[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	/// applies `f` to each element of `self`
2378	#[inline(always)]
2379	pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2380		for_each_mat(self, f);
2381	}
2382
2383	/// applies `f` to each element of `self`, while passing the indices of the
2384	/// position of the current element
2385	#[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	/// applies `f` to each element of the lower triangular half of `self`,
2394	/// while passing the indices of the position of the current element
2395	///
2396	/// `diag` specifies whether the diagonal should be included or excluded
2397	#[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	/// applies `f` to each element of the upper triangular half of `self`,
2407	/// while passing the indices of the position of the current element
2408	///
2409	/// `diag` specifies whether the diagonal should be included or excluded
2410	#[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	/// applies `f` to each element of the lower triangular half of `self`
2420	///
2421	/// `diag` specifies whether the diagonal should be included or excluded
2422	#[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	/// applies `f` to each element of the upper triangular half of `self`
2432	///
2433	/// `diag` specifies whether the diagonal should be included or excluded
2434	#[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	/// applies `f` to each element of `self` and collect its result into a new
2444	/// matrix
2445	#[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	/// applies `f` to each element of `self` and collect its result into a new
2462	/// matrix
2463	#[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	/// applies `f` to each element of `self`
2493	#[inline(always)]
2494	pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2495		for_each_col(self, f);
2496	}
2497
2498	/// applies `f` to each element of `self`, while passing the indices of the
2499	/// position of the current element
2500	#[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	/// applies `f` to each element of `self` and collect its result into a new
2509	/// matrix
2510	#[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	/// applies `f` to each element of `self` and collect its result into a new
2526	/// matrix
2527	#[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	/// applies `f` to each element of `self`
2564	#[inline(always)]
2565	pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2566		for_each_col(self, f);
2567	}
2568
2569	/// applies `f` to each element of `self`, while passing the indices of the
2570	/// position of the current element
2571	#[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	/// applies `f` to each element of `self` and collect its result into a new
2580	/// matrix
2581	#[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	/// applies `f` to each element of `self` and collect its result into a new
2597	/// matrix
2598	#[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	/// applies `f` to each element of `self`
2627	#[inline(always)]
2628	pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2629		for_each_diag(self, f);
2630	}
2631
2632	/// applies `f` to each element of `self`, while passing the indices of the
2633	/// position of the current element
2634	#[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	/// applies `f` to each element of `self` and collect its result into a new
2643	/// matrix
2644	#[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	/// applies `f` to each element of `self` and collect its result into a new
2661	/// matrix
2662	#[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	/// applies `f` to each element of `self`
2700	#[inline(always)]
2701	pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2702		for_each_diag(self, f);
2703	}
2704
2705	/// applies `f` to each element of `self`, while passing the indices of the
2706	/// position of the current element
2707	#[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	/// applies `f` to each element of `self` and collect its result into a new
2716	/// matrix
2717	#[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	/// applies `f` to each element of `self` and collect its result into a new
2734	/// matrix
2735	#[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	/// applies `f` to each element of `self`
2765	#[inline(always)]
2766	pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2767		for_each_row(self, f);
2768	}
2769
2770	/// applies `f` to each element of `self`, while passing the indices of the
2771	/// position of the current element
2772	#[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	/// applies `f` to each element of `self` and collect its result into a new
2781	/// matrix
2782	#[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	/// applies `f` to each element of `self` and collect its result into a new
2798	/// matrix
2799	#[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	/// applies `f` to each element of `self`
2836	#[inline(always)]
2837	pub fn for_each(self, f: impl FnMut(<Self as MatIndex>::Item)) {
2838		for_each_row(self, f);
2839	}
2840
2841	/// applies `f` to each element of `self`, while passing the indices of the
2842	/// position of the current element
2843	#[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	/// applies `f` to each element of `self` and collect its result into a new
2852	/// matrix
2853	#[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	/// applies `f` to each element of `self` and collect its result into a new
2869	/// matrix
2870	#[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}