1use std::marker::PhantomData;
2use std::ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo};
3use std::slice;
4
5use crate::ReshapableStorage;
6use crate::base::allocator::Allocator;
7use crate::base::default_allocator::DefaultAllocator;
8use crate::base::dimension::{Const, Dim, DimName, Dyn, IsNotStaticOne, U1};
9use crate::base::iter::MatrixIter;
10use crate::base::storage::{IsContiguous, Owned, RawStorage, RawStorageMut, Storage};
11use crate::base::{Matrix, Scalar};
12use crate::constraint::{DimEq, ShapeConstraint};
13
14macro_rules! view_storage_impl (
15 ($doc: expr_2021; $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 impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> $T<'a, T, R, C, RStride, CStride> {
37 #[inline]
43 pub const unsafe fn from_raw_parts(ptr: $Ptr,
44 shape: (R, C),
45 strides: (RStride, CStride))
46 -> Self
47 where RStride: Dim,
48 CStride: Dim {
49
50 $T {
51 ptr,
52 shape,
53 strides,
54 _phantoms: PhantomData
55 }
56 }
57 }
58
59 impl<'a, T, R: Dim, C: Dim> $T<'a, T, R, C, Dyn, Dyn> {
61 #[inline]
68 pub unsafe fn new_unchecked<RStor, CStor, S>(storage: $SRef, start: (usize, usize), shape: (R, C))
69 -> $T<'a, T, R, C, S::RStride, S::CStride>
70 where RStor: Dim,
71 CStor: Dim,
72 S: $Storage<T, RStor, CStor> { unsafe {
73
74 let strides = storage.strides();
75 $T::new_with_strides_unchecked(storage, start, shape, strides)
76 }}
77
78 #[inline]
84 pub unsafe fn new_with_strides_unchecked<S, RStor, CStor, RStride, CStride>(storage: $SRef,
85 start: (usize, usize),
86 shape: (R, C),
87 strides: (RStride, CStride))
88 -> $T<'a, T, R, C, RStride, CStride>
89 where RStor: Dim,
90 CStor: Dim,
91 S: $Storage<T, RStor, CStor>,
92 RStride: Dim,
93 CStride: Dim { unsafe {
94 $T::from_raw_parts(storage.$get_addr(start.0, start.1), shape, strides)
95 }}
96 }
97
98 impl <'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
99 $T<'a, T, R, C, RStride, CStride>
100 where
101 Self: RawStorage<T, R, C> + IsContiguous
102 {
103 pub fn into_slice(self) -> &'a [T] {
105 let (nrows, ncols) = self.shape();
106 if nrows.value() != 0 && ncols.value() != 0 {
107 let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1);
108 unsafe { slice::from_raw_parts(self.ptr, sz + 1) }
109 } else {
110 unsafe { slice::from_raw_parts(self.ptr, 0) }
111 }
112 }
113 }
114 }
115);
116
117view_storage_impl!("A matrix data storage for a matrix view. Only contains an internal reference \
118 to another matrix data storage.";
119 RawStorage as &'a S; SliceStorage => ViewStorage.get_address_unchecked(*const T as &'a T));
120
121view_storage_impl!("A mutable matrix data storage for mutable matrix view. Only contains an \
122 internal mutable reference to another matrix data storage.";
123 RawStorageMut as &'a mut S; SliceStorageMut => ViewStorageMut.get_address_unchecked_mut(*mut T as &'a mut T)
124);
125
126impl<T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Copy
127 for ViewStorage<'_, T, R, C, RStride, CStride>
128{
129}
130
131unsafe impl<'a, T: Sync, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Send
134 for ViewStorage<'a, T, R, C, RStride, CStride>
135{
136}
137
138unsafe impl<'a, T: Sync, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Sync
141 for ViewStorage<'a, T, R, C, RStride, CStride>
142{
143}
144
145impl<T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Clone
146 for ViewStorage<'_, T, R, C, RStride, CStride>
147{
148 #[inline]
149 fn clone(&self) -> Self {
150 *self
151 }
152}
153
154unsafe impl<'a, T: Send, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Send
157 for ViewStorageMut<'a, T, R, C, RStride, CStride>
158{
159}
160
161unsafe impl<'a, T: Sync, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Sync
164 for ViewStorageMut<'a, T, R, C, RStride, CStride>
165{
166}
167
168impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
169 ViewStorageMut<'a, T, R, C, RStride, CStride>
170where
171 Self: RawStorageMut<T, R, C> + IsContiguous,
172{
173 pub fn into_slice_mut(self) -> &'a mut [T] {
175 let (nrows, ncols) = self.shape();
176 if nrows.value() != 0 && ncols.value() != 0 {
177 let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1);
178 unsafe { slice::from_raw_parts_mut(self.ptr, sz + 1) }
179 } else {
180 unsafe { slice::from_raw_parts_mut(self.ptr, 0) }
181 }
182 }
183}
184
185macro_rules! storage_impl(
186 ($($T: ident),* $(,)*) => {$(
187 unsafe impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> RawStorage<T, R, C>
188 for $T<'a, T, R, C, RStride, CStride> {
189
190 type RStride = RStride;
191 type CStride = CStride;
192
193 #[inline]
194 fn ptr(&self) -> *const T {
195 self.ptr
196 }
197
198 #[inline]
199 fn shape(&self) -> (R, C) {
200 self.shape
201 }
202
203 #[inline]
204 fn strides(&self) -> (Self::RStride, Self::CStride) {
205 self.strides
206 }
207
208 #[inline]
209 fn is_contiguous(&self) -> bool {
210 if (RStride::is::<U1>() && C::is::<U1>()) || (CStride::is::<U1>() && R::is::<U1>()) { true
215 }
216 else {
217 let (nrows, _) = self.shape();
218 let (srows, scols) = self.strides();
219
220 srows.value() == 1 && scols.value() == nrows.value()
221 }
222 }
223
224 #[inline]
225 unsafe fn as_slice_unchecked(&self) -> &[T] { unsafe {
226 let (nrows, ncols) = self.shape();
227 if nrows.value() != 0 && ncols.value() != 0 {
228 let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1);
229 slice::from_raw_parts(self.ptr, sz + 1)
230 }
231 else {
232 slice::from_raw_parts(self.ptr, 0)
233 }
234 }}
235 }
236
237 unsafe impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Storage<T, R, C>
238 for $T<'a, T, R, C, RStride, CStride> {
239 #[inline]
240 fn into_owned(self) -> Owned<T, R, C>
241 where DefaultAllocator: Allocator<R, C> {
242 self.clone_owned()
243 }
244
245 #[inline]
246 fn clone_owned(&self) -> Owned<T, R, C>
247 where DefaultAllocator: Allocator<R, C> {
248 let (nrows, ncols) = self.shape();
249 let it = MatrixIter::new(self).cloned();
250 DefaultAllocator::allocate_from_iterator(nrows, ncols, it)
251 }
252
253 #[inline]
254 fn forget_elements(self) {
255 }
257 }
258 )*}
259);
260
261storage_impl!(ViewStorage, ViewStorageMut);
262
263unsafe impl<T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> RawStorageMut<T, R, C>
264 for ViewStorageMut<'_, T, R, C, RStride, CStride>
265{
266 #[inline]
267 fn ptr_mut(&mut self) -> *mut T {
268 self.ptr
269 }
270
271 #[inline]
272 unsafe fn as_mut_slice_unchecked(&mut self) -> &mut [T] {
273 unsafe {
274 let (nrows, ncols) = self.shape();
275 if nrows.value() != 0 && ncols.value() != 0 {
276 let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1);
277 slice::from_raw_parts_mut(self.ptr, sz + 1)
278 } else {
279 slice::from_raw_parts_mut(self.ptr, 0)
280 }
281 }
282 }
283}
284
285unsafe impl<T, R: Dim, CStride: Dim> IsContiguous for ViewStorage<'_, T, R, U1, U1, CStride> {}
286unsafe impl<T, R: Dim, CStride: Dim> IsContiguous for ViewStorageMut<'_, T, R, U1, U1, CStride> {}
287
288unsafe impl<T, R: DimName, C: Dim + IsNotStaticOne> IsContiguous
289 for ViewStorage<'_, T, R, C, U1, R>
290{
291}
292unsafe impl<T, R: DimName, C: Dim + IsNotStaticOne> IsContiguous
293 for ViewStorageMut<'_, T, R, C, U1, R>
294{
295}
296
297impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
298 #[inline]
299 fn assert_view_index(
300 &self,
301 start: (usize, usize),
302 shape: (usize, usize),
303 steps: (usize, usize),
304 ) {
305 let my_shape = self.shape();
306 assert!(
311 start.0 + (steps.0 + 1) * shape.0 <= my_shape.0 + steps.0,
312 "Matrix slicing out of bounds."
313 );
314 assert!(
315 start.1 + (steps.1 + 1) * shape.1 <= my_shape.1 + steps.1,
316 "Matrix slicing out of bounds."
317 );
318 }
319}
320
321macro_rules! matrix_view_impl (
322 ($me: ident: $Me: ty, $MatrixView: ident, $ViewStorage: ident, $Storage: ident.$get_addr: ident (), $data: expr_2021;
323 $row: ident,
324 $row_part: ident,
325 $rows: ident,
326 $rows_with_step: ident,
327 $fixed_rows: ident,
328 $fixed_rows_with_step: ident,
329 $rows_generic: ident,
330 $rows_generic_with_step: ident,
331 $column: ident,
332 $column_part: ident,
333 $columns: ident,
334 $columns_with_step: ident,
335 $fixed_columns: ident,
336 $fixed_columns_with_step: ident,
337 $columns_generic: ident,
338 $columns_generic_with_step: ident,
339 $slice: ident => $view:ident,
340 $slice_with_steps: ident => $view_with_steps:ident,
341 $fixed_slice: ident => $fixed_view:ident,
342 $fixed_slice_with_steps: ident => $fixed_view_with_steps:ident,
343 $generic_slice: ident => $generic_view:ident,
344 $generic_slice_with_steps: ident => $generic_view_with_steps:ident,
345 $rows_range_pair: ident,
346 $columns_range_pair: ident) => {
347 #[inline]
354 pub fn $row($me: $Me, i: usize) -> $MatrixView<'_, T, U1, C, S::RStride, S::CStride> {
355 $me.$fixed_rows::<1>(i)
356 }
357
358 #[inline]
360 pub fn $row_part($me: $Me, i: usize, n: usize) -> $MatrixView<'_, T, U1, Dyn, S::RStride, S::CStride> {
361 $me.$generic_view((i, 0), (Const::<1>, Dyn(n)))
362 }
363
364 #[inline]
366 pub fn $rows($me: $Me, first_row: usize, nrows: usize)
367 -> $MatrixView<'_, T, Dyn, C, S::RStride, S::CStride> {
368
369 $me.$rows_generic(first_row, Dyn(nrows))
370 }
371
372 #[inline]
374 pub fn $rows_with_step($me: $Me, first_row: usize, nrows: usize, step: usize)
375 -> $MatrixView<'_, T, Dyn, C, Dyn, S::CStride> {
376
377 $me.$rows_generic_with_step(first_row, Dyn(nrows), step)
378 }
379
380 #[inline]
382 pub fn $fixed_rows<const RVIEW: usize>($me: $Me, first_row: usize)
383 -> $MatrixView<'_, T, Const<RVIEW>, C, S::RStride, S::CStride> {
384
385 $me.$rows_generic(first_row, Const::<RVIEW>)
386 }
387
388 #[inline]
391 pub fn $fixed_rows_with_step<const RVIEW: usize>($me: $Me, first_row: usize, step: usize)
392 -> $MatrixView<'_, T, Const<RVIEW>, C, Dyn, S::CStride> {
393
394 $me.$rows_generic_with_step(first_row, Const::<RVIEW>, step)
395 }
396
397 #[inline]
400 pub fn $rows_generic<RView: Dim>($me: $Me, row_start: usize, nrows: RView)
401 -> $MatrixView<'_, T, RView, C, S::RStride, S::CStride> {
402
403 let my_shape = $me.shape_generic();
404 $me.assert_view_index((row_start, 0), (nrows.value(), my_shape.1.value()), (0, 0));
405
406 let shape = (nrows, my_shape.1);
407
408 unsafe {
409 let data = $ViewStorage::new_unchecked($data, (row_start, 0), shape);
410 Matrix::from_data_statically_unchecked(data)
411 }
412 }
413
414 #[inline]
417 pub fn $rows_generic_with_step<RView>($me: $Me, row_start: usize, nrows: RView, step: usize)
418 -> $MatrixView<'_, T, RView, C, Dyn, S::CStride>
419 where RView: Dim {
420
421 let my_shape = $me.shape_generic();
422 let my_strides = $me.data.strides();
423 $me.assert_view_index((row_start, 0), (nrows.value(), my_shape.1.value()), (step, 0));
424
425 let strides = (Dyn((step + 1) * my_strides.0.value()), my_strides.1);
426 let shape = (nrows, my_shape.1);
427
428 unsafe {
429 let data = $ViewStorage::new_with_strides_unchecked($data, (row_start, 0), shape, strides);
430 Matrix::from_data_statically_unchecked(data)
431 }
432 }
433
434 #[inline]
441 pub fn $column($me: $Me, i: usize) -> $MatrixView<'_, T, R, U1, S::RStride, S::CStride> {
442 $me.$fixed_columns::<1>(i)
443 }
444
445 #[inline]
447 pub fn $column_part($me: $Me, i: usize, n: usize) -> $MatrixView<'_, T, Dyn, U1, S::RStride, S::CStride> {
448 $me.$generic_view((0, i), (Dyn(n), Const::<1>))
449 }
450
451 #[inline]
453 pub fn $columns($me: $Me, first_col: usize, ncols: usize)
454 -> $MatrixView<'_, T, R, Dyn, S::RStride, S::CStride> {
455
456 $me.$columns_generic(first_col, Dyn(ncols))
457 }
458
459 #[inline]
462 pub fn $columns_with_step($me: $Me, first_col: usize, ncols: usize, step: usize)
463 -> $MatrixView<'_, T, R, Dyn, S::RStride, Dyn> {
464
465 $me.$columns_generic_with_step(first_col, Dyn(ncols), step)
466 }
467
468 #[inline]
470 pub fn $fixed_columns<const CVIEW: usize>($me: $Me, first_col: usize)
471 -> $MatrixView<'_, T, R, Const<CVIEW>, S::RStride, S::CStride> {
472
473 $me.$columns_generic(first_col, Const::<CVIEW>)
474 }
475
476 #[inline]
479 pub fn $fixed_columns_with_step<const CVIEW: usize>($me: $Me, first_col: usize, step: usize)
480 -> $MatrixView<'_, T, R, Const<CVIEW>, S::RStride, Dyn> {
481
482 $me.$columns_generic_with_step(first_col, Const::<CVIEW>, step)
483 }
484
485 #[inline]
488 pub fn $columns_generic<CView: Dim>($me: $Me, first_col: usize, ncols: CView)
489 -> $MatrixView<'_, T, R, CView, S::RStride, S::CStride> {
490
491 let my_shape = $me.shape_generic();
492 $me.assert_view_index((0, first_col), (my_shape.0.value(), ncols.value()), (0, 0));
493 let shape = (my_shape.0, ncols);
494
495 unsafe {
496 let data = $ViewStorage::new_unchecked($data, (0, first_col), shape);
497 Matrix::from_data_statically_unchecked(data)
498 }
499 }
500
501
502 #[inline]
505 pub fn $columns_generic_with_step<CView: Dim>($me: $Me, first_col: usize, ncols: CView, step: usize)
506 -> $MatrixView<'_, T, R, CView, S::RStride, Dyn> {
507
508 let my_shape = $me.shape_generic();
509 let my_strides = $me.data.strides();
510
511 $me.assert_view_index((0, first_col), (my_shape.0.value(), ncols.value()), (0, step));
512
513 let strides = (my_strides.0, Dyn((step + 1) * my_strides.1.value()));
514 let shape = (my_shape.0, ncols);
515
516 unsafe {
517 let data = $ViewStorage::new_with_strides_unchecked($data, (0, first_col), shape, strides);
518 Matrix::from_data_statically_unchecked(data)
519 }
520 }
521
522 #[inline]
530 #[deprecated = slice_deprecation_note!($view)]
531 pub fn $slice($me: $Me, start: (usize, usize), shape: (usize, usize))
532 -> $MatrixView<'_, T, Dyn, Dyn, S::RStride, S::CStride> {
533 $me.$view(start, shape)
534 }
535
536 #[inline]
539 pub fn $view($me: $Me, start: (usize, usize), shape: (usize, usize))
540 -> $MatrixView<'_, T, Dyn, Dyn, S::RStride, S::CStride> {
541
542 $me.assert_view_index(start, shape, (0, 0));
543 let shape = (Dyn(shape.0), Dyn(shape.1));
544
545 unsafe {
546 let data = $ViewStorage::new_unchecked($data, start, shape);
547 Matrix::from_data_statically_unchecked(data)
548 }
549 }
550
551 #[inline]
556 #[deprecated = slice_deprecation_note!($view_with_steps)]
557 pub fn $slice_with_steps($me: $Me, start: (usize, usize), shape: (usize, usize), steps: (usize, usize))
558 -> $MatrixView<'_, T, Dyn, Dyn, Dyn, Dyn> {
559 $me.$view_with_steps(start, shape, steps)
560 }
561
562 #[inline]
567 pub fn $view_with_steps($me: $Me, start: (usize, usize), shape: (usize, usize), steps: (usize, usize))
568 -> $MatrixView<'_, T, Dyn, Dyn, Dyn, Dyn> {
569 let shape = (Dyn(shape.0), Dyn(shape.1));
570 $me.$generic_view_with_steps(start, shape, steps)
571 }
572
573 #[inline]
576 #[deprecated = slice_deprecation_note!($fixed_view)]
577 pub fn $fixed_slice<const RVIEW: usize, const CVIEW: usize>($me: $Me, irow: usize, icol: usize)
578 -> $MatrixView<'_, T, Const<RVIEW>, Const<CVIEW>, S::RStride, S::CStride> {
579 $me.$fixed_view(irow, icol)
580 }
581
582 #[inline]
585 pub fn $fixed_view<const RVIEW: usize, const CVIEW: usize>($me: $Me, irow: usize, icol: usize)
586 -> $MatrixView<'_, T, Const<RVIEW>, Const<CVIEW>, S::RStride, S::CStride> {
587
588 $me.assert_view_index((irow, icol), (RVIEW, CVIEW), (0, 0));
589 let shape = (Const::<RVIEW>, Const::<CVIEW>);
590
591 unsafe {
592 let data = $ViewStorage::new_unchecked($data, (irow, icol), shape);
593 Matrix::from_data_statically_unchecked(data)
594 }
595 }
596
597 #[inline]
602 #[deprecated = slice_deprecation_note!($fixed_view_with_steps)]
603 pub fn $fixed_slice_with_steps<const RVIEW: usize, const CVIEW: usize>($me: $Me, start: (usize, usize), steps: (usize, usize))
604 -> $MatrixView<'_, T, Const<RVIEW>, Const<CVIEW>, Dyn, Dyn> {
605 $me.$fixed_view_with_steps(start, steps)
606 }
607
608 #[inline]
613 pub fn $fixed_view_with_steps<const RVIEW: usize, const CVIEW: usize>($me: $Me, start: (usize, usize), steps: (usize, usize))
614 -> $MatrixView<'_, T, Const<RVIEW>, Const<CVIEW>, Dyn, Dyn> {
615 let shape = (Const::<RVIEW>, Const::<CVIEW>);
616 $me.$generic_view_with_steps(start, shape, steps)
617 }
618
619 #[inline]
621 #[deprecated = slice_deprecation_note!($generic_view)]
622 pub fn $generic_slice<RView, CView>($me: $Me, start: (usize, usize), shape: (RView, CView))
623 -> $MatrixView<'_, T, RView, CView, S::RStride, S::CStride>
624 where RView: Dim,
625 CView: Dim {
626 $me.$generic_view(start, shape)
627 }
628
629 #[inline]
631 pub fn $generic_view<RView, CView>($me: $Me, start: (usize, usize), shape: (RView, CView))
632 -> $MatrixView<'_, T, RView, CView, S::RStride, S::CStride>
633 where RView: Dim,
634 CView: Dim {
635
636 $me.assert_view_index(start, (shape.0.value(), shape.1.value()), (0, 0));
637
638 unsafe {
639 let data = $ViewStorage::new_unchecked($data, start, shape);
640 Matrix::from_data_statically_unchecked(data)
641 }
642 }
643
644 #[inline]
646 #[deprecated = slice_deprecation_note!($generic_view_with_steps)]
647 pub fn $generic_slice_with_steps<RView, CView>($me: $Me,
648 start: (usize, usize),
649 shape: (RView, CView),
650 steps: (usize, usize))
651 -> $MatrixView<'_, T, RView, CView, Dyn, Dyn>
652 where RView: Dim,
653 CView: Dim {
654 $me.$generic_view_with_steps(start, shape, steps)
655 }
656
657 #[inline]
659 pub fn $generic_view_with_steps<RView, CView>($me: $Me,
660 start: (usize, usize),
661 shape: (RView, CView),
662 steps: (usize, usize))
663 -> $MatrixView<'_, T, RView, CView, Dyn, Dyn>
664 where RView: Dim,
665 CView: Dim {
666
667 $me.assert_view_index(start, (shape.0.value(), shape.1.value()), steps);
668
669 let my_strides = $me.data.strides();
670 let strides = (Dyn((steps.0 + 1) * my_strides.0.value()),
671 Dyn((steps.1 + 1) * my_strides.1.value()));
672
673 unsafe {
674 let data = $ViewStorage::new_with_strides_unchecked($data, start, shape, strides);
675 Matrix::from_data_statically_unchecked(data)
676 }
677 }
678
679 #[inline]
688 pub fn $rows_range_pair<Range1: DimRange<R>, Range2: DimRange<R>>($me: $Me, r1: Range1, r2: Range2)
689 -> ($MatrixView<'_, T, Range1::Size, C, S::RStride, S::CStride>,
690 $MatrixView<'_, T, Range2::Size, C, S::RStride, S::CStride>) {
691
692 let (nrows, ncols) = $me.shape_generic();
693 let strides = $me.data.strides();
694
695 let start1 = r1.begin(nrows);
696 let start2 = r2.begin(nrows);
697
698 let end1 = r1.end(nrows);
699 let end2 = r2.end(nrows);
700
701 let nrows1 = r1.size(nrows);
702 let nrows2 = r2.size(nrows);
703
704 assert!(start2 >= end1 || start1 >= end2, "Rows range pair: the ranges must not overlap.");
705 assert!(end2 <= nrows.value(), "Rows range pair: index out of range.");
706
707 unsafe {
708 let ptr1 = $data.$get_addr(start1, 0);
709 let ptr2 = $data.$get_addr(start2, 0);
710
711 let data1 = $ViewStorage::from_raw_parts(ptr1, (nrows1, ncols), strides);
712 let data2 = $ViewStorage::from_raw_parts(ptr2, (nrows2, ncols), strides);
713 let view1 = Matrix::from_data_statically_unchecked(data1);
714 let view2 = Matrix::from_data_statically_unchecked(data2);
715
716 (view1, view2)
717 }
718 }
719
720 #[inline]
724 pub fn $columns_range_pair<Range1: DimRange<C>, Range2: DimRange<C>>($me: $Me, r1: Range1, r2: Range2)
725 -> ($MatrixView<'_, T, R, Range1::Size, S::RStride, S::CStride>,
726 $MatrixView<'_, T, R, Range2::Size, S::RStride, S::CStride>) {
727
728 let (nrows, ncols) = $me.shape_generic();
729 let strides = $me.data.strides();
730
731 let start1 = r1.begin(ncols);
732 let start2 = r2.begin(ncols);
733
734 let end1 = r1.end(ncols);
735 let end2 = r2.end(ncols);
736
737 let ncols1 = r1.size(ncols);
738 let ncols2 = r2.size(ncols);
739
740 assert!(start2 >= end1 || start1 >= end2, "Columns range pair: the ranges must not overlap.");
741 assert!(end2 <= ncols.value(), "Columns range pair: index out of range.");
742
743 unsafe {
744 let ptr1 = $data.$get_addr(0, start1);
745 let ptr2 = $data.$get_addr(0, start2);
746
747 let data1 = $ViewStorage::from_raw_parts(ptr1, (nrows, ncols1), strides);
748 let data2 = $ViewStorage::from_raw_parts(ptr2, (nrows, ncols2), strides);
749 let view1 = Matrix::from_data_statically_unchecked(data1);
750 let view2 = Matrix::from_data_statically_unchecked(data2);
751
752 (view1, view2)
753 }
754 }
755 }
756);
757
758#[deprecated = "Use MatrixView instead."]
765pub type MatrixSlice<'a, T, R, C, RStride = U1, CStride = R> =
766 MatrixView<'a, T, R, C, RStride, CStride>;
767
768pub type MatrixView<'a, T, R, C, RStride = U1, CStride = R> =
770 Matrix<T, R, C, ViewStorage<'a, T, R, C, RStride, CStride>>;
771
772#[deprecated = "Use MatrixViewMut instead."]
779pub type MatrixSliceMut<'a, T, R, C, RStride = U1, CStride = R> =
780 MatrixViewMut<'a, T, R, C, RStride, CStride>;
781
782pub type MatrixViewMut<'a, T, R, C, RStride = U1, CStride = R> =
784 Matrix<T, R, C, ViewStorageMut<'a, T, R, C, RStride, CStride>>;
785
786impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
788 matrix_view_impl!(
789 self: &Self, MatrixView, ViewStorage, RawStorage.get_address_unchecked(), &self.data;
790 row,
791 row_part,
792 rows,
793 rows_with_step,
794 fixed_rows,
795 fixed_rows_with_step,
796 rows_generic,
797 rows_generic_with_step,
798 column,
799 column_part,
800 columns,
801 columns_with_step,
802 fixed_columns,
803 fixed_columns_with_step,
804 columns_generic,
805 columns_generic_with_step,
806 slice => view,
807 slice_with_steps => view_with_steps,
808 fixed_slice => fixed_view,
809 fixed_slice_with_steps => fixed_view_with_steps,
810 generic_slice => generic_view,
811 generic_slice_with_steps => generic_view_with_steps,
812 rows_range_pair,
813 columns_range_pair);
814}
815
816impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
818 matrix_view_impl!(
819 self: &mut Self, MatrixViewMut, ViewStorageMut, RawStorageMut.get_address_unchecked_mut(), &mut self.data;
820 row_mut,
821 row_part_mut,
822 rows_mut,
823 rows_with_step_mut,
824 fixed_rows_mut,
825 fixed_rows_with_step_mut,
826 rows_generic_mut,
827 rows_generic_with_step_mut,
828 column_mut,
829 column_part_mut,
830 columns_mut,
831 columns_with_step_mut,
832 fixed_columns_mut,
833 fixed_columns_with_step_mut,
834 columns_generic_mut,
835 columns_generic_with_step_mut,
836 slice_mut => view_mut,
837 slice_with_steps_mut => view_with_steps_mut,
838 fixed_slice_mut => fixed_view_mut,
839 fixed_slice_with_steps_mut => fixed_view_with_steps_mut,
840 generic_slice_mut => generic_view_mut,
841 generic_slice_with_steps_mut => generic_view_with_steps_mut,
842 rows_range_pair_mut,
843 columns_range_pair_mut);
844}
845
846pub trait DimRange<D: Dim> {
854 type Size: Dim;
856
857 fn begin(&self, shape: D) -> usize;
859 fn end(&self, shape: D) -> usize;
862 fn size(&self, shape: D) -> Self::Size;
864}
865
866#[deprecated = slice_deprecation_note!(DimRange)]
870pub trait SliceRange<D: Dim>: DimRange<D> {}
871
872#[allow(deprecated)]
873impl<R: DimRange<D>, D: Dim> SliceRange<D> for R {}
874
875impl<D: Dim> DimRange<D> for usize {
876 type Size = U1;
877
878 #[inline(always)]
879 fn begin(&self, _: D) -> usize {
880 *self
881 }
882
883 #[inline(always)]
884 fn end(&self, _: D) -> usize {
885 *self + 1
886 }
887
888 #[inline(always)]
889 fn size(&self, _: D) -> Self::Size {
890 Const::<1>
891 }
892}
893
894impl<D: Dim> DimRange<D> for Range<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, _: D) -> usize {
904 self.end
905 }
906
907 #[inline(always)]
908 fn size(&self, _: D) -> Self::Size {
909 Dyn(self.end - self.start)
910 }
911}
912
913impl<D: Dim> DimRange<D> for RangeFrom<usize> {
914 type Size = Dyn;
915
916 #[inline(always)]
917 fn begin(&self, _: D) -> usize {
918 self.start
919 }
920
921 #[inline(always)]
922 fn end(&self, dim: D) -> usize {
923 dim.value()
924 }
925
926 #[inline(always)]
927 fn size(&self, dim: D) -> Self::Size {
928 Dyn(dim.value() - self.start)
929 }
930}
931
932impl<D: Dim> DimRange<D> for RangeTo<usize> {
933 type Size = Dyn;
934
935 #[inline(always)]
936 fn begin(&self, _: D) -> usize {
937 0
938 }
939
940 #[inline(always)]
941 fn end(&self, _: D) -> usize {
942 self.end
943 }
944
945 #[inline(always)]
946 fn size(&self, _: D) -> Self::Size {
947 Dyn(self.end)
948 }
949}
950
951impl<D: Dim> DimRange<D> for RangeFull {
952 type Size = D;
953
954 #[inline(always)]
955 fn begin(&self, _: D) -> usize {
956 0
957 }
958
959 #[inline(always)]
960 fn end(&self, dim: D) -> usize {
961 dim.value()
962 }
963
964 #[inline(always)]
965 fn size(&self, dim: D) -> Self::Size {
966 dim
967 }
968}
969
970impl<D: Dim> DimRange<D> for RangeInclusive<usize> {
971 type Size = Dyn;
972
973 #[inline(always)]
974 fn begin(&self, _: D) -> usize {
975 *self.start()
976 }
977
978 #[inline(always)]
979 fn end(&self, _: D) -> usize {
980 *self.end() + 1
981 }
982
983 #[inline(always)]
984 fn size(&self, _: D) -> Self::Size {
985 Dyn(*self.end() + 1 - *self.start())
986 }
987}
988
989impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
992 #[inline]
995 #[must_use]
996 #[deprecated = slice_deprecation_note!(view_range)]
997 pub fn slice_range<RowRange, ColRange>(
998 &self,
999 rows: RowRange,
1000 cols: ColRange,
1001 ) -> MatrixView<'_, T, RowRange::Size, ColRange::Size, S::RStride, S::CStride>
1002 where
1003 RowRange: DimRange<R>,
1004 ColRange: DimRange<C>,
1005 {
1006 let (nrows, ncols) = self.shape_generic();
1007 self.generic_view(
1008 (rows.begin(nrows), cols.begin(ncols)),
1009 (rows.size(nrows), cols.size(ncols)),
1010 )
1011 }
1012
1013 #[inline]
1016 #[must_use]
1017 pub fn view_range<RowRange, ColRange>(
1018 &self,
1019 rows: RowRange,
1020 cols: ColRange,
1021 ) -> MatrixView<'_, T, RowRange::Size, ColRange::Size, S::RStride, S::CStride>
1022 where
1023 RowRange: DimRange<R>,
1024 ColRange: DimRange<C>,
1025 {
1026 let (nrows, ncols) = self.shape_generic();
1027 self.generic_view(
1028 (rows.begin(nrows), cols.begin(ncols)),
1029 (rows.size(nrows), cols.size(ncols)),
1030 )
1031 }
1032
1033 #[inline]
1035 #[must_use]
1036 pub fn rows_range<RowRange: DimRange<R>>(
1037 &self,
1038 rows: RowRange,
1039 ) -> MatrixView<'_, T, RowRange::Size, C, S::RStride, S::CStride> {
1040 self.view_range(rows, ..)
1041 }
1042
1043 #[inline]
1045 #[must_use]
1046 pub fn columns_range<ColRange: DimRange<C>>(
1047 &self,
1048 cols: ColRange,
1049 ) -> MatrixView<'_, T, R, ColRange::Size, S::RStride, S::CStride> {
1050 self.view_range(.., cols)
1051 }
1052}
1053
1054impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
1057 #[deprecated = slice_deprecation_note!(view_range_mut)]
1060 pub fn slice_range_mut<RowRange, ColRange>(
1061 &mut self,
1062 rows: RowRange,
1063 cols: ColRange,
1064 ) -> MatrixViewMut<'_, T, RowRange::Size, ColRange::Size, S::RStride, S::CStride>
1065 where
1066 RowRange: DimRange<R>,
1067 ColRange: DimRange<C>,
1068 {
1069 self.view_range_mut(rows, cols)
1070 }
1071
1072 pub fn view_range_mut<RowRange, ColRange>(
1075 &mut self,
1076 rows: RowRange,
1077 cols: ColRange,
1078 ) -> MatrixViewMut<'_, T, RowRange::Size, ColRange::Size, S::RStride, S::CStride>
1079 where
1080 RowRange: DimRange<R>,
1081 ColRange: DimRange<C>,
1082 {
1083 let (nrows, ncols) = self.shape_generic();
1084 self.generic_view_mut(
1085 (rows.begin(nrows), cols.begin(ncols)),
1086 (rows.size(nrows), cols.size(ncols)),
1087 )
1088 }
1089
1090 #[inline]
1092 pub fn rows_range_mut<RowRange: DimRange<R>>(
1093 &mut self,
1094 rows: RowRange,
1095 ) -> MatrixViewMut<'_, T, RowRange::Size, C, S::RStride, S::CStride> {
1096 self.view_range_mut(rows, ..)
1097 }
1098
1099 #[inline]
1101 pub fn columns_range_mut<ColRange: DimRange<C>>(
1102 &mut self,
1103 cols: ColRange,
1104 ) -> MatrixViewMut<'_, T, R, ColRange::Size, S::RStride, S::CStride> {
1105 self.view_range_mut(.., cols)
1106 }
1107}
1108
1109impl<'a, T, R, C, RStride, CStride> From<MatrixViewMut<'a, T, R, C, RStride, CStride>>
1110 for MatrixView<'a, T, R, C, RStride, CStride>
1111where
1112 R: Dim,
1113 C: Dim,
1114 RStride: Dim,
1115 CStride: Dim,
1116{
1117 fn from(view_mut: MatrixViewMut<'a, T, R, C, RStride, CStride>) -> Self {
1118 let data = ViewStorage {
1119 ptr: view_mut.data.ptr,
1120 shape: view_mut.data.shape,
1121 strides: view_mut.data.strides,
1122 _phantoms: PhantomData,
1123 };
1124
1125 unsafe { Matrix::from_data_statically_unchecked(data) }
1126 }
1127}
1128
1129impl<T, R, C, S> Matrix<T, R, C, S>
1130where
1131 R: Dim,
1132 C: Dim,
1133 S: RawStorage<T, R, C>,
1134{
1135 pub fn as_view<RView, CView, RViewStride, CViewStride>(
1159 &self,
1160 ) -> MatrixView<'_, T, RView, CView, RViewStride, CViewStride>
1161 where
1162 RView: Dim,
1163 CView: Dim,
1164 RViewStride: Dim,
1165 CViewStride: Dim,
1166 ShapeConstraint: DimEq<R, RView>
1167 + DimEq<C, CView>
1168 + DimEq<RViewStride, S::RStride>
1169 + DimEq<CViewStride, S::CStride>,
1170 {
1171 self.into()
1173 }
1174}
1175
1176impl<T, R, C, S> Matrix<T, R, C, S>
1177where
1178 R: Dim,
1179 C: Dim,
1180 S: RawStorageMut<T, R, C>,
1181{
1182 pub fn as_view_mut<RView, CView, RViewStride, CViewStride>(
1206 &mut self,
1207 ) -> MatrixViewMut<'_, T, RView, CView, RViewStride, CViewStride>
1208 where
1209 RView: Dim,
1210 CView: Dim,
1211 RViewStride: Dim,
1212 CViewStride: Dim,
1213 ShapeConstraint: DimEq<R, RView>
1214 + DimEq<C, CView>
1215 + DimEq<RViewStride, S::RStride>
1216 + DimEq<CViewStride, S::CStride>,
1217 {
1218 self.into()
1220 }
1221}
1222
1223impl<'a, T, R1, C1, R2, C2> ReshapableStorage<T, R1, C1, R2, C2>
1225 for ViewStorage<'a, T, R1, C1, U1, R1>
1226where
1227 T: Scalar,
1228 R1: Dim,
1229 C1: Dim,
1230 R2: Dim,
1231 C2: Dim,
1232{
1233 type Output = ViewStorage<'a, T, R2, C2, U1, R2>;
1234
1235 fn reshape_generic(self, nrows: R2, ncols: C2) -> Self::Output {
1236 let (r1, c1) = self.shape();
1237 assert_eq!(nrows.value() * ncols.value(), r1.value() * c1.value());
1238 let ptr = self.ptr();
1239 let new_shape = (nrows, ncols);
1240 let strides = (U1::name(), nrows);
1241 unsafe { ViewStorage::from_raw_parts(ptr, new_shape, strides) }
1242 }
1243}
1244
1245impl<'a, T, R1, C1, R2, C2> ReshapableStorage<T, R1, C1, R2, C2>
1247 for ViewStorageMut<'a, T, R1, C1, U1, R1>
1248where
1249 T: Scalar,
1250 R1: Dim,
1251 C1: Dim,
1252 R2: Dim,
1253 C2: Dim,
1254{
1255 type Output = ViewStorageMut<'a, T, R2, C2, U1, R2>;
1256
1257 fn reshape_generic(mut self, nrows: R2, ncols: C2) -> Self::Output {
1258 let (r1, c1) = self.shape();
1259 assert_eq!(nrows.value() * ncols.value(), r1.value() * c1.value());
1260 let ptr = self.ptr_mut();
1261 let new_shape = (nrows, ncols);
1262 let strides = (U1::name(), nrows);
1263 unsafe { ViewStorageMut::from_raw_parts(ptr, new_shape, strides) }
1264 }
1265}