zone_alloc/
strong_registry.rs1#[cfg(not(feature = "std"))]
2extern crate alloc;
3
4#[cfg(feature = "std")]
5extern crate core;
6
7#[cfg(not(feature = "std"))]
8use alloc::vec::Vec;
9use core::marker::PhantomData;
10
11use crate::{
12 BorrowError,
13 ElementRef,
14 ElementRefMut,
15 Handle,
16 Registry,
17};
18
19pub trait StrongHandle: From<Handle> {
25 fn handle(&self) -> Handle;
27}
28
29#[derive(Default)]
34pub struct StrongRegistry<H, T> {
35 registry: Registry<T>,
36 phantom_handle: PhantomData<H>,
37}
38
39impl<H, T> StrongRegistry<H, T>
40where
41 H: StrongHandle,
42{
43 pub fn new() -> Self {
45 Self {
46 registry: Registry::new(),
47 phantom_handle: PhantomData,
48 }
49 }
50
51 pub fn with_capacity(size: usize) -> Self {
53 Self {
54 registry: Registry::with_capacity(size),
55 phantom_handle: PhantomData,
56 }
57 }
58
59 pub fn is_empty(&self) -> bool {
61 self.registry.is_empty()
62 }
63
64 pub fn len(&self) -> usize {
66 self.registry.len()
67 }
68
69 pub fn register(&self, value: T) -> H {
71 H::from(self.registry.register(value))
72 }
73
74 pub fn register_extend<I>(&self, iterable: I) -> (H, H)
79 where
80 I: IntoIterator<Item = T>,
81 {
82 let (a, b) = self.registry.register_extend(iterable);
83 (H::from(a), H::from(b))
84 }
85
86 pub fn reserve(&self, additional: usize) {
88 self.registry.reserve(additional)
89 }
90
91 pub fn into_vec(self) -> Vec<T> {
95 self.registry.into_vec()
96 }
97
98 pub fn iter(&self) -> impl Iterator<Item = Result<ElementRef<T>, BorrowError>> {
101 self.registry.iter()
102 }
103
104 pub fn iter_mut(&mut self) -> impl Iterator<Item = Result<ElementRefMut<T>, BorrowError>> {
107 self.registry.iter_mut()
108 }
109
110 pub fn get_unchecked(&self, handle: H) -> ElementRef<T> {
114 self.registry.get_unchecked(handle.handle())
115 }
116
117 pub fn get(&self, handle: H) -> Result<ElementRef<T>, BorrowError> {
119 self.registry.get(handle.handle())
120 }
121
122 pub fn get_mut_unchecked(&self, handle: H) -> ElementRefMut<T> {
126 self.registry.get_mut_unchecked(handle.handle())
127 }
128
129 pub fn get_mut(&self, handle: H) -> Result<ElementRefMut<T>, BorrowError> {
131 self.registry.get_mut(handle.handle())
132 }
133
134 pub fn safe_to_drop(&mut self) -> bool {
138 self.registry.safe_to_drop()
139 }
140}
141
142#[cfg(test)]
143mod strong_registry_test {
144 use core::cell::Cell;
145
146 use crate::{
147 Handle,
148 StrongHandle,
149 StrongRegistry,
150 };
151
152 struct DropCounter<'c>(&'c Cell<u32>);
154
155 impl<'c> Drop for DropCounter<'c> {
156 fn drop(&mut self) {
157 self.0.set(self.0.get() + 1);
158 }
159 }
160
161 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
162 struct NodeHandle(Handle);
163
164 impl From<Handle> for NodeHandle {
165 fn from(value: Handle) -> Self {
166 Self(value)
167 }
168 }
169
170 impl StrongHandle for NodeHandle {
171 fn handle(&self) -> Handle {
172 self.0
173 }
174 }
175
176 struct Node<'d, T> {
180 parent: Option<NodeHandle>,
181 value: T,
182 #[allow(dead_code)]
183 drop_counter: DropCounter<'d>,
184 }
185
186 impl<'a, 'd, T> Node<'d, T> {
187 pub fn new(parent: Option<NodeHandle>, value: T, drop_counter: DropCounter<'d>) -> Self {
188 Self {
189 parent,
190 value,
191 drop_counter,
192 }
193 }
194 }
195
196 #[test]
197 fn works_exactly_like_registry() {
198 let drop_counter = Cell::new(0);
199 {
200 let registry = StrongRegistry::with_capacity(2);
201 assert!(registry.is_empty());
202
203 let mut handle = registry.register(Node::new(None, 1, DropCounter(&drop_counter)));
205 assert_eq!(registry.len(), 1);
206 assert!(!registry.is_empty());
207 handle = registry.register(Node::new(Some(handle), 2, DropCounter(&drop_counter)));
208 assert_eq!(registry.len(), 2);
209 handle = registry.register(Node::new(Some(handle), 3, DropCounter(&drop_counter)));
210 assert_eq!(registry.len(), 3);
211 handle = registry.register(Node::new(Some(handle), 4, DropCounter(&drop_counter)));
212 assert_eq!(registry.len(), 4);
213
214 let mut node = registry.get(handle).unwrap();
215 assert_eq!(node.value, 4);
216 node = registry.get(node.parent.unwrap()).unwrap();
217 assert_eq!(node.value, 3);
218 node = registry.get(node.parent.unwrap()).unwrap();
219 assert_eq!(node.value, 2);
220 node = registry.get(node.parent.unwrap()).unwrap();
221 assert_eq!(node.value, 1);
222 assert_eq!(node.parent, None);
223 assert_eq!(drop_counter.get(), 0);
224 }
225 assert_eq!(drop_counter.get(), 4);
227 }
228}