1#![no_std]
2#![cfg_attr(feature = "meta", feature(ptr_metadata))]
3#![warn(clippy::pedantic)]
4
5use core::ptr::NonNull;
6
7#[cfg(feature = "non_null_const")]
8use non_null_const::NonNullConst;
9
10#[cfg(feature = "meta")]
11use core::ptr::Pointee;
12
13mod non_null;
14mod null;
15pub use null::*;
16#[cfg(feature = "alloc")]
17mod alloc;
18mod other;
19mod raw;
20mod r#ref;
21
22#[inline]
23#[must_use]
24fn is_valid_ref<P: Ptr + ?Sized>(ptr: &P) -> bool
25where
26 P::Target: Sized,
27{
28 !ptr.is_null() && ptr.is_aligned()
29}
30
31cfg_tt::cfg_tt! {
32 pub trait Ptr {
34 type Target: ?Sized #[cfg(feature = "meta")](+ Pointee);
36
37 #[must_use]
39 fn as_ptr(&self) -> *const Self::Target;
40
41 #[inline]
43 #[must_use]
44 fn addr(&self) -> usize {
45 self.as_ptr().addr()
46 }
47
48 #[inline]
50 #[must_use]
51 fn is_null(&self) -> bool {
52 self.as_ptr().is_null()
53 }
54
55 #[inline]
57 #[must_use]
58 fn is_aligned(&self) -> bool
59 where
60 Self::Target: Sized,
61 {
62 self.as_ptr().is_aligned()
63 }
64
65 #[inline]
71 #[must_use]
72 unsafe fn as_ref<'a>(&self) -> Option<&'a Self::Target>
73 where
74 Self::Target: Sized,
75 {
76 is_valid_ref(self).then(|| unsafe { self.as_ref_unchecked() })
77 }
78
79 #[inline]
84 #[must_use]
85 unsafe fn as_ref_unchecked<'a>(&self) -> &'a Self::Target {
86 unsafe { &*self.as_ptr() }
87 }
88 }
89}
90
91pub trait PtrMut: Ptr {
93 #[must_use]
95 fn as_mut_ptr(&mut self) -> *mut Self::Target;
96
97 #[inline]
103 #[must_use]
104 unsafe fn as_mut<'a>(&mut self) -> Option<&'a mut Self::Target>
105 where
106 Self::Target: Sized,
107 {
108 is_valid_ref(self).then(|| unsafe { self.as_mut_unchecked() })
109 }
110
111 #[inline]
116 #[must_use]
117 unsafe fn as_mut_unchecked<'a>(&mut self) -> &'a mut Self::Target {
118 unsafe { &mut *self.as_mut_ptr() }
119 }
120}
121
122pub trait RawPtr: Ptr + Sized + Copy {
124 #[inline]
125 #[must_use]
126 fn cast<U>(self) -> *const U {
127 self.as_ptr().cast()
128 }
129
130 #[inline]
131 #[must_use]
132 fn cast_mut(self) -> *mut Self::Target {
133 self.as_ptr().cast_mut()
134 }
135}
136
137pub trait RawMutPtr: PtrMut + Sized + Copy {
139 #[inline]
140 #[must_use]
141 fn cast<U>(mut self) -> *mut U {
142 self.as_mut_ptr().cast()
143 }
144
145 #[inline]
146 #[must_use]
147 fn cast_const(mut self) -> *const Self::Target {
148 self.as_mut_ptr().cast_const()
149 }
150}
151
152pub unsafe trait NonNullPtr: Ptr {
157 #[cfg(feature = "non_null_const")]
158 #[inline]
159 #[must_use]
160 fn as_non_null_const(&self) -> NonNullConst<Self::Target> {
162 let ptr = self.as_ptr();
163 unsafe { NonNullConst::new_unchecked(ptr) }
164 }
165}
166
167pub unsafe trait NonNullMutPtr: PtrMut + NonNullPtr {
172 #[inline]
174 #[must_use]
175 fn as_non_null(&mut self) -> NonNull<Self::Target> {
176 let ptr = self.as_mut_ptr();
177 unsafe { NonNull::new_unchecked(ptr) }
178 }
179}