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