use crate::{ConcurrentVec, elem::ConcurrentElement, helpers::DefaultPinVec};
use core::ops::RangeBounds;
use orx_fixed_vec::IntoConcurrentPinnedVec;
#[derive(Clone, Copy)]
pub struct ConcurrentSlice<'a, T, P = DefaultPinVec<T>>
where
P: IntoConcurrentPinnedVec<ConcurrentElement<T>>,
{
pub(super) vec: &'a ConcurrentVec<T, P>,
pub(super) a: usize,
pub(super) len: usize,
}
impl<'a, T, P> ConcurrentSlice<'a, T, P>
where
P: IntoConcurrentPinnedVec<ConcurrentElement<T>>,
{
pub(crate) fn new(vec: &'a ConcurrentVec<T, P>, a: usize, len: usize) -> Self {
Self { vec, a, len }
}
#[inline(always)]
pub(super) fn idx(&self, i: usize) -> Option<usize> {
match i < self.len {
true => Some(self.a + i),
false => None,
}
}
#[inline(always)]
pub fn len(&self) -> usize {
self.len
}
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn slice<R: RangeBounds<usize>>(&self, range: R) -> ConcurrentSlice<'_, T, P> {
let [a, b] = orx_pinned_vec::utils::slice::vec_range_limits(&range, Some(self.len()));
let len = b - a;
ConcurrentSlice::new(self.vec, self.a + a, len)
}
#[inline(always)]
pub fn get(&self, i: usize) -> Option<&ConcurrentElement<T>> {
match i < self.len {
true => unsafe { self.vec.core.get(self.a + i) },
false => None,
}
}
#[inline(always)]
pub fn get_cloned(&self, i: usize) -> Option<T>
where
T: Clone,
{
match i < self.len {
true => unsafe { self.vec.core.get(self.a + i) }.map(|e| e.cloned()),
false => None,
}
}
#[inline(always)]
pub fn get_copied(&self, i: usize) -> Option<T>
where
T: Copy,
{
self.get_cloned(i)
}
pub fn iter(&self) -> impl Iterator<Item = &ConcurrentElement<T>> {
let b = self.a + self.len;
unsafe { self.vec.core.iter_over_range(self.a..b) }
}
pub fn iter_cloned(&self) -> impl Iterator<Item = T> + '_
where
T: Clone,
{
let b = self.a + self.len;
unsafe { self.vec.core.iter_over_range(self.a..b) }.map(|elem| elem.cloned())
}
}