use crate::{
misc::{ BufferTooSmall, RangeBoundsExt },
traits::{ ArrayRef, ArrayMut, ArrayAlloc, CanAlloc },
std::{
cmp::Ordering, ops::RangeBounds,
fmt::{ self, Debug, Formatter },
hash::{ Hash, Hasher },
slice::{ Iter as SliceIter, IterMut as SliceIterMut }
}
};
pub struct Array<Wrapped> {
wrapped: Wrapped
}
impl<Wrapped> Array<Wrapped> {
pub const fn new(array: Wrapped) -> Self {
Self { wrapped: array }
}
#[inline(always)]
pub fn into_inner(self) -> Wrapped {
self.wrapped
}
}
impl<Wrapped> AsRef<Array<Wrapped>> for Array<Wrapped> {
fn as_ref(&self) -> &Array<Wrapped> {
self
}
}
impl<T, Wrapped> ArrayRef<T> for Array<Wrapped> where Wrapped: AsRef<[T]> {
fn as_slice(&self) -> &[T] {
self.wrapped.as_ref()
}
fn len(&self) -> usize {
self.as_slice().len()
}
fn is_empty(&self) -> bool {
self.as_slice().is_empty()
}
fn get(&self, index: usize) -> Option<&T> {
self.as_slice().get(index)
}
fn get_n<Range>(&self, range: Range) -> Option<Array<&[T]>> where Range: RangeBounds<usize> {
let slice = self.as_slice();
let range = range.into_absolute(0, slice.len())?;
slice.get(range).map(Array::new)
}
fn first(&self) -> Option<&T> {
self.as_slice().first()
}
fn last(&self) -> Option<&T> {
self.as_slice().last()
}
fn iter(&self) -> SliceIter<T> {
self.as_slice().iter()
}
fn clone_to<Source>(&self, dest: &mut Source) -> Result<(), BufferTooSmall> where Source: ArrayMut<T>, T: Clone {
if self.len() > dest.len() {
Err(BufferTooSmall)?;
}
dest.iter_mut().zip(self.iter()).for_each(|(t, e)| *t = e.clone());
Ok(())
}
}
impl<T, Wrapped> ArrayMut<T> for Array<Wrapped> where Wrapped: AsRef<[T]> + AsMut<[T]> {
fn as_slice_mut(&mut self) -> &mut [T] {
self.wrapped.as_mut()
}
fn get_mut(&mut self, index: usize) -> Option<&mut T> {
self.as_slice_mut().get_mut(index)
}
fn get_n_mut<Range>(&mut self, range: Range) -> Option<Array<&mut [T]>> where Range: RangeBounds<usize> {
let slice = self.as_slice_mut();
let range = range.into_absolute(0, slice.len())?;
slice.get_mut(range).map(Array::new)
}
fn first_mut(&mut self) -> Option<&mut T> {
self.as_slice_mut().first_mut()
}
fn last_mut(&mut self) -> Option<&mut T> {
self.as_slice_mut().last_mut()
}
fn iter_mut(&mut self) -> SliceIterMut<T> {
self.as_slice_mut().iter_mut()
}
fn rotate_left(&mut self, count: usize) {
if self.is_empty() {
return;
}
let count = count % self.len();
self.as_slice_mut().rotate_left(count);
}
fn rotate_right(&mut self, count: usize) {
if self.is_empty() {
return;
}
let count = count % self.len();
self.as_slice_mut().rotate_right(count);
}
fn reverse(&mut self) {
self.as_slice_mut().reverse()
}
}
impl<T, Wrapped> ArrayAlloc<T> for Array<Wrapped> where Wrapped: AsRef<[T]> + AsMut<[T]> + CanAlloc<T> {
type Error = Wrapped::Error;
fn alloc_new() -> Result<Self, Self::Error> {
Ok(Self::new(Wrapped::alloc_new()?))
}
fn alloc_clone<Source>(elements: &Source) -> Result<Self, Self::Error> where Source: ArrayRef<T>, T: Clone {
let mut this = Self::alloc_new()?;
this.push_n_back(elements)?;
Ok(this)
}
fn grow_with(&mut self, len: usize, mut init: impl FnMut() -> T) -> Result<(), Self::Error> {
for _ in 0 .. len.saturating_sub(self.len()) {
self.push_back(init())?;
}
Ok(())
}
fn grow(&mut self, len: usize) -> Result<(), Self::Error> where T: Default {
self.grow_with(len, T::default)
}
fn shrink(&mut self, len: usize) -> Result<(), Self::Error> {
for _ in 0 .. self.len().saturating_sub(len) {
let _ = self.wrapped.pop()?;
}
Ok(())
}
fn push_front(&mut self, element: T) -> Result<(), Self::Error> {
self.push_back(element)?;
self.rotate_right(1);
Ok(())
}
fn push_n_front<Source>(&mut self, elements: &Source) -> Result<(), Self::Error>
where Source: ArrayRef<T>, T: Clone
{
self.push_n_back(elements)?;
self.rotate_right(elements.len());
Ok(())
}
fn push_back(&mut self, element: T) -> Result<(), Self::Error> {
self.wrapped.push(element)
}
fn push_n_back<Source>(&mut self, elements: &Source) -> Result<(), Self::Error>
where Source: ArrayRef<T>, T: Clone
{
elements.iter().cloned().try_for_each(|e| self.push_back(e))
}
fn pop_front(&mut self) -> Result<Option<T>, Self::Error> {
self.rotate_left(1);
self.pop_back()
}
fn pop_n_front(&mut self, len: usize) -> Result<Option<Self>, Self::Error> {
self.rotate_left(len);
self.pop_n_back(len)
}
fn pop_back(&mut self) -> Result<Option<T>, Self::Error> {
self.wrapped.pop()
}
fn pop_n_back(&mut self, len: usize) -> Result<Option<Self>, Self::Error> {
if self.len() < len {
return Ok(None)
}
let mut popped = Self::alloc_new()?;
for _ in 0 .. len {
let element = self.pop_back()?.expect("Failed to pop existing element?!");
popped.push_back(element)?;
}
popped.reverse();
Ok(Some(popped))
}
}
impl<Wrapped> Debug for Array<Wrapped> where Wrapped: Debug {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
self.wrapped.fmt(f)
}
}
impl<Wrapped> Default for Array<Wrapped> where Wrapped: Default {
fn default() -> Self {
Self { wrapped: Wrapped::default() }
}
}
impl<Wrapped> Copy for Array<Wrapped> where Wrapped: Copy {
}
impl<Wrapped> Clone for Array<Wrapped> where Wrapped: Clone {
fn clone(&self) -> Self {
Self { wrapped: self.wrapped.clone() }
}
}
impl<Wrapped> PartialEq for Array<Wrapped> where Wrapped: PartialEq {
fn eq(&self, other: &Self) -> bool {
self.wrapped.eq(&other.wrapped)
}
}
impl<Wrapped> Eq for Array<Wrapped> where Wrapped: Eq {
}
impl<Wrapped> PartialOrd for Array<Wrapped> where Wrapped: PartialOrd {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.wrapped.partial_cmp(&other.wrapped)
}
}
impl<Wrapped> Ord for Array<Wrapped> where Wrapped: Ord {
fn cmp(&self, other: &Self) -> Ordering {
self.wrapped.cmp(&other.wrapped)
}
}
impl<Wrapped> Hash for Array<Wrapped> where Wrapped: Hash {
fn hash<H: Hasher>(&self, state: &mut H) {
self.wrapped.hash(state)
}
}
impl<Wrapped> IntoIterator for Array<Wrapped> where Wrapped: IntoIterator {
type Item = Wrapped::Item;
type IntoIter = Wrapped::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.wrapped.into_iter()
}
}