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, Dyn, IsNotStaticOne, U1};
8use crate::base::iter::MatrixIter;
9use crate::base::storage::{IsContiguous, Owned, RawStorage, RawStorageMut, Storage};
10use crate::base::{Matrix, Scalar};
11use crate::constraint::{DimEq, ShapeConstraint};
12use crate::ReshapableStorage;
13
14macro_rules! view_storage_impl (
15 ($doc: expr; $Storage: ident as $SRef: ty; $legacy_name:ident => $T: ident.$get_addr: ident ($Ptr: ty as $Ref: ty)) => {
16 #[doc = $doc]
17 #[derive(Debug)]
18 pub struct $T<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> {
19 ptr: $Ptr,
20 shape: (R, C),
21 strides: (RStride, CStride),
22 _phantoms: PhantomData<$Ref>,
23 }
24
25 #[doc = $doc]
26 #[doc = stringify!($T)]
31 #[deprecated = "Use ViewStorage(Mut) instead."]
34 pub type $legacy_name<'a, T, R, C, RStride, CStride> = $T<'a, T, R, C, RStride, CStride>;
35
36 unsafe impl<'a, T: Send, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Send
37 for $T<'a, T, R, C, RStride, CStride>
38 {}
39
40 unsafe impl<'a, T: Sync, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Sync
41 for $T<'a, T, R, C, RStride, CStride>
42 {}
43
44 impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> $T<'a, T, R, C, RStride, CStride> {
45 #[inline]
51 pub unsafe fn from_raw_parts(ptr: $Ptr,
52 shape: (R, C),
53 strides: (RStride, CStride))
54 -> Self
55 where RStride: Dim,
56 CStride: Dim {
57
58 $T {
59 ptr,
60 shape,
61 strides,
62 _phantoms: PhantomData
63 }
64 }
65 }
66
67 impl<'a, T, R: Dim, C: Dim> $T<'a, T, R, C, Dyn, Dyn> {
69 #[inline]
76 pub unsafe fn new_unchecked<RStor, CStor, S>(storage: $SRef, start: (usize, usize), shape: (R, C))
77 -> $T<'a, T, R, C, S::RStride, S::CStride>
78 where RStor: Dim,
79 CStor: Dim,
80 S: $Storage<T, RStor, CStor> {
81
82 let strides = storage.strides();
83 $T::new_with_strides_unchecked(storage, start, shape, strides)
84 }
85
86 #[inline]
92 pub unsafe fn new_with_strides_unchecked<S, RStor, CStor, RStride, CStride>(storage: $SRef,
93 start: (usize, usize),
94 shape: (R, C),
95 strides: (RStride, CStride))
96 -> $T<'a, T, R, C, RStride, CStride>
97 where RStor: Dim,
98 CStor: Dim,
99 S: $Storage<T, RStor, CStor>,
100 RStride: Dim,
101 CStride: Dim {
102 $T::from_raw_parts(storage.$get_addr(start.0, start.1), shape, strides)
103 }
104 }
105
106 impl <'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
107 $T<'a, T, R, C, RStride, CStride>
108 where
109 Self: RawStorage<T, R, C> + IsContiguous
110 {
111 pub fn into_slice(self) -> &'a [T] {
113 let (nrows, ncols) = self.shape();
114 if nrows.value() != 0 && ncols.value() != 0 {
115 let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1);
116 unsafe { slice::from_raw_parts(self.ptr, sz + 1) }
117 } else {
118 unsafe { slice::from_raw_parts(self.ptr, 0) }
119 }
120 }
121 }
122 }
123);
124
125view_storage_impl!("A matrix data storage for a matrix view. Only contains an internal reference \
126 to another matrix data storage.";
127 RawStorage as &'a S; SliceStorage => ViewStorage.get_address_unchecked(*const T as &'a T));
128
129view_storage_impl!("A mutable matrix data storage for mutable matrix view. Only contains an \
130 internal mutable reference to another matrix data storage.";
131 RawStorageMut as &'a mut S; SliceStorageMut => ViewStorageMut.get_address_unchecked_mut(*mut T as &'a mut T)
132);
133
134impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Copy
135 for ViewStorage<'a, T, R, C, RStride, CStride>
136{
137}
138
139impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Clone
140 for ViewStorage<'a, T, R, C, RStride, CStride>
141{
142 #[inline]
143 fn clone(&self) -> Self {
144 *self
145 }
146}
147
148impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
149 ViewStorageMut<'a, T, R, C, RStride, CStride>
150where
151 Self: RawStorageMut<T, R, C> + IsContiguous,
152{
153 pub fn into_slice_mut(self) -> &'a mut [T] {
155 let (nrows, ncols) = self.shape();
156 if nrows.value() != 0 && ncols.value() != 0 {
157 let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1);
158 unsafe { slice::from_raw_parts_mut(self.ptr, sz + 1) }
159 } else {
160 unsafe { slice::from_raw_parts_mut(self.ptr, 0) }
161 }
162 }
163}
164
165macro_rules! storage_impl(
166 ($($T: ident),* $(,)*) => {$(
167 unsafe impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> RawStorage<T, R, C>
168 for $T<'a, T, R, C, RStride, CStride> {
169
170 type RStride = RStride;
171 type CStride = CStride;
172
173 #[inline]
174 fn ptr(&self) -> *const T {
175 self.ptr
176 }
177
178 #[inline]
179 fn shape(&self) -> (R, C) {
180 self.shape
181 }
182
183 #[inline]
184 fn strides(&self) -> (Self::RStride, Self::CStride) {
185 self.strides
186 }
187
188 #[inline]
189 fn is_contiguous(&self) -> bool {
190 if (RStride::is::<U1>() && C::is::<U1>()) || (CStride::is::<U1>() && R::is::<U1>()) { true
195 }
196 else {
197 let (nrows, _) = self.shape();
198 let (srows, scols) = self.strides();
199
200 srows.value() == 1 && scols.value() == nrows.value()
201 }
202 }
203
204 #[inline]
205 unsafe fn as_slice_unchecked(&self) -> &[T] {
206 let (nrows, ncols) = self.shape();
207 if nrows.value() != 0 && ncols.value() != 0 {
208 let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1);
209 slice::from_raw_parts(self.ptr, sz + 1)
210 }
211 else {
212 slice::from_raw_parts(self.ptr, 0)
213 }
214 }
215 }
216
217 unsafe impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Storage<T, R, C>
218 for $T<'a, T, R, C, RStride, CStride> {
219 #[inline]
220 fn into_owned(self) -> Owned<T, R, C>
221 where DefaultAllocator: Allocator<R, C> {
222 self.clone_owned()
223 }
224
225 #[inline]
226 fn clone_owned(&self) -> Owned<T, R, C>
227 where DefaultAllocator: Allocator<R, C> {
228 let (nrows, ncols) = self.shape();
229 let it = MatrixIter::new(self).cloned();
230 DefaultAllocator::allocate_from_iterator(nrows, ncols, it)
231 }
232
233 #[inline]
234 fn forget_elements(self) {
235 }
237 }
238 )*}
239);
240
241storage_impl!(ViewStorage, ViewStorageMut);
242
243unsafe impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> RawStorageMut<T, R, C>
244 for ViewStorageMut<'a, T, R, C, RStride, CStride>
245{
246 #[inline]
247 fn ptr_mut(&mut self) -> *mut T {
248 self.ptr
249 }
250
251 #[inline]
252 unsafe fn as_mut_slice_unchecked(&mut self) -> &mut [T] {
253 let (nrows, ncols) = self.shape();
254 if nrows.value() != 0 && ncols.value() != 0 {
255 let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1);
256 slice::from_raw_parts_mut(self.ptr, sz + 1)
257 } else {
258 slice::from_raw_parts_mut(self.ptr, 0)
259 }
260 }
261}
262
263unsafe impl<'a, T, R: Dim, CStride: Dim> IsContiguous for ViewStorage<'a, T, R, U1, U1, CStride> {}
264unsafe impl<'a, T, R: Dim, CStride: Dim> IsContiguous
265 for ViewStorageMut<'a, T, R, U1, U1, CStride>
266{
267}
268
269unsafe impl<'a, T, R: DimName, C: Dim + IsNotStaticOne> IsContiguous
270 for ViewStorage<'a, T, R, C, U1, R>
271{
272}
273unsafe impl<'a, T, R: DimName, C: Dim + IsNotStaticOne> IsContiguous
274 for ViewStorageMut<'a, T, R, C, U1, R>
275{
276}
277
278impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
279 #[inline]
280 fn assert_view_index(
281 &self,
282 start: (usize, usize),
283 shape: (usize, usize),
284 steps: (usize, usize),
285 ) {
286 let my_shape = self.shape();
287 assert!(
292 start.0 + (steps.0 + 1) * shape.0 <= my_shape.0 + steps.0,
293 "Matrix slicing out of bounds."
294 );
295 assert!(
296 start.1 + (steps.1 + 1) * shape.1 <= my_shape.1 + steps.1,
297 "Matrix slicing out of bounds."
298 );
299 }
300}
301
302macro_rules! matrix_view_impl (
303 ($me: ident: $Me: ty, $MatrixView: ident, $ViewStorage: ident, $Storage: ident.$get_addr: ident (), $data: expr;
304 $row: ident,
305 $row_part: ident,
306 $rows: ident,
307 $rows_with_step: ident,
308 $fixed_rows: ident,
309 $fixed_rows_with_step: ident,
310 $rows_generic: ident,
311 $rows_generic_with_step: ident,
312 $column: ident,
313 $column_part: ident,
314 $columns: ident,
315 $columns_with_step: ident,
316 $fixed_columns: ident,
317 $fixed_columns_with_step: ident,
318 $columns_generic: ident,
319 $columns_generic_with_step: ident,
320 $slice: ident => $view:ident,
321 $slice_with_steps: ident => $view_with_steps:ident,
322 $fixed_slice: ident => $fixed_view:ident,
323 $fixed_slice_with_steps: ident => $fixed_view_with_steps:ident,
324 $generic_slice: ident => $generic_view:ident,
325 $generic_slice_with_steps: ident => $generic_view_with_steps:ident,
326 $rows_range_pair: ident,
327 $columns_range_pair: ident) => {
328 #[inline]
335 pub fn $row($me: $Me, i: usize) -> $MatrixView<'_, T, U1, C, S::RStride, S::CStride> {
336 $me.$fixed_rows::<1>(i)
337 }
338
339 #[inline]
341 pub fn $row_part($me: $Me, i: usize, n: usize) -> $MatrixView<'_, T, U1, Dyn, S::RStride, S::CStride> {
342 $me.$generic_view((i, 0), (Const::<1>, Dyn(n)))
343 }
344
345 #[inline]
347 pub fn $rows($me: $Me, first_row: usize, nrows: usize)
348 -> $MatrixView<'_, T, Dyn, C, S::RStride, S::CStride> {
349
350 $me.$rows_generic(first_row, Dyn(nrows))
351 }
352
353 #[inline]
355 pub fn $rows_with_step($me: $Me, first_row: usize, nrows: usize, step: usize)
356 -> $MatrixView<'_, T, Dyn, C, Dyn, S::CStride> {
357
358 $me.$rows_generic_with_step(first_row, Dyn(nrows), step)
359 }
360
361 #[inline]
363 pub fn $fixed_rows<const RVIEW: usize>($me: $Me, first_row: usize)
364 -> $MatrixView<'_, T, Const<RVIEW>, C, S::RStride, S::CStride> {
365
366 $me.$rows_generic(first_row, Const::<RVIEW>)
367 }
368
369 #[inline]
372 pub fn $fixed_rows_with_step<const RVIEW: usize>($me: $Me, first_row: usize, step: usize)
373 -> $MatrixView<'_, T, Const<RVIEW>, C, Dyn, S::CStride> {
374
375 $me.$rows_generic_with_step(first_row, Const::<RVIEW>, step)
376 }
377
378 #[inline]
381 pub fn $rows_generic<RView: Dim>($me: $Me, row_start: usize, nrows: RView)
382 -> $MatrixView<'_, T, RView, C, S::RStride, S::CStride> {
383
384 let my_shape = $me.shape_generic();
385 $me.assert_view_index((row_start, 0), (nrows.value(), my_shape.1.value()), (0, 0));
386
387 let shape = (nrows, my_shape.1);
388
389 unsafe {
390 let data = $ViewStorage::new_unchecked($data, (row_start, 0), shape);
391 Matrix::from_data_statically_unchecked(data)
392 }
393 }
394
395 #[inline]
398 pub fn $rows_generic_with_step<RView>($me: $Me, row_start: usize, nrows: RView, step: usize)
399 -> $MatrixView<'_, T, RView, C, Dyn, S::CStride>
400 where RView: Dim {
401
402 let my_shape = $me.shape_generic();
403 let my_strides = $me.data.strides();
404 $me.assert_view_index((row_start, 0), (nrows.value(), my_shape.1.value()), (step, 0));
405
406 let strides = (Dyn((step + 1) * my_strides.0.value()), my_strides.1);
407 let shape = (nrows, my_shape.1);
408
409 unsafe {
410 let data = $ViewStorage::new_with_strides_unchecked($data, (row_start, 0), shape, strides);
411 Matrix::from_data_statically_unchecked(data)
412 }
413 }
414
415 #[inline]
422 pub fn $column($me: $Me, i: usize) -> $MatrixView<'_, T, R, U1, S::RStride, S::CStride> {
423 $me.$fixed_columns::<1>(i)
424 }
425
426 #[inline]
428 pub fn $column_part($me: $Me, i: usize, n: usize) -> $MatrixView<'_, T, Dyn, U1, S::RStride, S::CStride> {
429 $me.$generic_view((0, i), (Dyn(n), Const::<1>))
430 }
431
432 #[inline]
434 pub fn $columns($me: $Me, first_col: usize, ncols: usize)
435 -> $MatrixView<'_, T, R, Dyn, S::RStride, S::CStride> {
436
437 $me.$columns_generic(first_col, Dyn(ncols))
438 }
439
440 #[inline]
443 pub fn $columns_with_step($me: $Me, first_col: usize, ncols: usize, step: usize)
444 -> $MatrixView<'_, T, R, Dyn, S::RStride, Dyn> {
445
446 $me.$columns_generic_with_step(first_col, Dyn(ncols), step)
447 }
448
449 #[inline]
451 pub fn $fixed_columns<const CVIEW: usize>($me: $Me, first_col: usize)
452 -> $MatrixView<'_, T, R, Const<CVIEW>, S::RStride, S::CStride> {
453
454 $me.$columns_generic(first_col, Const::<CVIEW>)
455 }
456
457 #[inline]
460 pub fn $fixed_columns_with_step<const CVIEW: usize>($me: $Me, first_col: usize, step: usize)
461 -> $MatrixView<'_, T, R, Const<CVIEW>, S::RStride, Dyn> {
462
463 $me.$columns_generic_with_step(first_col, Const::<CVIEW>, step)
464 }
465
466 #[inline]
469 pub fn $columns_generic<CView: Dim>($me: $Me, first_col: usize, ncols: CView)
470 -> $MatrixView<'_, T, R, CView, S::RStride, S::CStride> {
471
472 let my_shape = $me.shape_generic();
473 $me.assert_view_index((0, first_col), (my_shape.0.value(), ncols.value()), (0, 0));
474 let shape = (my_shape.0, ncols);
475
476 unsafe {
477 let data = $ViewStorage::new_unchecked($data, (0, first_col), shape);
478 Matrix::from_data_statically_unchecked(data)
479 }
480 }
481
482
483 #[inline]
486 pub fn $columns_generic_with_step<CView: Dim>($me: $Me, first_col: usize, ncols: CView, step: usize)
487 -> $MatrixView<'_, T, R, CView, S::RStride, Dyn> {
488
489 let my_shape = $me.shape_generic();
490 let my_strides = $me.data.strides();
491
492 $me.assert_view_index((0, first_col), (my_shape.0.value(), ncols.value()), (0, step));
493
494 let strides = (my_strides.0, Dyn((step + 1) * my_strides.1.value()));
495 let shape = (my_shape.0, ncols);
496
497 unsafe {
498 let data = $ViewStorage::new_with_strides_unchecked($data, (0, first_col), shape, strides);
499 Matrix::from_data_statically_unchecked(data)
500 }
501 }
502
503 #[inline]
511 #[deprecated = slice_deprecation_note!($view)]
512 pub fn $slice($me: $Me, start: (usize, usize), shape: (usize, usize))
513 -> $MatrixView<'_, T, Dyn, Dyn, S::RStride, S::CStride> {
514 $me.$view(start, shape)
515 }
516
517 #[inline]
520 pub fn $view($me: $Me, start: (usize, usize), shape: (usize, usize))
521 -> $MatrixView<'_, T, Dyn, Dyn, S::RStride, S::CStride> {
522
523 $me.assert_view_index(start, shape, (0, 0));
524 let shape = (Dyn(shape.0), Dyn(shape.1));
525
526 unsafe {
527 let data = $ViewStorage::new_unchecked($data, start, shape);
528 Matrix::from_data_statically_unchecked(data)
529 }
530 }
531
532 #[inline]
537 #[deprecated = slice_deprecation_note!($view_with_steps)]
538 pub fn $slice_with_steps($me: $Me, start: (usize, usize), shape: (usize, usize), steps: (usize, usize))
539 -> $MatrixView<'_, T, Dyn, Dyn, Dyn, Dyn> {
540 $me.$view_with_steps(start, shape, steps)
541 }
542
543 #[inline]
548 pub fn $view_with_steps($me: $Me, start: (usize, usize), shape: (usize, usize), steps: (usize, usize))
549 -> $MatrixView<'_, T, Dyn, Dyn, Dyn, Dyn> {
550 let shape = (Dyn(shape.0), Dyn(shape.1));
551 $me.$generic_view_with_steps(start, shape, steps)
552 }
553
554 #[inline]
557 #[deprecated = slice_deprecation_note!($fixed_view)]
558 pub fn $fixed_slice<const RVIEW: usize, const CVIEW: usize>($me: $Me, irow: usize, icol: usize)
559 -> $MatrixView<'_, T, Const<RVIEW>, Const<CVIEW>, S::RStride, S::CStride> {
560 $me.$fixed_view(irow, icol)
561 }
562
563 #[inline]
566 pub fn $fixed_view<const RVIEW: usize, const CVIEW: usize>($me: $Me, irow: usize, icol: usize)
567 -> $MatrixView<'_, T, Const<RVIEW>, Const<CVIEW>, S::RStride, S::CStride> {
568
569 $me.assert_view_index((irow, icol), (RVIEW, CVIEW), (0, 0));
570 let shape = (Const::<RVIEW>, Const::<CVIEW>);
571
572 unsafe {
573 let data = $ViewStorage::new_unchecked($data, (irow, icol), shape);
574 Matrix::from_data_statically_unchecked(data)
575 }
576 }
577
578 #[inline]
583 #[deprecated = slice_deprecation_note!($fixed_view_with_steps)]
584 pub fn $fixed_slice_with_steps<const RVIEW: usize, const CVIEW: usize>($me: $Me, start: (usize, usize), steps: (usize, usize))
585 -> $MatrixView<'_, T, Const<RVIEW>, Const<CVIEW>, Dyn, Dyn> {
586 $me.$fixed_view_with_steps(start, steps)
587 }
588
589 #[inline]
594 pub fn $fixed_view_with_steps<const RVIEW: usize, const CVIEW: usize>($me: $Me, start: (usize, usize), steps: (usize, usize))
595 -> $MatrixView<'_, T, Const<RVIEW>, Const<CVIEW>, Dyn, Dyn> {
596 let shape = (Const::<RVIEW>, Const::<CVIEW>);
597 $me.$generic_view_with_steps(start, shape, steps)
598 }
599
600 #[inline]
602 #[deprecated = slice_deprecation_note!($generic_view)]
603 pub fn $generic_slice<RView, CView>($me: $Me, start: (usize, usize), shape: (RView, CView))
604 -> $MatrixView<'_, T, RView, CView, S::RStride, S::CStride>
605 where RView: Dim,
606 CView: Dim {
607 $me.$generic_view(start, shape)
608 }
609
610 #[inline]
612 pub fn $generic_view<RView, CView>($me: $Me, start: (usize, usize), shape: (RView, CView))
613 -> $MatrixView<'_, T, RView, CView, S::RStride, S::CStride>
614 where RView: Dim,
615 CView: Dim {
616
617 $me.assert_view_index(start, (shape.0.value(), shape.1.value()), (0, 0));
618
619 unsafe {
620 let data = $ViewStorage::new_unchecked($data, start, shape);
621 Matrix::from_data_statically_unchecked(data)
622 }
623 }
624
625 #[inline]
627 #[deprecated = slice_deprecation_note!($generic_view_with_steps)]
628 pub fn $generic_slice_with_steps<RView, CView>($me: $Me,
629 start: (usize, usize),
630 shape: (RView, CView),
631 steps: (usize, usize))
632 -> $MatrixView<'_, T, RView, CView, Dyn, Dyn>
633 where RView: Dim,
634 CView: Dim {
635 $me.$generic_view_with_steps(start, shape, steps)
636 }
637
638 #[inline]
640 pub fn $generic_view_with_steps<RView, CView>($me: $Me,
641 start: (usize, usize),
642 shape: (RView, CView),
643 steps: (usize, usize))
644 -> $MatrixView<'_, T, RView, CView, Dyn, Dyn>
645 where RView: Dim,
646 CView: Dim {
647
648 $me.assert_view_index(start, (shape.0.value(), shape.1.value()), steps);
649
650 let my_strides = $me.data.strides();
651 let strides = (Dyn((steps.0 + 1) * my_strides.0.value()),
652 Dyn((steps.1 + 1) * my_strides.1.value()));
653
654 unsafe {
655 let data = $ViewStorage::new_with_strides_unchecked($data, start, shape, strides);
656 Matrix::from_data_statically_unchecked(data)
657 }
658 }
659
660 #[inline]
669 pub fn $rows_range_pair<Range1: DimRange<R>, Range2: DimRange<R>>($me: $Me, r1: Range1, r2: Range2)
670 -> ($MatrixView<'_, T, Range1::Size, C, S::RStride, S::CStride>,
671 $MatrixView<'_, T, Range2::Size, C, S::RStride, S::CStride>) {
672
673 let (nrows, ncols) = $me.shape_generic();
674 let strides = $me.data.strides();
675
676 let start1 = r1.begin(nrows);
677 let start2 = r2.begin(nrows);
678
679 let end1 = r1.end(nrows);
680 let end2 = r2.end(nrows);
681
682 let nrows1 = r1.size(nrows);
683 let nrows2 = r2.size(nrows);
684
685 assert!(start2 >= end1 || start1 >= end2, "Rows range pair: the ranges must not overlap.");
686 assert!(end2 <= nrows.value(), "Rows range pair: index out of range.");
687
688 unsafe {
689 let ptr1 = $data.$get_addr(start1, 0);
690 let ptr2 = $data.$get_addr(start2, 0);
691
692 let data1 = $ViewStorage::from_raw_parts(ptr1, (nrows1, ncols), strides);
693 let data2 = $ViewStorage::from_raw_parts(ptr2, (nrows2, ncols), strides);
694 let view1 = Matrix::from_data_statically_unchecked(data1);
695 let view2 = Matrix::from_data_statically_unchecked(data2);
696
697 (view1, view2)
698 }
699 }
700
701 #[inline]
705 pub fn $columns_range_pair<Range1: DimRange<C>, Range2: DimRange<C>>($me: $Me, r1: Range1, r2: Range2)
706 -> ($MatrixView<'_, T, R, Range1::Size, S::RStride, S::CStride>,
707 $MatrixView<'_, T, R, Range2::Size, S::RStride, S::CStride>) {
708
709 let (nrows, ncols) = $me.shape_generic();
710 let strides = $me.data.strides();
711
712 let start1 = r1.begin(ncols);
713 let start2 = r2.begin(ncols);
714
715 let end1 = r1.end(ncols);
716 let end2 = r2.end(ncols);
717
718 let ncols1 = r1.size(ncols);
719 let ncols2 = r2.size(ncols);
720
721 assert!(start2 >= end1 || start1 >= end2, "Columns range pair: the ranges must not overlap.");
722 assert!(end2 <= ncols.value(), "Columns range pair: index out of range.");
723
724 unsafe {
725 let ptr1 = $data.$get_addr(0, start1);
726 let ptr2 = $data.$get_addr(0, start2);
727
728 let data1 = $ViewStorage::from_raw_parts(ptr1, (nrows, ncols1), strides);
729 let data2 = $ViewStorage::from_raw_parts(ptr2, (nrows, ncols2), strides);
730 let view1 = Matrix::from_data_statically_unchecked(data1);
731 let view2 = Matrix::from_data_statically_unchecked(data2);
732
733 (view1, view2)
734 }
735 }
736 }
737);
738
739#[deprecated = "Use MatrixView instead."]
746pub type MatrixSlice<'a, T, R, C, RStride = U1, CStride = R> =
747 MatrixView<'a, T, R, C, RStride, CStride>;
748
749pub type MatrixView<'a, T, R, C, RStride = U1, CStride = R> =
751 Matrix<T, R, C, ViewStorage<'a, T, R, C, RStride, CStride>>;
752
753#[deprecated = "Use MatrixViewMut instead."]
760pub type MatrixSliceMut<'a, T, R, C, RStride = U1, CStride = R> =
761 MatrixViewMut<'a, T, R, C, RStride, CStride>;
762
763pub type MatrixViewMut<'a, T, R, C, RStride = U1, CStride = R> =
765 Matrix<T, R, C, ViewStorageMut<'a, T, R, C, RStride, CStride>>;
766
767impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
769 matrix_view_impl!(
770 self: &Self, MatrixView, ViewStorage, RawStorage.get_address_unchecked(), &self.data;
771 row,
772 row_part,
773 rows,
774 rows_with_step,
775 fixed_rows,
776 fixed_rows_with_step,
777 rows_generic,
778 rows_generic_with_step,
779 column,
780 column_part,
781 columns,
782 columns_with_step,
783 fixed_columns,
784 fixed_columns_with_step,
785 columns_generic,
786 columns_generic_with_step,
787 slice => view,
788 slice_with_steps => view_with_steps,
789 fixed_slice => fixed_view,
790 fixed_slice_with_steps => fixed_view_with_steps,
791 generic_slice => generic_view,
792 generic_slice_with_steps => generic_view_with_steps,
793 rows_range_pair,
794 columns_range_pair);
795}
796
797impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
799 matrix_view_impl!(
800 self: &mut Self, MatrixViewMut, ViewStorageMut, RawStorageMut.get_address_unchecked_mut(), &mut self.data;
801 row_mut,
802 row_part_mut,
803 rows_mut,
804 rows_with_step_mut,
805 fixed_rows_mut,
806 fixed_rows_with_step_mut,
807 rows_generic_mut,
808 rows_generic_with_step_mut,
809 column_mut,
810 column_part_mut,
811 columns_mut,
812 columns_with_step_mut,
813 fixed_columns_mut,
814 fixed_columns_with_step_mut,
815 columns_generic_mut,
816 columns_generic_with_step_mut,
817 slice_mut => view_mut,
818 slice_with_steps_mut => view_with_steps_mut,
819 fixed_slice_mut => fixed_view_mut,
820 fixed_slice_with_steps_mut => fixed_view_with_steps_mut,
821 generic_slice_mut => generic_view_mut,
822 generic_slice_with_steps_mut => generic_view_with_steps_mut,
823 rows_range_pair_mut,
824 columns_range_pair_mut);
825}
826
827pub trait DimRange<D: Dim> {
835 type Size: Dim;
837
838 fn begin(&self, shape: D) -> usize;
840 fn end(&self, shape: D) -> usize;
843 fn size(&self, shape: D) -> Self::Size;
845}
846
847#[deprecated = slice_deprecation_note!(DimRange)]
851pub trait SliceRange<D: Dim>: DimRange<D> {}
852
853#[allow(deprecated)]
854impl<R: DimRange<D>, D: Dim> SliceRange<D> for R {}
855
856impl<D: Dim> DimRange<D> for usize {
857 type Size = U1;
858
859 #[inline(always)]
860 fn begin(&self, _: D) -> usize {
861 *self
862 }
863
864 #[inline(always)]
865 fn end(&self, _: D) -> usize {
866 *self + 1
867 }
868
869 #[inline(always)]
870 fn size(&self, _: D) -> Self::Size {
871 Const::<1>
872 }
873}
874
875impl<D: Dim> DimRange<D> for Range<usize> {
876 type Size = Dyn;
877
878 #[inline(always)]
879 fn begin(&self, _: D) -> usize {
880 self.start
881 }
882
883 #[inline(always)]
884 fn end(&self, _: D) -> usize {
885 self.end
886 }
887
888 #[inline(always)]
889 fn size(&self, _: D) -> Self::Size {
890 Dyn(self.end - self.start)
891 }
892}
893
894impl<D: Dim> DimRange<D> for RangeFrom<usize> {
895 type Size = Dyn;
896
897 #[inline(always)]
898 fn begin(&self, _: D) -> usize {
899 self.start
900 }
901
902 #[inline(always)]
903 fn end(&self, dim: D) -> usize {
904 dim.value()
905 }
906
907 #[inline(always)]
908 fn size(&self, dim: D) -> Self::Size {
909 Dyn(dim.value() - self.start)
910 }
911}
912
913impl<D: Dim> DimRange<D> for RangeTo<usize> {
914 type Size = Dyn;
915
916 #[inline(always)]
917 fn begin(&self, _: D) -> usize {
918 0
919 }
920
921 #[inline(always)]
922 fn end(&self, _: D) -> usize {
923 self.end
924 }
925
926 #[inline(always)]
927 fn size(&self, _: D) -> Self::Size {
928 Dyn(self.end)
929 }
930}
931
932impl<D: Dim> DimRange<D> for RangeFull {
933 type Size = D;
934
935 #[inline(always)]
936 fn begin(&self, _: D) -> usize {
937 0
938 }
939
940 #[inline(always)]
941 fn end(&self, dim: D) -> usize {
942 dim.value()
943 }
944
945 #[inline(always)]
946 fn size(&self, dim: D) -> Self::Size {
947 dim
948 }
949}
950
951impl<D: Dim> DimRange<D> for RangeInclusive<usize> {
952 type Size = Dyn;
953
954 #[inline(always)]
955 fn begin(&self, _: D) -> usize {
956 *self.start()
957 }
958
959 #[inline(always)]
960 fn end(&self, _: D) -> usize {
961 *self.end() + 1
962 }
963
964 #[inline(always)]
965 fn size(&self, _: D) -> Self::Size {
966 Dyn(*self.end() + 1 - *self.start())
967 }
968}
969
970impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
973 #[inline]
976 #[must_use]
977 #[deprecated = slice_deprecation_note!(view_range)]
978 pub fn slice_range<RowRange, ColRange>(
979 &self,
980 rows: RowRange,
981 cols: ColRange,
982 ) -> MatrixView<'_, T, RowRange::Size, ColRange::Size, S::RStride, S::CStride>
983 where
984 RowRange: DimRange<R>,
985 ColRange: DimRange<C>,
986 {
987 let (nrows, ncols) = self.shape_generic();
988 self.generic_view(
989 (rows.begin(nrows), cols.begin(ncols)),
990 (rows.size(nrows), cols.size(ncols)),
991 )
992 }
993
994 #[inline]
997 #[must_use]
998 pub fn view_range<RowRange, ColRange>(
999 &self,
1000 rows: RowRange,
1001 cols: ColRange,
1002 ) -> MatrixView<'_, T, RowRange::Size, ColRange::Size, S::RStride, S::CStride>
1003 where
1004 RowRange: DimRange<R>,
1005 ColRange: DimRange<C>,
1006 {
1007 let (nrows, ncols) = self.shape_generic();
1008 self.generic_view(
1009 (rows.begin(nrows), cols.begin(ncols)),
1010 (rows.size(nrows), cols.size(ncols)),
1011 )
1012 }
1013
1014 #[inline]
1016 #[must_use]
1017 pub fn rows_range<RowRange: DimRange<R>>(
1018 &self,
1019 rows: RowRange,
1020 ) -> MatrixView<'_, T, RowRange::Size, C, S::RStride, S::CStride> {
1021 self.view_range(rows, ..)
1022 }
1023
1024 #[inline]
1026 #[must_use]
1027 pub fn columns_range<ColRange: DimRange<C>>(
1028 &self,
1029 cols: ColRange,
1030 ) -> MatrixView<'_, T, R, ColRange::Size, S::RStride, S::CStride> {
1031 self.view_range(.., cols)
1032 }
1033}
1034
1035impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
1038 #[deprecated = slice_deprecation_note!(view_range_mut)]
1041 pub fn slice_range_mut<RowRange, ColRange>(
1042 &mut self,
1043 rows: RowRange,
1044 cols: ColRange,
1045 ) -> MatrixViewMut<'_, T, RowRange::Size, ColRange::Size, S::RStride, S::CStride>
1046 where
1047 RowRange: DimRange<R>,
1048 ColRange: DimRange<C>,
1049 {
1050 self.view_range_mut(rows, cols)
1051 }
1052
1053 pub fn view_range_mut<RowRange, ColRange>(
1056 &mut self,
1057 rows: RowRange,
1058 cols: ColRange,
1059 ) -> MatrixViewMut<'_, T, RowRange::Size, ColRange::Size, S::RStride, S::CStride>
1060 where
1061 RowRange: DimRange<R>,
1062 ColRange: DimRange<C>,
1063 {
1064 let (nrows, ncols) = self.shape_generic();
1065 self.generic_view_mut(
1066 (rows.begin(nrows), cols.begin(ncols)),
1067 (rows.size(nrows), cols.size(ncols)),
1068 )
1069 }
1070
1071 #[inline]
1073 pub fn rows_range_mut<RowRange: DimRange<R>>(
1074 &mut self,
1075 rows: RowRange,
1076 ) -> MatrixViewMut<'_, T, RowRange::Size, C, S::RStride, S::CStride> {
1077 self.view_range_mut(rows, ..)
1078 }
1079
1080 #[inline]
1082 pub fn columns_range_mut<ColRange: DimRange<C>>(
1083 &mut self,
1084 cols: ColRange,
1085 ) -> MatrixViewMut<'_, T, R, ColRange::Size, S::RStride, S::CStride> {
1086 self.view_range_mut(.., cols)
1087 }
1088}
1089
1090impl<'a, T, R, C, RStride, CStride> From<MatrixViewMut<'a, T, R, C, RStride, CStride>>
1091 for MatrixView<'a, T, R, C, RStride, CStride>
1092where
1093 R: Dim,
1094 C: Dim,
1095 RStride: Dim,
1096 CStride: Dim,
1097{
1098 fn from(view_mut: MatrixViewMut<'a, T, R, C, RStride, CStride>) -> Self {
1099 let data = ViewStorage {
1100 ptr: view_mut.data.ptr,
1101 shape: view_mut.data.shape,
1102 strides: view_mut.data.strides,
1103 _phantoms: PhantomData,
1104 };
1105
1106 unsafe { Matrix::from_data_statically_unchecked(data) }
1107 }
1108}
1109
1110impl<T, R, C, S> Matrix<T, R, C, S>
1111where
1112 R: Dim,
1113 C: Dim,
1114 S: RawStorage<T, R, C>,
1115{
1116 pub fn as_view<RView, CView, RViewStride, CViewStride>(
1140 &self,
1141 ) -> MatrixView<'_, T, RView, CView, RViewStride, CViewStride>
1142 where
1143 RView: Dim,
1144 CView: Dim,
1145 RViewStride: Dim,
1146 CViewStride: Dim,
1147 ShapeConstraint: DimEq<R, RView>
1148 + DimEq<C, CView>
1149 + DimEq<RViewStride, S::RStride>
1150 + DimEq<CViewStride, S::CStride>,
1151 {
1152 self.into()
1154 }
1155}
1156
1157impl<T, R, C, S> Matrix<T, R, C, S>
1158where
1159 R: Dim,
1160 C: Dim,
1161 S: RawStorageMut<T, R, C>,
1162{
1163 pub fn as_view_mut<RView, CView, RViewStride, CViewStride>(
1187 &mut self,
1188 ) -> MatrixViewMut<'_, T, RView, CView, RViewStride, CViewStride>
1189 where
1190 RView: Dim,
1191 CView: Dim,
1192 RViewStride: Dim,
1193 CViewStride: Dim,
1194 ShapeConstraint: DimEq<R, RView>
1195 + DimEq<C, CView>
1196 + DimEq<RViewStride, S::RStride>
1197 + DimEq<CViewStride, S::CStride>,
1198 {
1199 self.into()
1201 }
1202}
1203
1204impl<'a, T, R1, C1, R2, C2> ReshapableStorage<T, R1, C1, R2, C2>
1206 for ViewStorage<'a, T, R1, C1, U1, R1>
1207where
1208 T: Scalar,
1209 R1: Dim,
1210 C1: Dim,
1211 R2: Dim,
1212 C2: Dim,
1213{
1214 type Output = ViewStorage<'a, T, R2, C2, U1, R2>;
1215
1216 fn reshape_generic(self, nrows: R2, ncols: C2) -> Self::Output {
1217 let (r1, c1) = self.shape();
1218 assert_eq!(nrows.value() * ncols.value(), r1.value() * c1.value());
1219 let ptr = self.ptr();
1220 let new_shape = (nrows, ncols);
1221 let strides = (U1::name(), nrows);
1222 unsafe { ViewStorage::from_raw_parts(ptr, new_shape, strides) }
1223 }
1224}
1225
1226impl<'a, T, R1, C1, R2, C2> ReshapableStorage<T, R1, C1, R2, C2>
1228 for ViewStorageMut<'a, T, R1, C1, U1, R1>
1229where
1230 T: Scalar,
1231 R1: Dim,
1232 C1: Dim,
1233 R2: Dim,
1234 C2: Dim,
1235{
1236 type Output = ViewStorageMut<'a, T, R2, C2, U1, R2>;
1237
1238 fn reshape_generic(mut self, nrows: R2, ncols: C2) -> Self::Output {
1239 let (r1, c1) = self.shape();
1240 assert_eq!(nrows.value() * ncols.value(), r1.value() * c1.value());
1241 let ptr = self.ptr_mut();
1242 let new_shape = (nrows, ncols);
1243 let strides = (U1::name(), nrows);
1244 unsafe { ViewStorageMut::from_raw_parts(ptr, new_shape, strides) }
1245 }
1246}