zone_alloc/
lib.rs

1//! Data types for zone-based (also known as region-based or arena-based) data allocation.
2//!
3//! # Examples
4//!
5//! ## Linked List Nodes with [`Arena<T>`]
6//! ```
7//! use zone_alloc::Arena;
8//!
9//! #[derive(Debug, PartialEq, Eq)]
10//! struct Node<'a, T> {
11//!     parent: Option<&'a Node<'a, T>>,
12//!     value: T,
13//! }
14//!
15//! impl<'a, T> Node<'a, T> {
16//!     pub fn new(parent: Option<&'a Node<'a, T>>, value: T) -> Self {
17//!         Self { parent, value }
18//!     }
19//! }
20//!
21//! fn main() {
22//!     let arena = Arena::new();
23//!     let node = arena.alloc(Node::new(None, 1));
24//!     let node = arena.alloc(Node::new(Some(node), 2));
25//!     let node = arena.alloc(Node::new(Some(node), 3));
26//!
27//!     assert_eq!(node.value, 3);
28//!     assert_eq!(node.parent.unwrap().value, 2);
29//!     assert_eq!(node.parent.unwrap().parent.unwrap().value, 1);
30//!     assert_eq!(node.parent.unwrap().parent.unwrap().parent, None);
31//! }
32//! ```
33//!
34//! ## Circular References with [`Registry<T>`]
35//! ```
36//! use zone_alloc::{
37//!     Handle,
38//!     Registry,
39//! };
40//!
41//! #[derive(Debug, PartialEq, Eq)]
42//! struct Node<T> {
43//!     parent: Option<Handle>,
44//!     value: T,
45//! }
46//!
47//! impl<T> Node<T> {
48//!     pub fn new(parent: Option<Handle>, value: T) -> Self {
49//!         Self { parent, value }
50//!     }
51//! }
52//!
53//! fn main() {
54//!     let registry = Registry::new();
55//!     let root_handle = registry.register(Node::new(None, "first"));
56//!     let handle = registry.register(Node::new(Some(root_handle), "second"));
57//!     let handle = registry.register(Node::new(Some(handle), "third"));
58//!     registry.get_mut_unchecked(root_handle).parent = Some(handle);
59//!
60//!     let node = registry.get(handle).unwrap();
61//!     assert_eq!(node.value, "third");
62//!     let node = registry.get(node.parent.unwrap()).unwrap();
63//!     assert_eq!(node.value, "second");
64//!     let node = registry.get(node.parent.unwrap()).unwrap();
65//!     assert_eq!(node.value, "first");
66//!     let node = registry.get(node.parent.unwrap()).unwrap();
67//!     assert_eq!(node.value, "third");
68//! }
69//! ```
70//!
71//! ## Circular References with [`KeyedRegistry<T>`]
72//! ```
73//! #[cfg(not(feature = "std"))]
74//! extern crate alloc;
75//!
76//! #[cfg(not(feature = "std"))]
77//! use alloc::borrow::ToOwned;
78//!
79//! use zone_alloc::KeyedRegistry;
80//!
81//! #[derive(Debug, PartialEq, Eq)]
82//! struct Node<K, V> {
83//!     parent: Option<K>,
84//!     value: V,
85//! }
86//!
87//! impl<K, V> Node<K, V> {
88//!     pub fn new(parent: Option<K>, value: V) -> Self {
89//!         Self { parent, value }
90//!     }
91//! }
92//!
93//! fn main() {
94//!     let registry = KeyedRegistry::new();
95//!     registry.register("node-1".to_owned(), Node::new(None, "first"));
96//!     registry.register(
97//!         "node-2".to_owned(),
98//!         Node::new(Some("node-1".to_owned()), "second"),
99//!     );
100//!     registry.register(
101//!         "node-3".to_owned(),
102//!         Node::new(Some("node-2".to_owned()), "third"),
103//!     );
104//!     registry.get_mut_unchecked("node-1").parent = Some("node-3".to_owned());
105//!
106//!     let node = registry.get("node-3").unwrap();
107//!     assert_eq!(node.value, "third");
108//!     let node = registry.get(node.parent.as_ref().unwrap()).unwrap();
109//!     assert_eq!(node.value, "second");
110//!     let node = registry.get(node.parent.as_ref().unwrap()).unwrap();
111//!     assert_eq!(node.value, "first");
112//!     let node = registry.get(node.parent.as_ref().unwrap()).unwrap();
113//!     assert_eq!(node.value, "third");
114//! }
115//! ```
116//!
117//! ## Runtime Borrow Checking
118//! ```
119//! use zone_alloc::{
120//!     BorrowError,
121//!     Registry,
122//! };
123//!
124//! fn main() {
125//!     let registry = Registry::new();
126//!     registry.register_extend(100..200);
127//!
128//!     // Multiple immutable borrows on the same element.
129//!     let borrow_1 = registry.get(16);
130//!     let borrow_2 = registry.get(16);
131//!     let borrow_3 = registry.get(16);
132//!     assert!(borrow_1.as_ref().is_ok_and(|i| i.eq(&116)));
133//!     assert!(borrow_2.as_ref().is_ok_and(|i| i.eq(&116)));
134//!     assert!(borrow_3.as_ref().is_ok_and(|i| i.eq(&116)));
135//!
136//!     // Mutable borrow fails.
137//!     assert_eq!(
138//!         registry.get_mut(16).err(),
139//!         Some(BorrowError::AlreadyBorrowed)
140//!     );
141//!
142//!     // Another element can be borrowed independently.
143//!     let borrow_4 = registry.get(32);
144//!     assert!(borrow_4.as_ref().is_ok_and(|i| i.eq(&132)));
145//!     assert!(borrow_1.as_ref().is_ok_and(|i| i.eq(&116)));
146//!
147//!     // Only one mutable borrow allowed.
148//!     let mut borrow_5 = registry.get_mut(64).unwrap();
149//!     assert!(borrow_5.eq(&164));
150//!     *borrow_5 *= 2;
151//!     assert!(borrow_5.eq(&328));
152//!     assert_eq!(
153//!         registry.get_mut(64).err(),
154//!         Some(BorrowError::AlreadyBorrowed)
155//!     );
156//!     assert_eq!(registry.get(64).err(), Some(BorrowError::AlreadyBorrowed));
157//!
158//!     // Refetch to show updated value, and show that previous borrows are still valid.
159//!     drop(borrow_5);
160//!     let borrow_5 = registry.get(64);
161//!     assert!(borrow_5.as_ref().is_ok_and(|i| i.eq(&328)));
162//!     assert!(borrow_4.as_ref().is_ok_and(|i| i.eq(&132)));
163//!     assert!(borrow_1.as_ref().is_ok_and(|i| i.eq(&116)));
164//! }
165//! ```
166#![cfg_attr(not(feature = "std"), no_std)]
167#![feature(dropck_eyepatch)]
168#![feature(sync_unsafe_cell)]
169#![feature(trait_alias)]
170
171pub mod arena;
172mod base_registry;
173mod borrow_error;
174pub mod element;
175pub mod keyed_registry;
176pub mod registry;
177mod registry_container;
178pub mod strong_registry;
179
180pub use arena::Arena;
181pub use borrow_error::BorrowError;
182pub use element::{
183    ElementRef,
184    ElementRefMut,
185};
186pub use keyed_registry::KeyedRegistry;
187pub use registry::{
188    Handle,
189    Registry,
190};
191pub use registry_container::Key;
192pub use strong_registry::{
193    StrongHandle,
194    StrongRegistry,
195};