1use core::borrow::{Borrow, BorrowMut};
2use core::fmt::{self, Debug, Formatter};
3use core::hash::{Hash, Hasher};
4use core::marker::PhantomData;
5use core::ops::{Deref, DerefMut, Index, IndexMut};
6use core::slice;
7
8use crate::dim::{Const, Dim, Dyn};
9use crate::expr::{Apply, Expression, IntoExpression, Iter, Map, Zip};
10use crate::index::{self, Axis, DimIndex, Permutation, SliceIndex, Split, ViewIndex};
11use crate::layout::{Dense, Layout, Strided};
12use crate::mapping::{DenseMapping, Mapping, StridedMapping};
13use crate::raw_slice::RawSlice;
14use crate::shape::{DynRank, IntoShape, Rank, Shape};
15use crate::slice::Slice;
16
17pub struct View<'a, T, S: Shape = DynRank, L: Layout = Dense> {
19 slice: RawSlice<T, S, L>,
20 phantom: PhantomData<&'a T>,
21}
22
23pub struct ViewMut<'a, T, S: Shape = DynRank, L: Layout = Dense> {
25 slice: RawSlice<T, S, L>,
26 phantom: PhantomData<&'a mut T>,
27}
28
29pub type DView<'a, T, const N: usize, L = Dense> = View<'a, T, Rank<N>, L>;
31
32pub type DViewMut<'a, T, const N: usize, L = Dense> = ViewMut<'a, T, Rank<N>, L>;
34
35macro_rules! impl_view {
36 ($name:tt, $as_ptr:tt, $from_raw_parts:tt, $raw_mut:tt, {$($mut:tt)?}, $repeatable:tt) => {
37 impl<'a, T, S: Shape, L: Layout> $name<'a, T, S, L> {
38 #[inline]
44 pub fn into_at(
45 self,
46 index: usize,
47 ) -> $name<'a, T, S::Tail, L> {
48 self.into_axis_at(Const::<0>, index)
49 }
50
51 #[inline]
61 pub fn into_axis_at<A: Axis>(
62 $($mut)? self,
63 axis: A,
64 index: usize,
65 ) -> $name<'a, T, A::Remove<S>, Split<A, S, L>> {
66 unsafe { Self::axis_at(self.$as_ptr(), self.mapping(), axis, index) }
67 }
68
69 #[inline]
75 pub fn into_col(self, index: usize) -> $name<'a, T, (S::Head,), Strided> {
76 let shape = self.shape().with_dims(<(_, <S::Tail as Shape>::Head)>::from_dims);
77
78 self.into_shape(shape).into_view(.., index)
79 }
80
81 #[inline]
89 pub fn into_diag($($mut)? self, index: isize) -> $name<'a, T, (Dyn,), Strided> {
90 assert!(self.rank() == 2, "invalid rank");
91
92 let (offset, len) = if index >= 0 {
93 assert!(index as usize <= self.dim(1), "invalid diagonal");
94
95 (index * self.stride(1), self.dim(0).min(self.dim(1) - (index as usize)))
96 } else {
97 assert!(-index as usize <= self.dim(0), "invalid diagonal");
98
99 (-index * self.stride(0), self.dim(1).min(self.dim(0) - (-index as usize)))
100 };
101
102 let count = if len > 0 { offset } else { 0 }; let mapping = StridedMapping::new((len,), &[self.stride(0) + self.stride(1)]);
104
105 unsafe { $name::new_unchecked(self.$as_ptr().offset(count), mapping) }
106 }
107
108 #[inline]
110 pub fn into_dyn(self) -> $name<'a, T, DynRank, L> {
111 self.into_mapping()
112 }
113
114 #[inline]
120 pub fn into_flat(self) -> $name<'a, T, (Dyn,), L> {
121 let len = self.len();
122
123 self.into_shape([len])
124 }
125
126 #[inline]
133 pub fn into_mapping<R: Shape, K: Layout>($($mut)? self) -> $name<'a, T, R, K> {
134 let mapping = Mapping::remap(self.mapping());
135
136 unsafe { $name::new_unchecked(self.$as_ptr(), mapping) }
137 }
138
139 #[inline]
150 pub fn into_permuted<I: IntoShape<IntoShape: Permutation>>(
151 $($mut)? self,
152 perm: I,
153 ) -> $name<
154 'a,
155 T,
156 <I::IntoShape as Permutation>::Shape<S>,
157 <I::IntoShape as Permutation>::Layout<L>,
158 > {
159 let mapping = perm.into_dims(|dims| Mapping::permute(self.mapping(), dims));
160
161 unsafe { $name::new_unchecked(self.$as_ptr(), mapping) }
162 }
163
164 #[deprecated]
168 #[inline]
169 pub fn into_reordered(
170 $($mut)? self
171 ) -> $name<'a, T, S::Reverse, <S::Tail as Shape>::Layout<L>> {
172 let mapping = Mapping::transpose(self.mapping());
173
174 unsafe { $name::new_unchecked(self.$as_ptr(), mapping) }
175 }
176
177 #[inline]
183 pub fn into_row(self, index: usize) -> $name<'a, T, (<S::Tail as Shape>::Head,), L> {
184 let shape = self.shape().with_dims(<(S::Head, _)>::from_dims);
185
186 self.into_shape(shape).into_view(index, ..)
187 }
188
189 #[inline]
208 pub fn into_shape<I: IntoShape>(
209 $($mut)? self,
210 shape: I
211 ) -> $name<'a, T, I::IntoShape, L> {
212 let mapping = self.mapping().reshape(shape.into_shape());
213
214 unsafe { $name::new_unchecked(self.$as_ptr(), mapping) }
215 }
216
217 #[inline]
224 pub fn into_split_at(
225 self,
226 mid: usize,
227 ) -> (
228 $name<'a, T, <S::Tail as Shape>::Prepend<Dyn>, L>,
229 $name<'a, T, <S::Tail as Shape>::Prepend<Dyn>, L>,
230 ) {
231 self.into_split_axis_at(Const::<0>, mid)
232 }
233
234 #[inline]
245 pub fn into_split_axis_at<A: Axis>(
246 $($mut)? self,
247 axis: A,
248 mid: usize,
249 ) -> (
250 $name<'a, T, A::Resize<Dyn, S>, Split<A, S, L>>,
251 $name<'a, T, A::Resize<Dyn, S>, Split<A, S, L>>,
252 ) {
253 unsafe { Self::split_axis_at(self.$as_ptr(), self.mapping(), axis, mid) }
254 }
255
256 #[inline]
259 pub fn into_transposed(
260 $($mut)? self
261 ) -> $name<'a, T, S::Reverse, <S::Tail as Shape>::Layout<L>> {
262 let mapping = Mapping::transpose(self.mapping());
263
264 unsafe { $name::new_unchecked(self.$as_ptr(), mapping) }
265 }
266
267 #[inline]
273 pub unsafe fn new_unchecked(ptr: *$raw_mut T, mapping: L::Mapping<S>) -> Self {
274 let slice = unsafe { RawSlice::new_unchecked(ptr as *mut T, mapping) };
275
276 Self { slice, phantom: PhantomData }
277 }
278
279 #[inline]
280 pub(crate) unsafe fn axis_at<A: Axis>(
281 ptr: *$raw_mut T,
282 mapping: &L::Mapping<S>,
283 axis: A,
284 index: usize,
285 ) -> $name<'a, T, A::Remove<S>, Split<A, S, L>> {
286 let size = mapping.dim(axis.index(mapping.rank()));
287
288 if index >= size {
289 index::panic_bounds_check(index, size);
290 }
291
292 let new_mapping = axis.remove(mapping);
293
294 let offset = mapping.stride(axis.index(mapping.rank())) * index as isize;
296 let count = if new_mapping.is_empty() { 0 } else { offset };
297
298 unsafe { $name::new_unchecked(ptr.offset(count), new_mapping) }
299 }
300
301 #[inline]
302 pub(crate) unsafe fn split_axis_at<A: Axis>(
303 ptr: *$raw_mut T,
304 mapping: &L::Mapping<S>,
305 axis: A,
306 mid: usize,
307 ) -> (
308 $name<'a, T, A::Resize<Dyn, S>, Split<A, S, L>>,
309 $name<'a, T, A::Resize<Dyn, S>, Split<A, S, L>>,
310 ) {
311 let index = axis.index(mapping.rank());
312 let size = mapping.dim(index);
313
314 if mid > size {
315 index::panic_bounds_check(mid, size);
316 }
317
318 let first_mapping = axis.resize(mapping, mid);
319 let second_mapping = axis.resize(mapping, size - mid);
320
321 let offset = mapping.stride(index) * mid as isize;
323 let count = if second_mapping.is_empty() { 0 } else { offset };
324
325 unsafe {
326 let first = $name::new_unchecked(ptr, first_mapping);
327 let second = $name::new_unchecked(ptr.offset(count), second_mapping);
328
329 (first, second)
330 }
331 }
332 }
333
334 impl<'a, T, U, S: Shape, L: Layout> Apply<U> for &'a $name<'_, T, S, L> {
335 type Output<F: FnMut(&'a T) -> U> = Map<Self::IntoExpr, F>;
336 type ZippedWith<I: IntoExpression, F: FnMut((&'a T, I::Item)) -> U> =
337 Map<Zip<Self::IntoExpr, I::IntoExpr>, F>;
338
339 #[inline]
340 fn apply<F: FnMut(&'a T) -> U>(self, f: F) -> Self::Output<F> {
341 self.expr().map(f)
342 }
343
344 #[inline]
345 fn zip_with<I: IntoExpression, F>(self, expr: I, f: F) -> Self::ZippedWith<I, F>
346 where
347 F: FnMut((&'a T, I::Item)) -> U,
348 {
349 self.expr().zip(expr).map(f)
350 }
351 }
352
353 impl<T, U: ?Sized, S: Shape, L: Layout> AsRef<U> for $name<'_, T, S, L>
354 where
355 Slice<T, S, L>: AsRef<U>,
356 {
357 #[inline]
358 fn as_ref(&self) -> &U {
359 (**self).as_ref()
360 }
361 }
362
363 impl<T, S: Shape, L: Layout> Borrow<Slice<T, S, L>> for $name<'_, T, S, L> {
364 #[inline]
365 fn borrow(&self) -> &Slice<T, S, L> {
366 self
367 }
368 }
369
370 impl<T: Debug, S: Shape, L: Layout> Debug for $name<'_, T, S, L> {
371 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
372 (**self).fmt(f)
373 }
374 }
375
376 impl<T, S: Shape, L: Layout> Deref for $name<'_, T, S, L> {
377 type Target = Slice<T, S, L>;
378
379 #[inline]
380 fn deref(&self) -> &Self::Target {
381 self.slice.as_slice()
382 }
383 }
384
385 impl<'a, T, S: Shape, L: Layout> Expression for $name<'a, T, S, L> {
386 type Shape = S;
387
388 const IS_REPEATABLE: bool = $repeatable;
389
390 #[inline]
391 fn shape(&self) -> &S {
392 (**self).shape()
393 }
394
395 #[inline]
396 unsafe fn get_unchecked(&mut self, index: usize) -> &'a $($mut)? T {
397 let count = self.slice.mapping().inner_stride() * index as isize;
398
399 unsafe { &$($mut)? *self.slice.$as_ptr().offset(count) }
400 }
401
402 #[inline]
403 fn inner_rank(&self) -> usize {
404 if L::IS_DENSE {
405 if S::RANK == Some(0) { usize::MAX } else { self.rank() }
407 } else {
408 if self.rank() > 0 { 1 } else { usize::MAX }
410 }
411 }
412
413 #[inline]
414 unsafe fn reset_dim(&mut self, index: usize, count: usize) {
415 let count = -self.stride(index) * count as isize;
416 let ptr = self.slice.as_mut_ptr();
417
418 unsafe {
419 self.slice.set_ptr(ptr.offset(count));
420 }
421 }
422
423 #[inline]
424 unsafe fn step_dim(&mut self, index: usize) {
425 let ptr = self.slice.as_mut_ptr();
426
427 unsafe {
428 self.slice.set_ptr(ptr.offset(self.stride(index)));
429 }
430 }
431 }
432
433 impl<'a, T, S: Shape, L: Layout, I> From<&'a $($mut)? I> for $name<'a, T, S, L>
434 where
435 &'a $($mut)? I: IntoExpression<IntoExpr = $name<'a, T, S, L>>
436 {
437 #[inline]
438 fn from(value: &'a $($mut)? I) -> Self {
439 value.into_expr()
440 }
441 }
442
443 impl<'a, T> From<&'a $($mut)? [T]> for $name<'a, T, (Dyn,)> {
444 #[inline]
445 fn from(value: &'a $($mut)? [T]) -> Self {
446 let mapping = DenseMapping::new((value.len(),));
447
448 unsafe { Self::new_unchecked(value.$as_ptr(), mapping) }
449 }
450 }
451
452 impl<'a, T, D: Dim> From<$name<'a, T, (D,)>> for &'a $($mut)? [T] {
453 #[inline]
454 fn from($($mut)? value: $name<T, (D,)>) -> Self {
455 unsafe { slice::$from_raw_parts(value.$as_ptr(), value.len()) }
456 }
457 }
458
459 impl<T: Hash, S: Shape, L: Layout> Hash for $name<'_, T, S, L> {
460 #[inline]
461 fn hash<H: Hasher>(&self, state: &mut H) {
462 (**self).hash(state)
463 }
464 }
465
466 impl<T, S: Shape, L: Layout, I: SliceIndex<T, S, L>> Index<I> for $name<'_, T, S, L> {
467 type Output = I::Output;
468
469 #[inline]
470 fn index(&self, index: I) -> &I::Output {
471 index.index(self)
472 }
473 }
474
475 impl<'a, T, S: Shape, L: Layout> IntoExpression for &'a $name<'_, T, S, L> {
476 type Shape = S;
477 type IntoExpr = View<'a, T, S, L>;
478
479 #[inline]
480 fn into_expr(self) -> Self::IntoExpr {
481 self.expr()
482 }
483 }
484
485 impl<'a, T, S: Shape, L: Layout> IntoIterator for &'a $name<'_, T, S, L> {
486 type Item = &'a T;
487 type IntoIter = Iter<View<'a, T, S, L>>;
488
489 #[inline]
490 fn into_iter(self) -> Self::IntoIter {
491 self.expr().into_iter()
492 }
493 }
494
495 impl<'a, T, S: Shape, L: Layout> IntoIterator for $name<'a, T, S, L> {
496 type Item = &'a $($mut)? T;
497 type IntoIter = Iter<Self>;
498
499 #[inline]
500 fn into_iter(self) -> Iter<Self> {
501 Iter::new(self)
502 }
503 }
504 };
505}
506
507impl_view!(View, as_ptr, from_raw_parts, const, {}, true);
508impl_view!(ViewMut, as_mut_ptr, from_raw_parts_mut, mut, {mut}, false);
509
510macro_rules! impl_into_view {
511 ($n:tt, ($($xyz:tt),+), ($($abc:tt),+), ($($idx:tt),+)) => {
512 impl<'a, T, $($xyz: Dim,)+ L: Layout> View<'a, T, ($($xyz,)+), L> {
513 #[inline]
519 pub fn into_view<$($abc: DimIndex),+>(
520 self,
521 $($idx: $abc),+
522 ) -> View<
523 'a,
524 T,
525 <($($abc,)+) as ViewIndex>::Shape<($($xyz,)+)>,
526 <($($abc,)+) as ViewIndex>::Layout<L>,
527 > {
528 let (offset, mapping) = ($($idx,)+).view_index(self.mapping());
529
530 let count = if mapping.is_empty() { 0 } else { offset };
532
533 unsafe { View::new_unchecked(self.as_ptr().offset(count), mapping) }
534 }
535 }
536
537 impl<'a, T, $($xyz: Dim,)+ L: Layout> ViewMut<'a, T, ($($xyz,)+), L> {
538 #[inline]
544 pub fn into_view<$($abc: DimIndex),+>(
545 mut self,
546 $($idx: $abc),+
547 ) -> ViewMut<
548 'a,
549 T,
550 <($($abc,)+) as ViewIndex>::Shape<($($xyz,)+)>,
551 <($($abc,)+) as ViewIndex>::Layout<L>,
552 > {
553 let (offset, mapping) = ($($idx,)+).view_index(self.mapping());
554
555 let count = if mapping.is_empty() { 0 } else { offset };
557
558 unsafe { ViewMut::new_unchecked(self.as_mut_ptr().offset(count), mapping) }
559 }
560 }
561 };
562}
563
564impl_into_view!(1, (X), (A), (a));
565impl_into_view!(2, (X, Y), (A, B), (a, b));
566impl_into_view!(3, (X, Y, Z), (A, B, C), (a, b, c));
567impl_into_view!(4, (X, Y, Z, W), (A, B, C, D), (a, b, c, d));
568impl_into_view!(5, (X, Y, Z, W, U), (A, B, C, D, E), (a, b, c, d, e));
569impl_into_view!(6, (X, Y, Z, W, U, V), (A, B, C, D, E, F), (a, b, c, d, e, f));
570
571impl<'a, T, U, S: Shape, L: Layout> Apply<U> for &'a mut ViewMut<'_, T, S, L> {
572 type Output<F: FnMut(&'a mut T) -> U> = Map<Self::IntoExpr, F>;
573 type ZippedWith<I: IntoExpression, F: FnMut((&'a mut T, I::Item)) -> U> =
574 Map<Zip<Self::IntoExpr, I::IntoExpr>, F>;
575
576 #[inline]
577 fn apply<F: FnMut(&'a mut T) -> U>(self, f: F) -> Self::Output<F> {
578 self.expr_mut().map(f)
579 }
580
581 #[inline]
582 fn zip_with<I: IntoExpression, F>(self, expr: I, f: F) -> Self::ZippedWith<I, F>
583 where
584 F: FnMut((&'a mut T, I::Item)) -> U,
585 {
586 self.expr_mut().zip(expr).map(f)
587 }
588}
589
590impl<T, U: ?Sized, S: Shape, L: Layout> AsMut<U> for ViewMut<'_, T, S, L>
591where
592 Slice<T, S, L>: AsMut<U>,
593{
594 #[inline]
595 fn as_mut(&mut self) -> &mut U {
596 (**self).as_mut()
597 }
598}
599
600impl<T, S: Shape, L: Layout> BorrowMut<Slice<T, S, L>> for ViewMut<'_, T, S, L> {
601 #[inline]
602 fn borrow_mut(&mut self) -> &mut Slice<T, S, L> {
603 self
604 }
605}
606
607impl<T, S: Shape, L: Layout> Clone for View<'_, T, S, L> {
608 #[inline]
609 fn clone(&self) -> Self {
610 Self { slice: self.slice.clone(), phantom: PhantomData }
611 }
612
613 #[inline]
614 fn clone_from(&mut self, source: &Self) {
615 self.slice.clone_from(&source.slice);
616 }
617}
618
619impl<T, S: Shape, L: Layout<Mapping<S>: Copy>> Copy for View<'_, T, S, L> {}
620
621impl<T, S: Shape, L: Layout> DerefMut for ViewMut<'_, T, S, L> {
622 #[inline]
623 fn deref_mut(&mut self) -> &mut Self::Target {
624 self.slice.as_mut_slice()
625 }
626}
627
628macro_rules! impl_from_array_ref {
629 (($($xyz:tt),+), ($($abc:tt),+), $array:tt) => {
630 impl<'a, T $(,$xyz: Dim + From<Const<$abc>>)+ $(,const $abc: usize)+> From<&'a $array>
631 for View<'a, T, ($($xyz,)+)>
632 {
633 #[inline]
634 fn from(value: &'a $array) -> Self {
635 let mapping = DenseMapping::new(($($xyz::from(Const::<$abc>),)+));
636
637 _ = mapping.shape().checked_len().expect("invalid length");
638
639 unsafe { Self::new_unchecked(value.as_ptr().cast(), mapping) }
640 }
641 }
642
643 impl<'a, T $(,$xyz: Dim + From<Const<$abc>>)+ $(,const $abc: usize)+> From<&'a mut $array>
644 for ViewMut<'a, T, ($($xyz,)+)>
645 {
646 #[inline]
647 fn from(value: &'a mut $array) -> Self {
648 let mapping = DenseMapping::new(($($xyz::from(Const::<$abc>),)+));
649
650 _ = mapping.shape().checked_len().expect("invalid length");
651
652 unsafe { Self::new_unchecked(value.as_mut_ptr().cast(), mapping) }
653 }
654 }
655
656 impl<'a, T $(,const $abc: usize)+> From<View<'a, T, ($(Const<$abc>,)+)>> for &'a $array {
657 #[inline]
658 fn from(value: View<'a, T, ($(Const<$abc>,)+)>) -> Self {
659 unsafe { &*value.as_ptr().cast() }
660 }
661 }
662
663 impl<'a, T $(,const $abc: usize)+> From<ViewMut<'a, T, ($(Const<$abc>,)+)>>
664 for &'a mut $array
665 {
666 #[inline]
667 fn from(mut value: ViewMut<'a, T, ($(Const<$abc>,)+)>) -> Self {
668 unsafe { &mut *value.as_mut_ptr().cast() }
669 }
670 }
671 };
672}
673
674impl_from_array_ref!((X), (A), [T; A]);
675impl_from_array_ref!((X, Y), (A, B), [[T; B]; A]);
676impl_from_array_ref!((X, Y, Z), (A, B, C), [[[T; C]; B]; A]);
677impl_from_array_ref!((X, Y, Z, W), (A, B, C, D), [[[[T; D]; C]; B]; A]);
678impl_from_array_ref!((X, Y, Z, W, U), (A, B, C, D, E), [[[[[T; E]; D]; C]; B]; A]);
679impl_from_array_ref!((X, Y, Z, W, U, V), (A, B, C, D, E, F), [[[[[[T; F]; E]; D]; C]; B]; A]);
680
681impl<T, S: Shape, L: Layout, I: SliceIndex<T, S, L>> IndexMut<I> for ViewMut<'_, T, S, L> {
682 #[inline]
683 fn index_mut(&mut self, index: I) -> &mut I::Output {
684 index.index_mut(self)
685 }
686}
687
688impl<'a, T, S: Shape, L: Layout> IntoExpression for &'a mut ViewMut<'_, T, S, L> {
689 type Shape = S;
690 type IntoExpr = ViewMut<'a, T, S, L>;
691
692 #[inline]
693 fn into_expr(self) -> Self::IntoExpr {
694 self.expr_mut()
695 }
696}
697
698impl<'a, T, S: Shape, L: Layout> IntoIterator for &'a mut ViewMut<'_, T, S, L> {
699 type Item = &'a mut T;
700 type IntoIter = Iter<ViewMut<'a, T, S, L>>;
701
702 #[inline]
703 fn into_iter(self) -> Self::IntoIter {
704 self.expr_mut().into_iter()
705 }
706}
707
708unsafe impl<T: Sync, S: Shape, L: Layout> Send for View<'_, T, S, L> {}
709unsafe impl<T: Sync, S: Shape, L: Layout> Sync for View<'_, T, S, L> {}
710
711unsafe impl<T: Send, S: Shape, L: Layout> Send for ViewMut<'_, T, S, L> {}
712unsafe impl<T: Sync, S: Shape, L: Layout> Sync for ViewMut<'_, T, S, L> {}