1pub unsafe trait Ointer<const N: usize> {
2 type Pointer;
3 const LOW_MASK: usize = { !0usize >> N };
4 const HIGH_MASK: usize = { !Self::LOW_MASK };
5 const MIN_SIGNED: isize = { isize::MIN >> Self::SHIFT_BITS };
6 const MAX_SIGNED: isize = { isize::MAX >> Self::SHIFT_BITS };
7 const SHIFT_BITS: usize = {
8 if cfg!(target_pointer_width = "128") {
9 128 - N
10 } else if cfg!(target_pointer_width = "64") {
11 64 - N
12 } else if cfg!(target_pointer_width = "32") {
13 32 - N
14 } else if cfg!(target_pointer_width = "16") {
15 16 - N
16 } else {
17 panic!("Unsupported target pointer width")
18 }
19 };
20 #[inline(always)]
22 fn get_bool(&self) -> bool {
23 self.get_usize() != 0
24 }
25 #[inline(always)]
27 fn get_isize(&self) -> isize {
28 unsafe { *(self as *const Self as *const isize) >> Self::SHIFT_BITS }
29 }
30 #[inline(always)]
32 fn get_usize(&self) -> usize {
33 unsafe { *(self as *const Self as *const usize) >> Self::SHIFT_BITS }
34 }
35 #[inline(always)]
37 fn get_ptr_as_usize(&self) -> usize {
38 unsafe { *(self as *const Self as *const usize) & Self::LOW_MASK }
39 }
40 #[inline(always)]
42 fn set_bool(&mut self, b: bool) {
43 self.set_isize(if b { -1 } else { 0 })
44 }
45 #[inline(always)]
47 fn set_isize(&mut self, i: isize) {
48 if i < Self::MIN_SIGNED || i > Self::MAX_SIGNED {
49 panic!("No enough bits to be stolen.")
50 }
51 let p = self as *mut Self as *mut usize;
52 unsafe {
53 *p = (*p & Self::LOW_MASK) | ((i as usize) << Self::SHIFT_BITS);
54 }
55 }
56 #[inline(always)]
58 fn set_usize(&mut self, u: usize) {
59 if (u >> N) != 0 {
60 panic!("No enough bits to be stolen.")
61 }
62 let p = self as *mut Self as *mut usize;
63 unsafe {
64 *p = (*p & Self::LOW_MASK) | (u << Self::SHIFT_BITS);
65 }
66 }
67 #[inline(always)]
69 fn set_ptr(&mut self, p: &mut Self::Pointer) {
70 let u = unsafe { *(p as *mut Self::Pointer as *mut usize) };
71 unsafe {
72 *(self as *mut Self as *mut usize) = u;
73 }
74 self.assert_stealable();
75 }
76 #[inline(always)]
78 fn assert_stealable(&self) {
79 assert_eq!(self.get_bool(), false);
80 }
81 #[inline(always)]
83 fn get<T: Copy>(&self) -> T
84 where
85 Self: OinterGet<T, N>,
86 {
87 self.get_high_bits()
88 }
89 #[inline(always)]
91 fn set_mut<T: Copy>(&mut self, x: T)
92 where
93 Self: OinterSet<T, N>,
94 {
95 self.set_high_bits_mut(x);
96 }
97 #[inline(always)]
99 fn map<T: Copy, R, F: FnOnce(T, &Self::Pointer) -> R>(&self, f: F) -> R
100 where
101 Self: OinterGet<T, N>,
102 {
103 let x = self.get_high_bits();
104 let u = self.get_ptr_as_usize();
105 let p = unsafe { &*(&u as *const usize as *const Self::Pointer) };
106 f(x, p)
107 }
108 #[inline(always)]
110 fn map_mut<T: Copy, R, F: FnOnce(&mut T, &mut Self::Pointer) -> R>(&mut self, f: F) -> R
111 where
112 Self: OinterGet<T, N> + OinterSet<T, N>,
113 {
114 let mut x = self.get_high_bits();
115 let mut u = self.get_ptr_as_usize();
116 let p = unsafe { &mut *(&mut u as *mut usize as *mut Self::Pointer) };
117 let ret = f(&mut x, p);
118 self.set_ptr(p);
119 self.set_high_bits_mut(x);
120 ret
121 }
122}
123
124pub unsafe trait OinterGet<T: Copy, const N: usize>: Ointer<N> {
125 #[inline(always)]
127 fn get_high_bits(&self) -> T {
128 use core::mem::size_of;
129 let u = self.get_usize();
130 let x = if size_of::<T>() == 8 {
131 unsafe { *(&(u as u64) as *const u64 as *const T) }
132 } else if size_of::<T>() == 4 {
133 unsafe { *(&(u as u32) as *const u32 as *const T) }
134 } else if size_of::<T>() == 2 {
135 unsafe { *(&(u as u16) as *const u16 as *const T) }
136 } else if size_of::<T>() == 1 {
137 unsafe { *(&(u as u8) as *const u8 as *const T) }
138 } else {
139 panic!("Unsupported value size")
140 };
141 x
142 }
143}
144
145pub unsafe trait OinterSet<T: Copy, const N: usize>: Ointer<N> {
146 #[inline(always)]
148 fn set_high_bits_mut(&mut self, x: T) {
149 use core::mem::size_of;
150 let u: usize = if size_of::<T>() == 8 {
151 unsafe { *(&x as *const T as *const u64) }
152 .try_into()
153 .unwrap()
154 } else if size_of::<T>() == 4 {
155 unsafe { *(&x as *const T as *const u32) }
156 .try_into()
157 .unwrap()
158 } else if size_of::<T>() == 2 {
159 unsafe { *(&x as *const T as *const u16) }
160 .try_into()
161 .unwrap()
162 } else if size_of::<T>() == 1 {
163 unsafe { *(&x as *const T as *const u8) }
164 .try_into()
165 .unwrap()
166 } else {
167 panic!("Unsupported value size")
168 };
169 self.set_usize(u);
170 }
171}
172
173unsafe impl<const N: usize, T: Copy, Ty: Ointer<N>> OinterGet<T, N> for Ty {}
174unsafe impl<const N: usize, T: Copy, Ty: Ointer<N>> OinterSet<T, N> for Ty {}
175
176#[macro_export]
178macro_rules! define_ointer {
179 ($ointer:ident, $pointer:ident, $bits:literal) => {
180 #[repr(transparent)]
181 pub struct $ointer<T: ?Sized>($pointer<T>);
182
183 unsafe impl<T: ?Sized> Ointer<$bits> for $ointer<T> {
184 type Pointer = $pointer<T>;
185 }
186
187 impl<T: ?Sized> core::convert::From<$pointer<T>> for $ointer<T> {
188 fn from(p: $pointer<T>) -> Self {
189 let s = Self(p);
190 s.assert_stealable();
191 s
192 }
193 }
194
195 impl<T> core::default::Default for $ointer<T>
196 where
197 Self: Ointer<$bits, Pointer = $pointer<T>>,
198 <Self as Ointer<$bits>>::Pointer: core::default::Default,
199 {
200 fn default() -> Self {
201 $pointer::default().into()
202 }
203 }
204
205 impl<T: ?Sized> core::clone::Clone for $ointer<T>
206 where
207 Self: Ointer<$bits, Pointer = $pointer<T>>,
208 <Self as Ointer<$bits>>::Pointer: Clone,
209 {
210 fn clone(&self) -> Self {
211 self.map(|u: usize, p| {
212 let mut o = Self(p.clone());
213 o.set_usize(u);
214 o
215 })
216 }
217 }
218
219 impl<T: ?Sized> core::fmt::Debug for $ointer<T>
220 where
221 Self: Ointer<$bits, Pointer = $pointer<T>>,
222 <Self as Ointer<$bits>>::Pointer: core::fmt::Debug,
223 {
224 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
225 self.map(|u: usize, p| (u, p).fmt(f))
226 }
227 }
228
229 impl<T: ?Sized> core::ops::Drop for $ointer<T>
230 where
231 Self: Ointer<$bits>,
232 {
233 fn drop(&mut self) {
234 self.set_bool(false);
235 }
236 }
237
238 impl<T: ?Sized> core::hash::Hash for $ointer<T>
239 where
240 Self: Ointer<$bits, Pointer = $pointer<T>>,
241 <Self as Ointer<$bits>>::Pointer: core::hash::Hash,
242 {
243 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
244 self.map(|u: usize, p| (u, p).hash(state))
245 }
246 }
247
248 impl<T: ?Sized> core::cmp::PartialEq for $ointer<T>
249 where
250 Self: Ointer<$bits, Pointer = $pointer<T>>,
251 <Self as Ointer<$bits>>::Pointer: core::cmp::PartialEq,
252 {
253 fn eq(&self, rhs: &Self) -> bool {
254 self.map(|u: usize, p| rhs.map(|c, q| (u, p).eq(&(c, q))))
255 }
256 }
257
258 impl<T: ?Sized> core::cmp::PartialOrd for $ointer<T>
259 where
260 Self: Ointer<$bits, Pointer = $pointer<T>>,
261 <Self as Ointer<$bits>>::Pointer: core::cmp::PartialOrd,
262 {
263 fn partial_cmp(&self, rhs: &Self) -> Option<core::cmp::Ordering> {
264 self.map(|u: usize, p| rhs.map(|c, q| (u, p).partial_cmp(&(c, q))))
265 }
266 }
267
268 impl<T: ?Sized> core::ops::Deref for $ointer<T>
269 where
270 Self: Ointer<$bits, Pointer = $pointer<T>>,
271 <Self as Ointer<$bits>>::Pointer: core::ops::Deref<Target = T>,
272 {
273 type Target = T;
274 fn deref(&self) -> &T {
275 self.map(|_: usize, p| unsafe { &*(p.deref() as *const T) })
276 }
277 }
278
279 impl<T: ?Sized> core::ops::DerefMut for $ointer<T>
280 where
281 Self: Ointer<$bits, Pointer = $pointer<T>>,
282 <Self as Ointer<$bits>>::Pointer: core::ops::DerefMut<Target = T>,
283 {
284 fn deref_mut(&mut self) -> &mut T {
285 self.map_mut(|_: &mut usize, p| unsafe { &mut *(p.deref_mut() as *mut T) })
286 }
287 }
288
289 impl<T: ?Sized> $ointer<T>
290 where
291 Self: Ointer<1>,
292 {
293 pub fn o(&self) -> bool {
295 self.get_bool()
296 }
297 pub fn flip(&mut self) {
299 self.set_bool(!self.o());
300 }
301 pub fn clone_and_flip(&self) -> Self
303 where
304 Self: Clone,
305 {
306 let mut o = self.clone();
307 o.flip();
308 o
309 }
310 }
311 };
312}
313
314macro_rules! define_ointer_methods {
315 ($ointer:ident, $pointer:ident, $bits:literal) => {
316 impl<T> $ointer<T>
317 where
318 Self: Ointer<$bits, Pointer = $pointer<T>>,
319 {
320 pub fn new(x: T) -> Self {
321 $pointer::new(x).into()
322 }
323 pub fn pin(x: T) -> core::pin::Pin<Self> {
324 unsafe { core::pin::Pin::new_unchecked(Self::new(x)) }
325 }
326 }
327 };
328}
329
330pub(crate) use define_ointer_methods;
331
332#[macro_export]
355macro_rules! define_ointer_strong {
356 ($ointer:ident, $pointer:ident, $bits:literal) => {
357 define_ointer!($ointer, $pointer, $bits);
358 define_ointer_methods!($ointer, $pointer, $bits);
359 };
360}
361
362#[macro_export]
397macro_rules! define_shared_ointer {
398 ($ointer_strong:ident, $pointer_strong:ident, $ointer_weak:ident, $pointer_weak:ident, $bits:literal) => {
399 define_ointer_strong!($ointer_strong, $pointer_strong, $bits);
400 define_ointer!($ointer_weak, $pointer_weak, $bits);
401 impl<T: ?Sized> $ointer_strong<T> {
402 pub fn downgrade(&self) -> $ointer_weak<T> {
403 self.map(|u: usize, p| {
404 let mut o: $ointer_weak<T> = $pointer_strong::downgrade(p).into();
405 o.set_usize(u);
406 o
407 })
408 }
409 pub fn strong_count(&self) -> usize {
410 self.map(|_: usize, p| $pointer_strong::strong_count(p))
411 }
412 pub fn weak_count(&self) -> usize {
413 self.map(|_: usize, p| $pointer_strong::weak_count(p))
414 }
415 }
416 impl<T: ?Sized> $ointer_weak<T> {
417 pub fn upgrade(&self) -> Option<$ointer_strong<T>> {
418 self.map(|u: usize, w| {
419 let p = w.upgrade();
420 p.map(|p| {
421 let mut o: $ointer_strong<T> = p.into();
422 o.set_usize(u);
423 o
424 })
425 })
426 }
427 }
428 };
429}
430
431#[macro_export]
474macro_rules! define_enum_ointers {
475 (
476 $name:ident {
477 $($pointer:ty = $unsigned:literal),*
478 },
479 $bits:literal
480 ) => {
481 paste::paste!{
482 #[repr(transparent)]
483 pub struct $name(core::num::NonZeroUsize);
484
485 unsafe impl Ointer<$bits> for $name {
486 type Pointer = core::num::NonZeroUsize;
487 }
488
489 impl $name {
490 #[inline(always)]
491 pub fn new<P: 'static>(u: usize, p: P) -> Self {
492 use core::any::TypeId;
493 use core::mem::size_of;
494 match u {
495 $($unsigned => {
496 if TypeId::of::<P>() != TypeId::of::<$pointer>() {
497 panic!("Unmatched pointer type")
498 }
499 if size_of::<P>() > size_of::<usize>() {
500 panic!("Size overflow")
501 }
502 let mut inner = $name(unsafe {
503 *(&p as *const P as *const core::num::NonZeroUsize)
504 });
505 inner.set_usize(u);
506 core::mem::forget(p);
507 inner
508 }),
509 *,
510 _ => panic!("Unmatched unsigned num")
511 }
512 }
513 #[inline(always)]
514 pub fn set_mut<P: 'static>(&mut self, u: usize, p: P) {
515 *self = Self::new(u, p);
516 }
517 #[inline(always)]
518 pub unsafe fn as_ointer<P: Ointer<$bits> + 'static>(&self) -> &P {
519 &*(self as *const Self as *const P)
520 }
521 #[inline(always)]
522 pub unsafe fn as_ointer_mut<P: Ointer<$bits> + 'static>(&mut self) -> &mut P {
523 &mut *(self as *mut Self as *mut P)
524 }
525 #[inline(always)]
526 pub fn map_enum<
527 R,
528 $([<F $unsigned>]: FnOnce(&$pointer) -> R),
529 *
530 >(
531 &self,
532 $([<f $unsigned>]: [<F $unsigned>]),
533 *
534 ) -> R {
535 let u = self.get_usize();
536 match u {
537 $($unsigned => {
538 let mut u = self.get_ptr_as_usize();
539 let p = unsafe {
540 &mut *(&mut u as *mut usize as *mut Self)
541 };
542 p.set_usize(0);
543 [<f $unsigned>](unsafe {
544 &*(p as *const Self as *const $pointer)
545 })
546 }),
547 *,
548 _ => panic!("Unmatched unsigned num")
549 }
550 }
551 #[inline(always)]
552 pub fn map_enum_mut<
553 R,
554 $([<F $unsigned>]: FnOnce(&mut $pointer) -> R),
555 *
556 >(
557 &mut self,
558 $([<f $unsigned>]: [<F $unsigned>]),
559 *
560 ) -> R {
561 let u = self.get_usize();
562 match u {
563 $($unsigned => {
564 self.set_usize(0);
565 let r = [<f $unsigned>](unsafe {
566 &mut *(self as *mut Self as *mut $pointer)
567 });
568 self.set_usize(u);
569 r
570 }),
571 *,
572 _ => panic!("Unmatched unsigned num")
573 }
574 }
575 }
576
577 impl core::clone::Clone for $name
578 where
579 $(
580 $pointer: core::clone::Clone
581 ), *
582 {
583 fn clone(&self) -> Self {
584 self.map_enum($(|p| Self::new($unsigned, p.clone())), *)
585 }
586 }
587
588 impl core::ops::Drop for $name {
589 fn drop(&mut self) {
590 self.map_enum_mut(
591 $(|p| {
592 $unsigned;
593 unsafe {
594 core::mem::ManuallyDrop::drop(
595 &mut *(
596 p as *mut $pointer
597 as *mut core::mem::ManuallyDrop<$pointer>
598 )
599 );
600 }
601 }), *
602 );
603 }
604 }
605 }
606 };
607}
608
609pub use define_enum_ointers;
610pub use define_ointer;
611pub use define_ointer_strong;
612pub use define_shared_ointer;