use crate::{utils, Capacity};
use core::{
array,
cmp::Ordering,
mem,
ops::{Deref, DerefMut},
};
pub trait List: Sized {
type Item;
fn new_filled_with<F: FnMut(usize) -> Option<Self::Item>>(n: usize, f: F) -> Self;
fn max_capacity(&self) -> Capacity;
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn get(&self, index: usize) -> Option<&Self::Item>;
fn get_mut(&mut self, index: usize) -> Option<&mut Self::Item>;
fn insert(&mut self, index: usize, element: Self::Item);
fn remove(&mut self, index: usize) -> Self::Item;
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde-1", derive(serde::Serialize, serde::Deserialize))]
pub struct FixedList<T: Default, const N: usize>(
#[cfg_attr(
feature = "serde-1",
serde(
bound(
serialize = "T: serde::Serialize",
deserialize = "T: serde::Deserialize<'de>"
),
serialize_with = "utils::serialize_array",
deserialize_with = "utils::deserialize_array"
)
)]
[T; N],
usize,
);
impl<T: Default, const N: usize> List for FixedList<T, N> {
type Item = T;
fn new_filled_with<F: FnMut(usize) -> Option<Self::Item>>(n: usize, mut f: F) -> Self {
let arr = utils::make_array(|i| match f(i) {
Some(data) if i < n => data,
_ => T::default(),
});
Self(arr, N)
}
fn max_capacity(&self) -> Capacity {
Capacity::Limited(N)
}
fn len(&self) -> usize {
self.1
}
fn get(&self, index: usize) -> Option<&Self::Item> {
self.0.get(index)
}
fn get_mut(&mut self, index: usize) -> Option<&mut Self::Item> {
self.0.get_mut(index)
}
fn insert(&mut self, index: usize, element: Self::Item) {
#[cold]
#[inline(never)]
fn assert_failed(index: usize, len: usize) -> ! {
panic!(
"insertion index (is {}) should be <= len (is {})",
index, len
);
}
let len = self.len();
if index > len {
assert_failed(index, len);
}
self.0[index] = element;
if index == len {
self.1 += 1;
}
}
fn remove(&mut self, index: usize) -> Self::Item {
#[cold]
#[inline(never)]
fn assert_failed(index: usize, len: usize) -> ! {
panic!("removal index (is {}) should be < len (is {})", index, len);
}
let len = self.len();
if index >= len {
assert_failed(index, len);
}
let data = mem::take(&mut self.0[index]);
for i in index + 1..len {
let value = mem::take(&mut self.0[i]);
self.0[i - 1] = value;
}
data
}
}
impl<T: Default, const N: usize> Deref for FixedList<T, N> {
type Target = [T; N];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T: Default, const N: usize> DerefMut for FixedList<T, N> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T: Default, const N: usize> From<FixedList<T, N>> for [T; N] {
fn from(list: FixedList<T, N>) -> Self {
list.0
}
}
impl<T, U, const N: usize> PartialEq<[U; N]> for FixedList<T, N>
where
T: PartialEq<U> + Default,
{
fn eq(&self, other: &[U; N]) -> bool {
PartialEq::eq(&self.0, &*other)
}
}
impl<T, const N: usize> PartialOrd<[T; N]> for FixedList<T, N>
where
T: PartialOrd<T> + Default,
{
fn partial_cmp(&self, other: &[T; N]) -> Option<Ordering> {
PartialOrd::partial_cmp(&self.0, &*other)
}
}
impl<T: Default, const N: usize> IntoIterator for FixedList<T, N> {
type Item = T;
type IntoIter = array::IntoIter<Self::Item, N>;
fn into_iter(self) -> Self::IntoIter {
array::IntoIter::new(self.0)
}
}
#[cfg(any(feature = "alloc", feature = "std"))]
#[doc(inline)]
#[cfg_attr(feature = "docs", doc(cfg(any(alloc, std))))]
pub use self::alloc::DynamicList;
#[cfg(any(feature = "alloc", feature = "std"))]
mod alloc {
use super::*;
use core::iter::FromIterator;
use std::vec::Vec;
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde-1", derive(serde::Serialize, serde::Deserialize))]
pub struct DynamicList<T>(Vec<T>);
impl<T> List for DynamicList<T> {
type Item = T;
fn new_filled_with<F: FnMut(usize) -> Option<Self::Item>>(n: usize, mut f: F) -> Self {
let mut inner = Vec::new();
for i in 0..n {
if let Some(data) = f(i) {
inner.push(data);
}
}
Self(inner)
}
fn max_capacity(&self) -> Capacity {
Capacity::Unlimited
}
fn len(&self) -> usize {
self.0.len()
}
fn get(&self, index: usize) -> Option<&Self::Item> {
self.0.get(index)
}
fn get_mut(&mut self, index: usize) -> Option<&mut Self::Item> {
self.0.get_mut(index)
}
fn insert(&mut self, index: usize, element: Self::Item) {
self.0.insert(index, element)
}
fn remove(&mut self, index: usize) -> Self::Item {
self.0.remove(index)
}
}
impl<T> Deref for DynamicList<T> {
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for DynamicList<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T> From<DynamicList<T>> for Vec<T> {
fn from(list: DynamicList<T>) -> Self {
list.0
}
}
impl<T> From<Vec<T>> for DynamicList<T> {
fn from(vec: Vec<T>) -> Self {
Self(vec)
}
}
impl<T, const N: usize> From<[T; N]> for DynamicList<T> {
fn from(arr: [T; N]) -> Self {
Self(Vec::from(arr))
}
}
impl<T> FromIterator<T> for DynamicList<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
Self(iter.into_iter().collect())
}
}
impl<T, U> PartialEq<Vec<U>> for DynamicList<T>
where
T: PartialEq<U>,
{
fn eq(&self, other: &Vec<U>) -> bool {
PartialEq::eq(&*self.0, &**other)
}
}
impl<T, U, const N: usize> PartialEq<[U; N]> for DynamicList<T>
where
T: PartialEq<U>,
{
fn eq(&self, other: &[U; N]) -> bool {
PartialEq::eq(&*self.0, &*other)
}
}
impl<T> PartialOrd<Vec<T>> for DynamicList<T>
where
T: PartialOrd<T>,
{
fn partial_cmp(&self, other: &Vec<T>) -> Option<Ordering> {
PartialOrd::partial_cmp(&*self.0, &**other)
}
}
impl<T> IntoIterator for DynamicList<T> {
type Item = T;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
}