Skip to content

Commit

Permalink
All IntoOwned implemented
Browse files Browse the repository at this point in the history
Signed-off-by: Moritz Hoffmann <[email protected]>
  • Loading branch information
antiguru committed May 27, 2024
1 parent 606a240 commit 055b903
Show file tree
Hide file tree
Showing 6 changed files with 248 additions and 37 deletions.
87 changes: 79 additions & 8 deletions src/impls/columns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,10 @@ where
}

fn index(&self, index: Self::Index) -> Self::ReadItem<'_> {
ReadColumns {
ReadColumns(Ok(ReadColumnsInner {
columns: &self.inner,
index: self.indices.index(index),
}
}))
}

fn reserve_regions<'a, I>(&mut self, regions: I)
Expand Down Expand Up @@ -156,7 +156,11 @@ where
}

/// Read the values of a row.
pub struct ReadColumns<'a, R>
pub struct ReadColumns<'a, R>(Result<ReadColumnsInner<'a, R>, &'a [R::Owned]>)
where
R: Region;

struct ReadColumnsInner<'a, R>
where
R: Region,
{
Expand All @@ -175,7 +179,17 @@ where
}
}

impl<'a, R> Clone for ReadColumnsInner<'a, R>
where
R: Region,
{
fn clone(&self) -> Self {
*self
}
}

impl<'a, R> Copy for ReadColumns<'a, R> where R: Region {}
impl<'a, R> Copy for ReadColumnsInner<'a, R> where R: Region {}

impl<'a, R> Debug for ReadColumns<'a, R>
where
Expand All @@ -197,6 +211,37 @@ where
self.into_iter()
}

/// Get the element at `offset`.
#[must_use]
pub fn get(&self, offset: usize) -> R::ReadItem<'a> {
match &self.0 {
Ok(inner) => inner.get(offset),
Err(slice) => IntoOwned::borrow_as(&slice[offset]),
}
}

/// Returns the length of this row.
#[must_use]
pub fn len(&self) -> usize {
match &self.0 {
Ok(inner) => inner.len(),
Err(slice) => slice.len(),
}
}

/// Returns `true` if this row is empty.
#[must_use]
pub fn is_empty(&self) -> bool {
match &self.0 {
Ok(inner) => inner.is_empty(),
Err(slice) => slice.is_empty(),
}
}
}
impl<'a, R> ReadColumnsInner<'a, R>
where
R: Region,
{
/// Get the element at `offset`.
#[must_use]
pub fn get(&self, offset: usize) -> R::ReadItem<'a> {
Expand Down Expand Up @@ -227,11 +272,15 @@ where
}

fn clone_onto(self, other: &mut Self::Owned) {
todo!()
let r = std::cmp::min(self.len(), other.len());
for (item, target) in self.iter().zip(other.iter_mut()) {
item.clone_onto(target);
}
other.extend(self.iter().skip(r).map(IntoOwned::into_owned));
}

fn borrow_as(owned: &'a Self::Owned) -> Self {
todo!()
Self(Err(owned.as_slice()))
}
}

Expand All @@ -243,14 +292,22 @@ where
type IntoIter = ReadColumnsIter<'a, R>;

fn into_iter(self) -> Self::IntoIter {
ReadColumnsIter {
iter: self.index.iter().zip(self.columns.iter()),
match self.0 {
Ok(inner) => ReadColumnsIter(Ok(ReadColumnsIterInner {
iter: inner.index.iter().zip(inner.columns.iter()),
})),
Err(slice) => ReadColumnsIter(Err(slice.iter())),
}
}
}

/// An iterator over the elements of a row.
pub struct ReadColumnsIter<'a, R: Region> {
pub struct ReadColumnsIter<'a, R: Region>(
Result<ReadColumnsIterInner<'a, R>, std::slice::Iter<'a, R::Owned>>,
);

/// An iterator over the elements of a row.
pub struct ReadColumnsIterInner<'a, R: Region> {
iter: std::iter::Zip<std::slice::Iter<'a, R::Index>, std::slice::Iter<'a, R>>,
}

