#![cfg_attr(not(feature = "std"), no_std)]
#![feature(core_intrinsics)]
#![feature(const_fn)]
#![feature(const_generics)]
#![feature(maybe_uninit_ref)]
#![feature(maybe_uninit_extra)]
#![feature(exact_size_is_empty)]
use crate::utils::*;
use core::cmp::{Ord, PartialEq};
use core::iter::FromIterator;
use core::marker::PhantomData;
use core::mem::MaybeUninit;
use core::ops::{Bound::Excluded, Bound::Included, Bound::Unbounded, Index, IndexMut, RangeBounds};
use core::ptr;
#[doc(hidden)]
pub mod macro_constructor;
mod macros;
mod utils;
pub struct StaticVec<T, const N: usize> {
data: [MaybeUninit<T>; N],
length: usize,
}
pub struct StaticVecIterConst<'a, T: 'a> {
start: *const T,
end: *const T,
marker: PhantomData<&'a T>,
}
pub struct StaticVecIterMut<'a, T: 'a> {
start: *mut T,
end: *mut T,
marker: PhantomData<&'a mut T>,
}
impl<T, const N: usize> StaticVec<T, {N}> {
#[inline(always)]
pub fn new() -> Self {
unsafe {
Self {
data: MaybeUninit::uninit().assume_init(),
length: 0,
}
}
}
#[inline]
pub fn new_from_slice(values: &[T]) -> Self
where T: Copy {
unsafe {
let mut _data: [MaybeUninit<T>; N] = MaybeUninit::uninit().assume_init();
let fill_length = values.len().min(N);
values
.as_ptr()
.copy_to_nonoverlapping(_data.as_mut_ptr() as *mut T, fill_length);
Self {
data: _data,
length: fill_length,
}
}
}
#[inline]
pub fn filled_with(initializer: fn() -> T) -> Self {
unsafe {
let mut _data: [MaybeUninit<T>; N] = MaybeUninit::uninit().assume_init();
for val in _data.iter_mut() {
val.write(initializer());
}
Self {
data: _data,
length: N,
}
}
}
#[inline(always)]
pub fn len(&self) -> usize {
self.length
}
#[inline(always)]
pub const fn capacity(&self) -> usize {
N
}
#[inline(always)]
pub unsafe fn set_len(&mut self, new_len: usize) {
self.length = new_len;
}
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.length == 0
}
#[inline(always)]
pub fn is_not_empty(&self) -> bool {
self.length > 0
}
#[inline(always)]
pub fn is_full(&self) -> bool {
self.length == N
}
#[inline(always)]
pub fn is_not_full(&self) -> bool {
self.length < N
}
#[inline(always)]
pub fn as_ptr(&self) -> *const T {
self.data.as_ptr() as *const T
}
#[inline(always)]
pub fn as_mut_ptr(&mut self) -> *mut T {
self.data.as_mut_ptr() as *mut T
}
#[inline(always)]
pub fn as_slice(&self) -> &[T] {
unsafe { &*(self.data.get_unchecked(0..self.length) as *const [MaybeUninit<T>] as *const [T]) }
}
#[inline(always)]
pub fn as_mut_slice(&mut self) -> &mut [T] {
unsafe {
&mut *(self.data.get_unchecked_mut(0..self.length) as *mut [MaybeUninit<T>] as *mut [T])
}
}
#[inline(always)]
pub fn push(&mut self, value: T) {
assert!(self.length < N, "No space left!");
unsafe { self.data.get_unchecked_mut(self.length).write(value) };
self.length += 1;
}
#[inline(always)]
pub fn pop(&mut self) -> Option<T> {
if self.length == 0 {
None
} else {
self.length -= 1;
unsafe { Some(self.data.get_unchecked(self.length).read()) }
}
}
#[inline(always)]
pub unsafe fn push_unchecked(&mut self, value: T) {
self.data.get_unchecked_mut(self.length).write(value);
self.length += 1;
}
#[inline(always)]
pub unsafe fn pop_unchecked(&mut self) -> T {
self.length -= 1;
self.data.get_unchecked(self.length).read()
}
#[inline]
pub fn remove(&mut self, index: usize) -> T {
assert!(index < self.length, "Out of range!");
unsafe {
let p = self.as_mut_ptr().add(index);
let res = p.read();
p.offset(1).copy_to(p, self.length - index - 1);
self.length -= 1;
res
}
}
#[inline(always)]
pub fn remove_item(&mut self, item: &T) -> Option<T>
where T: PartialEq {
if let Some(pos) = self.iter().position(|x| *x == *item) {
Some(self.remove(pos))
} else {
None
}
}
#[inline]
pub fn insert(&mut self, index: usize, value: T) {
assert!(
self.length < N && index <= self.length,
"Either you're out of range or there's no space left!"
);
unsafe {
let p = self.as_mut_ptr().add(index);
p.copy_to(p.offset(1), self.length - index);
p.write(value);
self.length += 1;
}
}
#[inline(always)]
pub fn clear(&mut self) {
unsafe {
ptr::drop_in_place(self.as_mut_slice());
}
self.length = 0;
}
#[cfg(feature = "std")]
#[inline(always)]
pub fn sort(&mut self)
where T: Ord {
self.as_mut_slice().sort();
}
#[inline(always)]
pub fn sort_unstable(&mut self)
where T: Ord {
self.as_mut_slice().sort_unstable();
}
#[inline(always)]
pub fn reverse(&mut self) {
self.as_mut_slice().reverse();
}
#[cfg(feature = "std")]
#[inline]
pub fn sorted(&mut self) -> Self
where T: Copy + Ord {
unsafe {
let mut res = Self::new();
res.length = self.length;
self
.as_ptr()
.copy_to_nonoverlapping(res.as_mut_ptr(), self.length);
res.sort();
res
}
}
#[inline]
pub fn sorted_unstable(&mut self) -> Self
where T: Copy + Ord {
unsafe {
let mut res = Self::new();
res.length = self.length;
self
.as_ptr()
.copy_to_nonoverlapping(res.as_mut_ptr(), self.length);
res.sort_unstable();
res
}
}
#[inline]
pub fn reversed(&mut self) -> Self
where T: Copy {
let mut res = Self::new();
res.length = self.length;
unsafe {
reverse_copy(
self.as_ptr(),
self.as_ptr().add(self.length),
res.as_mut_ptr(),
);
}
res
}
#[inline]
pub fn extend_from_slice(&mut self, other: &[T])
where T: Copy {
let mut added_length = other.len();
while self.length + added_length > N {
added_length -= 1;
}
unsafe {
other
.as_ptr()
.copy_to_nonoverlapping(self.as_mut_ptr().add(self.length), added_length);
}
self.length += added_length;
}
#[inline]
pub fn drain<R>(&mut self, range: R) -> Self
where R: RangeBounds<usize> {
let start = match range.start_bound() {
Included(&idx) => idx,
Excluded(&idx) => idx + 1,
Unbounded => 0,
};
let end = match range.end_bound() {
Included(&idx) => idx + 1,
Excluded(&idx) => idx,
Unbounded => self.length,
};
assert!(start <= end && end <= self.length, "Out of range!");
let mut res = Self::new();
res.length = end - start;
unsafe {
self
.as_ptr()
.add(start)
.copy_to_nonoverlapping(res.as_mut_ptr(), res.length);
self
.as_ptr()
.add(end)
.copy_to(self.as_mut_ptr().add(start), self.length - end);
}
self.length -= res.length;
res
}
#[inline(always)]
pub fn iter<'a>(&'a self) -> StaticVecIterConst<'a, T> {
unsafe {
StaticVecIterConst::<'a, T> {
start: self.as_ptr(),
end: self.as_ptr().add(self.length),
marker: PhantomData,
}
}
}
#[inline(always)]
pub fn iter_mut<'a>(&'a mut self) -> StaticVecIterMut<'a, T> {
unsafe {
StaticVecIterMut::<'a, T> {
start: self.as_mut_ptr(),
end: self.as_mut_ptr().add(self.length),
marker: PhantomData,
}
}
}
}
impl<T, const N: usize> Drop for StaticVec<T, {N}> {
#[inline(always)]
fn drop(&mut self) {
self.clear();
}
}
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, "Out of range!");
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, "Out of range!");
unsafe { self.data.get_unchecked_mut(index).get_mut() }
}
}
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, const N: usize> FromIterator<T> for StaticVec<T, {N}> {
#[inline(always)]
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut res = Self::new();
for value in iter {
if res.is_not_full() {
unsafe {
res.push_unchecked(value);
}
} else {
break;
}
}
res
}
}
impl<'a, T: 'a> Iterator for StaticVecIterConst<'a, T> {
type Item = &'a T;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
if self.start < self.end {
unsafe {
let res = Some(&*self.start);
self.start = self.start.offset(1);
res
}
} else {
None
}
}
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = distance_between(self.end, self.start);
(len, Some(len))
}
}
impl<'a, T: 'a> DoubleEndedIterator for StaticVecIterConst<'a, T> {
#[inline(always)]
fn next_back(&mut self) -> Option<Self::Item> {
if self.end > self.start {
unsafe {
self.end = self.end.offset(-1);
let res = Some(&*self.end);
res
}
} else {
None
}
}
}
impl<'a, T: 'a> ExactSizeIterator for StaticVecIterConst<'a, T> {
#[inline(always)]
fn len(&self) -> usize {
distance_between(self.end, self.start)
}
#[inline(always)]
fn is_empty(&self) -> bool {
distance_between(self.end, self.start) == 0
}
}
impl<'a, T: 'a> Iterator for StaticVecIterMut<'a, T> {
type Item = &'a mut T;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
if self.start < self.end {
unsafe {
let res = Some(&mut *self.start);
self.start = self.start.offset(1);
res
}
} else {
None
}
}
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = distance_between(self.end, self.start);
(len, Some(len))
}
}
impl<'a, T: 'a> DoubleEndedIterator for StaticVecIterMut<'a, T> {
#[inline(always)]
fn next_back(&mut self) -> Option<Self::Item> {
if self.end > self.start {
unsafe {
self.end = self.end.offset(-1);
let res = Some(&mut *self.end);
res
}
} else {
None
}
}
}
impl<'a, T: 'a> ExactSizeIterator for StaticVecIterMut<'a, T> {
#[inline(always)]
fn len(&self) -> usize {
distance_between(self.end, self.start)
}
#[inline(always)]
fn is_empty(&self) -> bool {
distance_between(self.end, self.start) == 0
}
}