Skip to main content

std_traits/
ptr.rs

1use core::fmt::Debug;
2
3use crate::{num::Integer, primitive::Primitive, reference::Mutability, util::cast_int};
4
5macro_rules! cast_ptr {
6    ($T:ty, $P:ty, $value:expr) => {
7        match <$P>::ptr_type() {
8            $crate::reference::Mutability::Const => unsafe {
9                $crate::util::transmute_unchecked::<*const $T, $P>($value as *const $T)
10            },
11            $crate::reference::Mutability::Mut => unsafe {
12                $crate::util::transmute_unchecked::<*mut $T, $P>($value as *mut $T)
13            },
14        }
15    };
16}
17
18pub(crate) use cast_ptr;
19
20pub trait Pointer<T: ?Sized>: Primitive + Copy + Debug + Sized {
21    #[must_use]
22    fn ptr_type() -> Mutability;
23
24    #[must_use]
25    fn cast_ptr<U: Sized, P: Pointer<U>>(self) -> P
26    where
27        Self: Sized;
28
29    #[must_use]
30    fn cast_int<I: Integer>(self) -> I
31    where
32        T: Sized;
33}
34
35macro_rules! impl_pointer {
36    ($mut:tt, $ty:expr) => {
37        impl<T: ?Sized> Primitive for *$mut T {}
38
39        impl<T: ?Sized> Pointer<T> for *$mut T {
40            fn ptr_type() -> Mutability {
41                $ty
42            }
43
44            fn cast_ptr<U: Sized, P: Pointer<U>>(self) -> P where Self: Sized {
45                cast_ptr!(T, P, self)
46            }
47
48            fn cast_int<I: Integer>(self) -> I where T: Sized {
49                cast_int!(self => I)
50            }
51        }
52    }
53}
54
55impl_pointer!(const, Mutability::Const);
56impl_pointer!(mut, Mutability::Mut);
57
58#[cfg(test)]
59mod test {
60    use super::*;
61
62    #[test]
63    fn test_cast() {
64        let ptr: *const u8 = "foo".as_ptr();
65        let int: usize = ptr.cast_int();
66        let ptr2: *const u8 = int.cast_ptr();
67
68        assert_eq!(ptr, ptr2);
69    }
70}