use super::slice::{Packable4, Packed4Slice};
use super::vec::Packed4Vec;
use crate::types::{Bf4, F4};
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Packed4Cow<'a, T: Packable4> {
Borrowed(Packed4Slice<'a, T>),
Owned(Packed4Vec<T>),
}
impl<'a, T: Packable4> Packed4Cow<'a, T> {
#[inline(always)]
pub fn borrowed(view: Packed4Slice<'a, T>) -> Self {
Self::Borrowed(view)
}
#[inline(always)]
pub fn owned(vec: Packed4Vec<T>) -> Self {
Self::Owned(vec)
}
#[inline(always)]
pub fn is_borrowed(&self) -> bool {
matches!(self, Self::Borrowed(_))
}
#[inline(always)]
pub fn is_owned(&self) -> bool {
matches!(self, Self::Owned(_))
}
#[inline]
pub fn from_packed_slice(data: &'a [u8], len: usize) -> Option<Self> {
Packed4Slice::new(data, len).map(Self::Borrowed)
}
#[inline]
pub fn as_view(&self) -> Packed4Slice<'_, T> {
match self {
Self::Borrowed(view) => *view,
Self::Owned(vec) => vec.as_view(),
}
}
#[inline(always)]
pub fn len(&self) -> usize {
match self {
Self::Borrowed(view) => view.len(),
Self::Owned(vec) => vec.len(),
}
}
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
pub fn get(&self, index: usize) -> Option<T> {
match self {
Self::Borrowed(view) => view.get(index),
Self::Owned(vec) => vec.get(index),
}
}
#[inline]
pub fn to_mut(&mut self) -> &mut Packed4Vec<T> {
if let Self::Borrowed(view) = *self {
let mut owned = Packed4Vec::with_capacity(view.len());
owned.data.extend_from_slice(view.data);
owned.len = view.len;
*self = Self::Owned(owned);
}
match self {
Self::Owned(ref mut vec) => vec,
_ => unreachable!(),
}
}
#[inline]
pub fn into_owned(self) -> Packed4Vec<T> {
match self {
Self::Borrowed(view) => {
let mut owned = Packed4Vec::with_capacity(view.len());
owned.data.extend_from_slice(view.data);
owned.len = view.len;
owned
}
Self::Owned(vec) => vec,
}
}
#[inline]
pub fn set(&mut self, index: usize, val: T) {
let vec = self.to_mut();
vec.set(index, val);
}
#[inline]
pub fn sub_slice(&self, range: core::ops::Range<usize>) -> Option<Packed4Cow<'_, T>> {
match self {
Self::Borrowed(view) => view.sub_slice(range).map(Packed4Cow::Borrowed),
Self::Owned(vec) => vec.as_view().sub_slice(range).map(Packed4Cow::Borrowed),
}
}
}
pub enum Packed4CowIntoIter<'a, T: Packable4> {
Borrowed(super::vec::Packed4Iter<'a, T>),
Owned {
vec: Packed4Vec<T>,
index: usize,
},
}
impl<'a, T: Packable4> Iterator for Packed4CowIntoIter<'a, T> {
type Item = T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
match self {
Self::Borrowed(iter) => iter.next(),
Self::Owned { vec, index } => {
let val = vec.get(*index);
if val.is_some() {
*index += 1;
}
val
}
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
match self {
Self::Borrowed(iter) => iter.size_hint(),
Self::Owned { vec, index } => {
let rem = vec.len() - *index;
(rem, Some(rem))
}
}
}
}
impl<'a, T: Packable4> ExactSizeIterator for Packed4CowIntoIter<'a, T> {}
impl<'a, T: Packable4> IntoIterator for &'a Packed4Cow<'a, T> {
type Item = T;
type IntoIter = super::vec::Packed4Iter<'a, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
match self {
Packed4Cow::Borrowed(view) => view.into_iter(),
Packed4Cow::Owned(vec) => vec.as_view().into_iter(),
}
}
}
impl<'a, T: Packable4> IntoIterator for Packed4Cow<'a, T> {
type Item = T;
type IntoIter = Packed4CowIntoIter<'a, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
match self {
Packed4Cow::Borrowed(view) => Packed4CowIntoIter::Borrowed(view.into_iter()),
Packed4Cow::Owned(vec) => Packed4CowIntoIter::Owned { vec, index: 0 },
}
}
}
impl<T: Packable4> Default for Packed4Cow<'static, T> {
#[inline(always)]
fn default() -> Self {
Self::Owned(Packed4Vec::new())
}
}
pub type PackedBf4Cow<'a> = Packed4Cow<'a, Bf4>;
pub type PackedF4Cow<'a> = Packed4Cow<'a, F4>;