#![cfg_attr(feature="no_std", no_std)]
#[cfg(feature="no_std")]
extern crate core as std;
extern crate typenum;
pub mod arr;
use typenum::uint::{Unsigned, UTerm, UInt};
use typenum::bit::{B0, B1};
use std::fmt::Debug;
use std::marker::PhantomData;
use std::mem;
use std::ops::{Deref, DerefMut};
use std::ptr;
use std::slice;
pub unsafe trait ArrayLength<T> : Unsigned {
type ArrayType;
}
unsafe impl<T> ArrayLength<T> for UTerm {
type ArrayType = ();
}
#[allow(dead_code)]
#[repr(C)]
pub struct GenericArrayImplEven<T, U> {
parent1: U,
parent2: U,
_marker: PhantomData<T>
}
impl<T: Clone, U: Clone> Clone for GenericArrayImplEven<T, U> {
fn clone(&self) -> GenericArrayImplEven<T, U> {
GenericArrayImplEven {
parent1: self.parent1.clone(),
parent2: self.parent2.clone(),
_marker: PhantomData
}
}
}
impl<T: Copy, U: Copy> Copy for GenericArrayImplEven<T, U> {}
#[allow(dead_code)]
#[repr(C)]
pub struct GenericArrayImplOdd<T, U> {
parent1: U,
parent2: U,
data: T
}
impl<T: Clone, U: Clone> Clone for GenericArrayImplOdd<T, U> {
fn clone(&self) -> GenericArrayImplOdd<T, U> {
GenericArrayImplOdd {
parent1: self.parent1.clone(),
parent2: self.parent2.clone(),
data: self.data.clone()
}
}
}
impl<T: Copy, U: Copy> Copy for GenericArrayImplOdd<T, U> {}
unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B0> {
type ArrayType = GenericArrayImplEven<T, N::ArrayType>;
}
unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B1> {
type ArrayType = GenericArrayImplOdd<T, N::ArrayType>;
}
#[allow(dead_code)]
pub struct GenericArray<T, U: ArrayLength<T>> {
data: U::ArrayType
}
impl<T, N> Deref for GenericArray<T, N> where N: ArrayLength<T> {
type Target = [T];
fn deref(&self) -> &[T] {
unsafe {
slice::from_raw_parts(self as *const Self as *const T, N::to_usize())
}
}
}
impl<T, N> DerefMut for GenericArray<T, N> where N: ArrayLength<T> {
fn deref_mut(&mut self) -> &mut [T] {
unsafe {
slice::from_raw_parts_mut(self as *mut Self as *mut T, N::to_usize())
}
}
}
impl<T: Default, N> GenericArray<T, N> where N: ArrayLength<T> {
pub fn new() -> GenericArray<T, N> {
unsafe {
let mut res: GenericArray<T, N> = mem::uninitialized();
for r in res.iter_mut() { ptr::write(r, T::default()) }
res
}
}
}
impl<T: Clone, N> GenericArray<T, N> where N: ArrayLength<T> {
pub fn from_slice(list: &[T]) -> GenericArray<T, N> {
assert_eq!(list.len(), N::to_usize());
unsafe {
let mut res: GenericArray<T, N> = mem::uninitialized();
for i in 0..N::to_usize() { ptr::write(&mut res[i], list[i].clone()) }
res
}
}
}
impl<T: Clone, N> Clone for GenericArray<T, N> where N: ArrayLength<T> {
fn clone(&self) -> GenericArray<T, N> {
unsafe {
let mut res: GenericArray<T, N> = mem::uninitialized();
for i in 0..N::to_usize() { ptr::write(&mut res[i], self[i].clone()) }
res
}
}
}
impl<T: Copy, N> Copy for GenericArray<T, N> where N: ArrayLength<T>, N::ArrayType: Copy {}
impl<T: PartialEq, N> PartialEq for GenericArray<T, N> where N: ArrayLength<T> {
fn eq(&self, other: &Self) -> bool { **self == **other }
}
impl<T: Eq, N> Eq for GenericArray<T, N> where N: ArrayLength<T> {}
impl<T: Debug, N> Debug for GenericArray<T, N> where N: ArrayLength<T> {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { self[..].fmt(fmt) }
}