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));