Skip to content

Commit bae6ffc

Browse files
committed
Rewrite multislice in terms of RawArrayViewMut
1 parent 0922b2b commit bae6ffc

File tree

2 files changed

+91
-44
lines changed

2 files changed

+91
-44
lines changed

src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,10 @@ pub use dimension::NdIndex;
122122
pub use dimension::IxDynImpl;
123123
pub use indexes::{indices, indices_of};
124124
pub use error::{ShapeError, ErrorKind};
125-
pub use slice::{Slice, SliceInfo, SliceNextDim, SliceOrIndex};
125+
pub use slice::{
126+
deref_raw_view_mut_into_view_with_life, deref_raw_view_mut_into_view_mut_with_life,
127+
life_of_view_mut, Slice, SliceInfo, SliceNextDim, SliceOrIndex
128+
};
126129

127130
use iterators::Baseiter;
128131
use iterators::{ElementsBase, ElementsBaseMut, Iter, IterMut, Lanes, LanesMut};

src/slice.rs

Lines changed: 87 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use error::{ShapeError, ErrorKind};
99
use std::ops::{Deref, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive};
1010
use std::fmt;
1111
use std::marker::PhantomData;
12-
use super::Dimension;
12+
use crate::{ArrayView, ArrayViewMut, Dimension, RawArrayViewMut};
1313

1414
/// A slice (range with step size).
1515
///
@@ -624,6 +624,32 @@ macro_rules! s(
624624
};
625625
);
626626