Expand All @@ -260,6 +317,20 @@ where
{
type Item = R::ReadItem<'a>;

fn next(&mut self) -> Option<Self::Item> {
match &mut self.0 {
Ok(inner) => inner.next(),
Err(slice) => slice.next().map(IntoOwned::borrow_as),
}
}
}

impl<'a, R> Iterator for ReadColumnsIterInner<'a, R>
where
R: Region,
{
type Item = R::ReadItem<'a>;

fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(&i, r)| r.index(i))
}
Expand Down
4 changes: 3 additions & 1 deletion src/impls/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ impl<R: OpinionatedRegion> OpinionatedRegion for OptionRegion<R> {
}

impl<'a, T> IntoOwned<'a> for Option<T>
where T: IntoOwned<'a> {
where
T: IntoOwned<'a>,
{
type Owned = Option<T::Owned>;

fn into_owned(self) -> Self::Owned {
Expand Down
134 changes: 118 additions & 16 deletions src/impls/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,11 @@ impl<C: Region, O: OffsetContainer<C::Index>> Region for SliceRegion<C, O> {

#[inline]
fn index(&self, (start, end): Self::Index) -> Self::ReadItem<'_> {
ReadSlice {
ReadSlice(Ok(ReadSliceInner {
region: self,
start,
end,
}
}))
}

#[inline]
Expand Down Expand Up @@ -144,13 +144,57 @@ impl<C: Region, O: OffsetContainer<C::Index>> Default for SliceRegion<C, O> {
}

/// A helper to read data out of a slice region.
pub struct ReadSlice<'a, C: Region, O: OffsetContainer<C::Index> = Vec<<C as Region>::Index>> {
pub struct ReadSlice<'a, C: Region, O: OffsetContainer<C::Index> = Vec<<C as Region>::Index>>(
Result<ReadSliceInner<'a, C, O>, &'a [C::Owned]>,
);

struct ReadSliceInner<'a, C: Region, O: OffsetContainer<C::Index> = Vec<<C as Region>::Index>> {
region: &'a SliceRegion<C, O>,
start: usize,
end: usize,
}

impl<C: Region, O: OffsetContainer<C::Index>> ReadSlice<'_, C, O> {
/// Read the n-th item from the underlying region.
///
/// # Panics
///
/// Panics if the index is out of bounds, i.e., it is larger than the
/// length of this slice representation.
#[inline]
#[must_use]
pub fn get(&self, index: usize) -> C::ReadItem<'_> {
match &self.0 {
Ok(inner) => inner.get(index),
Err(slice) => IntoOwned::borrow_as(&slice[index]),
}
}

/// The number of elements in this slice.
#[must_use]
pub fn len(&self) -> usize {
match self.0 {
Ok(inner) => inner.len(),
Err(slice) => slice.len(),
}
}

/// Returns `true` if the slice is empty.
#[must_use]
pub fn is_empty(&self) -> bool {
match self.0 {
Ok(inner) => inner.is_empty(),
Err(slice) => slice.is_empty(),
}
}

/// Returns an iterator over all contained items.
#[must_use]
pub fn iter(&self) -> <Self as IntoIterator>::IntoIter {
self.into_iter()
}
}
impl<C: Region, O: OffsetContainer<C::Index>> ReadSliceInner<'_, C, O> {
/// Read the n-th item from the underlying region.
///
/// # Panics
Expand Down Expand Up @@ -183,12 +227,6 @@ impl<C: Region, O: OffsetContainer<C::Index>> ReadSlice<'_, C, O> {
pub fn is_empty(&self) -> bool {
self.start == self.end
}

/// Returns an iterator over all contained items.
#[must_use]
pub fn iter(&self) -> <Self as IntoIterator>::IntoIter {
self.into_iter()
}
}

impl<C: Region, O: OffsetContainer<C::Index>> Debug for ReadSlice<'_, C, O>
Expand All @@ -207,23 +245,37 @@ impl<C: Region, O: OffsetContainer<C::Index>> Clone for ReadSlice<'_, C, O> {
}
}

impl<C: Region, O: OffsetContainer<C::Index>> Clone for ReadSliceInner<'_, C, O> {
#[inline]
fn clone(&self) -> Self {
*self
}
}

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

