use core::borrow::{Borrow, BorrowMut};
use core::cmp::Ordering;
use core::fmt::{self, Debug};
use core::hash::{Hash, Hasher};
use typenum::{consts, Const};
use super::{ArrayLength, ConstArrayLength, GenericArray, IntoArrayLength};
use crate::functional::*;
use crate::sequence::*;
impl<T: Default, N: ArrayLength> Default for GenericArray<T, N> {
#[inline(always)]
fn default() -> Self {
Self::generate(|_| T::default())
}
}
impl<T: Clone, N: ArrayLength> Clone for GenericArray<T, N> {
#[inline]
fn clone(&self) -> GenericArray<T, N> {
self.map(Clone::clone)
}
}
impl<T: Copy, N: ArrayLength> Copy for GenericArray<T, N> where N::ArrayType<T>: Copy {}
impl<T: PartialEq, N: ArrayLength> PartialEq for GenericArray<T, N> {
#[inline(always)]
fn eq(&self, other: &Self) -> bool {
**self == **other
}
}
impl<T: Eq, N: ArrayLength> Eq for GenericArray<T, N> {}
impl<T: PartialOrd, N: ArrayLength> PartialOrd for GenericArray<T, N> {
#[inline(always)]
fn partial_cmp(&self, other: &GenericArray<T, N>) -> Option<Ordering> {
PartialOrd::partial_cmp(self.as_slice(), other.as_slice())
}
}
impl<T: Ord, N: ArrayLength> Ord for GenericArray<T, N> {
#[inline(always)]
fn cmp(&self, other: &GenericArray<T, N>) -> Ordering {
Ord::cmp(self.as_slice(), other.as_slice())
}
}
impl<T: Debug, N: ArrayLength> Debug for GenericArray<T, N> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
self.as_slice().fmt(fmt)
}
}
impl<T, N: ArrayLength> Borrow<[T]> for GenericArray<T, N> {
#[inline(always)]
fn borrow(&self) -> &[T] {
self.as_slice()
}
}
impl<T, N: ArrayLength> BorrowMut<[T]> for GenericArray<T, N> {
#[inline(always)]
fn borrow_mut(&mut self) -> &mut [T] {
self.as_mut_slice()
}
}
impl<T, N: ArrayLength> AsRef<[T]> for GenericArray<T, N> {
#[inline(always)]
fn as_ref(&self) -> &[T] {
self.as_slice()
}
}
impl<T, N: ArrayLength> AsMut<[T]> for GenericArray<T, N> {
#[inline(always)]
fn as_mut(&mut self) -> &mut [T] {
self.as_mut_slice()
}
}
impl<T: Hash, N: ArrayLength> Hash for GenericArray<T, N> {
fn hash<H>(&self, state: &mut H)
where
H: Hasher,
{
Hash::hash(self.as_slice(), state)
}
}
impl<T, const N: usize> From<[T; N]> for GenericArray<T, ConstArrayLength<N>>
where
Const<N>: IntoArrayLength,
{
#[inline(always)]
fn from(value: [T; N]) -> Self {
GenericArray::from_array(value)
}
}
impl<T, const N: usize> From<GenericArray<T, ConstArrayLength<N>>> for [T; N]
where
Const<N>: IntoArrayLength,
{
#[inline(always)]
fn from(value: GenericArray<T, ConstArrayLength<N>>) -> Self {
value.into_array()
}
}
impl<'a, T, const N: usize> From<&'a [T; N]> for &'a GenericArray<T, ConstArrayLength<N>>
where
Const<N>: IntoArrayLength,
{
#[inline(always)]
fn from(slice: &'a [T; N]) -> Self {
unsafe { &*(slice.as_ptr() as *const GenericArray<T, ConstArrayLength<N>>) }
}
}
impl<'a, T, const N: usize> From<&'a mut [T; N]> for &'a mut GenericArray<T, ConstArrayLength<N>>
where
Const<N>: IntoArrayLength,
{
#[inline(always)]
fn from(slice: &'a mut [T; N]) -> Self {
unsafe { &mut *(slice.as_mut_ptr() as *mut GenericArray<T, ConstArrayLength<N>>) }
}
}
impl<T, const N: usize> AsRef<[T; N]> for GenericArray<T, ConstArrayLength<N>>
where
Const<N>: IntoArrayLength,
{
#[inline(always)]
fn as_ref(&self) -> &[T; N] {
unsafe { core::mem::transmute(self) }
}
}
impl<T, const N: usize> AsMut<[T; N]> for GenericArray<T, ConstArrayLength<N>>
where
Const<N>: IntoArrayLength,
{
#[inline(always)]
fn as_mut(&mut self) -> &mut [T; N] {
unsafe { core::mem::transmute(self) }
}
}
macro_rules! impl_tuple {
(@T $t:ident) => { T };
($($len:ty => ($($t:ident,)*);)*) => {$(
impl<T> From<($(impl_tuple!(@T $t),)*)> for GenericArray<T, $len> {
#[inline]
#[allow(non_snake_case)]
fn from(tuple: ($(impl_tuple!(@T $t),)*)) -> Self {
let ($($t,)*) = tuple;
GenericArray::from_array([$($t,)*])
}
}
impl<T> From<GenericArray<T, $len>> for ($(impl_tuple!(@T $t),)*) {
#[inline]
#[allow(non_snake_case)]
fn from(array: GenericArray<T, $len>) -> Self {
let [$($t),*] = array.into_array();
($($t,)*)
}
}
)*};
}
impl_tuple! {
consts::U1 => (A,);
consts::U2 => (A,B,);
consts::U3 => (A,B,C,);
consts::U4 => (A,B,C,D,);
consts::U5 => (A,B,C,D,E,);
consts::U6 => (A,B,C,D,E,F,);
consts::U7 => (A,B,C,D,E,F,G,);
consts::U8 => (A,B,C,D,E,F,G,H,);
consts::U9 => (A,B,C,D,E,F,G,H,I,);
consts::U10 => (A,B,C,D,E,F,G,H,I,J,);
consts::U11 => (A,B,C,D,E,F,G,H,I,J,K,);
consts::U12 => (A,B,C,D,E,F,G,H,I,J,K,L,);
}
#[cfg(test)]
mod tests {
use crate::*;
#[test]
fn test_from_inference() {
let a = arr![1, 2, 3, 4];
let _: [i8; 4] = a.into();
}
}