Skip to content

Commit

Permalink
Slice regions support nested slices and references
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
antiguru committed Feb 29, 2024
1 parent cae41d8 commit 9b3720a
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 44 deletions.
122 changes: 78 additions & 44 deletions src/impls/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ pub struct ReadSlice<'a, C: Region, O: OffsetContainer<C::Index> = Vec<<C as Reg
end: usize,
}

impl<'a, C: Region, O: OffsetContainer<C::Index>> ReadSlice<'a, C, O> {
impl<C: Region, O: OffsetContainer<C::Index>> ReadSlice<'_, C, O> {
/// Read the n-th item from the underlying region.
///
/// # Panics
Expand Down Expand Up @@ -162,23 +162,23 @@ impl<'a, C: Region, O: OffsetContainer<C::Index>> ReadSlice<'a, C, O> {
}
}

impl<'a, C: Region, O: OffsetContainer<C::Index>> Debug for ReadSlice<'a, C, O>
impl<C: Region, O: OffsetContainer<C::Index>> 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<C::Index>> Clone for ReadSlice<'a, C, O> {
impl<C: Region, O: OffsetContainer<C::Index>> Clone for ReadSlice<'_, C, O> {
#[inline]
fn clone(&self) -> Self {
*self
}
}

impl<'a, C: Region, O: OffsetContainer<C::Index>> Copy for ReadSlice<'a, C, O> {}
impl<C: Region, O: OffsetContainer<C::Index>> Copy for ReadSlice<'_, C, O> {}

impl<'a, C: Region, O: OffsetContainer<C::Index>> IntoIterator for ReadSlice<'a, C, O> {
type Item = C::ReadItem<'a>;
Expand Down Expand Up @@ -207,10 +207,11 @@ impl<'a, C: Region, O: OffsetContainer<C::Index>> Iterator for ReadSliceIter<'a,
}
}

impl<'a, C, T: 'a, O: OffsetContainer<C::Index>> CopyOnto<SliceRegion<C, O>> for &'a [T]
impl<C, T, O> CopyOnto<SliceRegion<C, O>> for &[T]
where
C: Region,
&'a T: CopyOnto<C>,
for<'a> &'a T: CopyOnto<C>,
O: OffsetContainer<C::Index>,
{
#[inline]
fn copy_onto(self, target: &mut SliceRegion<C, O>) -> <SliceRegion<C, O> as Region>::Index {
Expand All @@ -222,9 +223,11 @@ where
}
}

impl<'a, T, R: Region, O: OffsetContainer<R::Index>> ReserveItems<SliceRegion<R, O>> for &'a [T]
impl<T, R, O> ReserveItems<SliceRegion<R, O>> for &[T]
where
&'a T: ReserveItems<R> + 'a,
for<'a> &'a T: ReserveItems<R>,
R: Region,
O: OffsetContainer<R::Index>,
{
fn reserve_items<I>(target: &mut SliceRegion<R, O>, items: I)
where
Expand All @@ -235,49 +238,65 @@ where
}
}

