precomputed_map/
store.rs

1use core::marker::PhantomData;
2use crate::equivalent::Comparable;
3
4pub trait AsData {
5    type Data: ?Sized;
6    
7    fn as_data() -> &'static Self::Data;
8}
9
10pub trait AccessSeq {
11    type Item;
12    const LEN: usize;
13
14    fn index(index: usize) -> Option<Self::Item>;
15}
16
17pub trait Searchable: MapStore {
18    fn search<Q>(query: &Q) -> Option<usize>
19    where
20        Q: Comparable<Self::Key> + ?Sized;
21}
22
23pub trait MapStore {
24    type Key;
25    type Value;
26
27    const LEN: usize;
28
29    fn get_key(index: usize) -> Option<Self::Key>;
30    fn get_value(index: usize) -> Option<Self::Value>;    
31}
32
33pub struct SliceData<
34    const O: usize,
35    const L: usize,
36    D
37>(PhantomData<([u8; O], [u8; L], D)>);
38
39impl<
40    const B: usize,
41    const O: usize,
42    const L: usize,
43    D: AsData<Data = [u8; B]>
44> AsData for SliceData<O, L, D> {
45    type Data = [u8; L];
46
47    #[inline(always)]
48    fn as_data() -> &'static Self::Data {
49        D::as_data()[O..][..L].try_into().unwrap()
50    }
51}
52
53impl<const B: usize, D> AccessSeq for D
54where
55    D: AsData<Data = [u8; B]>
56{
57    type Item = u8;
58    const LEN: usize = B;
59
60    #[inline(always)]
61    fn index(index: usize) -> Option<Self::Item> {
62        D::as_data().get(index).copied()
63    }
64}
65
66impl<K> MapStore for K
67where
68    K: AccessSeq
69{
70    type Key = K::Item;
71    type Value = usize;
72
73    const LEN: usize = K::LEN;
74
75    #[inline(always)]
76    fn get_key(index: usize) -> Option<Self::Key> {
77        K::index(index)
78    }
79
80    #[inline(always)]
81    fn get_value(index: usize) -> Option<Self::Value> {
82        debug_assert!(index < Self::LEN);
83        
84        Some(index)
85    }
86}
87
88impl<K, V> MapStore for (K, V)
89where
90    K: AccessSeq,
91    V: AccessSeq
92{
93    type Key = K::Item;
94    type Value = V::Item;
95
96    const LEN: usize = {
97        if K::LEN != V::LEN {
98            panic!();
99        }
100
101        K::LEN
102    };
103
104    #[inline(always)]
105    fn get_key(index: usize) -> Option<Self::Key> {
106        K::index(index)
107    }
108
109    #[inline(always)]
110    fn get_value(index: usize) -> Option<Self::Value> {
111        V::index(index)
112    }
113}
114
115impl<K, V> Searchable for (K, V)
116where
117    K: Searchable + AccessSeq,
118    K: MapStore<Key = K::Item>,
119    V: AccessSeq,
120{
121    fn search<Q>(query: &Q) -> Option<usize>
122    where
123        Q: Comparable<K::Item> + ?Sized
124    {
125        K::search(query)
126    }
127}
128
129pub struct MapIter<'iter, D> {
130    next: usize,
131    _phantom: PhantomData<&'iter D>
132}
133
134impl<'iter, D> MapIter<'iter, D> {
135    pub(super) const fn new() -> Self {
136        MapIter { next: 0, _phantom: PhantomData }
137    }
138}
139
140impl<'iter, D> Iterator for MapIter<'iter, D>
141where
142    D: MapStore
143{
144    type Item = (D::Key, D::Value);
145
146    fn next(&mut self) -> Option<Self::Item> {
147        if self.next < D::LEN {
148            let k = D::get_key(self.next)?;
149            let v = D::get_value(self.next)?;
150            self.next += 1;
151            Some((k, v))
152        } else {
153            None
154        }
155    }
156}
157
158impl<'iter, D> ExactSizeIterator for MapIter<'iter, D>
159where
160    D: MapStore
161{
162    fn len(&self) -> usize {
163        D::LEN
164    }
165}
166
167impl<'iter, D> Clone for MapIter<'iter, D> {
168    #[inline]
169    fn clone(&self) -> Self {
170        MapIter {
171            next: self.next,
172            _phantom: PhantomData
173        }
174    }
175}