use smallvec::SmallVec;
use std::fmt;
use std::iter::FromIterator;
use std::ops::{Deref, DerefMut};
pub(crate) const STACK_DIMS: usize = 4;
#[derive(Clone, PartialEq, Eq, Default, Hash)]
pub struct Shape(SmallVec<[usize; STACK_DIMS]>);
impl Shape {
pub fn new() -> Self {
Self(SmallVec::new())
}
pub fn with_capacity(capacity: usize) -> Self {
Self(SmallVec::with_capacity(capacity))
}
pub fn push(&mut self, dim: usize) {
self.0.push(dim);
}
pub fn remove(&mut self, index: usize) -> usize {
self.0.remove(index)
}
pub fn insert(&mut self, index: usize, value: usize) {
self.0.insert(index, value);
}
pub fn swap(&mut self, a: usize, b: usize) {
self.0.swap(a, b);
}
pub fn as_slice(&self) -> &[usize] {
self.0.as_slice()
}
#[inline]
pub fn len(&self) -> usize {
self.0.len()
}
#[inline]
pub fn ndim(&self) -> usize {
self.0.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
impl Deref for Shape {
type Target = [usize];
fn deref(&self) -> &Self::Target {
self.0.as_slice()
}
}
impl DerefMut for Shape {
fn deref_mut(&mut self) -> &mut Self::Target {
self.0.as_mut_slice()
}
}
impl fmt::Debug for Shape {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl AsRef<[usize]> for Shape {
fn as_ref(&self) -> &[usize] {
self.0.as_slice()
}
}
impl From<SmallVec<[usize; STACK_DIMS]>> for Shape {
fn from(value: SmallVec<[usize; STACK_DIMS]>) -> Self {
Self(value)
}
}
impl From<Vec<usize>> for Shape {
fn from(value: Vec<usize>) -> Self {
Self(value.into_iter().collect())
}
}
impl From<&[usize]> for Shape {
fn from(value: &[usize]) -> Self {
Self(value.iter().copied().collect())
}
}
impl<const N: usize> From<[usize; N]> for Shape {
fn from(value: [usize; N]) -> Self {
Self(value.into_iter().collect())
}
}
impl FromIterator<usize> for Shape {
fn from_iter<T: IntoIterator<Item = usize>>(iter: T) -> Self {
Self(iter.into_iter().collect())
}
}