use crate::iterators::*;
use crate::utils::partial_compare;
use crate::StaticVec;
use core::cmp::{Eq, Ord, Ordering, PartialEq};
use core::fmt::{Debug, Formatter, Result};
use core::hash::{Hash, Hasher};
use core::iter::FromIterator;
use core::mem::MaybeUninit;
use core::ops::{Index, IndexMut, Range, RangeFull, RangeInclusive};
#[cfg(feature = "std")]
use std::io::{self, Error, ErrorKind, IoSlice, Read, Write};
impl<T, const N: usize> AsMut<T> for StaticVec<T, {N}> {
#[inline(always)]
fn as_mut(&mut self) -> &mut T {
assert!(self.length > 0);
unsafe { self.as_mut_ptr().as_mut().unwrap() }
}
}
impl<T, const N: usize> AsRef<T> for StaticVec<T, {N}> {
#[inline(always)]
fn as_ref(&self) -> &T {
assert!(self.length > 0);
unsafe { self.as_ptr().as_ref().unwrap() }
}
}
impl<T, const N: usize> AsMut<[T]> for StaticVec<T, {N}> {
#[inline(always)]
fn as_mut(&mut self) -> &mut [T] {
self.as_mut_slice()
}
}
impl<T, const N: usize> AsRef<[T]> for StaticVec<T, {N}> {
#[inline(always)]
fn as_ref(&self) -> &[T] {
self.as_slice()
}
}
impl<T: Clone, const N: usize> Clone for StaticVec<T, {N}> {
#[inline]
fn clone(&self) -> Self {
let mut res = Self::new();
for i in 0..self.length {
unsafe {
res
.data
.get_unchecked_mut(i)
.write(self.data.get_unchecked(i).get_ref().clone());
}
}
res.length = self.length;
res
}
}
impl<T: Debug, const N: usize> Debug for StaticVec<T, {N}> {
#[inline(always)]
fn fmt(&self, f: &mut Formatter) -> Result {
Debug::fmt(self.as_slice(), f)
}
}
impl<T, const N: usize> Default for StaticVec<T, {N}> {
#[inline(always)]
fn default() -> Self {
Self::new()
}
}
impl<T, const N: usize> Drop for StaticVec<T, {N}> {
#[inline(always)]
fn drop(&mut self) {
self.clear();
}
}
impl<T: Eq, const N: usize> Eq for StaticVec<T, {N}> {}
impl<T, const N: usize> Extend<T> for StaticVec<T, {N}> {
#[inline]
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
let mut it = iter.into_iter();
let mut i = self.length;
while i < N {
if let Some(val) = it.next() {
unsafe {
self.data.get_unchecked_mut(i).write(val);
}
} else {
break;
}
i += 1;
}
self.length = i;
}
}
impl<'a, T: 'a + Copy, const N: usize> Extend<&'a T> for StaticVec<T, {N}> {
#[inline]
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
let mut it = iter.into_iter();
let mut i = self.length;
while i < N {
if let Some(val) = it.next() {
unsafe {
self.data.get_unchecked_mut(i).write(*val);
}
} else {
break;
}
i += 1;
}
self.length = i;
}
}
impl<T: Copy, const N: usize> From<&[T]> for StaticVec<T, {N}> {
#[inline(always)]
fn from(values: &[T]) -> Self {
Self::new_from_slice(values)
}
}
impl<T: Copy, const N1: usize, const N2: usize> From<&[T; N1]> for StaticVec<T, {N2}> {
#[inline(always)]
fn from(values: &[T; N1]) -> Self {
Self::new_from_array(*values)
}
}
impl<T: Copy, const N1: usize, const N2: usize> From<[T; N1]> for StaticVec<T, {N2}> {
#[inline(always)]
fn from(values: [T; N1]) -> Self {
Self::new_from_array(values)
}
}
impl<T, const N: usize> FromIterator<T> for StaticVec<T, {N}> {
#[inline]
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut res = Self::new();
let mut it = iter.into_iter();
let mut i = 0;
while i < N {
if let Some(val) = it.next() {
unsafe {
res.data.get_unchecked_mut(i).write(val);
}
} else {
break;
}
i += 1;
}
res.length = i;
res
}
}
impl<'a, T: 'a + Copy, const N: usize> FromIterator<&'a T> for StaticVec<T, {N}> {
#[inline]
fn from_iter<I: IntoIterator<Item = &'a T>>(iter: I) -> Self {
let mut res = Self::new();
let mut it = iter.into_iter();
let mut i = 0;
while i < N {
if let Some(val) = it.next() {
unsafe {
res.data.get_unchecked_mut(i).write(*val);
}
} else {
break;
}
i += 1;
}
res.length = i;
res
}
}
impl<T: Hash, const N: usize> Hash for StaticVec<T, {N}> {
#[inline(always)]
fn hash<H: Hasher>(&self, state: &mut H) {
self.as_slice().hash(state);
}
}
impl<T, const N: usize> Index<usize> for StaticVec<T, {N}> {
type Output = T;
#[inline(always)]
fn index(&self, index: usize) -> &Self::Output {
assert!(index < self.length);
unsafe { self.data.get_unchecked(index).get_ref() }
}
}
impl<T, const N: usize> IndexMut<usize> for StaticVec<T, {N}> {
#[inline(always)]
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
assert!(index < self.length);
unsafe { self.data.get_unchecked_mut(index).get_mut() }
}
}
impl<T, const N: usize> Index<Range<usize>> for StaticVec<T, {N}> {
type Output = [T];
#[inline(always)]
fn index(&self, index: Range<usize>) -> &Self::Output {
assert!(index.start < index.end && index.end <= self.length);
unsafe { &*(self.data.get_unchecked(index) as *const [MaybeUninit<T>] as *const [T]) }
}
}
impl<T, const N: usize> IndexMut<Range<usize>> for StaticVec<T, {N}> {
#[inline(always)]
fn index_mut(&mut self, index: Range<usize>) -> &mut Self::Output {
assert!(index.start < index.end && index.end <= self.length);
unsafe { &mut *(self.data.get_unchecked_mut(index) as *mut [MaybeUninit<T>] as *mut [T]) }
}
}
impl<T, const N: usize> Index<RangeFull> for StaticVec<T, {N}> {
type Output = [T];
#[inline(always)]
fn index(&self, _index: RangeFull) -> &Self::Output {
self.as_slice()
}
}
impl<T, const N: usize> IndexMut<RangeFull> for StaticVec<T, {N}> {
#[inline(always)]
fn index_mut(&mut self, _index: RangeFull) -> &mut Self::Output {
self.as_mut_slice()
}
}
impl<T, const N: usize> Index<RangeInclusive<usize>> for StaticVec<T, {N}> {
type Output = [T];
#[inline(always)]
fn index(&self, index: RangeInclusive<usize>) -> &Self::Output {
assert!(index.start() <= index.end() && index.end() < &self.length);
unsafe { &*(self.data.get_unchecked(index) as *const [MaybeUninit<T>] as *const [T]) }
}
}
impl<T, const N: usize> IndexMut<RangeInclusive<usize>> for StaticVec<T, {N}> {
#[inline(always)]
fn index_mut(&mut self, index: RangeInclusive<usize>) -> &mut Self::Output {
assert!(index.start() <= index.end() && index.end() < &self.length);
unsafe { &mut *(self.data.get_unchecked_mut(index) as *mut [MaybeUninit<T>] as *mut [T]) }
}
}
impl<'a, T: 'a, const N: usize> IntoIterator for &'a StaticVec<T, {N}> {
type IntoIter = StaticVecIterConst<'a, T>;
type Item = <Self::IntoIter as Iterator>::Item;
#[inline(always)]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, T: 'a, const N: usize> IntoIterator for &'a mut StaticVec<T, {N}> {
type IntoIter = StaticVecIterMut<'a, T>;
type Item = <Self::IntoIter as Iterator>::Item;
#[inline(always)]
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<T: Ord, const N: usize> Ord for StaticVec<T, {N}> {
#[inline(always)]
fn cmp(&self, other: &StaticVec<T, {N}>) -> Ordering {
Ord::cmp(self.as_slice(), other.as_slice())
}
}
macro_rules! impl_partial_eq_with_as_slice {
($left:ty, $right:ty) => {
impl<T1, T2: PartialEq<T1>, const N1: usize, const N2: usize> PartialEq<$left> for $right {
#[inline(always)]
fn eq(&self, other: &$left) -> bool {
self.as_slice() == other.as_slice()
}
#[inline(always)]
fn ne(&self, other: &$left) -> bool {
self.as_slice() != other.as_slice()
}
}
};
}
macro_rules! impl_partial_eq_with_get_unchecked {
($left:ty, $right:ty) => {
impl<T1, T2: PartialEq<T1>, const N1: usize, const N2: usize> PartialEq<$left> for $right {
#[inline(always)]
fn eq(&self, other: &$left) -> bool {
unsafe { self.as_slice() == other.get_unchecked(..) }
}
#[inline(always)]
fn ne(&self, other: &$left) -> bool {
unsafe { self.as_slice() != other.get_unchecked(..) }
}
}
};
}
macro_rules! impl_partial_eq_with_equals_no_deref {
($left:ty, $right:ty) => {
impl<T1, T2: PartialEq<T1>, const N: usize> PartialEq<$left> for $right {
#[inline(always)]
fn eq(&self, other: &$left) -> bool {
self.as_slice() == other
}
#[inline(always)]
fn ne(&self, other: &$left) -> bool {
self.as_slice() != other
}
}
};
}
macro_rules! impl_partial_eq_with_equals_deref {
($left:ty, $right:ty) => {
impl<T1, T2: PartialEq<T1>, const N: usize> PartialEq<$left> for $right {
#[inline(always)]
fn eq(&self, other: &$left) -> bool {
self.as_slice() == *other
}
#[inline(always)]
fn ne(&self, other: &$left) -> bool {
self.as_slice() != *other
}
}
};
}
macro_rules! impl_partial_ord_with_as_slice {
($left:ty, $right:ty) => {
impl<T1, T2: PartialOrd<T1>, const N1: usize, const N2: usize> PartialOrd<$left> for $right {
#[inline(always)]
fn partial_cmp(&self, other: &$left) -> Option<Ordering> {
partial_compare(self.as_slice(), other.as_slice())
}
}
};
}
macro_rules! impl_partial_ord_with_get_unchecked {
($left:ty, $right:ty) => {
impl<T1, T2: PartialOrd<T1>, const N1: usize, const N2: usize> PartialOrd<$left> for $right {
#[inline(always)]
fn partial_cmp(&self, other: &$left) -> Option<Ordering> {
unsafe { partial_compare(self.as_slice(), other.get_unchecked(..)) }
}
}
};
}
macro_rules! impl_partial_ord_with_as_slice_against_slice {
($left:ty, $right:ty) => {
impl<T1, T2: PartialOrd<T1>, const N: usize> PartialOrd<$left> for $right {
#[inline(always)]
fn partial_cmp(&self, other: &$left) -> Option<Ordering> {
partial_compare(self.as_slice(), other)
}
}
};
}
impl_partial_eq_with_as_slice!(StaticVec<T1, {N1}>, StaticVec<T2, {N2}>);
impl_partial_eq_with_as_slice!(StaticVec<T1, {N1}>, &StaticVec<T2, {N2}>);
impl_partial_eq_with_as_slice!(StaticVec<T1, {N1}>, &mut StaticVec<T2, {N2}>);
impl_partial_eq_with_as_slice!(&StaticVec<T1, {N1}>, StaticVec<T2, {N2}>);
impl_partial_eq_with_as_slice!(&mut StaticVec<T1, {N1}>, StaticVec<T2, {N2}>);
impl_partial_eq_with_get_unchecked!([T1; N1], StaticVec<T2, {N2}>);
impl_partial_eq_with_get_unchecked!([T1; N1], &StaticVec<T2, {N2}>);
impl_partial_eq_with_get_unchecked!([T1; N1], &mut StaticVec<T2, {N2}>);
impl_partial_eq_with_get_unchecked!(&[T1; N1], StaticVec<T2, {N2}>);
impl_partial_eq_with_get_unchecked!(&mut [T1; N1], StaticVec<T2, {N2}>);
impl_partial_eq_with_equals_no_deref!([T1], StaticVec<T2, {N}>);
impl_partial_eq_with_equals_no_deref!([T1], &StaticVec<T2, {N}>);
impl_partial_eq_with_equals_no_deref!([T1], &mut StaticVec<T2, {N}>);
impl_partial_eq_with_equals_deref!(&[T1], StaticVec<T2, {N}>);
impl_partial_eq_with_equals_deref!(&mut [T1], StaticVec<T2, {N}>);
impl_partial_ord_with_as_slice!(StaticVec<T1, {N1}>, StaticVec<T2, {N2}>);
impl_partial_ord_with_as_slice!(StaticVec<T1, {N1}>, &StaticVec<T2, {N2}>);
impl_partial_ord_with_as_slice!(StaticVec<T1, {N1}>, &mut StaticVec<T2, {N2}>);
impl_partial_ord_with_as_slice!(&StaticVec<T1, {N1}>, StaticVec<T2, {N2}>);
impl_partial_ord_with_as_slice!(&mut StaticVec<T1, {N1}>, StaticVec<T2, {N2}>);
impl_partial_ord_with_get_unchecked!([T1; N1], StaticVec<T2, {N2}>);
impl_partial_ord_with_get_unchecked!([T1; N1], &StaticVec<T2, {N2}>);
impl_partial_ord_with_get_unchecked!([T1; N1], &mut StaticVec<T2, {N2}>);
impl_partial_ord_with_get_unchecked!(&[T1; N1], StaticVec<T2, {N2}>);
impl_partial_ord_with_get_unchecked!(&mut [T1; N1], StaticVec<T2, {N2}>);
impl_partial_ord_with_as_slice_against_slice!([T1], StaticVec<T2, {N}>);
impl_partial_ord_with_as_slice_against_slice!([T1], &StaticVec<T2, {N}>);
impl_partial_ord_with_as_slice_against_slice!([T1], &mut StaticVec<T2, {N}>);
impl_partial_ord_with_as_slice_against_slice!(&[T1], StaticVec<T2, {N}>);
impl_partial_ord_with_as_slice_against_slice!(&mut [T1], StaticVec<T2, {N}>);
#[cfg(feature = "std")]
impl<const N: usize> Read for StaticVec<u8, {N}> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let buf_len = buf.len();
if buf_len <= N {
unsafe {
buf.copy_from_slice(self.as_slice().get_unchecked(0..buf_len));
}
Ok(buf_len)
} else {
Err(Error::new(ErrorKind::Other, "Not enough data available!"))
}
}
}
#[cfg(feature = "std")]
impl<const N: usize> Write for StaticVec<u8, {N}> {
#[inline(always)]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let old_length = self.length;
self.extend_from_slice(buf);
Ok(self.length - old_length)
}
#[inline]
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
let len = bufs.iter().map(|b| b.len()).sum();
if self.length + len <= N {
for buf in bufs {
self.extend_from_slice(buf);
}
Ok(len)
} else {
Err(Error::new(ErrorKind::Other, "No space left!"))
}
}
#[inline(always)]
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
self.extend_from_slice(buf);
Ok(())
}
#[inline(always)]
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}