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