impl<'a, C, T, O: OffsetContainer<C::Index>> CopyOnto<SliceRegion<C, O>> for &'a Vec<T>
impl<C, T, O> CopyOnto<SliceRegion<C, O>> for Vec<T>
where
C: Region,
&'a [T]: CopyOnto<SliceRegion<C, O>>,
T: CopyOnto<C>,
O: OffsetContainer<C::Index>,
{
#[inline]
fn copy_onto(self, target: &mut SliceRegion<C, O>) -> <SliceRegion<C, O> 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<R::Index>> ReserveItems<SliceRegion<R, O>>
for &'a Vec<T>
impl<C, T, O> CopyOnto<SliceRegion<C, O>> for &Vec<T>
where
&'a T: ReserveItems<R>,
C: Region,
for<'a> &'a [T]: CopyOnto<SliceRegion<C, O>>,
O: OffsetContainer<C::Index>,
{
fn reserve_items<I>(target: &mut SliceRegion<R, O>, items: I)
where
I: Iterator<Item = Self> + Clone,
{
ReserveItems::reserve_items(target, items.map(Deref::deref));
#[inline]
fn copy_onto(self, target: &mut SliceRegion<C, O>) -> <SliceRegion<C, O> as Region>::Index {
self.as_slice().copy_onto(target)
}
}

impl<C, T, O: OffsetContainer<C::Index>> CopyOnto<SliceRegion<C, O>> for Vec<T>
impl<C, T, O> CopyOnto<SliceRegion<C, O>> for &&Vec<T>
where
C: Region,
T: CopyOnto<C>,
for<'a> &'a [T]: CopyOnto<SliceRegion<C, O>>,
O: OffsetContainer<C::Index>,
{
#[inline]
fn copy_onto(self, target: &mut SliceRegion<C, O>) -> <SliceRegion<C, O> 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<C::Index>> CopyOnto<SliceRegion<C, O>>
for ReadSlice<'a, C, O>
impl<T, R, O> ReserveItems<SliceRegion<R, O>> for &Vec<T>
where
C::ReadItem<'a>: CopyOnto<C>,
for<'a> &'a T: ReserveItems<R>,
R: Region,
O: OffsetContainer<R::Index>,
{
fn reserve_items<I>(target: &mut SliceRegion<R, O>, items: I)
where
I: Iterator<Item = Self> + Clone,
{
ReserveItems::reserve_items(target, items.map(Deref::deref));
}
}

impl<C, O> CopyOnto<SliceRegion<C, O>> for ReadSlice<'_, C, O>
where
for<'a> C::ReadItem<'a>: CopyOnto<C>,
C: Region,
O: OffsetContainer<C::Index>,
{
#[inline]
fn copy_onto(self, target: &mut SliceRegion<C, O>) -> <SliceRegion<C, O> as Region>::Index {
Expand All @@ -292,41 +311,56 @@ where
}
}

impl<'a, T, R: Region, O: OffsetContainer<R::Index>, const N: usize> CopyOnto<SliceRegion<R, O>>
for &'a [T; N]
impl<T, R, O, const N: usize> CopyOnto<SliceRegion<R, O>> for [T; N]
where
for<'b> &'b [T]: CopyOnto<SliceRegion<R, O>>,
for<'a> &'a [T]: CopyOnto<SliceRegion<R, O>>,
R: Region,
O: OffsetContainer<R::Index>,
{
#[inline]
fn copy_onto(self, target: &mut SliceRegion<R, O>) -> <SliceRegion<R, O> as Region>::Index {
self.as_slice().copy_onto(target)
}
}

impl<'a, T: 'a, R: Region, O: OffsetContainer<R::Index>, const N: usize>
ReserveItems<SliceRegion<R, O>> for &'a [T; N]
impl<T, R, O, const N: usize> CopyOnto<SliceRegion<R, O>> for &[T; N]
where
&'a T: ReserveItems<R>,
for<'a> &'a [T]: CopyOnto<SliceRegion<R, O>>,
R: Region,
O: OffsetContainer<R::Index>,
{
fn reserve_items<I>(target: &mut SliceRegion<R, O>, items: I)
where
I: Iterator<Item = Self> + Clone,
{
ReserveItems::reserve_items(target, items.map(<[T; N]>::as_slice));
#[inline]
fn copy_onto(self, target: &mut SliceRegion<R, O>) -> <SliceRegion<R, O> as Region>::Index {
self.as_slice().copy_onto(target)
}
}

impl<T, R: Region, O: OffsetContainer<R::Index>, const N: usize> CopyOnto<SliceRegion<R, O>>
for [T; N]
impl<T, R, O, const N: usize> CopyOnto<SliceRegion<R, O>> for &&[T; N]
where
for<'a> &'a [T]: CopyOnto<SliceRegion<R, O>>,
for<'b> &'b [T]: CopyOnto<SliceRegion<R, O>>,
R: Region,
O: OffsetContainer<R::Index>,
{
#[inline]
fn copy_onto(self, target: &mut SliceRegion<R, O>) -> <SliceRegion<R, O> as Region>::Index {
self.as_slice().copy_onto(target)
}
}

impl<T, R, O, const N: usize> ReserveItems<SliceRegion<R, O>> for &[T; N]
where
for<'a> &'a T: ReserveItems<R>,
R: Region,
O: OffsetContainer<R::Index>,
{
fn reserve_items<I>(target: &mut SliceRegion<R, O>, items: I)
where
I: Iterator<Item = Self> + Clone,
{
ReserveItems::reserve_items(target, items.map(<[T; N]>::as_slice));
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
21 changes: 21 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -648,4 +648,25 @@ mod tests {
let _read_item3 = read_item;
assert_eq!(vec![1, 2, 3], read_item.into_iter().collect::<Vec<_>>());
}

#[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]);
}
}

0 comments on commit 9b3720a

Please sign in to comment.