use std::marker::PhantomData;
use std::ops::{Index, IndexMut};
use std::slice;
pub struct CSliceIter<'a, 'b, T> {
inner: &'b CSlice<'a, T>,
pos: usize,
}
impl<'a, 'b, T> Iterator for CSliceIter<'a, 'b, T> {
type Item = &'b T;
fn next(&mut self) -> Option<Self::Item> {
if self.pos >= self.inner.len() {
None
} else {
self.pos += 1;
Some(unsafe { self.inner.get_unchecked(self.pos - 1) })
}
}
}
pub struct CSlice<'a, T> {
pub(crate) base: *const T,
pub(crate) len: usize,
pub(crate) _phantom: PhantomData<&'a ()>,
}
impl<'a, T> CSlice<'a, T> {
pub unsafe fn new(base: *const T, len: usize) -> CSlice<'a, T> {
assert!(!base.is_null());
CSlice {
base,
len,
_phantom: PhantomData,
}
}
pub fn get(&'a self, ofs: usize) -> Option<&'a T> {
if ofs < self.len {
Some(unsafe { &*self.base.add(ofs) })
} else {
None
}
}
pub unsafe fn get_unchecked(&'a self, ofs: usize) -> &'a T {
&*self.base.add(ofs)
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn iter<'b>(&'b self) -> CSliceIter<'a, 'b, T> {
CSliceIter {
inner: self,
pos: 0,
}
}
}
impl<'a, T> AsRef<[T]> for CSlice<'a, T> {
fn as_ref(&self) -> &[T] {
unsafe { slice::from_raw_parts(self.base as *const T, self.len) }
}
}
impl<'a, T> Index<usize> for CSlice<'a, T> {
type Output = T;
fn index(&self, index: usize) -> &T {
assert!(index < self.len);
unsafe { &*self.base.add(index) }
}
}
impl<'a, T: Clone> Into<Vec<T>> for CSlice<'a, T> {
fn into(self: CSlice<'a, T>) -> Vec<T> {
let mut v = Vec::with_capacity(self.len);
v.extend_from_slice(self.as_ref());
v
}
}
pub struct CSliceMutIter<'a, 'b, T> {
inner: &'b CSliceMut<'a, T>,
pos: usize,
}
impl<'a, 'b, T> Iterator for CSliceMutIter<'a, 'b, T> {
type Item = &'b T;
fn next(&mut self) -> Option<Self::Item> {
if self.pos >= self.inner.len() {
None
} else {
self.pos += 1;
Some(unsafe { self.inner.get_unchecked(self.pos - 1) })
}
}
}
pub struct CSliceMutIterMut<'a, 'b, T> {
inner: &'b mut CSliceMut<'a, T>,
pos: usize,
}
impl<'a, 'b, T> Iterator for CSliceMutIterMut<'a, 'b, T> {
type Item = &'b mut T;
fn next(&mut self) -> Option<Self::Item> {
if self.pos >= self.inner.len() {
None
} else {
self.pos += 1;
Some(unsafe { &mut *self.inner.base.add(self.pos - 1) })
}
}
}
pub struct CSliceMut<'a, T> {
pub(crate) base: *mut T,
pub(crate) len: usize,
pub(crate) _phantom: PhantomData<&'a ()>,
}
impl<'a, T> CSliceMut<'a, T> {
pub unsafe fn new(base: *mut T, len: usize) -> CSliceMut<'a, T> {
assert!(!base.is_null());
Self {
base,
len,
_phantom: PhantomData,
}
}
pub fn get(&self, ofs: usize) -> Option<&T> {
if ofs < self.len {
Some(unsafe { &*self.base.add(ofs) })
} else {
None
}
}
pub unsafe fn get_unchecked(&self, ofs: usize) -> &T {
&*self.base.add(ofs)
}
pub fn get_mut(&mut self, ofs: usize) -> Option<&mut T> {
if ofs < self.len {
Some(unsafe { &mut *self.base.add(ofs) })
} else {
None
}
}
pub unsafe fn get_unchecked_mut(&mut self, ofs: usize) -> &mut T {
&mut *self.base.add(ofs)
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn iter<'b>(&'b self) -> CSliceMutIter<'a, 'b, T> {
CSliceMutIter {
inner: self,
pos: 0,
}
}
pub fn iter_mut<'b>(&'b mut self) -> CSliceMutIterMut<'a, 'b, T> {
CSliceMutIterMut {
inner: self,
pos: 0,
}
}
}
impl<'a, T> AsRef<[T]> for CSliceMut<'a, T> {
fn as_ref(&self) -> &[T] {
unsafe { slice::from_raw_parts(self.base as *const T, self.len) }
}
}
impl<'a, T> AsMut<[T]> for CSliceMut<'a, T> {
fn as_mut(&mut self) -> &mut [T] {
unsafe { slice::from_raw_parts_mut(self.base, self.len) }
}
}
impl<'a, T> Index<usize> for CSliceMut<'a, T> {
type Output = T;
fn index(&self, index: usize) -> &T {
assert!(index < self.len);
unsafe { &*self.base.add(index) }
}
}
impl<'a, T> IndexMut<usize> for CSliceMut<'a, T> {
fn index_mut(&mut self, index: usize) -> &mut T {
assert!(index < self.len);
unsafe { &mut *self.base.add(index) }
}
}
impl<'a, T: Clone> Into<Vec<T>> for CSliceMut<'a, T> {
fn into(self: CSliceMut<'a, T>) -> Vec<T> {
let mut v = Vec::with_capacity(self.len);
v.extend_from_slice(self.as_ref());
v
}
}