use crate::prelude::{
Array, DynDenseSto, DynDenseStoMut, DynDenseStoRef, StDenseStoMut, StDenseStoRef,
};
use core::{
borrow::{Borrow, BorrowMut},
fmt,
iter::{FromIterator, IntoIterator},
mem::uninitialized,
ops::{Deref, DerefMut},
ptr::{copy_nonoverlapping, write},
slice::{Iter, IterMut},
};
#[cfg(feature = "serde1")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[derive(Clone, Copy, Default, Eq, Hash, PartialEq, PartialOrd)]
pub struct VecArray<A> {
array: A,
len: usize,
}
impl<A> VecArray<A>
where
A: Array,
{
pub fn new(array: A, len: usize) -> Self {
VecArray { array, len }
}
#[cfg(feature = "rand")]
pub fn new_rnd<F, R>(len: usize, rng: &mut R, mut cb: F) -> Self
where
F: FnMut(&mut R, usize) -> A::Item,
R: mop_common_deps::rand::Rng,
{
let mut this = Self::with_capacity();
assert!(len <= this.capacity());
(0..len).for_each(|idx| unsafe { this.push_unsafe(cb(rng, idx)) });
this
}
pub fn with_array(array: A) -> Self {
VecArray {
array,
len: A::SIZE,
}
}
pub fn with_capacity() -> Self {
VecArray {
array: unsafe { uninitialized() },
len: 0,
}
}
pub fn array(&self) -> &A {
&self.array
}
pub fn len(&self) -> usize {
self.len
}
pub fn try_push(&mut self, item: A::Item) -> bool {
if self.len < self.capacity() {
unsafe { self.push_unsafe(item) };
true
} else {
false
}
}
unsafe fn push_unsafe(&mut self, item: A::Item) {
write(self.offset_array_ptr(self.len), item);
self.len += 1;
}
unsafe fn offset_array_ptr(&mut self, count: usize) -> *mut A::Item {
self.array.as_mut_slice().as_mut_ptr().add(count)
}
}
impl<A> StDenseStoRef for VecArray<A>
where
A: Array,
{
type Item = A::Item;
fn as_slice(&self) -> &[A::Item] {
let slice = self.array.as_slice();
&slice[0..self.len]
}
}
impl<A> StDenseStoMut for VecArray<A>
where
A: Array,
{
fn as_mut_slice(&mut self) -> &mut [A::Item] {
let slice = self.array.as_mut_slice();
&mut slice[0..self.len]
}
}
impl<A> DynDenseStoRef for VecArray<A>
where
A: Array,
{
fn capacity(&self) -> usize {
A::SIZE
}
}
impl<A> DynDenseStoMut for VecArray<A>
where
A: Array,
{
fn clear(&mut self) {
self.len = 0;
}
fn extend(&mut self, other: &[Self::Item])
where
Self::Item: Copy,
{
let other_len = other.len();
assert!(self.len + other_len <= self.capacity());
unsafe {
copy_nonoverlapping(other.as_ptr(), self.offset_array_ptr(self.len), other_len);
}
self.len += other_len;
}
fn extend_from_clone(&mut self, other: &[Self::Item])
where
Self::Item: Clone,
{
let other_len = other.len();
assert!(self.len + other_len <= self.capacity());
other.iter().for_each(|x| unsafe {
write(self.offset_array_ptr(self.len), x.clone());
self.len += 1;
});
}
fn push(&mut self, item: A::Item) {
assert!(self.len < self.capacity());
unsafe { self.push_unsafe(item) };
}
fn swap(&mut self, a: usize, b: usize) {
self.as_mut_slice().swap(a, b);
}
fn truncate(&mut self, idx: usize) {
self.len = idx;
}
}
impl<A> DynDenseSto for VecArray<A>
where
A: Array,
{
fn new() -> Self {
VecArray::<A>::with_capacity()
}
}
impl<A> AsRef<[A::Item]> for VecArray<A>
where
A: Array,
{
fn as_ref(&self) -> &[A::Item] {
self
}
}
impl<A> AsMut<[A::Item]> for VecArray<A>
where
A: Array,
{
fn as_mut(&mut self) -> &mut [A::Item] {
self
}
}
impl<A> Borrow<[A::Item]> for VecArray<A>
where
A: Array,
{
fn borrow(&self) -> &[A::Item] {
self
}
}
impl<A> BorrowMut<[A::Item]> for VecArray<A>
where
A: Array,
{
fn borrow_mut(&mut self) -> &mut [A::Item] {
self
}
}
impl<A> Deref for VecArray<A>
where
A: Array,
{
type Target = [A::Item];
#[inline]
fn deref(&self) -> &[A::Item] {
self.as_slice()
}
}
impl<A> DerefMut for VecArray<A>
where
A: Array,
{
#[inline]
fn deref_mut(&mut self) -> &mut [A::Item] {
self.as_mut_slice()
}
}
impl<A> FromIterator<A::Item> for VecArray<A>
where
A: Array,
{
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = A::Item>,
{
let mut va = VecArray::with_capacity();
iter.into_iter().for_each(|x| va.push(x));
va
}
}
impl<'a, A> IntoIterator for &'a VecArray<A>
where
A: Array,
{
type Item = &'a A::Item;
type IntoIter = Iter<'a, A::Item>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, A> IntoIterator for &'a mut VecArray<A>
where
A: Array,
{
type Item = &'a mut A::Item;
type IntoIter = IterMut<'a, A::Item>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
#[cfg(feature = "serde1")]
impl<A> Serialize for VecArray<A>
where
A: Array,
A::Item: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.collect_seq(self)
}
}
#[cfg(feature = "serde1")]
impl<'de, A> Deserialize<'de> for VecArray<A>
where
A: Array,
A::Item: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
use core::marker::PhantomData;
use serde::de::{Error, SeqAccess, Visitor};
struct VecArrayVisitor<'de, A>(PhantomData<(&'de (), A)>);
impl<'de, A> Visitor<'de> for VecArrayVisitor<'de, A>
where
A: Array,
A::Item: Deserialize<'de>,
{
type Value = VecArray<A>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "an array with no more than {} items", A::SIZE)
}
fn visit_seq<SA>(self, mut seq: SA) -> Result<Self::Value, SA::Error>
where
SA: SeqAccess<'de>,
{
let mut values = VecArray::<A>::with_capacity();
while let Some(value) = seq.next_element()? {
if values.try_push(value) == false {
return Err(SA::Error::invalid_length(A::SIZE + 1, &self));
}
}
Ok(values)
}
}
deserializer.deserialize_seq(VecArrayVisitor::<A>(PhantomData))
}
}
impl<A> fmt::Debug for VecArray<A>
where
A: Array,
A::Item: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.as_slice().fmt(f)
}
}