use core::{ //array::TryFromSliceError, borrow::{ Borrow, BorrowMut }, cmp::Ordering, convert::TryFrom, fmt::{ self, Debug, }, hash::{ self, Hash, }, num::NonZeroUsize, ops::{ Deref, DerefMut, }, slice::{ Iter, IterMut }, }; use alloc::vec::Vec; use super::{ slice::*, vec::*, }; #[repr(transparent)] pub struct IdealArray(pub(crate) [T; N.get()]) where [T; N.get()]: Sized; impl IdealArray where [T; N.get()]: Sized { pub fn new(array: [T; N.get()]) -> Self { Self(array) } pub fn get(self) -> [T; N.get()] { self.0 } pub fn get_ref<'a>(&'a self) -> &'a [T; N.get()] { &self.0 } pub fn get_mut<'a>(&'a mut self) -> &'a mut [T; N.get()] { &mut self.0 } } impl AsMut<[T]> for IdealArray where [T; N.get()]: Sized { #[inline] fn as_mut(&mut self) -> &mut [T] { self.0.as_mut() } } impl AsMut> for IdealArray where [T; N.get()]: Sized { #[inline] fn as_mut(&mut self) -> &mut IdealSlice { unsafe {IdealSlice::new_mut_unchecked(self.0.as_mut())} } } impl AsRef<[T]> for IdealArray where [T; N.get()]: Sized { #[inline] fn as_ref(&self) -> &[T] { self.0.as_ref() } } impl AsRef> for IdealArray where [T; N.get()]: Sized { #[inline] fn as_ref(&self) -> &IdealSlice { unsafe {IdealSlice::new_ref_unchecked(self.0.as_ref())} } } impl Borrow<[T]> for IdealArray where [T; N.get()]: Sized { fn borrow(&self) -> &[T] { self.0.borrow() } } impl Borrow> for IdealArray where [T; N.get()]: Sized { fn borrow(&self) -> &IdealSlice { unsafe {IdealSlice::new_ref_unchecked(self.0.borrow())} } } impl BorrowMut<[T]> for IdealArray where [T; N.get()]: Sized { fn borrow_mut(&mut self) -> &mut [T] { self.0.borrow_mut() } } impl BorrowMut> for IdealArray where [T; N.get()]: Sized { #[inline] fn borrow_mut(&mut self) -> &mut IdealSlice { unsafe {IdealSlice::new_mut_unchecked(self.0.borrow_mut())} } } impl Clone for IdealArray where [T; N.get()]: Sized { fn clone(&self) -> Self { Self(self.0.clone()) } } impl Copy for IdealArray where [T; N.get()]: Sized {} impl Debug for IdealArray where [T; N.get()]: Sized { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {self.0.fmt(f)} } // TODO: Add Default implementation, either with macro or, if ever supported in the future, generically. // TODO: Replace Deref/DerefMut-coercion With Unsize-coercion if possible in the future. impl Deref for IdealArray where [T; N.get()]: Sized { type Target = IdealSlice; fn deref(&self) -> &Self::Target { unsafe {IdealSlice::new_ref_unchecked(&self.0)} } } impl DerefMut for IdealArray where [T; N.get()]: Sized { fn deref_mut(&mut self) -> &mut Self::Target { unsafe {IdealSlice::new_mut_unchecked(&mut self.0)} } } impl Eq for IdealArray where [T; N.get()]: Sized {} impl Hash for IdealArray where [T; N.get()]: Sized { fn hash(&self, state: &mut H) {self.0.hash(state)} } impl<'a, T, const N: NonZeroUsize> IntoIterator for &'a IdealArray where [T; N.get()]: Sized { type Item = &'a T; type IntoIter = Iter<'a, T>; fn into_iter(self) -> Self::IntoIter {self.0.iter()} } impl<'a, T, const N: NonZeroUsize> IntoIterator for &'a mut IdealArray where [T; N.get()]: Sized { type Item = &'a mut T; type IntoIter = IterMut<'a, T>; fn into_iter(self) -> Self::IntoIter {self.0.iter_mut()} } impl<'a, T: Ord, const N: NonZeroUsize> Ord for &'a IdealArray where [T; N.get()]: Sized { #[inline] fn cmp(&self, other: &Self) -> Ordering {self.0.cmp(&other.0)} } impl<'a, const N: NonZeroUsize, A, B: PartialEq> PartialEq<&'a [A]> for IdealArray where [B; N.get()]: Sized { #[inline] fn eq(&self, other: &&'a [A]) -> bool {self.0 == *other} #[inline] fn ne(&self, other: &&'a [A]) -> bool {self.0 != *other} } impl<'a, const N: NonZeroUsize, A, B: PartialEq> PartialEq<&'a mut [A]> for IdealArray where [B; N.get()]: Sized { #[inline] fn eq(&self, other: &&'a mut [A]) -> bool {self.0 == *other} #[inline] fn ne(&self, other: &&'a mut [A]) -> bool {self.0 != *other} } impl<'a, const N: NonZeroUsize, A, B: PartialEq> PartialEq<&'a IdealSlice> for IdealArray where [B; N.get()]: Sized { #[inline] fn eq(&self, other: &&'a IdealSlice) -> bool {self.0 == other.0} #[inline] fn ne(&self, other: &&'a IdealSlice) -> bool {self.0 != other.0} } impl<'a, const N: NonZeroUsize, A, B: PartialEq> PartialEq<&'a mut IdealSlice> for IdealArray where [B; N.get()]: Sized { #[inline] fn eq(&self, other: &&'a mut IdealSlice) -> bool {self.0 == other.0} #[inline] fn ne(&self, other: &&'a mut IdealSlice) -> bool {self.0 != other.0} } impl> PartialEq<[A; N.get()]> for IdealArray where [B; N.get()]: Sized { #[inline] fn eq(&self, other: &[A; N.get()]) -> bool {self.0 == *other} #[inline] fn ne(&self, other: &[A; N.get()]) -> bool {self.0 != *other} } impl> PartialEq> for IdealArray where [B; N.get()]: Sized { #[inline] fn eq(&self, other: &IdealArray) -> bool {self.0 == other.0} #[inline] fn ne(&self, other: &IdealArray) -> bool {self.0 != other.0} } impl> PartialEq<[A]> for IdealArray where [B; N.get()]: Sized { #[inline] fn eq(&self, other: &[A]) -> bool {self.0 == *other} #[inline] fn ne(&self, other: &[A]) -> bool {self.0 != *other} } impl> PartialEq> for IdealArray where [B; N.get()]: Sized { #[inline] fn eq(&self, other: &IdealSlice) -> bool {self.0 == other.0} #[inline] fn ne(&self, other: &IdealSlice) -> bool {self.0 != other.0} } impl, const N: NonZeroUsize> PartialOrd<[T; N.get()]> for IdealArray where [T; N.get()]: Sized { #[inline] fn partial_cmp(&self, other: &[T; N.get()]) -> Option {self.0.partial_cmp(other)} #[inline] fn lt(&self, other: &[T; N.get()]) -> bool {self.0.lt(other)} #[inline] fn le(&self, other: &[T; N.get()]) -> bool {self.0.le(other)} #[inline] fn ge(&self, other: &[T; N.get()]) -> bool {self.0.ge(other)} #[inline] fn gt(&self, other: &[T; N.get()]) -> bool {self.0.gt(other)} } impl, const N: NonZeroUsize> PartialOrd for IdealArray where [T; N.get()]: Sized { #[inline] fn partial_cmp(&self, other: &Self) -> Option {self.0.partial_cmp(&other.0)} #[inline] fn lt(&self, other: &Self) -> bool {self.0.lt(&other.0)} #[inline] fn le(&self, other: &Self) -> bool {self.0.le(&other.0)} #[inline] fn ge(&self, other: &Self) -> bool {self.0.ge(&other.0)} #[inline] fn gt(&self, other: &Self) -> bool {self.0.gt(&other.0)} } // TODO: Uncomment the following three (six) TryFrom implementations when they no longer trigger ICEs. // TODO: Implement TryFrom &[T] for ref owned, ref ref, mut mut /* impl TryFrom<&IdealSlice> for IdealArray where [T; N.get()]: Sized { type Error = TryFromSliceError; //#[inline] fn try_from(slice: &IdealSlice) -> Result { <[T; N.get()] as TryFrom<&[T]>>::try_from(&slice.0) } } impl<'a, T, const N: NonZeroUsize> TryFrom<&'a IdealSlice> for &'a IdealArray where [T; N.get()]: Sized, T: Copy { type Error = TryFromSliceError; #[inline] fn try_from(slice: &'a IdealSlice) -> Result { <[T; N.get()] as TryFrom<&'a [T]>>::try_from(&slice.0) } } impl<'a, T, const N: NonZeroUsize> TryFrom<&'a mut IdealSlice> for &'a mut IdealArray where [T; N.get()]: Sized, T: Copy { type Error = TryFromSliceError; #[inline] fn try_from(slice: &'a mut IdealSlice) -> Result { <[T; N.get()] as TryFrom<&'a mut [T]>>::try_from(&mut slice.0) } } */ impl TryFrom> for IdealArray where [T; N.get()]: Sized, T: Copy { type Error = Vec; fn try_from(vec: Vec) -> Result { <[T; N.get()] as TryFrom>>::try_from(vec).map(|ok| Self(ok)) } } impl TryFrom> for IdealArray where [T; N.get()]: Sized, T: Copy { type Error = IdealVec; fn try_from(vec: IdealVec) -> Result { Self::try_from(vec.0).map_err(|err| IdealVec(err)) } }