impl<'a, C, O> IntoOwned<'a> for ReadSlice<'a, C, O>
where C: Region, O: OffsetContainer<C::Index>,
where
C: Region,
O: OffsetContainer<C::Index>,
{
type Owned = Vec<C::Owned>;

fn into_owned(self) -> Self::Owned {
todo!()
self.iter().map(IntoOwned::into_owned).collect()
}

fn clone_onto(self, other: &mut Self::Owned) {
todo!()
let r = std::cmp::min(self.len(), other.len());
for (item, target) in self.iter().zip(other.iter_mut()) {
item.clone_onto(target);
}
other.extend(self.iter().skip(r).map(IntoOwned::into_owned));
}

fn borrow_as(owned: &'a Self::Owned) -> Self {
todo!()
Self(Err(owned.as_slice()))
}
}

Expand All @@ -232,18 +284,35 @@ impl<'a, C: Region, O: OffsetContainer<C::Index>> IntoIterator for ReadSlice<'a,
type IntoIter = ReadSliceIter<'a, C, O>;

fn into_iter(self) -> Self::IntoIter {
ReadSliceIter(self.region, self.start..self.end)
match self.0 {
Ok(inner) => {
ReadSliceIter(Ok(ReadSliceIterInner(inner.region, inner.start..inner.end)))
}
Err(slice) => ReadSliceIter(Err(slice.iter())),
}
}
}

/// An iterator over the items read from a slice region.
#[derive(Debug)]
pub struct ReadSliceIter<'a, C: Region, O: OffsetContainer<C::Index>>(
Result<ReadSliceIterInner<'a, C, O>, std::slice::Iter<'a, C::Owned>>,
);

impl<'a, C: Region, O: OffsetContainer<C::Index>> Clone for ReadSliceIter<'a, C, O> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}

/// An iterator over the items read from a slice region.
#[derive(Debug)]
pub struct ReadSliceIterInner<'a, C: Region, O: OffsetContainer<C::Index>>(
&'a SliceRegion<C, O>,
Range<usize>,
);

impl<'a, C: Region, O: OffsetContainer<C::Index>> Clone for ReadSliceIter<'a, C, O> {
impl<'a, C: Region, O: OffsetContainer<C::Index>> Clone for ReadSliceIterInner<'a, C, O> {
fn clone(&self) -> Self {
Self(self.0, self.1.clone())
}
Expand All @@ -252,6 +321,18 @@ impl<'a, C: Region, O: OffsetContainer<C::Index>> Clone for ReadSliceIter<'a, C,
impl<'a, C: Region, O: OffsetContainer<C::Index>> Iterator for ReadSliceIter<'a, C, O> {
type Item = C::ReadItem<'a>;

#[inline]
fn next(&mut self) -> Option<Self::Item> {
match &mut self.0 {
Ok(inner) => inner.next(),
Err(iter) => iter.next().map(IntoOwned::borrow_as),
}
}
}

impl<'a, C: Region, O: OffsetContainer<C::Index>> Iterator for ReadSliceIterInner<'a, C, O> {
type Item = C::ReadItem<'a>;

#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.1
Expand Down Expand Up @@ -343,7 +424,28 @@ where
{
#[inline]
fn push(&mut self, item: ReadSlice<'a, C, O>) -> <SliceRegion<C, O> as Region>::Index {
let ReadSlice { region, start, end } = item;
match item.0 {
Ok(inner) => self.push(inner),
Err(slice) => {
let start_len = self.slices.len();
for item in slice.iter().map(IntoOwned::borrow_as) {
let index = self.inner.push(item);
self.slices.push(index);
}
(start_len, self.slices.len())
}
}
}
}

impl<'a, C, O> Push<ReadSliceInner<'a, C, O>> for SliceRegion<C, O>
where
C: Region + Push<<C as Region>::ReadItem<'a>>,
O: OffsetContainer<C::Index>,
{
#[inline]
fn push(&mut self, item: ReadSliceInner<'a, C, O>) -> <SliceRegion<C, O> as Region>::Index {
let ReadSliceInner { region, start, end } = item;
let start_len = self.slices.len();
for index in start..end {
let index = region.slices.index(index);
Expand Down
Loading

0 comments on commit 055b903

Please sign in to comment.