1use core::{cmp, fmt, hash, ptr::NonNull};
7
8use crate::ffi;
9
10#[repr(C)]
11pub(crate) struct Opaque {
12 _data: [u8; 0],
14 _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
15}
16
17#[repr(transparent)]
19pub struct NonNullConst<T>(NonNull<T>)
20where
21 T: ?Sized;
22
23#[repr(transparent)]
25pub struct NonNullMut<T>(NonNull<T>)
26where
27 T: ?Sized;
28
29impl<T> NonNullConst<T>
30where
31 T: ?Sized,
32{
33 #[inline]
35 #[must_use]
36 pub const fn into_nonnull(self) -> NonNull<T> {
37 self.0
38 }
39 #[inline]
41 #[must_use]
42 pub const fn as_nonnull(&self) -> &NonNull<T> {
43 &self.0
44 }
45
46 #[inline]
52 #[must_use]
53 pub const unsafe fn new_unchecked(ptr: *const T) -> Self {
54 let mut_ptr = cast_mut(ptr);
56
57 let inner = unsafe { NonNull::new_unchecked(mut_ptr) };
59
60 Self(inner)
61 }
62
63 #[inline]
65 #[must_use]
66 pub fn new(ptr: *const T) -> Option<Self> {
67 let mut_ptr = cast_mut(ptr);
69
70 NonNull::new(mut_ptr).map(Self)
71 }
72
73 #[inline]
75 #[must_use]
76 pub const fn from_ref(r: &T) -> Self {
77 unsafe { Self::new_unchecked(r) }
79 }
80
81 #[inline]
83 #[must_use]
84 pub const fn as_ptr(&self) -> *const T {
85 self.0.as_ptr()
86 }
87
88 #[inline]
95 #[must_use]
96 pub unsafe fn as_ref<'a>(&self) -> &'a T {
97 unsafe { &*self.as_ptr() }
100 }
101
102 #[inline]
104 #[must_use]
105 pub const fn cast<U>(self) -> NonNullConst<U> {
106 let ptr = const_cast_to(self.0.as_ptr());
107
108 unsafe { NonNullConst::new_unchecked(ptr) }
110 }
111}
112
113impl NonNullConst<ffi::c_void> {
114 #[inline]
121 #[must_use]
122 pub const unsafe fn new_void_unchecked<U>(ptr: *const U) -> Self
123 where
124 U: ?Sized,
125 {
126 let void_ptr: *const ffi::c_void = const_cast_to(ptr);
128 let mut_void_ptr = cast_mut(void_ptr);
130
131 let inner = unsafe { NonNull::new_unchecked(mut_void_ptr) };
133
134 Self(inner)
135 }
136
137 #[inline]
140 #[must_use]
141 pub fn new_void<U>(ptr: *const U) -> Option<Self>
142 where
143 U: ?Sized,
144 {
145 let void_ptr: *const ffi::c_void = const_cast_to(ptr);
147 let mut_void_ptr = cast_mut(void_ptr);
149
150 NonNull::new(mut_void_ptr).map(Self)
151 }
152}
153
154#[cfg(feature = "std")]
155impl NonNullConst<ffi::c_char> {
156 #[inline]
164 #[must_use]
165 pub unsafe fn as_c_str(&self) -> &std::ffi::CStr {
166 unsafe { std::ffi::CStr::from_ptr(self.as_ptr()) }
167 }
168}
169
170impl<T> NonNullMut<T>
171where
172 T: ?Sized,
173{
174 #[inline]
176 #[must_use]
177 pub const fn into_nonnull(self) -> NonNull<T> {
178 self.0
179 }
180 #[inline]
182 #[must_use]
183 pub const fn as_nonnull(&self) -> &NonNull<T> {
184 &self.0
185 }
186
187 #[inline]
193 #[must_use]
194 pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
195 let inner = unsafe { NonNull::new_unchecked(ptr) };
197
198 Self(inner)
199 }
200
201 #[inline]
203 #[must_use]
204 pub fn new(ptr: *mut T) -> Option<Self> {
205 NonNull::new(ptr).map(Self)
206 }
207
208 #[inline]
210 #[must_use]
211 pub fn from_mut(r: &mut T) -> Self {
212 unsafe { Self::new_unchecked(r) }
214 }
215
216 #[inline]
218 #[must_use]
219 pub const fn as_ptr(&self) -> *mut T {
220 self.0.as_ptr()
221 }
222
223 #[inline]
230 #[must_use]
231 pub unsafe fn as_mut<'a>(&mut self) -> &'a mut T {
232 unsafe { &mut *self.as_ptr() }
233 }
234
235 #[inline]
237 #[must_use]
238 pub const fn cast<U>(self) -> NonNullMut<U> {
239 let ptr = mut_cast_to(self.0.as_ptr());
240
241 unsafe { NonNullMut::new_unchecked(ptr) }
243 }
244
245 #[inline]
247 #[must_use]
248 pub const fn cast_const(self) -> NonNullConst<T> {
249 let ptr = cast_const(self.0.as_ptr());
250
251 unsafe { NonNullConst::new_unchecked(ptr) }
253 }
254}
255
256impl NonNullMut<ffi::c_void> {
257 #[inline]
264 #[must_use]
265 pub const unsafe fn new_void_unchecked<U>(ptr: *mut U) -> Self
266 where
267 U: ?Sized,
268 {
269 let void_ptr: *mut ffi::c_void = mut_cast_to(ptr);
271
272 let inner = unsafe { NonNull::new_unchecked(void_ptr) };
274
275 Self(inner)
276 }
277
278 #[inline]
281 #[must_use]
282 pub fn new_void<U>(ptr: *mut U) -> Option<Self>
283 where
284 U: ?Sized,
285 {
286 let void_ptr: *mut ffi::c_void = mut_cast_to(ptr);
288
289 NonNull::new(void_ptr).map(Self)
290 }
291}
292
293impl<T> fmt::Debug for NonNullConst<T>
294where
295 T: ?Sized,
296{
297 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
298 fmt::Debug::fmt(&self.0, f)
300 }
301}
302impl<T> fmt::Pointer for NonNullConst<T>
303where
304 T: ?Sized,
305{
306 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
307 fmt::Pointer::fmt(&self.0, f)
309 }
310}
311
312impl<T> Clone for NonNullConst<T>
313where
314 T: ?Sized,
315{
316 #[inline(always)]
317 fn clone(&self) -> Self {
318 *self
319 }
320}
321impl<T> Copy for NonNullConst<T> where T: ?Sized {}
322
323impl<T> PartialEq for NonNullConst<T>
324where
325 T: ?Sized,
326{
327 #[inline]
328 fn eq(&self, other: &Self) -> bool {
329 #[allow(ambiguous_wide_pointer_comparisons)]
331 self.0.eq(&other.0)
332 }
333}
334impl<T> Eq for NonNullConst<T> where T: ?Sized {}
335
336impl<T> PartialOrd for NonNullConst<T>
337where
338 T: ?Sized,
339{
340 #[inline]
341 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
342 Some(self.cmp(other))
343 }
344}
345impl<T> Ord for NonNullConst<T>
346where
347 T: ?Sized,
348{
349 #[inline]
350 fn cmp(&self, other: &Self) -> cmp::Ordering {
351 #[allow(ambiguous_wide_pointer_comparisons)]
353 self.0.cmp(&other.0)
354 }
355}
356
357impl<T> hash::Hash for NonNullConst<T>
358where
359 T: ?Sized,
360{
361 #[inline]
362 fn hash<H: hash::Hasher>(&self, state: &mut H) {
363 self.0.hash(state)
365 }
366}
367
368impl<T> From<&T> for NonNullConst<T>
369where
370 T: ?Sized,
371{
372 #[inline]
376 fn from(r: &T) -> Self {
377 Self::from_ref(r)
378 }
379}
380
381impl<T> fmt::Debug for NonNullMut<T>
382where
383 T: ?Sized,
384{
385 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
386 fmt::Debug::fmt(&self.0, f)
388 }
389}
390impl<T> fmt::Pointer for NonNullMut<T>
391where
392 T: ?Sized,
393{
394 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
395 fmt::Pointer::fmt(&self.0, f)
397 }
398}
399
400impl<T> Clone for NonNullMut<T>
401where
402 T: ?Sized,
403{
404 #[inline(always)]
405 fn clone(&self) -> Self {
406 *self
407 }
408}
409impl<T> Copy for NonNullMut<T> where T: ?Sized {}
410
411impl<T> PartialEq for NonNullMut<T>
412where
413 T: ?Sized,
414{
415 #[inline]
416 fn eq(&self, other: &Self) -> bool {
417 #[allow(ambiguous_wide_pointer_comparisons)]
419 self.0.eq(&other.0)
420 }
421}
422impl<T> Eq for NonNullMut<T> where T: ?Sized {}
423
424impl<T> PartialOrd for NonNullMut<T>
425where
426 T: ?Sized,
427{
428 #[inline]
429 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
430 Some(self.cmp(other))
431 }
432}
433impl<T> Ord for NonNullMut<T>
434where
435 T: ?Sized,
436{
437 #[inline]
438 fn cmp(&self, other: &Self) -> cmp::Ordering {
439 #[allow(ambiguous_wide_pointer_comparisons)]
441 self.0.cmp(&other.0)
442 }
443}
444
445impl<T> hash::Hash for NonNullMut<T>
446where
447 T: ?Sized,
448{
449 #[inline]
450 fn hash<H: hash::Hasher>(&self, state: &mut H) {
451 self.0.hash(state)
453 }
454}
455
456impl<T> From<&mut T> for NonNullMut<T>
457where
458 T: ?Sized,
459{
460 #[inline]
464 fn from(r: &mut T) -> Self {
465 Self::from_mut(r)
466 }
467}
468
469const fn cast_mut<T>(p: *const T) -> *mut T
470where
471 T: ?Sized,
472{
473 p as _
474}
475
476const fn cast_const<T>(p: *mut T) -> *const T
477where
478 T: ?Sized,
479{
480 p as _
481}
482
483const fn const_cast_to<T, U>(p: *const T) -> *const U
484where
485 T: ?Sized,
486{
487 p as _
488}
489
490const fn mut_cast_to<T, U>(p: *mut T) -> *mut U
491where
492 T: ?Sized,
493{
494 p as _
495}