Skip to content

Commit

Permalink
Introduce storage trait to abstract storage of slices
Browse files Browse the repository at this point in the history
Signed-off-by: Moritz Hoffmann <[email protected]>
  • Loading branch information
antiguru committed May 22, 2024
1 parent 2487d33 commit 7f2b7d5
Show file tree
Hide file tree
Showing 3 changed files with 267 additions and 54 deletions.
1 change: 1 addition & 0 deletions src/impls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ pub mod option;
pub mod result;
pub mod slice;
pub mod slice_copy;
pub mod storage;
pub mod string;
pub mod tuple;
115 changes: 61 additions & 54 deletions src/impls/slice_copy.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
//! A region that stores slices of copy types.
use std::marker::PhantomData;

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::impls::storage::Storage;
use crate::{CopyIter, CopyOnto, Region, ReserveItems};

/// A container for owned types.
Expand All @@ -29,11 +32,13 @@ use crate::{CopyIter, CopyOnto, Region, ReserveItems};
/// ```
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct OwnedRegion<T> {
slices: Vec<T>,
pub struct OwnedRegion<T, S: Storage<T> = Vec<T>> {
slices: S,
offset: usize,
_marker: PhantomData<T>,
}

impl<T> Region for OwnedRegion<T> {
impl<T, S: Storage<T>> Region for OwnedRegion<T, S> {
type ReadItem<'a> = &'a [T] where Self: 'a;
type Index = (usize, usize);

Expand All @@ -42,143 +47,145 @@ impl<T> Region for OwnedRegion<T> {
Self: 'a,
{
Self {
slices: Vec::with_capacity(regions.map(|r| r.slices.len()).sum()),
slices: S::merge_regions(regions.map(|r| &r.slices)),
offset: 0,
_marker: PhantomData,
}
}

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

fn reserve_regions<'a, I>(&mut self, regions: I)
where
Self: 'a,
I: Iterator<Item = &'a Self> + Clone,
{
self.slices.reserve(regions.map(|r| r.slices.len()).sum());
self.slices.reserve_regions(regions.map(|r| &r.slices));
}

#[inline]
fn clear(&mut self) {
self.slices.clear();
}

fn heap_size<F: FnMut(usize, usize)>(&self, mut callback: F) {
let size_of_t = std::mem::size_of::<T>();
callback(
self.slices.len() * size_of_t,
self.slices.capacity() * size_of_t,
);
fn heap_size<F: FnMut(usize, usize)>(&self, callback: F) {
self.slices.heap_size(callback);
}
}

impl<T> Default for OwnedRegion<T> {
impl<T, S: Storage<T>> Default for OwnedRegion<T, S> {
fn default() -> Self {
Self {
slices: Vec::default(),
slices: S::default(),
offset: 0,
_marker: PhantomData,
}
}
}

impl<T, const N: usize> CopyOnto<OwnedRegion<T>> for [T; N] {
impl<T, S: Storage<T>, const N: usize> CopyOnto<OwnedRegion<T, S>> for [T; N] {
#[inline]
fn copy_onto(self, target: &mut OwnedRegion<T>) -> <OwnedRegion<T> as Region>::Index {
let start = target.slices.len();
target.slices.extend(self);
(start, target.slices.len())
fn copy_onto(self, target: &mut OwnedRegion<T, S>) -> <OwnedRegion<T> as Region>::Index {
let start = target.offset;
target.offset = target.slices.extend(self);
(start, target.offset)
}
}

impl<T: Clone, const N: usize> CopyOnto<OwnedRegion<T>> for &[T; N] {
impl<T: Clone, S: Storage<T>, const N: usize> CopyOnto<OwnedRegion<T, S>> for &[T; N] {
#[inline]
fn copy_onto(self, target: &mut OwnedRegion<T>) -> <OwnedRegion<T> as Region>::Index {
let start = target.slices.len();
target.slices.extend_from_slice(self);
(start, target.slices.len())
fn copy_onto(self, target: &mut OwnedRegion<T, S>) -> <OwnedRegion<T, S> as Region>::Index {
let start = target.offset;
target.offset = target.slices.extend_from_slice(self);
(start, target.offset)
}
}

impl<T: Clone, const N: usize> CopyOnto<OwnedRegion<T>> for &&[T; N] {
impl<T: Clone, S: Storage<T>, const N: usize> CopyOnto<OwnedRegion<T, S>> for &&[T; N] {
#[inline]
fn copy_onto(self, target: &mut OwnedRegion<T>) -> <OwnedRegion<T> as Region>::Index {
fn copy_onto(self, target: &mut OwnedRegion<T, S>) -> <OwnedRegion<T, S> as Region>::Index {
(*self).copy_onto(target)
}
}

impl<T: Clone, const N: usize> ReserveItems<OwnedRegion<T>> for &[T; N] {
fn reserve_items<I>(target: &mut OwnedRegion<T>, items: I)
impl<T: Clone, S: Storage<T>, const N: usize> ReserveItems<OwnedRegion<T, S>> for &[T; N] {
fn reserve_items<I>(target: &mut OwnedRegion<T, S>, items: I)
where
I: Iterator<Item = Self> + Clone,
{
target.slices.reserve(items.map(|i| i.len()).sum());
}
}

impl<T: Clone> CopyOnto<OwnedRegion<T>> for &[T] {
impl<T: Clone, S: Storage<T>> CopyOnto<OwnedRegion<T, S>> for &[T] {
#[inline]
fn copy_onto(self, target: &mut OwnedRegion<T>) -> <OwnedRegion<T> as Region>::Index {
let start = target.slices.len();
target.slices.extend_from_slice(self);
(start, target.slices.len())
fn copy_onto(self, target: &mut OwnedRegion<T, S>) -> <OwnedRegion<T> as Region>::Index {
let start = target.offset;
target.offset = target.slices.extend_from_slice(self);
(start, target.offset)
}
}

impl<T: Clone> CopyOnto<OwnedRegion<T>> for &&[T]
impl<T: Clone, S: Storage<T>> CopyOnto<OwnedRegion<T, S>> for &&[T]
where
for<'a> &'a [T]: CopyOnto<OwnedRegion<T>>,
for<'a> &'a [T]: CopyOnto<OwnedRegion<T, S>>,
{
#[inline]
fn copy_onto(self, target: &mut OwnedRegion<T>) -> <OwnedRegion<T> as Region>::Index {
fn copy_onto(self, target: &mut OwnedRegion<T, S>) -> <OwnedRegion<T> as Region>::Index {
(*self).copy_onto(target)
}
}

impl<T> ReserveItems<OwnedRegion<T>> for &[T] {
fn reserve_items<I>(target: &mut OwnedRegion<T>, items: I)
impl<T, S: Storage<T>> ReserveItems<OwnedRegion<T, S>> for &[T] {
fn reserve_items<I>(target: &mut OwnedRegion<T, S>, items: I)
where
I: Iterator<Item = Self> + Clone,
{
target.slices.reserve(items.map(<[T]>::len).sum());
}
}

impl<T> CopyOnto<OwnedRegion<T>> for Vec<T> {
impl<T, S: Storage<T>> CopyOnto<OwnedRegion<T, S>> for Vec<T> {
#[inline]
fn copy_onto(mut self, target: &mut OwnedRegion<T>) -> <OwnedRegion<T> as Region>::Index {
let start = target.slices.len();
target.slices.append(&mut self);
(start, target.slices.len())
fn copy_onto(mut self, target: &mut OwnedRegion<T, S>) -> <OwnedRegion<T> as Region>::Index {
let start = target.offset;
target.offset = target.slices.append(&mut self);
(start, target.offset)
}
}

impl<T: Clone> CopyOnto<OwnedRegion<T>> for &Vec<T> {
impl<T: Clone, S: Storage<T>> CopyOnto<OwnedRegion<T, S>> for &Vec<T> {
#[inline]
fn copy_onto(self, target: &mut OwnedRegion<T>) -> <OwnedRegion<T> as Region>::Index {
fn copy_onto(self, target: &mut OwnedRegion<T, S>) -> <OwnedRegion<T> as Region>::Index {
self.as_slice().copy_onto(target)
}
}

impl<T> ReserveItems<OwnedRegion<T>> for &Vec<T> {
fn reserve_items<I>(target: &mut OwnedRegion<T>, items: I)
impl<T, S: Storage<T>> ReserveItems<OwnedRegion<T, S>> for &Vec<T> {
fn reserve_items<I>(target: &mut OwnedRegion<T, S>, items: I)
where
I: Iterator<Item = Self> + Clone,
{
ReserveItems::reserve_items(target, items.map(Vec::as_slice));
}
}

impl<T: Clone, I: IntoIterator<Item = T>> CopyOnto<OwnedRegion<T>> for CopyIter<I> {
impl<T: Clone, S: Storage<T>, I: IntoIterator<Item = T>> CopyOnto<OwnedRegion<T, S>>
for CopyIter<I>
{
#[inline]
fn copy_onto(self, target: &mut OwnedRegion<T>) -> <OwnedRegion<T> as Region>::Index {
let start = target.slices.len();
target.slices.extend(self.0);
(start, target.slices.len())
fn copy_onto(self, target: &mut OwnedRegion<T, S>) -> <OwnedRegion<T, S> as Region>::Index {
let start = target.offset;
target.offset = target.slices.extend(self.0);
(start, target.offset)
}
}

impl<T, J: IntoIterator<Item = T>> ReserveItems<OwnedRegion<T>> for CopyIter<J> {
fn reserve_items<I>(target: &mut OwnedRegion<T>, items: I)
impl<T, S: Storage<T>, J: IntoIterator<Item = T>> ReserveItems<OwnedRegion<T, S>> for CopyIter<J> {
fn reserve_items<I>(target: &mut OwnedRegion<T, S>, items: I)
where
I: Iterator<Item = Self> + Clone,
{
Expand Down
Loading

0 comments on commit 7f2b7d5

Please sign in to comment.