627+
/// Returns a ZST representing the lifetime of the mutable view.
628+
#[doc(hidden)]
629+
pub fn life_of_view_mut<'a, A, D: Dimension>(
630+
_view: &ArrayViewMut<'a, A, D>
631+
) -> PhantomData<&'a mut A> {
632+
PhantomData
633+
}
634+
635+
/// Derefs the raw mutable view into a view, using the given lifetime.
636+
#[doc(hidden)]
637+
pub unsafe fn deref_raw_view_mut_into_view_with_life<'a, A, D: Dimension>(
638+
raw: RawArrayViewMut<A, D>,
639+
_life: PhantomData<&'a mut A>,
640+
) -> ArrayView<'a, A, D> {
641+
raw.deref_into_view()
642+
}
643+
644+
/// Derefs the raw mutable view into a mutable view, using the given lifetime.
645+
#[doc(hidden)]
646+
pub unsafe fn deref_raw_view_mut_into_view_mut_with_life<'a, A, D: Dimension>(
647+
raw: RawArrayViewMut<A, D>,
648+
_life: PhantomData<&'a mut A>,
649+
) -> ArrayViewMut<'a, A, D> {
650+
raw.deref_into_view_mut()
651+
}
652+
627653
/// Take multiple slices simultaneously.
628654
///
629655
/// This macro makes it possible to take multiple slices of the same array, as
@@ -706,110 +732,124 @@ macro_rules! s(
706732
/// ```
707733
#[macro_export]
708734
macro_rules! multislice(
709-
(
710-
@check $view:expr,
711-
$info:expr,
712-
()
713-
) => {};
735+
(@check $view:expr, $info:expr, ()) => {};
714736
// Check that $info doesn't intersect $other.
715-
(
716-
@check $view:expr,
717-
$info:expr,
718-
($other:expr,)
719-
) => {
737+
(@check $view:expr, $info:expr, ($other:expr,)) => {
720738
assert!(
721739
!$crate::slices_intersect(&$view.raw_dim(), $info, $other),
722740
"Slice {:?} must not intersect slice {:?}", $info, $other
723741
)
724742
};
725743
// Check that $info doesn't intersect any of the other info in the tuple.
726-
(
727-
@check $view:expr,
728-
$info:expr,
729-
($other:expr, $($more:tt)*)
730-
) => {
744+
(@check $view:expr, $info:expr, ($other:expr, $($more:tt)*)) => {
731745
{
732746
multislice!(@check $view, $info, ($other,));
733747
multislice!(@check $view, $info, ($($more)*));
734748
}
735749
};
750+
// Create the (mutable) slice.
751+
(@slice $view:expr, $life:expr, mut $info:expr) => {
752+
#[allow(unsafe_code)]
753+
unsafe {
754+
$crate::deref_raw_view_mut_into_view_mut_with_life(
755+
$view.clone().slice_move($info),
756+
$life,
757+
)
758+
}
759+
};
760+
// Create the (read-only) slice.
761+
(@slice $view:expr, $life:expr, $info:expr) => {
762+
#[allow(unsafe_code)]
763+
unsafe {
764+
$crate::deref_raw_view_mut_into_view_with_life(
765+
$view.clone().slice_move($info),
766+
$life,
767+
)
768+
}
769+
};
736770
// Parse last slice (mutable), no trailing comma.
737771
(
738-
@parse $view:expr,
772+
@parse $view:expr, $life:expr,
739773
($($sliced:tt)*),
740774
($($mut_info:tt)*),
741775
($($immut_info:tt)*),
742776
(mut $info:expr)
743777
) => {
744-
match $info {
745-
info => {
746-
multislice!(@check $view, info, ($($mut_info)*));
747-
multislice!(@check $view, info, ($($immut_info)*));
748-
($($sliced)* unsafe { $view.aliasing_view_mut() }.slice_move(info))
749-
}
750-
}
778+
// Add trailing comma.
779+
multislice!(
780+
@parse $view, $life,
781+
($($sliced)*),
782+
($($mut_info)*),
783+
($($immut_info)*),
784+
(mut $info,)
785+
)
751786
};
752787
// Parse last slice (read-only), no trailing comma.
753788
(
754-
@parse $view:expr,
789+
@parse $view:expr, $life:expr,
755790
($($sliced:tt)*),
756791
($($mut_info:tt)*),
757792
($($immut_info:tt)*),
758793
($info:expr)
759794
) => {
760-
match $info {
761-
info => {
762-
multislice!(@check $view, info, ($($mut_info)*));
763-
($($sliced)* unsafe { $view.aliasing_view() }.slice_move(info))
764-
}
765-
}
795+
// Add trailing comma.
796+
multislice!(
797+
@parse $view, $life,
798+
($($sliced)*),
799+
($($mut_info)*),
800+
($($immut_info)*),
801+
($info,)
802+
)
766803
};
767804
// Parse last slice (mutable), with trailing comma.
768805
(
769-
@parse $view:expr,
806+
@parse $view:expr, $life:expr,
770807
($($sliced:tt)*),
771808
($($mut_info:tt)*),
772809
($($immut_info:tt)*),
773810
(mut $info:expr,)
774811
) => {
775812
match $info {
776813
info => {
814+
// Check for overlap with all previous mutable and immutable slices.
777815
multislice!(@check $view, info, ($($mut_info)*));
778816
multislice!(@check $view, info, ($($immut_info)*));
779-
($($sliced)* unsafe { $view.aliasing_view_mut() }.slice_move(info))
817+
($($sliced)* multislice!(@slice $view, $life, mut info),)
780818
}
781819
}
782820
};
783821
// Parse last slice (read-only), with trailing comma.
784822
(
785-
@parse $view:expr,
823+
@parse $view:expr, $life:expr,
786824
($($sliced:tt)*),
787825
($($mut_info:tt)*),
788826
($($immut_info:tt)*),
789827
($info:expr,)
790828
) => {
791829
match $info {
792830
info => {
831+
// Check for overlap with all previous mutable slices.
793832
multislice!(@check $view, info, ($($mut_info)*));
794-
($($sliced)* unsafe { $view.aliasing_view() }.slice_move(info))
833+
($($sliced)* multislice!(@slice $view, $life, info),)
795834
}
796835
}
797836
};
798837
// Parse a mutable slice.
799838
(
800-
@parse $view:expr,
839+
@parse $view:expr, $life:expr,
801840
($($sliced:tt)*),
802841
($($mut_info:tt)*),
803842
($($immut_info:tt)*),
804843
(mut $info:expr, $($t:tt)*)
805844
) => {
806845
match $info {
807846
info => {
847+
// Check for overlap with all previous mutable and immutable slices.
808848
multislice!(@check $view, info, ($($mut_info)*));
809849
multislice!(@check $view, info, ($($immut_info)*));
810850
multislice!(
811-
@parse $view,
812-
($($sliced)* unsafe { $view.aliasing_view_mut() }.slice_move(info),),
851+
@parse $view, $life,
852+
($($sliced)* multislice!(@slice $view, $life, mut info),),
813853
($($mut_info)* info,),
814854
($($immut_info)*),
815855
($($t)*)
@@ -819,18 +859,19 @@ macro_rules! multislice(
819859
};
820860
// Parse a read-only slice.
821861
(
822-
@parse $view:expr,
862+
@parse $view:expr, $life:expr,
823863
($($sliced:tt)*),
824864
($($mut_info:tt)*),
825865
($($immut_info:tt)*),
826866
($info:expr, $($t:tt)*)
827867
) => {
828868
match $info {
829869
info => {
870+
// Check for overlap with all previous mutable slices.
830871
multislice!(@check $view, info, ($($mut_info)*));
831872
multislice!(
832-
@parse $view,
833-
($($sliced)* unsafe { $view.aliasing_view() }.slice_move(info),),
873+
@parse $view, $life,
874+
($($sliced)* multislice!(@slice $view, $life, info),),
834875
($($mut_info)*),
835876
($($immut_info)* info,),
836877
($($t)*)
@@ -841,8 +882,11 @@ macro_rules! multislice(
841882
// Entry point.
842883
($arr:expr, ($($t:tt)*)) => {
843884
{
844-
let view = $crate::ArrayBase::view_mut(&mut $arr);
845-
multislice!(@parse view, (), (), (), ($($t)*))
885+
let (life, raw_view) = {
886+
let mut view = $crate::ArrayBase::view_mut(&mut $arr);
887+
($crate::life_of_view_mut(&view), view.raw_view_mut())
888+
};
889+
multislice!(@parse raw_view, life, (), (), (), ($($t)*))
846890
}
847891
};
848892
);

0 commit comments

Comments
 (0)