stack/
array.rs

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);