ointer/
ointer.rs

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    /// Get high `N` bits and return `false` if they are all `0`.
21    #[inline(always)]
22    fn get_bool(&self) -> bool {
23        self.get_usize() != 0
24    }
25    /// Get high `N` bits and cast as `isize`.
26    #[inline(always)]
27    fn get_isize(&self) -> isize {
28        unsafe { *(self as *const Self as *const isize) >> Self::SHIFT_BITS }
29    }
30    /// Get high `N` bits and cast as `usize`.
31    #[inline(always)]
32    fn get_usize(&self) -> usize {
33        unsafe { *(self as *const Self as *const usize) >> Self::SHIFT_BITS }
34    }
35    /// Get stored pointer and cast as `usize`.
36    #[inline(always)]
37    fn get_ptr_as_usize(&self) -> usize {
38        unsafe { *(self as *const Self as *const usize) & Self::LOW_MASK }
39    }
40    /// Set high `N` bits all to `1` if `true`, all to `0` if `false`.
41    #[inline(always)]
42    fn set_bool(&mut self, b: bool) {
43        self.set_isize(if b { -1 } else { 0 })
44    }
45    /// Set high `N` bits from `isize`.
46    #[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    /// Set high `N` bits from `usize`.
57    #[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    /// Store pointer to low bits.
68    #[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    /// Assert high `N` bits is all `0`.
77    #[inline(always)]
78    fn assert_stealable(&self) {
79        assert_eq!(self.get_bool(), false);
80    }
81    /// Get high `N` bits and cast as `T`.
82    #[inline(always)]
83    fn get<T: Copy>(&self) -> T
84    where
85        Self: OinterGet<T, N>,
86    {
87        self.get_high_bits()
88    }
89    /// Set high `N` bits from `T`.
90    #[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    /// Map `&Self` as `&T`(from high `N` bits) and `&Self::Pointer`, then map fn `f`.
98    #[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    /// Map `&mut Self` as `&mut T`(from high `N` bits) and `&mut Self::Pointer`, map fn `f`, then store changes back.
109    #[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    /// Get high `N` bits and cast as `T`.
126    #[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    /// Set high `N` bits from `T`.
147    #[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 used to define `Weak` like `ointer`s.
177#[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            /// Get first bit and cast as bool.
294            pub fn o(&self) -> bool {
295                self.get_bool()
296            }
297            /// Flip first bit.
298            pub fn flip(&mut self) {
299                self.set_bool(!self.o());
300            }
301            /// Clone and flip.
302            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 used to define `Box`/`Rc`/`Arc` like `ointer`s.
333/// This crate defines `BBox`(called byte stolen `Box`) that wraps `Box` and steal high 8-bits(1-byte), by using
334/// `define_ointer_strong!(BBox, Box, 8);`
335/// And define `OBox`(called orientable `Box`) by using
336/// `define_ointer_strong!(OBox, Box, 1);`
337///
338/// Tests over`OBox`
339/// ```
340/// use ointer::{OBox, Ointer};
341/// use std::pin::Pin;
342/// let mut o = OBox::new(1);
343/// assert_eq!(*o, 1);
344/// assert_eq!(o.get::<bool>(), false);
345/// assert_eq!(*o, 1);
346/// *o = i32::default();
347/// assert_eq!(*o, i32::default());
348/// o.set_bool(true);
349/// let b = o.get_bool();
350/// assert_eq!(b, true);
351/// o.set_mut(false);
352/// assert_eq!(o, Pin::into_inner(OBox::pin(Default::default())));
353/// ```
354#[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 used to define `Rc/Weak` or `Arc/Weak` like shared `ointer`s.
363/// This crate defines `BRc/BWeak`(called byte stolen `Rc/Weak`) that wraps `Rc/Weak` and steal high 8-bits(1-byte), by using
364/// `define_shared_ointer!(BRc, Rc, BWeak, Weak, 8);`
365/// And define `ORc/OWeak`(called orientable `Rc/Weak`) by using
366/// `define_shared_ointer!(ORc, Rc, OWeak, Weak, 1);`
367///
368/// Tests over `BArc`
369/// ```
370/// use ointer::{sync::BArc, Ointer};
371/// use core::mem::size_of;
372/// let mut o = BArc::new(1);
373/// assert_eq!(*o, 1);
374/// assert_eq!(o.get::<bool>(), false);
375///
376/// // Define a small enum for testing.
377/// #[derive(Clone, Copy, PartialEq, Debug)]
378/// enum MySmallEnum {
379///     _A,
380///     B,
381///     _C,
382/// }
383/// assert_eq!(size_of::<MySmallEnum>(), 1);
384///
385/// o.set_mut(MySmallEnum::B);
386/// assert_eq!(*o, 1);
387/// assert_eq!(o.get::<MySmallEnum>(), MySmallEnum::B);
388///
389/// // Modify the bool and pointer inside the ointer.
390/// o.map_mut(|b: &mut bool, p| {
391///     *b = !*b;
392///     *p = Default::default();
393/// });
394/// assert_eq!(*o.downgrade().upgrade().unwrap(), Default::default());
395/// ```
396#[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 used to define custom enum `ointer`s with the same size of `usize`.
432///
433/// Example testing usage:
434/// ```
435/// use ointer::{define_enum_ointers, Ointer};
436/// use std::sync::Arc;
437/// use core::mem::size_of;
438/// let mut a = Arc::new(13);
439/// // Define custom enum ointers using MyEnumOinters.
440/// define_enum_ointers!(
441///     MyEnumOinters {
442///         Box<f64> = 1,
443///         Arc<i32> = 2,
444///         i32 = 5
445///     },
446///     8
447/// );
448/// let mut e = MyEnumOinters::new(2, a.clone());
449/// assert_eq!(Arc::strong_count(&a), 2);
450/// // Perform operations on the enum ointer.
451/// assert_eq!(
452///     e.map_enum_mut(
453///         |_| panic!(),
454///         |p| {
455///             let i = **p;
456///             *p = Arc::new(15);
457///             assert_eq!(Arc::strong_count(&a), 1);
458///             a = p.clone();
459///             i
460///         },
461///         |_| panic!()
462///     ),
463///     13
464/// );
465/// assert_eq!(e.map_enum(|_| panic!(), |p1| **p1, |_| panic!()), 15);
466/// assert_eq!(Arc::strong_count(&a), 2);
467/// // Set the enum ointer to a new value (Box<f64>).
468/// e.set_mut(1, Box::new(2.0));
469/// assert_eq!(Arc::strong_count(&a), 1);
470/// assert_eq!(e.map_enum(|p| **p, |_| panic!(), |_| panic!()), 2.0);
471/// assert_eq!(size_of::<MyEnumOinters>(), size_of::<usize>());
472/// ```
473#[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;