1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
use std::ops::{Index, IndexMut, Deref, DerefMut, Range, RangeFrom, RangeTo, RangeFull}; use std::mem::{MaybeUninit, transmute}; use std::hash::Hash; use std::fmt::Debug; pub unsafe trait Array: Sized { type Item; type Index: ArrayIndex; fn len() -> usize; fn as_ptr(&self) -> *const Self::Item; fn as_mut_ptr(&mut self) -> *mut Self::Item; fn as_uninit(this: &MaybeUninit<Self>) -> &[MaybeUninit<Self::Item>]; fn as_uninit_mut(this: &mut MaybeUninit<Self>) -> &mut [MaybeUninit<Self::Item>]; } pub trait ArrayIndex: Sized + Copy + Clone + Default + Hash + Debug + PartialEq + Eq + PartialOrd + Ord { fn to_usize(self) -> usize; fn from_usize(u: usize) -> Self; } impl ArrayIndex for u8 { #[inline] fn to_usize(self) -> usize { self as usize } #[inline] fn from_usize(u: usize) -> Self { u as Self } } impl ArrayIndex for u16 { #[inline] fn to_usize(self) -> usize { self as usize } #[inline] fn from_usize(u: usize) -> Self { u as Self } } impl ArrayIndex for u32 { #[inline] fn to_usize(self) -> usize { self as usize } #[inline] fn from_usize(u: usize) -> Self { u as Self } } pub trait Addressable<T>: Index<usize, Output=T> + IndexMut<usize> + Index<Range<usize>, Output=[<Self as Index<usize>>::Output]> + IndexMut<Range<usize>> + Index<RangeFrom<usize>, Output=[<Self as Index<usize>>::Output]> + IndexMut<RangeFrom<usize>> + Index<RangeTo<usize>, Output=[<Self as Index<usize>>::Output]> + IndexMut<RangeTo<usize>> + Index<RangeFull, Output=[<Self as Index<usize>>::Output]> + IndexMut<RangeFull> + Deref<Target=[<Self as Index<usize>>::Output]> + DerefMut where <Self as Index<usize>>::Output: Sized { } impl<T, U> Addressable<U> for T where T: Index<usize, Output=U> + IndexMut<usize> + Index<Range<usize>, Output=[<T as Index<usize>>::Output]> + IndexMut<Range<usize>> + Index<RangeFrom<usize>, Output=[<T as Index<usize>>::Output]> + IndexMut<RangeFrom<usize>> + Index<RangeTo<usize>, Output=[<T as Index<usize>>::Output]> + IndexMut<RangeTo<usize>> + Index<RangeFull, Output=[<T as Index<usize>>::Output]> + IndexMut<RangeFull> + Deref<Target=[<T as Index<usize>>::Output]> + DerefMut, <T as Index<usize>>::Output: Sized { } macro_rules! array_impl { ($i:ty => $t:expr) => { unsafe impl<T> Array for [T; $t] { type Item = T; type Index = $i; fn len() -> usize { $t } fn as_ptr(&self) -> *const Self::Item { self[..].as_ptr() } fn as_mut_ptr(&mut self) -> *mut Self::Item { self[..].as_mut_ptr() } fn as_uninit(this: &MaybeUninit<Self>) -> &[MaybeUninit<Self::Item>] { unsafe { &transmute::<_, &[MaybeUninit<T>; $t]>(this)[..] } } fn as_uninit_mut(this: &mut MaybeUninit<Self>) -> &mut [MaybeUninit<Self::Item>] { unsafe { &mut transmute::<_, &mut [MaybeUninit<T>; $t]>(this)[..] } } } }; ($i:ty => $($t:expr),+) => { $( array_impl!($i => $t); )+ }; } array_impl!(u8 => 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 0x40, 0x80 ); array_impl!(u16 => 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000 ); array_impl!(u32 => 0x10000, 0x20000, 0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000 );