faer/mat/
mat_index.rs

1use super::*;
2use crate::internal_prelude::*;
3use crate::into_range::IntoRange;
4use crate::{Idx, IdxInc, assert, debug_assert};
5
6impl<'a, R: Shape, C: Shape, T, Rs: Stride, Cs: Stride, RowRange: IntoRange<IdxInc<R>, Len<R>: 'a>, ColRange: IntoRange<IdxInc<C>, Len<C>: 'a>>
7	MatIndex<RowRange, ColRange> for MatRef<'a, T, R, C, Rs, Cs>
8{
9	type Target = MatRef<'a, T, RowRange::Len<R>, ColRange::Len<C>, Rs, Cs>;
10
11	#[track_caller]
12	#[inline]
13	fn get(this: Self, row: RowRange, col: ColRange) -> Self::Target {
14		let row = row.into_range(R::start(), this.nrows().end());
15		let col = col.into_range(C::start(), this.ncols().end());
16		assert!(all(
17			row.start <= row.end,
18			row.end <= this.nrows(),
19			col.start <= col.end,
20			col.end <= this.ncols(),
21		));
22		let nrows = unsafe { RowRange::Len::<R>::new_unbound(row.end.unbound() - row.start.unbound()) };
23		let ncols = unsafe { ColRange::Len::<C>::new_unbound(col.end.unbound() - col.start.unbound()) };
24
25		this.submatrix(row.start, col.start, nrows, ncols)
26	}
27
28	#[track_caller]
29	#[inline]
30	unsafe fn get_unchecked(this: Self, row: RowRange, col: ColRange) -> Self::Target {
31		let row = row.into_range(R::start(), this.nrows().end());
32		let col = col.into_range(C::start(), this.ncols().end());
33
34		debug_assert!(all(
35			row.start <= row.end,
36			row.end <= this.nrows(),
37			col.start <= col.end,
38			col.end <= this.ncols(),
39		));
40		let nrows = unsafe { RowRange::Len::<R>::new_unbound(row.end.unbound() - row.start.unbound()) };
41		let ncols = unsafe { ColRange::Len::<C>::new_unbound(col.end.unbound() - col.start.unbound()) };
42
43		this.submatrix(row.start, col.start, nrows, ncols)
44	}
45}
46
47impl<'a, R: Shape, C: Shape, T, Rs: Stride, Cs: Stride, RowRange: IntoRange<IdxInc<R>, Len<R>: 'a>, ColRange: IntoRange<IdxInc<C>, Len<C>: 'a>>
48	MatIndex<RowRange, ColRange> for MatMut<'a, T, R, C, Rs, Cs>
49{
50	type Target = MatMut<'a, T, RowRange::Len<R>, ColRange::Len<C>, Rs, Cs>;
51
52	#[track_caller]
53	#[inline]
54	fn get(this: Self, row: RowRange, col: ColRange) -> Self::Target {
55		let row = row.into_range(R::start(), this.nrows().end());
56		let col = col.into_range(C::start(), this.ncols().end());
57		assert!(all(
58			row.start <= row.end,
59			row.end <= this.nrows(),
60			col.start <= col.end,
61			col.end <= this.ncols(),
62		));
63
64		let nrows = unsafe { RowRange::Len::<R>::new_unbound(row.end.unbound() - row.start.unbound()) };
65		let ncols = unsafe { ColRange::Len::<C>::new_unbound(col.end.unbound() - col.start.unbound()) };
66		this.submatrix_mut(row.start, col.start, nrows, ncols)
67	}
68
69	#[track_caller]
70	#[inline]
71	unsafe fn get_unchecked(this: Self, row: RowRange, col: ColRange) -> Self::Target {
72		let row = row.into_range(R::start(), this.nrows().end());
73		let col = col.into_range(C::start(), this.ncols().end());
74
75		debug_assert!(all(
76			row.start <= row.end,
77			row.end <= this.nrows(),
78			col.start <= col.end,
79			col.end <= this.ncols(),
80		));
81
82		let nrows = unsafe { RowRange::Len::<R>::new_unbound(row.end.unbound() - row.start.unbound()) };
83		let ncols = unsafe { ColRange::Len::<C>::new_unbound(col.end.unbound() - col.start.unbound()) };
84		this.submatrix_mut(row.start, col.start, nrows, ncols)
85	}
86}
87
88macro_rules! row_impl {
89    ($R: ty $(,$tt: tt)?) => {
90        impl<'a $(, $tt)?, C: Shape, T, Rs: Stride, Cs: Stride, ColRange: IntoRange<IdxInc<C>, Len<C>: 'a>>
91            MatIndex<Idx<$R>, ColRange> for MatRef<'a, T, $R, C, Rs, Cs>
92        {
93            type Target = RowRef<'a, T, ColRange::Len<C>, Cs>;
94
95            #[track_caller]
96            #[inline]
97            fn get(this: Self, row: Idx<$R>, col: ColRange) -> Self::Target {
98                let col = col.into_range(C::start(), this.ncols().end());
99                assert!(all(
100                    row < this.nrows(),
101                    col.start <= col.end,
102                    col.end <= this.ncols(),
103                ));
104
105                let ncols =
106                    unsafe { ColRange::Len::<C>::new_unbound(col.end.unbound() - col.start.unbound()) };
107                this.subcols(col.start, ncols).row(row)
108            }
109
110            #[track_caller]
111            #[inline]
112            unsafe fn get_unchecked(this: Self, row: Idx<$R>, col: ColRange) -> Self::Target {
113                let col = col.into_range(C::start(), this.ncols().end());
114                debug_assert!(all(
115                    row < this.nrows(),
116                    col.start <= col.end,
117                    col.end <= this.ncols(),
118                ));
119                let ncols =
120                    unsafe { ColRange::Len::<C>::new_unbound(col.end.unbound() - col.start.unbound()) };
121                this.subcols(col.start, ncols).row(row)
122            }
123        }
124
125        impl<'a $(, $tt)?, C: Shape, T, Rs: Stride, Cs: Stride, ColRange: IntoRange<IdxInc<C>, Len<C>: 'a>>
126            MatIndex<Idx<$R>, ColRange> for MatMut<'a, T, $R, C, Rs, Cs>
127        {
128            type Target = RowMut<'a, T, ColRange::Len<C>, Cs>;
129
130            #[track_caller]
131            #[inline]
132            fn get(this: Self, row: Idx<$R>, col: ColRange) -> Self::Target {
133                let col = col.into_range(C::start(), this.ncols().end());
134                assert!(all(
135                    row < this.nrows(),
136                    col.start <= col.end,
137                    col.end <= this.ncols(),
138                ));
139                let ncols =
140                    unsafe { ColRange::Len::<C>::new_unbound(col.end.unbound() - col.start.unbound()) };
141                this.subcols_mut(col.start, ncols).row_mut(row)
142            }
143
144            #[track_caller]
145            #[inline]
146            unsafe fn get_unchecked(this: Self, row: Idx<$R>, col: ColRange) -> Self::Target {
147                let col = col.into_range(C::start(), this.ncols().end());
148                debug_assert!(all(
149                    row < this.nrows(),
150                    col.start <= col.end,
151                    col.end <= this.ncols(),
152                ));
153                let ncols =
154                    unsafe { ColRange::Len::<C>::new_unbound(col.end.unbound() - col.start.unbound()) };
155                this.subcols_mut(col.start, ncols).row_mut(row)
156            }
157        }
158    };
159}
160
161macro_rules! col_impl {
162    ($C: ty $(,$tt: tt)?) => {
163        impl<'a $(, $tt)?, R: Shape, T, Rs: Stride, Cs: Stride, RowRange: IntoRange<IdxInc<R>, Len<R>: 'a>>
164            MatIndex<RowRange, Idx<$C>> for MatRef<'a, T, R, $C, Rs, Cs>
165        {
166            type Target = ColRef<'a, T, RowRange::Len<R>, Rs>;
167
168            #[track_caller]
169            #[inline]
170            fn get(this: Self, row: RowRange, col: Idx<$C>) -> Self::Target {
171                let row = row.into_range(R::start(), this.nrows().end());
172                assert!(all(
173                    col < this.ncols(),
174                    row.start <= row.end,
175                    row.end <= this.nrows(),
176                ));
177                let nrows =
178                    unsafe { RowRange::Len::<R>::new_unbound(row.end.unbound() - row.start.unbound()) };
179                this.subrows(row.start, nrows).col(col)
180            }
181
182            #[track_caller]
183            #[inline]
184            unsafe fn get_unchecked(this: Self, row: RowRange, col: Idx<$C>) -> Self::Target {
185                let row = row.into_range(R::start(), this.nrows().end());
186                assert!(all(
187                    col < this.ncols(),
188                    row.start <= row.end,
189                    row.end <= this.nrows(),
190                ));
191                let nrows =
192                    unsafe { RowRange::Len::<R>::new_unbound(row.end.unbound() - row.start.unbound()) };
193                this.subrows(row.start, nrows).col(col)
194            }
195        }
196
197        impl<'a $(, $tt)?, R: Shape, T, Rs: Stride, Cs: Stride, RowRange: IntoRange<IdxInc<R>, Len<R>: 'a>>
198            MatIndex<RowRange, Idx<$C>> for MatMut<'a, T, R, $C, Rs, Cs>
199        {
200            type Target = ColMut<'a, T, RowRange::Len<R>, Rs>;
201
202            #[track_caller]
203            #[inline]
204            fn get(this: Self, row: RowRange, col: Idx<$C>) -> Self::Target {
205                let row = row.into_range(R::start(), this.nrows().end());
206                assert!(all(
207                    col < this.ncols(),
208                    row.start <= row.end,
209                    row.end <= this.nrows(),
210                ));
211                let nrows =
212                    unsafe { RowRange::Len::<R>::new_unbound(row.end.unbound() - row.start.unbound()) };
213                this.subrows_mut(row.start, nrows).col_mut(col)
214            }
215
216            #[track_caller]
217            #[inline]
218            unsafe fn get_unchecked(this: Self, row: RowRange, col: Idx<$C>) -> Self::Target {
219                let row = row.into_range(R::start(), this.nrows().end());
220                assert!(all(
221                    col < this.ncols(),
222                    row.start <= row.end,
223                    row.end <= this.nrows(),
224                ));
225                let nrows =
226                    unsafe { RowRange::Len::<R>::new_unbound(row.end.unbound() - row.start.unbound()) };
227                this.subrows_mut(row.start, nrows).col_mut(col)
228            }
229        }
230    };
231}
232
233macro_rules! idx_impl {
234    (($R: ty $(,$Rtt: tt)?),($C: ty $(,$Ctt: tt)?)) => {
235        impl<'a $(, $Rtt)? $(, $Ctt)?, T, Rs: Stride, Cs: Stride>
236            MatIndex<Idx<$R>, Idx<$C>> for MatRef<'a, T, $R, $C, Rs, Cs> {
237            type Target = &'a T;
238
239            #[track_caller]
240            #[inline]
241            fn get(this: Self, row: Idx<$R>, col: Idx<$C>) -> Self::Target {
242                this.at(row, col)
243            }
244
245            #[track_caller]
246            #[inline]
247            unsafe fn get_unchecked(this: Self, row: Idx<$R>, col: Idx<$C>) -> Self::Target {
248                this.at_unchecked(row, col)
249            }
250        }
251
252        impl<'a $(, $Rtt)? $(, $Ctt)?, T, Rs: Stride, Cs: Stride>
253            MatIndex<Idx<$R>, Idx<$C>> for MatMut<'a, T, $R, $C, Rs, Cs> {
254            type Target = &'a mut T;
255
256            #[track_caller]
257            #[inline]
258            fn get(this: Self, row: Idx<$R>, col: Idx<$C>) -> Self::Target {
259                this.at_mut(row, col)
260            }
261
262            #[track_caller]
263            #[inline]
264            unsafe fn get_unchecked(this: Self, row: Idx<$R>, col: Idx<$C>) -> Self::Target {
265                this.at_mut_unchecked(row, col)
266            }
267        }
268    };
269}
270
271row_impl!(usize);
272row_impl!(Dim<'N>, 'N);
273
274col_impl!(usize);
275col_impl!(Dim<'N>, 'N);
276
277idx_impl!((usize), (usize));
278idx_impl!((usize), (Dim<'N>, 'N));
279idx_impl!((Dim<'M>, 'M), (usize));
280idx_impl!((Dim<'M>, 'M), (Dim<'N>, 'N));