Skip to main content

embed_collections/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![cfg_attr(docsrs, allow(unused_attributes))]
3#![cfg_attr(not(feature = "std"), no_std)]
4#![doc = include_str!("../README.md")]
5
6extern crate alloc;
7#[cfg(any(feature = "std", test))]
8extern crate std;
9
10use alloc::boxed::Box;
11use alloc::rc::Rc;
12use alloc::sync::Arc;
13use core::ptr::NonNull;
14
15/// Abstract pointer trait to support various pointer types in collections.
16///
17/// This trait allows the collections to work with:
18/// - `Box<T>`: Owned, automatically dropped.
19/// - `Arc<T>`: Shared ownership.
20/// - `Rc<T>`: Single thread ownership.
21/// - `NonNull<T>`: Raw non-null pointers (manual memory management).
22/// - `*const T`: Raw pointers (recommend to use `NonNull<T>` instead)
23pub trait Pointer: Sized {
24    type Target;
25
26    fn as_ref(&self) -> &Self::Target;
27
28    #[inline(always)]
29    fn as_ptr(&self) -> *const Self::Target {
30        self.as_ref() as *const Self::Target
31    }
32
33    #[allow(clippy::missing_safety_doc)]
34    unsafe fn from_raw(p: *const Self::Target) -> Self;
35
36    fn into_raw(self) -> *const Self::Target;
37}
38
39pub trait SmartPointer: Pointer {
40    fn new(t: Self::Target) -> Self;
41}
42
43#[allow(clippy::unnecessary_cast)]
44impl<T> Pointer for *const T {
45    type Target = T;
46
47    #[inline]
48    fn as_ref(&self) -> &Self::Target {
49        unsafe { &**self }
50    }
51
52    #[inline]
53    unsafe fn from_raw(p: *const Self::Target) -> Self {
54        p as *const T
55    }
56
57    #[inline]
58    fn into_raw(self) -> *const Self::Target {
59        self as *const T
60    }
61}
62
63#[allow(clippy::unnecessary_cast)]
64impl<T> Pointer for *mut T {
65    type Target = T;
66
67    #[inline]
68    fn as_ref(&self) -> &Self::Target {
69        unsafe { &**self }
70    }
71
72    #[inline]
73    unsafe fn from_raw(p: *const Self::Target) -> Self {
74        p as *mut T
75    }
76
77    #[inline]
78    fn into_raw(self) -> *const Self::Target {
79        self as *mut T
80    }
81}
82
83impl<T> Pointer for NonNull<T> {
84    type Target = T;
85
86    #[inline]
87    fn as_ref(&self) -> &Self::Target {
88        unsafe { self.as_ref() }
89    }
90
91    #[inline]
92    unsafe fn from_raw(p: *const Self::Target) -> Self {
93        unsafe { NonNull::new_unchecked(p as *mut T) }
94    }
95
96    #[inline]
97    fn into_raw(self) -> *const Self::Target {
98        self.as_ptr()
99    }
100}
101
102impl<T> Pointer for Box<T> {
103    type Target = T;
104
105    #[inline]
106    fn as_ref(&self) -> &Self::Target {
107        self
108    }
109
110    #[inline]
111    unsafe fn from_raw(p: *const Self::Target) -> Self {
112        unsafe { Box::from_raw(p as *mut T) }
113    }
114
115    #[inline]
116    fn into_raw(self) -> *const Self::Target {
117        Box::into_raw(self)
118    }
119}
120
121impl<T> SmartPointer for Box<T> {
122    #[inline]
123    fn new(inner: T) -> Self {
124        Box::new(inner)
125    }
126}
127
128impl<T> Pointer for Rc<T> {
129    type Target = T;
130
131    #[inline]
132    fn as_ref(&self) -> &Self::Target {
133        self
134    }
135
136    #[inline]
137    unsafe fn from_raw(p: *const Self::Target) -> Self {
138        unsafe { Rc::from_raw(p) }
139    }
140
141    #[inline]
142    fn into_raw(self) -> *const Self::Target {
143        Rc::into_raw(self)
144    }
145}
146
147impl<T> SmartPointer for Rc<T> {
148    #[inline]
149    fn new(inner: T) -> Self {
150        Rc::new(inner)
151    }
152}
153
154impl<T> Pointer for Arc<T> {
155    type Target = T;
156
157    #[inline]
158    fn as_ref(&self) -> &Self::Target {
159        self
160    }
161
162    #[inline]
163    unsafe fn from_raw(p: *const Self::Target) -> Self {
164        unsafe { Arc::from_raw(p) }
165    }
166
167    #[inline]
168    fn into_raw(self) -> *const Self::Target {
169        Arc::into_raw(self)
170    }
171}
172
173impl<T> SmartPointer for Arc<T> {
174    #[inline]
175    fn new(inner: T) -> Self {
176        Arc::new(inner)
177    }
178}
179
180impl<T> Pointer for &T {
181    type Target = T;
182
183    #[inline]
184    fn as_ref(&self) -> &Self::Target {
185        self
186    }
187
188    #[inline]
189    unsafe fn from_raw(p: *const Self::Target) -> Self {
190        unsafe { &*p }
191    }
192
193    #[inline]
194    fn into_raw(self) -> *const Self::Target {
195        self as *const T
196    }
197}
198
199#[cfg(feature = "avl")]
200pub mod avl;
201pub mod const_vec;
202pub use const_vec::ConstVec;
203#[cfg(feature = "dlist")]
204pub mod dlist;
205pub mod seg_list;
206pub use seg_list::SegList;
207#[cfg(feature = "slist")]
208pub mod slist;
209#[cfg(feature = "slist")]
210pub mod slist_owned;
211pub mod various;
212pub use various::Various;
213#[cfg(feature = "btree")]
214pub mod btree;
215#[cfg(feature = "btree")]
216pub use btree::BTreeMap;
217
218#[cfg(test)]
219pub mod test;
220
221/// Cache line size in bytes
222#[cfg(any(
223    target_arch = "x86_64",
224    target_arch = "aarch64",
225    target_arch = "arm64ec",
226    target_arch = "powerpc64",
227))]
228pub const CACHE_LINE_SIZE: usize = 64;
229#[cfg(not(any(
230    target_arch = "x86_64",
231    target_arch = "aarch64",
232    target_arch = "arm64ec",
233    target_arch = "powerpc64",
234)))]
235pub const CACHE_LINE_SIZE: usize = 32;
236
237/// logging macro for development
238#[macro_export(local_inner_macros)]
239macro_rules! trace_log {
240    ($($arg:tt)+)=>{
241        #[cfg(feature="trace_log")]
242        {
243            log::debug!($($arg)+);
244        }
245    };
246}
247
248/// logging macro for development
249#[macro_export(local_inner_macros)]
250macro_rules! print_log {
251    ($($arg:tt)+)=>{
252        #[cfg(feature="trace_log")]
253        {
254            log::debug!($($arg)+);
255        }
256        #[cfg(not(feature="trace_log"))]
257        {
258            std::println!($($arg)+);
259        }
260    };
261}