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