1pub mod data_stack;
2pub mod lifetime;
3pub mod managed;
4pub mod managed_box;
5pub mod shared;
6pub mod type_hash;
7
8pub trait Initialize: Sized {
9 fn initialize() -> Self;
10
11 unsafe fn initialize_raw(data: *mut ()) {
13 unsafe { data.cast::<Self>().write(Self::initialize()) };
14 }
15}
16
17impl<T> Initialize for T
18where
19 T: Default,
20{
21 fn initialize() -> Self {
22 Self::default()
23 }
24}
25
26pub trait Finalize: Sized {
27 unsafe fn finalize_raw(data: *mut ()) {
29 unsafe { data.cast::<Self>().read_unaligned() };
30 }
31}
32
33impl<T> Finalize for T {}
34
35#[inline]
36pub fn pointer_alignment_padding(pointer: *const u8, alignment: usize) -> usize {
37 let mut result = (pointer as usize) % alignment;
38 if result > 0 {
39 result = alignment - result;
40 }
41 result
42}
43
44pub unsafe fn non_zero_alloc(mut layout: std::alloc::Layout) -> *mut u8 {
46 unsafe {
47 if layout.size() == 0 {
48 layout = std::alloc::Layout::from_size_align_unchecked(1, layout.align());
49 }
50 let result = std::alloc::alloc(layout);
51 #[cfg(feature = "alloc-backtrace")]
52 println!(
53 "* Alloc {:p} ({:?}):\n{}",
54 result,
55 layout,
56 std::backtrace::Backtrace::force_capture()
57 );
58 result
59 }
60}
61
62pub unsafe fn non_zero_dealloc(ptr: *mut u8, mut layout: std::alloc::Layout) {
64 unsafe {
65 if layout.size() == 0 {
66 layout = std::alloc::Layout::from_size_align_unchecked(1, layout.align());
67 }
68 #[cfg(feature = "alloc-backtrace")]
69 println!(
70 "* Dealloc {:p} ({:?}):\n{}",
71 ptr,
72 layout,
73 std::backtrace::Backtrace::force_capture()
74 );
75 std::alloc::dealloc(ptr, layout);
76 }
77}
78
79pub unsafe fn non_zero_realloc(
81 ptr: *mut u8,
82 mut layout: std::alloc::Layout,
83 new_size: usize,
84) -> *mut u8 {
85 unsafe {
86 if layout.size() == 0 {
87 layout = std::alloc::Layout::from_size_align_unchecked(1, layout.align());
88 }
89 let result = std::alloc::realloc(ptr, layout, new_size);
90 #[cfg(feature = "alloc-backtrace")]
91 println!(
92 "* Realloc {:p} -> {:p} ({:?}):\n{}",
93 ptr,
94 result,
95 layout,
96 std::backtrace::Backtrace::force_capture()
97 );
98 result
99 }
100}
101
102pub unsafe fn non_zero_alloc_zeroed(mut layout: std::alloc::Layout) -> *mut u8 {
104 unsafe {
105 if layout.size() == 0 {
106 layout = std::alloc::Layout::from_size_align_unchecked(1, layout.align());
107 }
108 let result = std::alloc::alloc_zeroed(layout);
109 #[cfg(feature = "alloc-backtrace")]
110 println!(
111 "* Alloc zeroed {:p} ({:?}):\n{}",
112 result,
113 layout,
114 std::backtrace::Backtrace::force_capture()
115 );
116 result
117 }
118}
119
120#[macro_export]
121macro_rules! does_implement_trait {
122 ($trait:path => $identifier:ident < $type:ident >) => {
123 pub fn $identifier<$type>() -> bool {
124 struct ImplementsTrait<'a, $type> {
125 implements: &'a std::cell::Cell<bool>,
126 _marker: std::marker::PhantomData<$type>,
127 }
128
129 #[allow(clippy::non_canonical_clone_impl)]
130 impl<$type> Clone for ImplementsTrait<'_, $type> {
131 fn clone(&self) -> Self {
132 self.implements.set(false);
133 ImplementsTrait {
134 implements: self.implements,
135 _marker: std::marker::PhantomData,
136 }
137 }
138 }
139
140 impl<$type: $trait> Copy for ImplementsTrait<'_, $type> {}
141
142 let implements = std::cell::Cell::new(true);
143 let _ = [ImplementsTrait::<$type> {
144 implements: &implements,
145 _marker: std::marker::PhantomData,
146 }]
147 .clone();
148 implements.get()
149 }
150 };
151}
152
153does_implement_trait!(Send => is_send<T>);
154does_implement_trait!(Sync => is_sync<T>);
155does_implement_trait!(Copy => is_copy<T>);
156does_implement_trait!(Clone => is_clone<T>);
157does_implement_trait!(Sized => is_sized<T>);
158does_implement_trait!(Unpin => is_unpin<T>);
159does_implement_trait!(ToString => is_to_string<T>);
160
161#[cfg(test)]
162mod tests {
163 use super::*;
164 use std::{marker::PhantomPinned, rc::Rc};
165
166 struct Foo;
167
168 #[test]
169 fn test_does_implement_trait() {
170 assert!(is_send::<i32>());
171 assert!(!is_send::<Rc<i32>>());
172
173 assert!(is_sync::<i32>());
174 assert!(!is_sync::<Rc<i32>>());
175
176 assert!(is_copy::<i32>());
177 assert!(!is_copy::<Foo>());
178
179 assert!(is_clone::<i32>());
180 assert!(!is_clone::<Foo>());
181
182 assert!(is_sized::<[i32; 1]>());
183
184 assert!(is_unpin::<&i32>());
185 assert!(!is_unpin::<PhantomPinned>());
186
187 assert!(is_to_string::<i32>());
188 assert!(!is_to_string::<Foo>());
189 }
190}