use core::{fmt, hash, iter::FromIterator, mem::MaybeUninit, ops, ptr, slice};
use generic_array::{ArrayLength, GenericArray};
use hash32;
impl<A> crate::i::Vec<A> {
pub const fn new() -> Self {
Self {
buffer: MaybeUninit::uninit(),
len: 0,
}
}
}
impl<T, N> crate::i::Vec<GenericArray<T, N>>
where
N: ArrayLength<T>,
{
pub(crate) fn as_slice(&self) -> &[T] {
unsafe { slice::from_raw_parts(self.buffer.as_ptr() as *const T, self.len) }
}
pub(crate) fn as_mut_slice(&mut self) -> &mut [T] {
unsafe { slice::from_raw_parts_mut(self.buffer.as_mut_ptr() as *mut T, self.len) }
}
pub(crate) fn capacity(&self) -> usize {
N::to_usize()
}
pub(crate) fn clear(&mut self) {
self.truncate(0);
}
pub(crate) fn clone(&self) -> Self
where
T: Clone,
{
let mut new = Self::new();
new.extend_from_slice(self.as_slice()).unwrap();
new
}
pub(crate) fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = T>,
{
for elem in iter {
self.push(elem).ok().unwrap()
}
}
pub(crate) fn extend_from_slice(&mut self, other: &[T]) -> Result<(), ()>
where
T: Clone,
{
if self.len + other.len() > self.capacity() {
Err(())
} else {
for elem in other {
unsafe {
self.push_unchecked(elem.clone());
}
}
Ok(())
}
}
pub(crate) fn is_full(&self) -> bool {
self.len == self.capacity()
}
pub(crate) unsafe fn pop_unchecked(&mut self) -> T {
debug_assert!(!self.as_slice().is_empty());
self.len -= 1;
(self.buffer.as_ptr() as *const T).add(self.len).read()
}
pub(crate) fn push(&mut self, item: T) -> Result<(), T> {
if self.len < self.capacity() {
unsafe { self.push_unchecked(item) }
Ok(())
} else {
Err(item)
}
}
pub(crate) unsafe fn push_unchecked(&mut self, item: T) {
(self.buffer.as_mut_ptr() as *mut T)
.add(self.len)
.write(item);
self.len += 1;
}
unsafe fn swap_remove_unchecked(&mut self, index: usize) -> T {
let length = self.len;
debug_assert!(index < length);
ptr::swap(
self.as_mut_slice().get_unchecked_mut(index),
self.as_mut_slice().get_unchecked_mut(length - 1),
);
self.pop_unchecked()
}
pub(crate) fn swap_remove(&mut self, index: usize) -> T {
assert!(index < self.len);
unsafe { self.swap_remove_unchecked(index) }
}
pub(crate) fn truncate(&mut self, len: usize) {
unsafe {
while len < self.len {
self.len -= 1;
let len = self.len;
ptr::drop_in_place(self.as_mut_slice().get_unchecked_mut(len));
}
}
}
}
#[repr(transparent)]
pub struct Vec<T, N>(#[doc(hidden)] pub crate::i::Vec<GenericArray<T, N>>)
where
N: ArrayLength<T>;
impl<T, N> Clone for Vec<T, N>
where
N: ArrayLength<T>,
T: Clone,
{
fn clone(&self) -> Self {
Vec(self.0.clone())
}
}
impl<T, N> Vec<T, N>
where
N: ArrayLength<T>,
{
pub fn new() -> Self {
Vec(crate::i::Vec::new())
}
#[inline]
pub fn from_slice(other: &[T]) -> Result<Self, ()>
where
T: Clone,
{
let mut v = Vec::new();
v.extend_from_slice(other)?;
Ok(v)
}
pub fn capacity(&self) -> usize {
self.0.capacity()
}
pub fn clear(&mut self) {
self.0.clear()
}
pub fn extend_from_slice(&mut self, other: &[T]) -> Result<(), ()>
where
T: Clone,
{
self.0.extend_from_slice(other)
}
pub fn pop(&mut self) -> Option<T> {
if self.0.len != 0 {
Some(unsafe { self.0.pop_unchecked() })
} else {
None
}
}
pub fn push(&mut self, item: T) -> Result<(), T> {
self.0.push(item)
}
pub(crate) unsafe fn push_unchecked(&mut self, item: T) {
self.0.push_unchecked(item)
}
pub fn truncate(&mut self, len: usize) {
unsafe {
while len < self.len() {
self.0.len -= 1;
let len = self.len();
ptr::drop_in_place(self.get_unchecked_mut(len));
}
}
}
pub fn resize(&mut self, new_len: usize, value: T) -> Result<(), ()>
where
T: Clone,
{
if new_len > self.capacity() {
return Err(());
}
if new_len > self.len() {
while self.len() < new_len {
self.push(value.clone()).ok();
}
} else {
self.truncate(new_len);
}
Ok(())
}
pub fn resize_default(&mut self, new_len: usize) -> Result<(), ()>
where
T: Clone + Default,
{
self.resize(new_len, T::default())
}
pub unsafe fn set_len(&mut self, new_len: usize) {
debug_assert!(new_len <= self.capacity());
self.0.len = new_len
}
pub fn swap_remove(&mut self, index: usize) -> T {
self.0.swap_remove(index)
}
pub(crate) unsafe fn swap_remove_unchecked(&mut self, index: usize) -> T {
self.0.swap_remove_unchecked(index)
}
pub(crate) fn is_full(&self) -> bool {
self.0.is_full()
}
#[inline]
pub fn starts_with(&self, needle: &[T]) -> bool
where
T: PartialEq,
{
let n = needle.len();
self.len() >= n && needle == &self[..n]
}
#[inline]
pub fn ends_with(&self, needle: &[T]) -> bool
where
T: PartialEq,
{
let (v, n) = (self.len(), needle.len());
v >= n && needle == &self[v - n..]
}
}
impl<T, N> Default for Vec<T, N>
where
N: ArrayLength<T>,
{
fn default() -> Self {
Self::new()
}
}
impl<T, N> fmt::Debug for Vec<T, N>
where
T: fmt::Debug,
N: ArrayLength<T>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
<[T] as fmt::Debug>::fmt(self, f)
}
}
impl<N> fmt::Write for Vec<u8, N>
where
N: ArrayLength<u8>,
{
fn write_str(&mut self, s: &str) -> fmt::Result {
match self.extend_from_slice(s.as_bytes()) {
Ok(()) => Ok(()),
Err(_) => Err(fmt::Error),
}
}
}
impl<T, N> Drop for Vec<T, N>
where
N: ArrayLength<T>,
{
fn drop(&mut self) {
unsafe { ptr::drop_in_place(&mut self[..]) }
}
}
impl<T, N> Extend<T> for Vec<T, N>
where
N: ArrayLength<T>,
{
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = T>,
{
self.0.extend(iter)
}
}
impl<'a, T, N> Extend<&'a T> for Vec<T, N>
where
T: 'a + Copy,
N: ArrayLength<T>,
{
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = &'a T>,
{
self.extend(iter.into_iter().cloned())
}
}
impl<T, N> hash::Hash for Vec<T, N>
where
T: core::hash::Hash,
N: ArrayLength<T>,
{
fn hash<H: hash::Hasher>(&self, state: &mut H) {
<[T] as hash::Hash>::hash(self, state)
}
}
impl<T, N> hash32::Hash for Vec<T, N>
where
T: hash32::Hash,
N: ArrayLength<T>,
{
fn hash<H: hash32::Hasher>(&self, state: &mut H) {
<[T] as hash32::Hash>::hash(self, state)
}
}
impl<'a, T, N> IntoIterator for &'a Vec<T, N>
where
N: ArrayLength<T>,
{
type Item = &'a T;
type IntoIter = slice::Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, T, N> IntoIterator for &'a mut Vec<T, N>
where
N: ArrayLength<T>,
{
type Item = &'a mut T;
type IntoIter = slice::IterMut<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<T, N> FromIterator<T> for Vec<T, N>
where
N: ArrayLength<T>,
{
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = T>,
{
let mut vec = Vec::new();
for i in iter {
vec.push(i).ok().expect("Vec::from_iter overflow");
}
vec
}
}
pub struct IntoIter<T, N>
where
N: ArrayLength<T>,
{
vec: Vec<T, N>,
next: usize,
}
impl<T, N> Iterator for IntoIter<T, N>
where
N: ArrayLength<T>,
{
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if self.next < self.vec.len() {
let item = unsafe {
(self.vec.0.buffer.as_ptr() as *const T)
.add(self.next)
.read()
};
self.next += 1;
Some(item)
} else {
None
}
}
}
impl<T, N> Clone for IntoIter<T, N>
where
T: Clone,
N: ArrayLength<T>,
{
fn clone(&self) -> Self {
let mut vec = Vec::new();
if self.next < self.vec.len() {
let s = unsafe {
slice::from_raw_parts(
(self.vec.0.buffer.as_ptr() as *const T).add(self.next),
self.vec.len() - self.next,
)
};
vec.extend_from_slice(s).ok();
}
Self { vec, next: 0 }
}
}
impl<T, N> Drop for IntoIter<T, N>
where
N: ArrayLength<T>,
{
fn drop(&mut self) {
unsafe {
ptr::drop_in_place(&mut self.vec[self.next..]);
self.vec.0.len = 0;
}
}
}
impl<T, N> IntoIterator for Vec<T, N>
where
N: ArrayLength<T>,
{
type Item = T;
type IntoIter = IntoIter<T, N>;
fn into_iter(self) -> Self::IntoIter {
IntoIter { vec: self, next: 0 }
}
}
impl<A, B, N1, N2> PartialEq<Vec<B, N2>> for Vec<A, N1>
where
N1: ArrayLength<A>,
N2: ArrayLength<B>,
A: PartialEq<B>,
{
fn eq(&self, other: &Vec<B, N2>) -> bool {
<[A]>::eq(self, &**other)
}
}
macro_rules! eq {
($Lhs:ty, $Rhs:ty) => {
impl<'a, 'b, A, B, N> PartialEq<$Rhs> for $Lhs
where
A: PartialEq<B>,
N: ArrayLength<A>,
{
fn eq(&self, other: &$Rhs) -> bool {
<[A]>::eq(self, &other[..])
}
}
};
}
eq!(Vec<A, N>, [B]);
eq!(Vec<A, N>, &'a [B]);
eq!(Vec<A, N>, &'a mut [B]);
macro_rules! array {
($($N:expr),+) => {
$(
eq!(Vec<A, N>, [B; $N]);
eq!(Vec<A, N>, &'a [B; $N]);
)+
}
}
array!(
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 32
);
impl<T, N> Eq for Vec<T, N>
where
N: ArrayLength<T>,
T: Eq,
{
}
impl<T, N> ops::Deref for Vec<T, N>
where
N: ArrayLength<T>,
{
type Target = [T];
fn deref(&self) -> &[T] {
self.0.as_slice()
}
}
impl<T, N> ops::DerefMut for Vec<T, N>
where
N: ArrayLength<T>,
{
fn deref_mut(&mut self) -> &mut [T] {
self.0.as_mut_slice()
}
}
impl<T, N> AsRef<Vec<T, N>> for Vec<T, N>
where
N: ArrayLength<T>,
{
#[inline]
fn as_ref(&self) -> &Self {
self
}
}
impl<T, N> AsMut<Vec<T, N>> for Vec<T, N>
where
N: ArrayLength<T>,
{
#[inline]
fn as_mut(&mut self) -> &mut Self {
self
}
}
impl<T, N> AsRef<[T]> for Vec<T, N>
where
N: ArrayLength<T>,
{
#[inline]
fn as_ref(&self) -> &[T] {
self
}
}
impl<T, N> AsMut<[T]> for Vec<T, N>
where
N: ArrayLength<T>,
{
#[inline]
fn as_mut(&mut self) -> &mut [T] {
self
}
}
#[cfg(test)]
mod tests {
use crate::{consts::*, Vec};
use as_slice::AsSlice;
use core::fmt::Write;
#[test]
fn static_new() {
static mut _V: Vec<i32, U4> = Vec(crate::i::Vec::new());
}
macro_rules! droppable {
() => {
struct Droppable;
impl Droppable {
fn new() -> Self {
unsafe {
COUNT += 1;
}
Droppable
}
}
impl Drop for Droppable {
fn drop(&mut self) {
unsafe {
COUNT -= 1;
}
}
}
static mut COUNT: i32 = 0;
};
}
#[test]
fn drop() {
droppable!();
{
let mut v: Vec<Droppable, U2> = Vec::new();
v.push(Droppable::new()).ok().unwrap();
v.push(Droppable::new()).ok().unwrap();
v.pop().unwrap();
}
assert_eq!(unsafe { COUNT }, 0);
{
let mut v: Vec<Droppable, U2> = Vec::new();
v.push(Droppable::new()).ok().unwrap();
v.push(Droppable::new()).ok().unwrap();
}
assert_eq!(unsafe { COUNT }, 0);
}
#[test]
fn eq() {
let mut xs: Vec<i32, U4> = Vec::new();
let mut ys: Vec<i32, U8> = Vec::new();
assert_eq!(xs, ys);
xs.push(1).unwrap();
ys.push(1).unwrap();
assert_eq!(xs, ys);
}
#[test]
fn full() {
let mut v: Vec<i32, U4> = Vec::new();
v.push(0).unwrap();
v.push(1).unwrap();
v.push(2).unwrap();
v.push(3).unwrap();
assert!(v.push(4).is_err());
}
#[test]
fn iter() {
let mut v: Vec<i32, U4> = Vec::new();
v.push(0).unwrap();
v.push(1).unwrap();
v.push(2).unwrap();
v.push(3).unwrap();
let mut items = v.iter();
assert_eq!(items.next(), Some(&0));
assert_eq!(items.next(), Some(&1));
assert_eq!(items.next(), Some(&2));
assert_eq!(items.next(), Some(&3));
assert_eq!(items.next(), None);
}
#[test]
fn iter_mut() {
let mut v: Vec<i32, U4> = Vec::new();
v.push(0).unwrap();
v.push(1).unwrap();
v.push(2).unwrap();
v.push(3).unwrap();
let mut items = v.iter_mut();
assert_eq!(items.next(), Some(&mut 0));
assert_eq!(items.next(), Some(&mut 1));
assert_eq!(items.next(), Some(&mut 2));
assert_eq!(items.next(), Some(&mut 3));
assert_eq!(items.next(), None);
}
#[test]
fn collect_from_iter() {
let slice = &[1, 2, 3];
let vec = slice.iter().cloned().collect::<Vec<_, U4>>();
assert_eq!(vec, slice);
}
#[test]
#[should_panic]
fn collect_from_iter_overfull() {
let slice = &[1, 2, 3];
let _vec = slice.iter().cloned().collect::<Vec<_, U2>>();
}
#[test]
fn iter_move() {
let mut v: Vec<i32, U4> = Vec::new();
v.push(0).unwrap();
v.push(1).unwrap();
v.push(2).unwrap();
v.push(3).unwrap();
let mut items = v.into_iter();
assert_eq!(items.next(), Some(0));
assert_eq!(items.next(), Some(1));
assert_eq!(items.next(), Some(2));
assert_eq!(items.next(), Some(3));
assert_eq!(items.next(), None);
}
#[test]
fn iter_move_drop() {
droppable!();
{
let mut vec: Vec<Droppable, U2> = Vec::new();
vec.push(Droppable::new()).ok().unwrap();
vec.push(Droppable::new()).ok().unwrap();
let mut items = vec.into_iter();
let _ = items.next();
let _ = items.next();
}
assert_eq!(unsafe { COUNT }, 0);
{
let mut vec: Vec<Droppable, U2> = Vec::new();
vec.push(Droppable::new()).ok().unwrap();
vec.push(Droppable::new()).ok().unwrap();
let _items = vec.into_iter();
}
assert_eq!(unsafe { COUNT }, 0);
{
let mut vec: Vec<Droppable, U2> = Vec::new();
vec.push(Droppable::new()).ok().unwrap();
vec.push(Droppable::new()).ok().unwrap();
let mut items = vec.into_iter();
let _ = items.next();
}
assert_eq!(unsafe { COUNT }, 0);
}
#[test]
fn push_and_pop() {
let mut v: Vec<i32, U4> = Vec::new();
assert_eq!(v.len(), 0);
assert_eq!(v.pop(), None);
assert_eq!(v.len(), 0);
v.push(0).unwrap();
assert_eq!(v.len(), 1);
assert_eq!(v.pop(), Some(0));
assert_eq!(v.len(), 0);
assert_eq!(v.pop(), None);
assert_eq!(v.len(), 0);
}
#[test]
fn resize_size_limit() {
let mut v: Vec<u8, U4> = Vec::new();
v.resize(0, 0).unwrap();
v.resize(4, 0).unwrap();
v.resize(5, 0).err().expect("full");
}
#[test]
fn resize_length_cases() {
let mut v: Vec<u8, U4> = Vec::new();
assert_eq!(v.len(), 0);
v.resize(1, 0).unwrap();
assert_eq!(v.len(), 1);
v.resize(3, 0).unwrap();
assert_eq!(v.len(), 3);
v.resize(3, 0).unwrap();
assert_eq!(v.len(), 3);
v.resize(2, 0).unwrap();
assert_eq!(v.len(), 2);
v.resize(0, 0).unwrap();
assert_eq!(v.len(), 0);
}
#[test]
fn resize_contents() {
let mut v: Vec<u8, U4> = Vec::new();
v.resize(1, 17).unwrap();
assert_eq!(v[0], 17);
v.resize(2, 18).unwrap();
assert_eq!(v[0], 17);
assert_eq!(v[1], 18);
v.resize(2, 0).unwrap();
assert_eq!(v[0], 17);
assert_eq!(v[1], 18);
v.resize(1, 0).unwrap();
assert_eq!(v[0], 17);
}
#[test]
fn resize_default() {
let mut v: Vec<u8, U4> = Vec::new();
v.resize_default(1).unwrap();
assert_eq!(v[0], 0);
}
#[test]
fn write() {
let mut v: Vec<u8, U4> = Vec::new();
write!(v, "{:x}", 1234).unwrap();
assert_eq!(&v[..], b"4d2");
}
#[test]
fn extend_from_slice() {
let mut v: Vec<u8, U4> = Vec::new();
assert_eq!(v.len(), 0);
v.extend_from_slice(&[1, 2]).unwrap();
assert_eq!(v.len(), 2);
assert_eq!(v.as_slice(), &[1, 2]);
v.extend_from_slice(&[3]).unwrap();
assert_eq!(v.len(), 3);
assert_eq!(v.as_slice(), &[1, 2, 3]);
assert!(v.extend_from_slice(&[4, 5]).is_err());
assert_eq!(v.len(), 3);
assert_eq!(v.as_slice(), &[1, 2, 3]);
}
#[test]
fn from_slice() {
let v: Vec<u8, U4> = Vec::from_slice(&[1, 2, 3]).unwrap();
assert_eq!(v.len(), 3);
assert_eq!(v.as_slice(), &[1, 2, 3]);
assert!(Vec::<u8, U2>::from_slice(&[1, 2, 3]).is_err());
}
#[test]
fn starts_with() {
let v: Vec<_, U8> = Vec::from_slice(b"ab").unwrap();
assert!(v.starts_with(&[]));
assert!(v.starts_with(b""));
assert!(v.starts_with(b"a"));
assert!(v.starts_with(b"ab"));
assert!(!v.starts_with(b"abc"));
assert!(!v.starts_with(b"ba"));
assert!(!v.starts_with(b"b"));
}
#[test]
fn ends_with() {
let v: Vec<_, U8> = Vec::from_slice(b"ab").unwrap();
assert!(v.ends_with(&[]));
assert!(v.ends_with(b""));
assert!(v.ends_with(b"b"));
assert!(v.ends_with(b"ab"));
assert!(!v.ends_with(b"abc"));
assert!(!v.ends_with(b"ba"));
assert!(!v.ends_with(b"a"));
}
}