1use std::marker::PhantomData;
2use std::ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo};
3use std::slice;
4
5use crate::base::allocator::Allocator;
6use crate::base::default_allocator::DefaultAllocator;
7use crate::base::dimension::{Const, Dim, DimName, Dynamic, IsNotStaticOne, U1};
8use crate::base::iter::MatrixIter;
9use crate::base::storage::{IsContiguous, Owned, RawStorage, RawStorageMut, Storage};
10use crate::base::{Matrix, Scalar};
11
12macro_rules! slice_storage_impl(
13 ($doc: expr; $Storage: ident as $SRef: ty; $T: ident.$get_addr: ident ($Ptr: ty as $Ref: ty)) => {
14 #[doc = $doc]
15 #[derive(Debug)]
16 pub struct $T<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> {
17 ptr: $Ptr,
18 shape: (R, C),
19 strides: (RStride, CStride),
20 _phantoms: PhantomData<$Ref>,
21 }
22
23 unsafe impl<'a, T: Send, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Send
24 for $T<'a, T, R, C, RStride, CStride>
25 {}
26
27 unsafe impl<'a, T: Sync, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Sync
28 for $T<'a, T, R, C, RStride, CStride>
29 {}
30
31 impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> $T<'a, T, R, C, RStride, CStride> {
32 #[inline]
34 pub unsafe fn from_raw_parts(ptr: $Ptr,
35 shape: (R, C),
36 strides: (RStride, CStride))
37 -> Self
38 where RStride: Dim,
39 CStride: Dim {
40
41 $T {
42 ptr,
43 shape,
44 strides,
45 _phantoms: PhantomData
46 }
47 }
48 }
49
50 impl<'a, T, R: Dim, C: Dim> $T<'a, T, R, C, Dynamic, Dynamic> {
52 #[inline]
54 pub unsafe fn new_unchecked<RStor, CStor, S>(storage: $SRef, start: (usize, usize), shape: (R, C))
55 -> $T<'a, T, R, C, S::RStride, S::CStride>
56 where RStor: Dim,
57 CStor: Dim,
58 S: $Storage<T, RStor, CStor> {
59
60 let strides = storage.strides();
61 $T::new_with_strides_unchecked(storage, start, shape, strides)
62 }
63
64 #[inline]
66 pub unsafe fn new_with_strides_unchecked<S, RStor, CStor, RStride, CStride>(storage: $SRef,
67 start: (usize, usize),
68 shape: (R, C),
69 strides: (RStride, CStride))
70 -> $T<'a, T, R, C, RStride, CStride>
71 where RStor: Dim,
72 CStor: Dim,
73 S: $Storage<T, RStor, CStor>,
74 RStride: Dim,
75 CStride: Dim {
76 $T::from_raw_parts(storage.$get_addr(start.0, start.1), shape, strides)
77 }
78 }
79
80 impl <'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
81 $T<'a, T, R, C, RStride, CStride>
82 where
83 Self: RawStorage<T, R, C> + IsContiguous
84 {
85 pub fn into_slice(self) -> &'a [T] {
87 let (nrows, ncols) = self.shape();
88 if nrows.value() != 0 && ncols.value() != 0 {
89 let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1);
90 unsafe { slice::from_raw_parts(self.ptr, sz + 1) }
91 } else {
92 unsafe { slice::from_raw_parts(self.ptr, 0) }
93 }
94 }
95 }
96 }
97);
98
99slice_storage_impl!("A matrix data storage for a matrix slice. Only contains an internal reference \
100 to another matrix data storage.";
101 RawStorage as &'a S; SliceStorage.get_address_unchecked(*const T as &'a T));
102
103slice_storage_impl!("A mutable matrix data storage for mutable matrix slice. Only contains an \
104 internal mutable reference to another matrix data storage.";
105 RawStorageMut as &'a mut S; SliceStorageMut.get_address_unchecked_mut(*mut T as &'a mut T)
106);
107
108impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Copy
109 for SliceStorage<'a, T, R, C, RStride, CStride>
110{
111}
112
113impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Clone
114 for SliceStorage<'a, T, R, C, RStride, CStride>
115{
116 #[inline]
117 fn clone(&self) -> Self {
118 Self {
119 ptr: self.ptr,
120 shape: self.shape,
121 strides: self.strides,
122 _phantoms: PhantomData,
123 }
124 }
125}
126
127impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
128 SliceStorageMut<'a, T, R, C, RStride, CStride>
129where
130 Self: RawStorageMut<T, R, C> + IsContiguous,
131{
132 pub fn into_slice_mut(self) -> &'a mut [T] {
134 let (nrows, ncols) = self.shape();
135 if nrows.value() != 0 && ncols.value() != 0 {
136 let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1);
137 unsafe { slice::from_raw_parts_mut(self.ptr, sz + 1) }
138 } else {
139 unsafe { slice::from_raw_parts_mut(self.ptr, 0) }
140 }
141 }
142}
143
144macro_rules! storage_impl(
145 ($($T: ident),* $(,)*) => {$(
146 unsafe impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> RawStorage<T, R, C>
147 for $T<'a, T, R, C, RStride, CStride> {
148
149 type RStride = RStride;
150 type CStride = CStride;
151
152 #[inline]
153 fn ptr(&self) -> *const T {
154 self.ptr
155 }
156
157 #[inline]
158 fn shape(&self) -> (R, C) {
159 self.shape
160 }
161
162 #[inline]
163 fn strides(&self) -> (Self::RStride, Self::CStride) {
164 self.strides
165 }
166
167 #[inline]
168 fn is_contiguous(&self) -> bool {
169 if (RStride::is::<U1>() && C::is::<U1>()) || (CStride::is::<U1>() && R::is::<U1>()) { true
174 }
175 else {
176 let (nrows, _) = self.shape();
177 let (srows, scols) = self.strides();
178
179 srows.value() == 1 && scols.value() == nrows.value()
180 }
181 }
182
183 #[inline]
184 unsafe fn as_slice_unchecked(&self) -> &[T] {
185 let (nrows, ncols) = self.shape();
186 if nrows.value() != 0 && ncols.value() != 0 {
187 let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1);
188 slice::from_raw_parts(self.ptr, sz + 1)
189 }
190 else {
191 slice::from_raw_parts(self.ptr, 0)
192 }
193 }
194 }
195
196 unsafe impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Storage<T, R, C>
197 for $T<'a, T, R, C, RStride, CStride> {
198 #[inline]
199 fn into_owned(self) -> Owned<T, R, C>
200 where DefaultAllocator: Allocator<T, R, C> {
201 self.clone_owned()
202 }
203
204 #[inline]
205 fn clone_owned(&self) -> Owned<T, R, C>
206 where DefaultAllocator: Allocator<T, R, C> {
207 let (nrows, ncols) = self.shape();
208 let it = MatrixIter::new(self).cloned();
209 DefaultAllocator::allocate_from_iterator(nrows, ncols, it)
210 }
211 }
212 )*}
213);
214
215storage_impl!(SliceStorage, SliceStorageMut);
216
217unsafe impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> RawStorageMut<T, R, C>
218 for SliceStorageMut<'a, T, R, C, RStride, CStride>
219{
220 #[inline]
221 fn ptr_mut(&mut self) -> *mut T {
222 self.ptr
223 }
224
225 #[inline]
226 unsafe fn as_mut_slice_unchecked(&mut self) -> &mut [T] {
227 let (nrows, ncols) = self.shape();
228 if nrows.value() != 0 && ncols.value() != 0 {
229 let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1);
230 slice::from_raw_parts_mut(self.ptr, sz + 1)
231 } else {
232 slice::from_raw_parts_mut(self.ptr, 0)
233 }
234 }
235}
236
237unsafe impl<'a, T, R: Dim, CStride: Dim> IsContiguous for SliceStorage<'a, T, R, U1, U1, CStride> {}
238unsafe impl<'a, T, R: Dim, CStride: Dim> IsContiguous
239 for SliceStorageMut<'a, T, R, U1, U1, CStride>
240{
241}
242
243unsafe impl<'a, T, R: DimName, C: Dim + IsNotStaticOne> IsContiguous
244 for SliceStorage<'a, T, R, C, U1, R>
245{
246}
247unsafe impl<'a, T, R: DimName, C: Dim + IsNotStaticOne> IsContiguous
248 for SliceStorageMut<'a, T, R, C, U1, R>
249{
250}
251
252impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
253 #[inline]
254 fn assert_slice_index(
255 &self,
256 start: (usize, usize),
257 shape: (usize, usize),
258 steps: (usize, usize),
259 ) {
260 let my_shape = self.shape();
261 assert!(
266 start.0 + (steps.0 + 1) * shape.0 <= my_shape.0 + steps.0,
267 "Matrix slicing out of bounds."
268 );
269 assert!(
270 start.1 + (steps.1 + 1) * shape.1 <= my_shape.1 + steps.1,
271 "Matrix slicing out of bounds."
272 );
273 }
274}
275
276macro_rules! matrix_slice_impl(
277 ($me: ident: $Me: ty, $MatrixSlice: ident, $SliceStorage: ident, $Storage: ident.$get_addr: ident (), $data: expr;
278 $row: ident,
279 $row_part: ident,
280 $rows: ident,
281 $rows_with_step: ident,
282 $fixed_rows: ident,
283 $fixed_rows_with_step: ident,
284 $rows_generic: ident,
285 $rows_generic_with_step: ident,
286 $column: ident,
287 $column_part: ident,
288 $columns: ident,
289 $columns_with_step: ident,
290 $fixed_columns: ident,
291 $fixed_columns_with_step: ident,
292 $columns_generic: ident,
293 $columns_generic_with_step: ident,
294 $slice: ident,
295 $slice_with_steps: ident,
296 $fixed_slice: ident,
297 $fixed_slice_with_steps: ident,
298 $generic_slice: ident,
299 $generic_slice_with_steps: ident,
300 $rows_range_pair: ident,
301 $columns_range_pair: ident) => {
302 #[inline]
309 pub fn $row($me: $Me, i: usize) -> $MatrixSlice<'_, T, U1, C, S::RStride, S::CStride> {
310 $me.$fixed_rows::<1>(i)
311 }
312
313 #[inline]
315 pub fn $row_part($me: $Me, i: usize, n: usize) -> $MatrixSlice<'_, T, U1, Dynamic, S::RStride, S::CStride> {
316 $me.$generic_slice((i, 0), (Const::<1>, Dynamic::new(n)))
317 }
318
319 #[inline]
321 pub fn $rows($me: $Me, first_row: usize, nrows: usize)
322 -> $MatrixSlice<'_, T, Dynamic, C, S::RStride, S::CStride> {
323
324 $me.$rows_generic(first_row, Dynamic::new(nrows))
325 }
326
327 #[inline]
329 pub fn $rows_with_step($me: $Me, first_row: usize, nrows: usize, step: usize)
330 -> $MatrixSlice<'_, T, Dynamic, C, Dynamic, S::CStride> {
331
332 $me.$rows_generic_with_step(first_row, Dynamic::new(nrows), step)
333 }
334
335 #[inline]
337 pub fn $fixed_rows<const RSLICE: usize>($me: $Me, first_row: usize)
338 -> $MatrixSlice<'_, T, Const<RSLICE>, C, S::RStride, S::CStride> {
339
340 $me.$rows_generic(first_row, Const::<RSLICE>)
341 }
342
343 #[inline]
346 pub fn $fixed_rows_with_step<const RSLICE: usize>($me: $Me, first_row: usize, step: usize)
347 -> $MatrixSlice<'_, T, Const<RSLICE>, C, Dynamic, S::CStride> {
348
349 $me.$rows_generic_with_step(first_row, Const::<RSLICE>, step)
350 }
351
352 #[inline]
355 pub fn $rows_generic<RSlice: Dim>($me: $Me, row_start: usize, nrows: RSlice)
356 -> $MatrixSlice<'_, T, RSlice, C, S::RStride, S::CStride> {
357
358 let my_shape = $me.shape_generic();
359 $me.assert_slice_index((row_start, 0), (nrows.value(), my_shape.1.value()), (0, 0));
360
361 let shape = (nrows, my_shape.1);
362
363 unsafe {
364 let data = $SliceStorage::new_unchecked($data, (row_start, 0), shape);
365 Matrix::from_data_statically_unchecked(data)
366 }
367 }
368
369 #[inline]
372 pub fn $rows_generic_with_step<RSlice>($me: $Me, row_start: usize, nrows: RSlice, step: usize)
373 -> $MatrixSlice<'_, T, RSlice, C, Dynamic, S::CStride>
374 where RSlice: Dim {
375
376 let my_shape = $me.shape_generic();
377 let my_strides = $me.data.strides();
378 $me.assert_slice_index((row_start, 0), (nrows.value(), my_shape.1.value()), (step, 0));
379
380 let strides = (Dynamic::new((step + 1) * my_strides.0.value()), my_strides.1);
381 let shape = (nrows, my_shape.1);
382
383 unsafe {
384 let data = $SliceStorage::new_with_strides_unchecked($data, (row_start, 0), shape, strides);
385 Matrix::from_data_statically_unchecked(data)
386 }
387 }
388
389 #[inline]
396 pub fn $column($me: $Me, i: usize) -> $MatrixSlice<'_, T, R, U1, S::RStride, S::CStride> {
397 $me.$fixed_columns::<1>(i)
398 }
399
400 #[inline]
402 pub fn $column_part($me: $Me, i: usize, n: usize) -> $MatrixSlice<'_, T, Dynamic, U1, S::RStride, S::CStride> {
403 $me.$generic_slice((0, i), (Dynamic::new(n), Const::<1>))
404 }
405
406 #[inline]
408 pub fn $columns($me: $Me, first_col: usize, ncols: usize)
409 -> $MatrixSlice<'_, T, R, Dynamic, S::RStride, S::CStride> {
410
411 $me.$columns_generic(first_col, Dynamic::new(ncols))
412 }
413
414 #[inline]
417 pub fn $columns_with_step($me: $Me, first_col: usize, ncols: usize, step: usize)
418 -> $MatrixSlice<'_, T, R, Dynamic, S::RStride, Dynamic> {
419
420 $me.$columns_generic_with_step(first_col, Dynamic::new(ncols), step)
421 }
422
423 #[inline]
425 pub fn $fixed_columns<const CSLICE: usize>($me: $Me, first_col: usize)
426 -> $MatrixSlice<'_, T, R, Const<CSLICE>, S::RStride, S::CStride> {
427
428 $me.$columns_generic(first_col, Const::<CSLICE>)
429 }
430
431 #[inline]
434 pub fn $fixed_columns_with_step<const CSLICE: usize>($me: $Me, first_col: usize, step: usize)
435 -> $MatrixSlice<'_, T, R, Const<CSLICE>, S::RStride, Dynamic> {
436
437 $me.$columns_generic_with_step(first_col, Const::<CSLICE>, step)
438 }
439
440 #[inline]
443 pub fn $columns_generic<CSlice: Dim>($me: $Me, first_col: usize, ncols: CSlice)
444 -> $MatrixSlice<'_, T, R, CSlice, S::RStride, S::CStride> {
445
446 let my_shape = $me.shape_generic();
447 $me.assert_slice_index((0, first_col), (my_shape.0.value(), ncols.value()), (0, 0));
448 let shape = (my_shape.0, ncols);
449
450 unsafe {
451 let data = $SliceStorage::new_unchecked($data, (0, first_col), shape);
452 Matrix::from_data_statically_unchecked(data)
453 }
454 }
455
456
457 #[inline]
460 pub fn $columns_generic_with_step<CSlice: Dim>($me: $Me, first_col: usize, ncols: CSlice, step: usize)
461 -> $MatrixSlice<'_, T, R, CSlice, S::RStride, Dynamic> {
462
463 let my_shape = $me.shape_generic();
464 let my_strides = $me.data.strides();
465
466 $me.assert_slice_index((0, first_col), (my_shape.0.value(), ncols.value()), (0, step));
467
468 let strides = (my_strides.0, Dynamic::new((step + 1) * my_strides.1.value()));
469 let shape = (my_shape.0, ncols);
470
471 unsafe {
472 let data = $SliceStorage::new_with_strides_unchecked($data, (0, first_col), shape, strides);
473 Matrix::from_data_statically_unchecked(data)
474 }
475 }
476
477 #[inline]
485 pub fn $slice($me: $Me, start: (usize, usize), shape: (usize, usize))
486 -> $MatrixSlice<'_, T, Dynamic, Dynamic, S::RStride, S::CStride> {
487
488 $me.assert_slice_index(start, shape, (0, 0));
489 let shape = (Dynamic::new(shape.0), Dynamic::new(shape.1));
490
491 unsafe {
492 let data = $SliceStorage::new_unchecked($data, start, shape);
493 Matrix::from_data_statically_unchecked(data)
494 }
495 }
496
497
498 #[inline]
503 pub fn $slice_with_steps($me: $Me, start: (usize, usize), shape: (usize, usize), steps: (usize, usize))
504 -> $MatrixSlice<'_, T, Dynamic, Dynamic, Dynamic, Dynamic> {
505 let shape = (Dynamic::new(shape.0), Dynamic::new(shape.1));
506
507 $me.$generic_slice_with_steps(start, shape, steps)
508 }
509
510 #[inline]
513 pub fn $fixed_slice<const RSLICE: usize, const CSLICE: usize>($me: $Me, irow: usize, icol: usize)
514 -> $MatrixSlice<'_, T, Const<RSLICE>, Const<CSLICE>, S::RStride, S::CStride> {
515
516 $me.assert_slice_index((irow, icol), (RSLICE, CSLICE), (0, 0));
517 let shape = (Const::<RSLICE>, Const::<CSLICE>);
518
519 unsafe {
520 let data = $SliceStorage::new_unchecked($data, (irow, icol), shape);
521 Matrix::from_data_statically_unchecked(data)
522 }
523 }
524
525 #[inline]
530 pub fn $fixed_slice_with_steps<const RSLICE: usize, const CSLICE: usize>($me: $Me, start: (usize, usize), steps: (usize, usize))
531 -> $MatrixSlice<'_, T, Const<RSLICE>, Const<CSLICE>, Dynamic, Dynamic> {
532 let shape = (Const::<RSLICE>, Const::<CSLICE>);
533 $me.$generic_slice_with_steps(start, shape, steps)
534 }
535
536 #[inline]
538 pub fn $generic_slice<RSlice, CSlice>($me: $Me, start: (usize, usize), shape: (RSlice, CSlice))
539 -> $MatrixSlice<'_, T, RSlice, CSlice, S::RStride, S::CStride>
540 where RSlice: Dim,
541 CSlice: Dim {
542
543 $me.assert_slice_index(start, (shape.0.value(), shape.1.value()), (0, 0));
544
545 unsafe {
546 let data = $SliceStorage::new_unchecked($data, start, shape);
547 Matrix::from_data_statically_unchecked(data)
548 }
549 }
550
551 #[inline]
553 pub fn $generic_slice_with_steps<RSlice, CSlice>($me: $Me,
554 start: (usize, usize),
555 shape: (RSlice, CSlice),
556 steps: (usize, usize))
557 -> $MatrixSlice<'_, T, RSlice, CSlice, Dynamic, Dynamic>
558 where RSlice: Dim,
559 CSlice: Dim {
560
561 $me.assert_slice_index(start, (shape.0.value(), shape.1.value()), steps);
562
563 let my_strides = $me.data.strides();
564 let strides = (Dynamic::new((steps.0 + 1) * my_strides.0.value()),
565 Dynamic::new((steps.1 + 1) * my_strides.1.value()));
566
567 unsafe {
568 let data = $SliceStorage::new_with_strides_unchecked($data, start, shape, strides);
569 Matrix::from_data_statically_unchecked(data)
570 }
571 }
572
573 #[inline]
582 pub fn $rows_range_pair<Range1: SliceRange<R>, Range2: SliceRange<R>>($me: $Me, r1: Range1, r2: Range2)
583 -> ($MatrixSlice<'_, T, Range1::Size, C, S::RStride, S::CStride>,
584 $MatrixSlice<'_, T, Range2::Size, C, S::RStride, S::CStride>) {
585
586 let (nrows, ncols) = $me.shape_generic();
587 let strides = $me.data.strides();
588
589 let start1 = r1.begin(nrows);
590 let start2 = r2.begin(nrows);
591
592 let end1 = r1.end(nrows);
593 let end2 = r2.end(nrows);
594
595 let nrows1 = r1.size(nrows);
596 let nrows2 = r2.size(nrows);
597
598 assert!(start2 >= end1 || start1 >= end2, "Rows range pair: the slice ranges must not overlap.");
599 assert!(end2 <= nrows.value(), "Rows range pair: index out of range.");
600
601 unsafe {
602 let ptr1 = $data.$get_addr(start1, 0);
603 let ptr2 = $data.$get_addr(start2, 0);
604
605 let data1 = $SliceStorage::from_raw_parts(ptr1, (nrows1, ncols), strides);
606 let data2 = $SliceStorage::from_raw_parts(ptr2, (nrows2, ncols), strides);
607 let slice1 = Matrix::from_data_statically_unchecked(data1);
608 let slice2 = Matrix::from_data_statically_unchecked(data2);
609
610 (slice1, slice2)
611 }
612 }
613
614 #[inline]
618 pub fn $columns_range_pair<Range1: SliceRange<C>, Range2: SliceRange<C>>($me: $Me, r1: Range1, r2: Range2)
619 -> ($MatrixSlice<'_, T, R, Range1::Size, S::RStride, S::CStride>,
620 $MatrixSlice<'_, T, R, Range2::Size, S::RStride, S::CStride>) {
621
622 let (nrows, ncols) = $me.shape_generic();
623 let strides = $me.data.strides();
624
625 let start1 = r1.begin(ncols);
626 let start2 = r2.begin(ncols);
627
628 let end1 = r1.end(ncols);
629 let end2 = r2.end(ncols);
630
631 let ncols1 = r1.size(ncols);
632 let ncols2 = r2.size(ncols);
633
634 assert!(start2 >= end1 || start1 >= end2, "Columns range pair: the slice ranges must not overlap.");
635 assert!(end2 <= ncols.value(), "Columns range pair: index out of range.");
636
637 unsafe {
638 let ptr1 = $data.$get_addr(0, start1);
639 let ptr2 = $data.$get_addr(0, start2);
640
641 let data1 = $SliceStorage::from_raw_parts(ptr1, (nrows, ncols1), strides);
642 let data2 = $SliceStorage::from_raw_parts(ptr2, (nrows, ncols2), strides);
643 let slice1 = Matrix::from_data_statically_unchecked(data1);
644 let slice2 = Matrix::from_data_statically_unchecked(data2);
645
646 (slice1, slice2)
647 }
648 }
649 }
650);
651
652pub type MatrixSlice<'a, T, R, C, RStride = U1, CStride = R> =
654 Matrix<T, R, C, SliceStorage<'a, T, R, C, RStride, CStride>>;
655pub type MatrixSliceMut<'a, T, R, C, RStride = U1, CStride = R> =
657 Matrix<T, R, C, SliceStorageMut<'a, T, R, C, RStride, CStride>>;
658
659impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
661 matrix_slice_impl!(
662 self: &Self, MatrixSlice, SliceStorage, RawStorage.get_address_unchecked(), &self.data;
663 row,
664 row_part,
665 rows,
666 rows_with_step,
667 fixed_rows,
668 fixed_rows_with_step,
669 rows_generic,
670 rows_generic_with_step,
671 column,
672 column_part,
673 columns,
674 columns_with_step,
675 fixed_columns,
676 fixed_columns_with_step,
677 columns_generic,
678 columns_generic_with_step,
679 slice,
680 slice_with_steps,
681 fixed_slice,
682 fixed_slice_with_steps,
683 generic_slice,
684 generic_slice_with_steps,
685 rows_range_pair,
686 columns_range_pair);
687}
688
689impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
691 matrix_slice_impl!(
692 self: &mut Self, MatrixSliceMut, SliceStorageMut, RawStorageMut.get_address_unchecked_mut(), &mut self.data;
693 row_mut,
694 row_part_mut,
695 rows_mut,
696 rows_with_step_mut,
697 fixed_rows_mut,
698 fixed_rows_with_step_mut,
699 rows_generic_mut,
700 rows_generic_with_step_mut,
701 column_mut,
702 column_part_mut,
703 columns_mut,
704 columns_with_step_mut,
705 fixed_columns_mut,
706 fixed_columns_with_step_mut,
707 columns_generic_mut,
708 columns_generic_with_step_mut,
709 slice_mut,
710 slice_with_steps_mut,
711 fixed_slice_mut,
712 fixed_slice_with_steps_mut,
713 generic_slice_mut,
714 generic_slice_with_steps_mut,
715 rows_range_pair_mut,
716 columns_range_pair_mut);
717}
718
719pub trait SliceRange<D: Dim> {
727 type Size: Dim;
729
730 fn begin(&self, shape: D) -> usize;
732 fn end(&self, shape: D) -> usize;
735 fn size(&self, shape: D) -> Self::Size;
737}
738
739impl<D: Dim> SliceRange<D> for usize {
740 type Size = U1;
741
742 #[inline(always)]
743 fn begin(&self, _: D) -> usize {
744 *self
745 }
746
747 #[inline(always)]
748 fn end(&self, _: D) -> usize {
749 *self + 1
750 }
751
752 #[inline(always)]
753 fn size(&self, _: D) -> Self::Size {
754 Const::<1>
755 }
756}
757
758impl<D: Dim> SliceRange<D> for Range<usize> {
759 type Size = Dynamic;
760
761 #[inline(always)]
762 fn begin(&self, _: D) -> usize {
763 self.start
764 }
765
766 #[inline(always)]
767 fn end(&self, _: D) -> usize {
768 self.end
769 }
770
771 #[inline(always)]
772 fn size(&self, _: D) -> Self::Size {
773 Dynamic::new(self.end - self.start)
774 }
775}
776
777impl<D: Dim> SliceRange<D> for RangeFrom<usize> {
778 type Size = Dynamic;
779
780 #[inline(always)]
781 fn begin(&self, _: D) -> usize {
782 self.start
783 }
784
785 #[inline(always)]
786 fn end(&self, dim: D) -> usize {
787 dim.value()
788 }
789
790 #[inline(always)]
791 fn size(&self, dim: D) -> Self::Size {
792 Dynamic::new(dim.value() - self.start)
793 }
794}
795
796impl<D: Dim> SliceRange<D> for RangeTo<usize> {
797 type Size = Dynamic;
798
799 #[inline(always)]
800 fn begin(&self, _: D) -> usize {
801 0
802 }
803
804 #[inline(always)]
805 fn end(&self, _: D) -> usize {
806 self.end
807 }
808
809 #[inline(always)]
810 fn size(&self, _: D) -> Self::Size {
811 Dynamic::new(self.end)
812 }
813}
814
815impl<D: Dim> SliceRange<D> for RangeFull {
816 type Size = D;
817
818 #[inline(always)]
819 fn begin(&self, _: D) -> usize {
820 0
821 }
822
823 #[inline(always)]
824 fn end(&self, dim: D) -> usize {
825 dim.value()
826 }
827
828 #[inline(always)]
829 fn size(&self, dim: D) -> Self::Size {
830 dim
831 }
832}
833
834impl<D: Dim> SliceRange<D> for RangeInclusive<usize> {
835 type Size = Dynamic;
836
837 #[inline(always)]
838 fn begin(&self, _: D) -> usize {
839 *self.start()
840 }
841
842 #[inline(always)]
843 fn end(&self, _: D) -> usize {
844 *self.end() + 1
845 }
846
847 #[inline(always)]
848 fn size(&self, _: D) -> Self::Size {
849 Dynamic::new(*self.end() + 1 - *self.start())
850 }
851}
852
853impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
856 #[inline]
859 #[must_use]
860 pub fn slice_range<RowRange, ColRange>(
861 &self,
862 rows: RowRange,
863 cols: ColRange,
864 ) -> MatrixSlice<'_, T, RowRange::Size, ColRange::Size, S::RStride, S::CStride>
865 where
866 RowRange: SliceRange<R>,
867 ColRange: SliceRange<C>,
868 {
869 let (nrows, ncols) = self.shape_generic();
870 self.generic_slice(
871 (rows.begin(nrows), cols.begin(ncols)),
872 (rows.size(nrows), cols.size(ncols)),
873 )
874 }
875
876 #[inline]
878 #[must_use]
879 pub fn rows_range<RowRange: SliceRange<R>>(
880 &self,
881 rows: RowRange,
882 ) -> MatrixSlice<'_, T, RowRange::Size, C, S::RStride, S::CStride> {
883 self.slice_range(rows, ..)
884 }
885
886 #[inline]
888 #[must_use]
889 pub fn columns_range<ColRange: SliceRange<C>>(
890 &self,
891 cols: ColRange,
892 ) -> MatrixSlice<'_, T, R, ColRange::Size, S::RStride, S::CStride> {
893 self.slice_range(.., cols)
894 }
895}
896
897impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
900 pub fn slice_range_mut<RowRange, ColRange>(
903 &mut self,
904 rows: RowRange,
905 cols: ColRange,
906 ) -> MatrixSliceMut<'_, T, RowRange::Size, ColRange::Size, S::RStride, S::CStride>
907 where
908 RowRange: SliceRange<R>,
909 ColRange: SliceRange<C>,
910 {
911 let (nrows, ncols) = self.shape_generic();
912 self.generic_slice_mut(
913 (rows.begin(nrows), cols.begin(ncols)),
914 (rows.size(nrows), cols.size(ncols)),
915 )
916 }
917
918 #[inline]
920 pub fn rows_range_mut<RowRange: SliceRange<R>>(
921 &mut self,
922 rows: RowRange,
923 ) -> MatrixSliceMut<'_, T, RowRange::Size, C, S::RStride, S::CStride> {
924 self.slice_range_mut(rows, ..)
925 }
926
927 #[inline]
929 pub fn columns_range_mut<ColRange: SliceRange<C>>(
930 &mut self,
931 cols: ColRange,
932 ) -> MatrixSliceMut<'_, T, R, ColRange::Size, S::RStride, S::CStride> {
933 self.slice_range_mut(.., cols)
934 }
935}
936
937impl<'a, T, R, C, RStride, CStride> From<MatrixSliceMut<'a, T, R, C, RStride, CStride>>
938 for MatrixSlice<'a, T, R, C, RStride, CStride>
939where
940 R: Dim,
941 C: Dim,
942 RStride: Dim,
943 CStride: Dim,
944{
945 fn from(slice_mut: MatrixSliceMut<'a, T, R, C, RStride, CStride>) -> Self {
946 let data = SliceStorage {
947 ptr: slice_mut.data.ptr,
948 shape: slice_mut.data.shape,
949 strides: slice_mut.data.strides,
950 _phantoms: PhantomData,
951 };
952
953 unsafe { Matrix::from_data_statically_unchecked(data) }
954 }
955}