From 9b3720ac3c90ea107a7216ed8e3d5de9e4e66f8f Mon Sep 17 00:00:00 2001 From: Moritz Hoffmann Date: Thu, 29 Feb 2024 15:15:21 -0500 Subject: [PATCH] Slice regions support nested slices and references This changes the slice region to support copy-onto for && types, which is needed to support arbitrarily nested slices and things that look like slices. Probably want to establish a rule that copy-onto should be implemented for owned types, references and references to references. Signed-off-by: Moritz Hoffmann --- src/impls/slice.rs | 122 +++++++++++++++++++++++++++++---------------- src/lib.rs | 21 ++++++++ 2 files changed, 99 insertions(+), 44 deletions(-) diff --git a/src/impls/slice.rs b/src/impls/slice.rs index 1870791..7de69ee 100644 --- a/src/impls/slice.rs +++ b/src/impls/slice.rs @@ -121,7 +121,7 @@ pub struct ReadSlice<'a, C: Region, O: OffsetContainer = Vec<> ReadSlice<'a, C, O> { +impl> ReadSlice<'_, C, O> { /// Read the n-th item from the underlying region. /// /// # Panics @@ -162,23 +162,23 @@ impl<'a, C: Region, O: OffsetContainer> ReadSlice<'a, C, O> { } } -impl<'a, C: Region, O: OffsetContainer> Debug for ReadSlice<'a, C, O> +impl> Debug for ReadSlice<'_, C, O> where - C::ReadItem<'a>: Debug, + for<'a> C::ReadItem<'a>: Debug, { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_list().entries(self.iter()).finish() } } -impl<'a, C: Region, O: OffsetContainer> Clone for ReadSlice<'a, C, O> { +impl> Clone for ReadSlice<'_, C, O> { #[inline] fn clone(&self) -> Self { *self } } -impl<'a, C: Region, O: OffsetContainer> Copy for ReadSlice<'a, C, O> {} +impl> Copy for ReadSlice<'_, C, O> {} impl<'a, C: Region, O: OffsetContainer> IntoIterator for ReadSlice<'a, C, O> { type Item = C::ReadItem<'a>; @@ -207,10 +207,11 @@ impl<'a, C: Region, O: OffsetContainer> Iterator for ReadSliceIter<'a, } } -impl<'a, C, T: 'a, O: OffsetContainer> CopyOnto> for &'a [T] +impl CopyOnto> for &[T] where C: Region, - &'a T: CopyOnto, + for<'a> &'a T: CopyOnto, + O: OffsetContainer, { #[inline] fn copy_onto(self, target: &mut SliceRegion) -> as Region>::Index { @@ -222,9 +223,11 @@ where } } -impl<'a, T, R: Region, O: OffsetContainer> ReserveItems> for &'a [T] +impl ReserveItems> for &[T] where - &'a T: ReserveItems + 'a, + for<'a> &'a T: ReserveItems, + R: Region, + O: OffsetContainer, { fn reserve_items(target: &mut SliceRegion, items: I) where @@ -235,49 +238,65 @@ where } } -impl<'a, C, T, O: OffsetContainer> CopyOnto> for &'a Vec +impl CopyOnto> for Vec where C: Region, - &'a [T]: CopyOnto>, + T: CopyOnto, + O: OffsetContainer, { #[inline] fn copy_onto(self, target: &mut SliceRegion) -> as Region>::Index { - self.as_slice().copy_onto(target) + let start = target.slices.len(); + target + .slices + .extend(self.into_iter().map(|t| t.copy_onto(&mut target.inner))); + (start, target.slices.len()) } } -impl<'a, T: 'a, R: Region, O: OffsetContainer> ReserveItems> - for &'a Vec +impl CopyOnto> for &Vec where - &'a T: ReserveItems, + C: Region, + for<'a> &'a [T]: CopyOnto>, + O: OffsetContainer, { - fn reserve_items(target: &mut SliceRegion, items: I) - where - I: Iterator + Clone, - { - ReserveItems::reserve_items(target, items.map(Deref::deref)); + #[inline] + fn copy_onto(self, target: &mut SliceRegion) -> as Region>::Index { + self.as_slice().copy_onto(target) } } -impl> CopyOnto> for Vec +impl CopyOnto> for &&Vec where C: Region, - T: CopyOnto, + for<'a> &'a [T]: CopyOnto>, + O: OffsetContainer, { #[inline] fn copy_onto(self, target: &mut SliceRegion) -> as Region>::Index { - let start = target.slices.len(); - target - .slices - .extend(self.into_iter().map(|t| t.copy_onto(&mut target.inner))); - (start, target.slices.len()) + self.as_slice().copy_onto(target) } } -impl<'a, C: Region + 'a, O: OffsetContainer> CopyOnto> - for ReadSlice<'a, C, O> +impl ReserveItems> for &Vec where - C::ReadItem<'a>: CopyOnto, + for<'a> &'a T: ReserveItems, + R: Region, + O: OffsetContainer, +{ + fn reserve_items(target: &mut SliceRegion, items: I) + where + I: Iterator + Clone, + { + ReserveItems::reserve_items(target, items.map(Deref::deref)); + } +} + +impl CopyOnto> for ReadSlice<'_, C, O> +where + for<'a> C::ReadItem<'a>: CopyOnto, + C: Region, + O: OffsetContainer, { #[inline] fn copy_onto(self, target: &mut SliceRegion) -> as Region>::Index { @@ -292,10 +311,11 @@ where } } -impl<'a, T, R: Region, O: OffsetContainer, const N: usize> CopyOnto> - for &'a [T; N] +impl CopyOnto> for [T; N] where - for<'b> &'b [T]: CopyOnto>, + for<'a> &'a [T]: CopyOnto>, + R: Region, + O: OffsetContainer, { #[inline] fn copy_onto(self, target: &mut SliceRegion) -> as Region>::Index { @@ -303,23 +323,23 @@ where } } -impl<'a, T: 'a, R: Region, O: OffsetContainer, const N: usize> - ReserveItems> for &'a [T; N] +impl CopyOnto> for &[T; N] where - &'a T: ReserveItems, + for<'a> &'a [T]: CopyOnto>, + R: Region, + O: OffsetContainer, { - fn reserve_items(target: &mut SliceRegion, items: I) - where - I: Iterator + Clone, - { - ReserveItems::reserve_items(target, items.map(<[T; N]>::as_slice)); + #[inline] + fn copy_onto(self, target: &mut SliceRegion) -> as Region>::Index { + self.as_slice().copy_onto(target) } } -impl, const N: usize> CopyOnto> - for [T; N] +impl CopyOnto> for &&[T; N] where - for<'a> &'a [T]: CopyOnto>, + for<'b> &'b [T]: CopyOnto>, + R: Region, + O: OffsetContainer, { #[inline] fn copy_onto(self, target: &mut SliceRegion) -> as Region>::Index { @@ -327,6 +347,20 @@ where } } +impl ReserveItems> for &[T; N] +where + for<'a> &'a T: ReserveItems, + R: Region, + O: OffsetContainer, +{ + fn reserve_items(target: &mut SliceRegion, items: I) + where + I: Iterator + Clone, + { + ReserveItems::reserve_items(target, items.map(<[T; N]>::as_slice)); + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/lib.rs b/src/lib.rs index cb7ed60..5c8f539 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -648,4 +648,25 @@ mod tests { let _read_item3 = read_item; assert_eq!(vec![1, 2, 3], read_item.into_iter().collect::>()); } + + #[test] + fn nested_slice_copy() { + let mut c = FlatStack::default_impl::<[[[[[u8; 1]; 1]; 1]; 1]; 1]>(); + + c.copy([[[[[1]]]]]); + c.copy(&[[[[[1]]]]]); + c.copy(&[[[[[&1]]]]]); + c.copy([[[[[&1]]]]]); + c.copy([[&[[[&1]]]]]); + c.copy([[[[[1]]; 1]; 1]; 1]); + c.copy(&[[[[[1; 1]; 1]; 1]; 1]; 1]); + c.copy(&[[[[[&1; 1]; 1]; 1]; 1]; 1]); + c.copy([[[[[&1; 1]; 1]; 1]; 1]; 1]); + c.copy([[&[[[&1; 1]; 1]; 1]; 1]; 1]); + c.copy([[vec![[[1; 1]; 1]; 1]; 1]; 1]); + c.copy(&[[vec![[[1; 1]; 1]; 1]; 1]; 1]); + c.copy(&[[vec![[[&1; 1]; 1]; 1]; 1]; 1]); + c.copy([[[vec![[&1; 1]; 1]; 1]; 1]; 1]); + c.copy([[&vec![[[&1; 1]; 1]; 1]; 1]; 1]); + } }