use core::{
borrow::{Borrow, BorrowMut},
cmp::Ordering,
convert::TryFrom,
fmt, hash,
hash::Hash,
ops::{Index, IndexMut},
slice::SliceIndex,
};
use crate::{iter::IterMove, Array, ArrayExt, ArrayShorthand, SizeError};
#[derive(Copy, Clone)]
#[repr(transparent)]
pub struct ArrayWrapper<A> {
array: A,
}
impl<A> ArrayWrapper<A>
where
A: Array,
{
#[inline]
pub fn new(inner: A) -> Self {
Self { array: inner }
}
#[inline]
pub fn into_inner(self) -> A {
self.array
}
}
impl<A> AsRef<A> for ArrayWrapper<A> {
#[inline]
fn as_ref(&self) -> &A {
&self.array
}
}
impl<A> AsMut<A> for ArrayWrapper<A> {
#[inline]
fn as_mut(&mut self) -> &mut A {
&mut self.array
}
}
impl<A> AsRef<[A::Item]> for ArrayWrapper<A>
where
A: Array,
{
#[inline]
fn as_ref(&self) -> &[A::Item] {
&self[..]
}
}
impl<A> AsMut<[A::Item]> for ArrayWrapper<A>
where
A: Array,
{
#[inline]
fn as_mut(&mut self) -> &mut [A::Item] {
&mut self[..]
}
}
impl<A> Borrow<[A::Item]> for ArrayWrapper<A>
where
A: Array,
{
#[inline]
fn borrow(&self) -> &[A::Item] {
self.as_slice()
}
}
impl<A> BorrowMut<[A::Item]> for ArrayWrapper<A>
where
A: Array,
{
#[inline]
fn borrow_mut(&mut self) -> &mut [A::Item] {
self.as_mut_slice()
}
}
impl<A> Default for ArrayWrapper<A>
where
A: Array,
A::Item: Default,
{
#[inline]
fn default() -> Self {
<_>::from_fn(|_| <_>::default())
}
}
impl<A> TryFrom<&[A::Item]> for ArrayWrapper<A>
where
A::Item: Copy,
A: Array,
{
type Error = SizeError;
#[inline]
fn try_from(slice: &[A::Item]) -> Result<Self, SizeError> {
Self::from_slice(slice)
}
}
impl<'a, A> TryFrom<&'a [A::Item]> for &'a ArrayWrapper<A>
where
A: Array,
{
type Error = &'a [A::Item];
#[inline]
fn try_from(slice: &'a [A::Item]) -> Result<Self, Self::Error> {
<_>::try_ref_cast(slice)
}
}
impl<'a, A> TryFrom<&'a mut [A::Item]> for &'a mut ArrayWrapper<A>
where
A: Array,
{
type Error = &'a mut [A::Item];
#[inline]
fn try_from(slice: &'a mut [A::Item]) -> Result<Self, Self::Error> {
<_>::try_mut_cast(slice)
}
}
impl<A> Hash for ArrayWrapper<A>
where
A::Item: Hash,
A: Array,
{
#[inline]
fn hash<H: hash::Hasher>(&self, state: &mut H) {
Hash::hash(&self[..], state)
}
}
impl<A> Eq for ArrayWrapper<A>
where
A: Array,
A::Item: Eq,
{
}
impl<A, B> PartialOrd<B> for ArrayWrapper<A>
where
A: Array,
B: Array<Item = A::Item>,
A::Item: PartialOrd,
{
#[inline]
fn partial_cmp(&self, other: &B) -> Option<Ordering> {
PartialOrd::partial_cmp(&self[..], other.as_slice())
}
#[inline]
fn lt(&self, other: &B) -> bool {
PartialOrd::lt(&self[..], other.as_slice())
}
#[inline]
fn le(&self, other: &B) -> bool {
PartialOrd::le(&self[..], other.as_slice())
}
#[inline]
fn gt(&self, other: &B) -> bool {
PartialOrd::gt(&self[..], other.as_slice())
}
#[inline]
fn ge(&self, other: &B) -> bool {
PartialOrd::ge(&self[..], other.as_slice())
}
}
impl<A> Ord for ArrayWrapper<A>
where
A: Array,
A::Item: Ord,
{
#[inline]
fn cmp(&self, other: &Self) -> Ordering {
Ord::cmp(&&self[..], &&other[..])
}
}
impl<A> fmt::Debug for ArrayWrapper<A>
where
A::Item: fmt::Debug,
A: Array,
{
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&&self[..], f)
}
}
impl<A> IntoIterator for ArrayWrapper<A>
where
A: Array,
{
type IntoIter = IterMove<Self>;
type Item = A::Item;
#[inline]
fn into_iter(self) -> Self::IntoIter {
IterMove::new(self)
}
}
impl<A, B> PartialEq<B> for ArrayWrapper<A>
where
A::Item: PartialEq<B::Item>,
A: Array,
B: Array,
{
#[inline]
fn eq(&self, other: &B) -> bool {
&self[..] == other.as_slice()
}
}
impl<A, T> PartialEq<ArrayWrapper<A>> for [T]
where
T: PartialEq<A::Item>,
A: Array,
{
#[inline]
fn eq(&self, other: &ArrayWrapper<A>) -> bool {
self[..] == other[..]
}
}
impl<'t, A, T> PartialEq<&'t [T]> for ArrayWrapper<A>
where
A::Item: PartialEq<T>,
A: Array,
{
#[inline]
fn eq(&self, other: &&'t [T]) -> bool {
self[..] == other[..]
}
}
impl<'t, A, T> PartialEq<ArrayWrapper<A>> for &'t [T]
where
T: PartialEq<A::Item>,
A: Array,
{
#[inline]
fn eq(&self, other: &ArrayWrapper<A>) -> bool {
self[..] == other[..]
}
}
impl<'t, A, T> PartialEq<&'t mut [T]> for ArrayWrapper<A>
where
A::Item: PartialEq<T>,
A: Array,
{
#[inline]
fn eq(&self, other: &&'t mut [T]) -> bool {
self[..] == other[..]
}
}
impl<'t, A, T> PartialEq<ArrayWrapper<A>> for &'t mut [T]
where
T: PartialEq<A::Item>,
A: Array,
{
#[inline]
fn eq(&self, other: &ArrayWrapper<A>) -> bool {
self[..] == other[..]
}
}
impl<A, T> PartialEq<[T]> for ArrayWrapper<A>
where
A::Item: PartialEq<T>,
A: Array,
{
#[inline]
fn eq(&self, other: &[T]) -> bool {
self[..] == other[..]
}
}
unsafe impl<A> Array for ArrayWrapper<A>
where
A: Array,
{
type Item = A::Item;
type Maybe = ArrayWrapper<A::Maybe>;
const SIZE: usize = A::SIZE;
crate::if_alloc! {
#[inline]
fn into_boxed_slice(self) -> alloc::boxed::Box<[Self::Item]> {
self.array.into_boxed_slice()
}
}
#[inline]
fn as_slice(&self) -> &[Self::Item] {
self.array.as_slice()
}
#[inline]
fn as_mut_slice(&mut self) -> &mut [Self::Item] {
self.array.as_mut_slice()
}
#[inline]
fn try_unfold<St, F, E>(init: St, f: F) -> Result<Self, E>
where
F: FnMut(&mut St) -> Result<Self::Item, E>,
{
Ok(Self {
array: A::try_unfold(init, f)?,
})
}
#[inline]
fn unfold<St, F>(init: St, f: F) -> Self
where
F: FnMut(&mut St) -> Self::Item,
{
Self {
array: A::unfold(init, f),
}
}
#[inline]
fn try_from_fn<F, E>(f: F) -> Result<Self, E>
where
F: FnMut(usize) -> Result<Self::Item, E>,
{
Ok(Self {
array: A::try_from_fn(f)?,
})
}
#[inline]
fn from_fn<F>(f: F) -> Self
where
F: FnMut(usize) -> Self::Item,
{
Self {
array: A::from_fn(f),
}
}
#[inline]
fn try_from_iter<I>(iter: I) -> Option<Self>
where
I: IntoIterator<Item = Self::Item>,
{
A::try_from_iter(iter.into_iter()).map(|array| Self { array })
}
#[inline]
fn into_uninit(self) -> Self::Maybe {
Self::Maybe {
array: self.array.into_uninit(),
}
}
}
impl<A, Idx> Index<Idx> for ArrayWrapper<A>
where
A: Array,
Idx: SliceIndex<[A::Item]>,
{
type Output = Idx::Output;
#[inline]
fn index(&self, index: Idx) -> &Self::Output {
self.array.index(index)
}
}
impl<A, Idx> IndexMut<Idx> for ArrayWrapper<A>
where
A: Array,
Idx: SliceIndex<[A::Item]>,
{
#[inline]
fn index_mut(&mut self, index: Idx) -> &mut Self::Output {
self.array.index_mut(index)
}
}