1#![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)]
17#![warn(unused_import_braces)]
18#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
19#![cfg_attr(feature = "cargo-clippy", allow(clippy::new_without_default))]
20#![cfg_attr(
21 feature = "cargo-clippy",
22 warn(
23 clippy::float_arithmetic,
24 clippy::mut_mut,
25 clippy::nonminimal_bool,
26 clippy::map_unwrap_or,
27 clippy::print_stdout,
28 clippy::unicode_not_nfc,
29 clippy::use_self
30 )
31)]
32#![no_std]
33
34#[cfg(test)]
35extern crate alloc;
36
37#[macro_use]
38extern crate cranelift_entity as entity;
39use crate::entity::packed_option;
40
41use core::borrow::BorrowMut;
42use core::cmp::Ordering;
43
44mod map;
45mod node;
46mod path;
47mod pool;
48mod set;
49
50pub use self::map::{Map, MapCursor, MapForest, MapIter};
51pub use self::set::{Set, SetCursor, SetForest, SetIter};
52
53use self::node::NodeData;
54use self::path::Path;
55use self::pool::NodePool;
56
57const INNER_SIZE: usize = 8;
60
61const MAX_PATH: usize = 16;
65
66pub trait Comparator<K>
71where
72 K: Copy,
73{
74 fn cmp(&self, a: K, b: K) -> Ordering;
78
79 fn search(&self, k: K, s: &[K]) -> Result<usize, usize> {
86 s.binary_search_by(|x| self.cmp(*x, k))
87 }
88}
89
90impl<K> Comparator<K> for ()
92where
93 K: Copy + Ord,
94{
95 fn cmp(&self, a: K, b: K) -> Ordering {
96 a.cmp(&b)
97 }
98}
99
100trait Forest {
102 type Key: Copy;
104
105 type Value: Copy;
107
108 type LeafKeys: Copy + BorrowMut<[Self::Key]>;
110
111 type LeafValues: Copy + BorrowMut<[Self::Value]>;
113
114 fn splat_key(key: Self::Key) -> Self::LeafKeys;
116
117 fn splat_value(value: Self::Value) -> Self::LeafValues;
119}
120
121#[derive(Clone, Copy, PartialEq, Eq)]
123struct Node(u32);
124entity_impl!(Node, "node");
125
126#[derive(Clone, Copy)]
128struct SetValue();
129
130fn slice_insert<T: Copy>(s: &mut [T], i: usize, x: T) {
132 for j in (i + 1..s.len()).rev() {
133 s[j] = s[j - 1];
134 }
135 s[i] = x;
136}
137
138fn slice_shift<T: Copy>(s: &mut [T], n: usize) {
140 for j in 0..s.len() - n {
141 s[j] = s[j + n];
142 }
143}
144
145#[cfg(test)]
146mod tests {
147 use super::*;
148 use crate::entity::EntityRef;
149
150 #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
152 pub struct Block(u32);
153 entity_impl!(Block, "block");
154
155 #[test]
156 fn comparator() {
157 let block1 = Block::new(1);
158 let block2 = Block::new(2);
159 let block3 = Block::new(3);
160 let block4 = Block::new(4);
161 let vals = [block1, block2, block4];
162 let comp = ();
163 assert_eq!(comp.search(block1, &vals), Ok(0));
164 assert_eq!(comp.search(block3, &vals), Err(2));
165 assert_eq!(comp.search(block4, &vals), Ok(2));
166 }
167
168 #[test]
169 fn slice_insertion() {
170 let mut a = ['a', 'b', 'c', 'd'];
171
172 slice_insert(&mut a[0..1], 0, 'e');
173 assert_eq!(a, ['e', 'b', 'c', 'd']);
174
175 slice_insert(&mut a, 0, 'a');
176 assert_eq!(a, ['a', 'e', 'b', 'c']);
177
178 slice_insert(&mut a, 3, 'g');
179 assert_eq!(a, ['a', 'e', 'b', 'g']);
180
181 slice_insert(&mut a, 1, 'h');
182 assert_eq!(a, ['a', 'h', 'e', 'b']);
183 }
184
185 #[test]
186 fn slice_shifting() {
187 let mut a = ['a', 'b', 'c', 'd'];
188
189 slice_shift(&mut a[0..1], 1);
190 assert_eq!(a, ['a', 'b', 'c', 'd']);
191
192 slice_shift(&mut a[1..], 1);
193 assert_eq!(a, ['a', 'c', 'd', 'd']);
194
195 slice_shift(&mut a, 2);
196 assert_eq!(a, ['d', 'd', 'd', 'd']);
197 }
198}