#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use crate::{CopyIter, CopyOnto, Region, ReserveItems};
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct CopyRegion<T: Copy> {
slices: Vec<T>,
}
impl<T: Copy> Region for CopyRegion<T> {
type ReadItem<'a> = &'a [T] where Self: 'a;
type Index = (usize, usize);
fn merge_regions<'a>(regions: impl Iterator<Item = &'a Self> + Clone) -> Self
where
Self: 'a,
{
Self {
slices: Vec::with_capacity(regions.map(|r| r.slices.len()).sum()),
}
}
#[inline]
fn index(&self, (start, end): Self::Index) -> Self::ReadItem<'_> {
&self.slices[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());
}
#[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,
);
}
}
impl<T: Copy> Default for CopyRegion<T> {
fn default() -> Self {
Self {
slices: Vec::default(),
}
}
}
impl<T> CopyOnto<CopyRegion<T>> for &[T]
where
T: Copy,
{
#[inline]
fn copy_onto(self, target: &mut CopyRegion<T>) -> <CopyRegion<T> as Region>::Index {
let start = target.slices.len();
target.slices.extend_from_slice(self);
(start, target.slices.len())
}
}
impl<T: Copy> ReserveItems<CopyRegion<T>> for &[T] {
fn reserve_items<I>(target: &mut CopyRegion<T>, items: I)
where
I: Iterator<Item = Self> + Clone,
{
target.slices.reserve(items.map(|i| i.len()).sum());
}
}
impl<T> CopyOnto<CopyRegion<T>> for &Vec<T>
where
T: Copy,
{
#[inline]
fn copy_onto(self, target: &mut CopyRegion<T>) -> <CopyRegion<T> as Region>::Index {
self.as_slice().copy_onto(target)
}
}
impl<T: Copy> ReserveItems<CopyRegion<T>> for &Vec<T> {
fn reserve_items<I>(target: &mut CopyRegion<T>, items: I)
where
I: Iterator<Item = Self> + Clone,
{
ReserveItems::reserve_items(target, items.map(Vec::as_slice))
}
}
impl<T, I: IntoIterator<Item = T>> CopyOnto<CopyRegion<T>> for CopyIter<I>
where
T: Copy,
{
#[inline]
fn copy_onto(self, target: &mut CopyRegion<T>) -> <CopyRegion<T> as Region>::Index {
let start = target.slices.len();
target.slices.extend(self.0);
(start, target.slices.len())
}
}
impl<T: Copy, J: IntoIterator<Item = T>> ReserveItems<CopyRegion<T>> for CopyIter<J> {
fn reserve_items<I>(target: &mut CopyRegion<T>, items: I)
where
I: Iterator<Item = Self> + Clone,
{
target
.slices
.reserve(items.flat_map(|i| i.0.into_iter()).count());
}
}