Skip to main content

atomic_tagged_ptr/ptr/
wrapper.rs

1use core::fmt;
2use core::ptr::NonNull;
3
4use super::TaggedPtr;
5
6/// A transparent wrapper around `Option<NonNull<T>>` returned by `AtomicTaggedPtr` operations.
7///
8/// It provides convenient helper methods to convert into raw const/mutable pointers,
9/// access the underlying `Option<NonNull<T>>`, and supports direct comparisons.
10#[repr(transparent)]
11pub struct Ptr<T> {
12    pub(crate) inner: Option<NonNull<T>>,
13}
14
15impl<T> Default for Ptr<T> {
16    #[inline]
17    fn default() -> Self {
18        Self { inner: None }
19    }
20}
21
22impl<T> Copy for Ptr<T> {}
23
24impl<T> Clone for Ptr<T> {
25    #[inline]
26    fn clone(&self) -> Self {
27        *self
28    }
29}
30
31impl<T> fmt::Debug for Ptr<T> {
32    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33        fmt::Debug::fmt(&self.inner, f)
34    }
35}
36
37impl<T> Ptr<T> {
38    /// Creates a new `Ptr` wrapper from an `Option<NonNull<T>>`.
39    #[inline]
40    pub const fn new(ptr: Option<NonNull<T>>) -> Self {
41        Self { inner: ptr }
42    }
43
44    /// Creates a null `Ptr`.
45    ///
46    /// # Examples
47    ///
48    /// ```rust
49    /// use atomic_tagged_ptr::Ptr;
50    ///
51    /// let p: Ptr<i32> = Ptr::null();
52    /// assert!(p.is_null());
53    /// ```
54    #[inline]
55    pub const fn null() -> Self {
56        Self { inner: None }
57    }
58
59    /// Creates a null `Ptr` (alias for `null`).
60    ///
61    /// # Examples
62    ///
63    /// ```rust
64    /// use atomic_tagged_ptr::Ptr;
65    ///
66    /// let p: Ptr<i32> = Ptr::none();
67    /// assert!(p.is_null());
68    /// ```
69    #[inline]
70    pub const fn none() -> Self {
71        Self { inner: None }
72    }
73
74    /// Casts to a pointer of another type.
75    ///
76    /// # Examples
77    ///
78    /// ```rust
79    /// use atomic_tagged_ptr::Ptr;
80    /// use std::ptr::NonNull;
81    ///
82    /// let val = 42u8;
83    /// let ptr = Ptr::new(NonNull::new(&val as *const u8 as *mut u8));
84    /// let casted: Ptr<i8> = ptr.cast();
85    /// ```
86    #[inline]
87    pub fn cast<U>(self) -> Ptr<U> {
88        Ptr {
89            inner: self.inner.map(|p| p.cast()),
90        }
91    }
92
93    /// Converts the pointer into a raw mutable pointer `*mut T`.
94    ///
95    /// Returns a null pointer if the underlying value is `None`.
96    ///
97    /// # Examples
98    ///
99    /// ```rust
100    /// use atomic_tagged_ptr::Ptr;
101    /// use std::ptr::NonNull;
102    ///
103    /// let mut val = 42;
104    /// let ptr = Ptr::new(NonNull::new(&mut val as *mut i32));
105    /// assert_eq!(unsafe { *ptr.as_mut_ptr() }, 42);
106    ///
107    /// let null_ptr: Ptr<i32> = Ptr::null();
108    /// assert!(null_ptr.as_mut_ptr().is_null());
109    /// ```
110    #[inline]
111    pub fn as_mut_ptr(self) -> *mut T {
112        self.inner
113            .map(|p| p.as_ptr())
114            .unwrap_or(core::ptr::null_mut())
115    }
116
117    /// Converts the pointer into a raw const pointer `*const T`.
118    ///
119    /// Returns a null pointer if the underlying value is `None`.
120    ///
121    /// # Examples
122    ///
123    /// ```rust
124    /// use atomic_tagged_ptr::Ptr;
125    /// use std::ptr::NonNull;
126    ///
127    /// let val = 42;
128    /// let ptr = Ptr::new(NonNull::new(&val as *const i32 as *mut i32));
129    /// assert_eq!(unsafe { *ptr.as_ptr() }, 42);
130    ///
131    /// let null_ptr: Ptr<i32> = Ptr::null();
132    /// assert!(null_ptr.as_ptr().is_null());
133    /// ```
134    #[inline]
135    pub fn as_ptr(self) -> *const T {
136        self.inner
137            .map(|p| p.as_ptr() as *const T)
138            .unwrap_or(core::ptr::null())
139    }
140
141    /// Obtains the underlying `Option<NonNull<T>>`.
142    ///
143    /// # Examples
144    ///
145    /// ```rust
146    /// use atomic_tagged_ptr::Ptr;
147    /// use std::ptr::NonNull;
148    ///
149    /// let val = 42;
150    /// let raw = NonNull::new(&val as *const i32 as *mut i32);
151    /// let ptr = Ptr::new(raw);
152    /// assert_eq!(ptr.option(), raw);
153    /// ```
154    #[inline]
155    pub const fn option(self) -> Option<NonNull<T>> {
156        self.inner
157    }
158
159    /// Obtains the underlying `Option<NonNull<T>>` (alias for `option`).
160    ///
161    /// # Examples
162    ///
163    /// ```rust
164    /// use atomic_tagged_ptr::Ptr;
165    /// use std::ptr::NonNull;
166    ///
167    /// let val = 42;
168    /// let raw = NonNull::new(&val as *const i32 as *mut i32);
169    /// let ptr = Ptr::new(raw);
170    /// assert_eq!(ptr.as_option(), raw);
171    /// ```
172    #[inline]
173    pub const fn as_option(self) -> Option<NonNull<T>> {
174        self.inner
175    }
176
177    /// Returns `true` if the pointer is null.
178    ///
179    /// # Examples
180    ///
181    /// ```rust
182    /// use atomic_tagged_ptr::Ptr;
183    ///
184    /// let p: Ptr<i32> = Ptr::null();
185    /// assert!(p.is_null());
186    /// ```
187    #[inline]
188    pub fn is_null(self) -> bool {
189        self.inner.is_none()
190    }
191
192    /// Returns `true` if the pointer is not null (is some).
193    ///
194    /// # Examples
195    ///
196    /// ```rust
197    /// use atomic_tagged_ptr::Ptr;
198    /// use std::ptr::NonNull;
199    ///
200    /// let val = 42;
201    /// let p = Ptr::new(NonNull::new(&val as *const i32 as *mut i32));
202    /// assert!(p.is_some());
203    /// ```
204    #[inline]
205    pub fn is_some(self) -> bool {
206        self.inner.is_some()
207    }
208
209    /// Returns `true` if the pointer is null (is none).
210    ///
211    /// # Examples
212    ///
213    /// ```rust
214    /// use atomic_tagged_ptr::Ptr;
215    ///
216    /// let p: Ptr<i32> = Ptr::null();
217    /// assert!(p.is_none());
218    /// ```
219    #[inline]
220    pub fn is_none(self) -> bool {
221        self.inner.is_none()
222    }
223
224    /// Returns a shared reference to the value if the pointer is not null.
225    ///
226    /// # Safety
227    ///
228    /// The caller must ensure that:
229    /// * The pointer is valid (aligned, points to a valid initialized value of type `T`).
230    /// * The memory is not mutated while the reference is active.
231    /// * The reference lifetime `'a` is correctly bounded.
232    ///
233    /// # Examples
234    ///
235    /// ```rust
236    /// use atomic_tagged_ptr::Ptr;
237    /// use std::ptr::NonNull;
238    ///
239    /// let val = 42;
240    /// let ptr = Ptr::new(NonNull::new(&val as *const i32 as *mut i32));
241    /// unsafe {
242    ///     assert_eq!(ptr.as_ref(), Some(&42));
243    /// }
244    /// ```
245    #[inline]
246    pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
247        self.inner.map(|p| unsafe { p.as_ref() })
248    }
249
250    /// Returns a mutable reference to the value if the pointer is not null.
251    ///
252    /// # Safety
253    ///
254    /// The caller must ensure that:
255    /// * The pointer is valid (aligned, points to a valid initialized value of type `T`).
256    /// * No other references (shared or mutable) to the same memory are active.
257    /// * The reference lifetime `'a` is correctly bounded.
258    ///
259    /// # Examples
260    ///
261    /// ```rust
262    /// use atomic_tagged_ptr::Ptr;
263    /// use std::ptr::NonNull;
264    ///
265    /// let mut val = 42;
266    /// let ptr = Ptr::new(NonNull::new(&mut val as *mut i32));
267    /// unsafe {
268    ///     let r = ptr.as_mut();
269    ///     assert_eq!(r, Some(&mut 42));
270    ///     *r.unwrap() = 100;
271    /// }
272    /// assert_eq!(val, 100);
273    /// ```
274    #[inline]
275    pub unsafe fn as_mut<'a>(mut self) -> Option<&'a mut T> {
276        self.inner.as_mut().map(|p| unsafe { p.as_mut() })
277    }
278
279    /// Unwraps the inner `NonNull<T>`, panicking with the given message if it is `None`.
280    ///
281    /// # Panics
282    ///
283    /// Panics if the pointer is null.
284    ///
285    /// # Examples
286    ///
287    /// ```rust
288    /// use atomic_tagged_ptr::Ptr;
289    /// use std::ptr::NonNull;
290    ///
291    /// let val = 42;
292    /// let ptr = Ptr::new(NonNull::new(&val as *const i32 as *mut i32));
293    /// let non_null = ptr.expect("should not be null");
294    /// assert_eq!(unsafe { *non_null.as_ptr() }, 42);
295    /// ```
296    #[inline]
297    pub fn expect(self, msg: &str) -> NonNull<T> {
298        self.inner.expect(msg)
299    }
300
301    /// Unwraps the inner `NonNull<T>`, panicking if it is `None`.
302    ///
303    /// # Panics
304    ///
305    /// Panics if the pointer is null.
306    ///
307    /// # Examples
308    ///
309    /// ```rust
310    /// use atomic_tagged_ptr::Ptr;
311    /// use std::ptr::NonNull;
312    ///
313    /// let val = 42;
314    /// let ptr = Ptr::new(NonNull::new(&val as *const i32 as *mut i32));
315    /// let non_null = ptr.unwrap();
316    /// assert_eq!(unsafe { *non_null.as_ptr() }, 42);
317    /// ```
318    #[inline]
319    pub fn unwrap(self) -> NonNull<T> {
320        self.inner
321            .expect("called `Ptr::unwrap()` on a null pointer")
322    }
323
324    /// Returns the contained `NonNull<T>` or a default.
325    ///
326    /// # Examples
327    ///
328    /// ```rust
329    /// use atomic_tagged_ptr::Ptr;
330    /// use std::ptr::NonNull;
331    ///
332    /// let val1 = 42;
333    /// let val2 = 84;
334    /// let non_null1 = NonNull::new(&val1 as *const i32 as *mut i32).unwrap();
335    /// let non_null2 = NonNull::new(&val2 as *const i32 as *mut i32).unwrap();
336    ///
337    /// let ptr = Ptr::new(Some(non_null1));
338    /// assert_eq!(ptr.unwrap_or(non_null2), non_null1);
339    ///
340    /// let null_ptr = Ptr::null();
341    /// assert_eq!(null_ptr.unwrap_or(non_null2), non_null2);
342    /// ```
343    #[inline]
344    pub fn unwrap_or(self, default: NonNull<T>) -> NonNull<T> {
345        self.inner.unwrap_or(default)
346    }
347
348    /// Maps the inner `NonNull<T>` pointer to a new pointer of another type.
349    ///
350    /// # Examples
351    ///
352    /// ```rust
353    /// use atomic_tagged_ptr::Ptr;
354    /// use std::ptr::NonNull;
355    ///
356    /// let val = 42u8;
357    /// let ptr = Ptr::new(NonNull::new(&val as *const u8 as *mut u8));
358    /// let mapped = ptr.map(|p| p.cast::<i8>());
359    /// assert_eq!(unsafe { *mapped.as_ptr() }, 42);
360    /// ```
361    #[inline]
362    pub fn map<U, F>(self, f: F) -> Ptr<U>
363    where
364        F: FnOnce(NonNull<T>) -> NonNull<U>,
365    {
366        Ptr::new(self.inner.map(f))
367    }
368
369    /// Maps the inner `NonNull<T>` pointer to a value, or returns a default value.
370    ///
371    /// # Examples
372    ///
373    /// ```rust
374    /// use atomic_tagged_ptr::Ptr;
375    /// use std::ptr::NonNull;
376    ///
377    /// let val = 42;
378    /// let ptr = Ptr::new(NonNull::new(&val as *const i32 as *mut i32));
379    /// let res = ptr.map_or(0, |p| unsafe { *p.as_ptr() });
380    /// assert_eq!(res, 42);
381    ///
382    /// let null_ptr = Ptr::null();
383    /// let res = null_ptr.map_or(0, |p| unsafe { *p.as_ptr() });
384    /// assert_eq!(res, 0);
385    /// ```
386    #[inline]
387    pub fn map_or<U, F>(self, default: U, f: F) -> U
388    where
389        F: FnOnce(NonNull<T>) -> U,
390    {
391        self.inner.map_or(default, f)
392    }
393
394    /// Maps the inner `NonNull<T>` pointer to a value, or evaluates a default closure.
395    ///
396    /// # Examples
397    ///
398    /// ```rust
399    /// use atomic_tagged_ptr::Ptr;
400    /// use std::ptr::NonNull;
401    ///
402    /// let val = 42;
403    /// let ptr = Ptr::new(NonNull::new(&val as *const i32 as *mut i32));
404    /// let res = ptr.map_or_else(|| 0, |p| unsafe { *p.as_ptr() });
405    /// assert_eq!(res, 42);
406    ///
407    /// let null_ptr = Ptr::null();
408    /// let res = null_ptr.map_or_else(|| 0, |p| unsafe { *p.as_ptr() });
409    /// assert_eq!(res, 0);
410    /// ```
411    #[inline]
412    pub fn map_or_else<U, D, F>(self, default: D, f: F) -> U
413    where
414        D: FnOnce() -> U,
415        F: FnOnce(NonNull<T>) -> U,
416    {
417        self.inner.map_or_else(default, f)
418    }
419
420    /// Reads the value from `self` without moving it. This leaves the memory in `self` unchanged.
421    ///
422    /// # Safety
423    ///
424    /// * The pointer must be non-null.
425    /// * The pointer must be valid for reads (correctly aligned, points to an initialized instance of `T`, etc.).
426    /// * The memory must not be mutated by another thread while being read.
427    ///
428    /// # Examples
429    ///
430    /// ```rust
431    /// use atomic_tagged_ptr::Ptr;
432    /// use std::ptr::NonNull;
433    ///
434    /// let val = 42;
435    /// let ptr = Ptr::new(NonNull::new(&val as *const i32 as *mut i32));
436    /// unsafe {
437    ///     assert_eq!(ptr.read(), 42);
438    /// }
439    /// ```
440    #[inline]
441    pub unsafe fn read(self) -> T {
442        // Safety: The caller guarantees the pointer is valid.
443        unsafe { core::ptr::read(self.as_ptr()) }
444    }
445
446    /// Performs a volatile read of the value from `self` without moving it.
447    ///
448    /// Volatile operations are intended for acting on I/O memory, and are never coalesced or
449    /// eliminated by the compiler.
450    ///
451    /// # Safety
452    ///
453    /// * The pointer must be non-null.
454    /// * The pointer must be valid for reads.
455    /// * The memory must not be mutated by another thread while being read.
456    ///
457    /// # Examples
458    ///
459    /// ```rust
460    /// use atomic_tagged_ptr::Ptr;
461    /// use std::ptr::NonNull;
462    ///
463    /// let val = 42;
464    /// let ptr = Ptr::new(NonNull::new(&val as *const i32 as *mut i32));
465    /// unsafe {
466    ///     assert_eq!(ptr.read_volatile(), 42);
467    /// }
468    /// ```
469    #[inline]
470    pub unsafe fn read_volatile(self) -> T {
471        // Safety: The caller guarantees the pointer is valid.
472        unsafe { core::ptr::read_volatile(self.as_ptr()) }
473    }
474
475    /// Reads the value from `self` without moving it, without requiring alignment.
476    ///
477    /// # Safety
478    ///
479    /// * The pointer must be non-null.
480    /// * The pointer must be valid for reads.
481    /// * The memory must not be mutated by another thread while being read.
482    ///
483    /// # Examples
484    ///
485    /// ```rust
486    /// use atomic_tagged_ptr::Ptr;
487    /// use std::ptr::NonNull;
488    ///
489    /// let val = 42;
490    /// let ptr = Ptr::new(NonNull::new(&val as *const i32 as *mut i32));
491    /// unsafe {
492    ///     assert_eq!(ptr.read_unaligned(), 42);
493    /// }
494    /// ```
495    #[inline]
496    pub unsafe fn read_unaligned(self) -> T {
497        // Safety: The caller guarantees the pointer is valid.
498        unsafe { core::ptr::read_unaligned(self.as_ptr()) }
499    }
500
501    /// Overwrites a memory location with the given value without reading or dropping the old value.
502    ///
503    /// # Safety
504    ///
505    /// * The pointer must be non-null.
506    /// * The pointer must be valid for writes (correctly aligned, etc.).
507    ///
508    /// # Examples
509    ///
510    /// ```rust
511    /// use atomic_tagged_ptr::Ptr;
512    /// use std::ptr::NonNull;
513    ///
514    /// let mut val = 0;
515    /// let ptr = Ptr::new(NonNull::new(&mut val as *mut i32));
516    /// unsafe {
517    ///     ptr.write(42);
518    /// }
519    /// assert_eq!(val, 42);
520    /// ```
521    #[inline]
522    pub unsafe fn write(self, val: T) {
523        // Safety: The caller guarantees the pointer is valid.
524        unsafe { core::ptr::write(self.as_mut_ptr(), val) }
525    }
526
527    /// Performs a volatile write of a memory location with the given value.
528    ///
529    /// # Safety
530    ///
531    /// * The pointer must be non-null.
532    /// * The pointer must be valid for writes.
533    ///
534    /// # Examples
535    ///
536    /// ```rust
537    /// use atomic_tagged_ptr::Ptr;
538    /// use std::ptr::NonNull;
539    ///
540    /// let mut val = 0;
541    /// let ptr = Ptr::new(NonNull::new(&mut val as *mut i32));
542    /// unsafe {
543    ///     ptr.write_volatile(42);
544    /// }
545    /// assert_eq!(val, 42);
546    /// ```
547    #[inline]
548    pub unsafe fn write_volatile(self, val: T) {
549        // Safety: The caller guarantees the pointer is valid.
550        unsafe { core::ptr::write_volatile(self.as_mut_ptr(), val) }
551    }
552
553    /// Overwrites a memory location with the given value without requiring alignment.
554    ///
555    /// # Safety
556    ///
557    /// * The pointer must be non-null.
558    /// * The pointer must be valid for writes.
559    ///
560    /// # Examples
561    ///
562    /// ```rust
563    /// use atomic_tagged_ptr::Ptr;
564    /// use std::ptr::NonNull;
565    ///
566    /// let mut val = 0;
567    /// let ptr = Ptr::new(NonNull::new(&mut val as *mut i32));
568    /// unsafe {
569    ///     ptr.write_unaligned(42);
570    /// }
571    /// assert_eq!(val, 42);
572    /// ```
573    #[inline]
574    pub unsafe fn write_unaligned(self, val: T) {
575        // Safety: The caller guarantees the pointer is valid.
576        unsafe { core::ptr::write_unaligned(self.as_mut_ptr(), val) }
577    }
578
579    /// Replaces the value at `self` with `val`, returning the old value.
580    ///
581    /// # Safety
582    ///
583    /// * The pointer must be non-null.
584    /// * The pointer must be valid for reads and writes.
585    ///
586    /// # Examples
587    ///
588    /// ```rust
589    /// use atomic_tagged_ptr::Ptr;
590    /// use std::ptr::NonNull;
591    ///
592    /// let mut val = 10;
593    /// let ptr = Ptr::new(NonNull::new(&mut val as *mut i32));
594    /// unsafe {
595    ///     let old = ptr.replace(20);
596    ///     assert_eq!(old, 10);
597    /// }
598    /// assert_eq!(val, 20);
599    /// ```
600    #[inline]
601    pub unsafe fn replace(self, val: T) -> T {
602        // Safety: The caller guarantees the pointer is valid.
603        unsafe { core::ptr::replace(self.as_mut_ptr(), val) }
604    }
605
606    /// Swaps the values at `self` and `with`.
607    ///
608    /// # Safety
609    ///
610    /// * Both pointers must be non-null.
611    /// * Both pointers must be valid for reads and writes.
612    /// * Both pointers must be properly aligned.
613    ///
614    /// # Examples
615    ///
616    /// ```rust
617    /// use atomic_tagged_ptr::Ptr;
618    /// use std::ptr::NonNull;
619    ///
620    /// let mut val1 = 10;
621    /// let mut val2 = 20;
622    /// let ptr1 = Ptr::new(NonNull::new(&mut val1 as *mut i32));
623    /// let ptr2 = Ptr::new(NonNull::new(&mut val2 as *mut i32));
624    /// unsafe {
625    ///     ptr1.swap(ptr2);
626    /// }
627    /// assert_eq!(val1, 20);
628    /// assert_eq!(val2, 10);
629    /// ```
630    #[inline]
631    pub unsafe fn swap(self, with: Ptr<T>) {
632        // Safety: The caller guarantees both pointers are valid.
633        unsafe { core::ptr::swap(self.as_mut_ptr(), with.as_mut_ptr()) }
634    }
635
636    /// Copies `count` items from `self` to `dest`. The source and destination may overlap.
637    ///
638    /// # Safety
639    ///
640    /// * Both pointers must be non-null.
641    /// * Both pointers must be valid for reads and writes.
642    /// * Both pointers must be properly aligned.
643    ///
644    /// # Examples
645    ///
646    /// ```rust
647    /// use atomic_tagged_ptr::Ptr;
648    /// use std::ptr::NonNull;
649    ///
650    /// let mut arr = [1, 2, 3];
651    /// let ptr1 = Ptr::new(NonNull::new(&mut arr[0] as *mut i32));
652    /// let ptr2 = Ptr::new(NonNull::new(&mut arr[1] as *mut i32));
653    /// unsafe {
654    ///     ptr1.copy_to(ptr2, 2);
655    /// }
656    /// assert_eq!(arr, [1, 1, 2]);
657    /// ```
658    #[inline]
659    pub unsafe fn copy_to(self, dest: Ptr<T>, count: usize) {
660        // Safety: The caller guarantees the pointers are valid.
661        unsafe { core::ptr::copy(self.as_ptr(), dest.as_mut_ptr(), count) }
662    }
663
664    /// Copies `count` items from `self` to `dest`. The source and destination must not overlap.
665    ///
666    /// # Safety
667    ///
668    /// * Both pointers must be non-null.
669    /// * Both pointers must be valid for reads and writes.
670    /// * Both pointers must be properly aligned.
671    /// * The memory regions must not overlap.
672    ///
673    /// # Examples
674    ///
675    /// ```rust
676    /// use atomic_tagged_ptr::Ptr;
677    /// use std::ptr::NonNull;
678    ///
679    /// let mut arr1 = [1, 2, 3];
680    /// let mut arr2 = [0, 0, 0];
681    /// let ptr1 = Ptr::new(NonNull::new(&mut arr1[0] as *mut i32));
682    /// let ptr2 = Ptr::new(NonNull::new(&mut arr2[0] as *mut i32));
683    /// unsafe {
684    ///     ptr1.copy_to_nonoverlapping(ptr2, 3);
685    /// }
686    /// assert_eq!(arr2, [1, 2, 3]);
687    /// ```
688    #[inline]
689    pub unsafe fn copy_to_nonoverlapping(self, dest: Ptr<T>, count: usize) {
690        // Safety: The caller guarantees the pointers are valid.
691        unsafe { core::ptr::copy_nonoverlapping(self.as_ptr(), dest.as_mut_ptr(), count) }
692    }
693
694    /// Copies `count` items from `src` to `self`. The source and destination may overlap.
695    ///
696    /// # Safety
697    ///
698    /// * Both pointers must be non-null.
699    /// * Both pointers must be valid for reads and writes.
700    /// * Both pointers must be properly aligned.
701    ///
702    /// # Examples
703    ///
704    /// ```rust
705    /// use atomic_tagged_ptr::Ptr;
706    /// use std::ptr::NonNull;
707    ///
708    /// let mut arr = [1, 2, 3];
709    /// let ptr1 = Ptr::new(NonNull::new(&mut arr[1] as *mut i32));
710    /// let ptr2 = Ptr::new(NonNull::new(&mut arr[0] as *mut i32));
711    /// unsafe {
712    ///     ptr1.copy_from(ptr2, 2);
713    /// }
714    /// assert_eq!(arr, [1, 1, 2]);
715    /// ```
716    #[inline]
717    pub unsafe fn copy_from(self, src: Ptr<T>, count: usize) {
718        // Safety: The caller guarantees the pointers are valid.
719        unsafe { core::ptr::copy(src.as_ptr(), self.as_mut_ptr(), count) }
720    }
721
722    /// Copies `count` items from `src` to `self`. The source and destination must not overlap.
723    ///
724    /// # Safety
725    ///
726    /// * Both pointers must be non-null.
727    /// * Both pointers must be valid for reads and writes.
728    /// * Both pointers must be properly aligned.
729    /// * The memory regions must not overlap.
730    ///
731    /// # Examples
732    ///
733    /// ```rust
734    /// use atomic_tagged_ptr::Ptr;
735    /// use std::ptr::NonNull;
736    ///
737    /// let mut arr1 = [1, 2, 3];
738    /// let mut arr2 = [0, 0, 0];
739    /// let ptr1 = Ptr::new(NonNull::new(&mut arr2[0] as *mut i32));
740    /// let ptr2 = Ptr::new(NonNull::new(&mut arr1[0] as *mut i32));
741    /// unsafe {
742    ///     ptr1.copy_from_nonoverlapping(ptr2, 3);
743    /// }
744    /// assert_eq!(arr2, [1, 2, 3]);
745    /// ```
746    #[inline]
747    pub unsafe fn copy_from_nonoverlapping(self, src: Ptr<T>, count: usize) {
748        // Safety: The caller guarantees the pointers are valid.
749        unsafe { core::ptr::copy_nonoverlapping(src.as_ptr(), self.as_mut_ptr(), count) }
750    }
751
752    /// Calculates the offset from a pointer.
753    ///
754    /// If the pointer is null, this returns a null pointer.
755    ///
756    /// # Safety
757    ///
758    /// Both the starting and resulting pointer must be either in bounds or one byte past the end of the same allocated object.
759    ///
760    /// # Examples
761    ///
762    /// ```rust
763    /// use atomic_tagged_ptr::Ptr;
764    /// use std::ptr::NonNull;
765    ///
766    /// let mut arr = [10, 20, 30];
767    /// let ptr = Ptr::new(NonNull::new(&mut arr[0] as *mut i32));
768    /// unsafe {
769    ///     let offset_ptr = ptr.offset(1);
770    ///     assert_eq!(offset_ptr.read(), 20);
771    /// }
772    /// ```
773    #[inline]
774    pub unsafe fn offset(self, count: isize) -> Self {
775        Self {
776            inner: self
777                .inner
778                .map(|p| unsafe { NonNull::new_unchecked(p.as_ptr().offset(count)) }),
779        }
780    }
781
782    /// Calculates the offset from a pointer (positive offset).
783    ///
784    /// If the pointer is null, this returns a null pointer.
785    ///
786    /// # Safety
787    ///
788    /// Both the starting and resulting pointer must be either in bounds or one byte past the end of the same allocated object.
789    ///
790    /// # Examples
791    ///
792    /// ```rust
793    /// use atomic_tagged_ptr::Ptr;
794    /// use std::ptr::NonNull;
795    ///
796    /// let mut arr = [10, 20, 30];
797    /// let ptr = Ptr::new(NonNull::new(&mut arr[0] as *mut i32));
798    /// unsafe {
799    ///     let offset_ptr = ptr.add(2);
800    ///     assert_eq!(offset_ptr.read(), 30);
801    /// }
802    /// ```
803    #[inline]
804    pub unsafe fn add(self, count: usize) -> Self {
805        Self {
806            inner: self
807                .inner
808                .map(|p| unsafe { NonNull::new_unchecked(p.as_ptr().add(count)) }),
809        }
810    }
811
812    /// Calculates the offset from a pointer (negative offset).
813    ///
814    /// If the pointer is null, this returns a null pointer.
815    ///
816    /// # Safety
817    ///
818    /// Both the starting and resulting pointer must be either in bounds or one byte past the end of the same allocated object.
819    ///
820    /// # Examples
821    ///
822    /// ```rust
823    /// use atomic_tagged_ptr::Ptr;
824    /// use std::ptr::NonNull;
825    ///
826    /// let mut arr = [10, 20, 30];
827    /// let ptr = Ptr::new(NonNull::new(&mut arr[2] as *mut i32));
828    /// unsafe {
829    ///     let offset_ptr = ptr.sub(1);
830    ///     assert_eq!(offset_ptr.read(), 20);
831    /// }
832    /// ```
833    #[inline]
834    pub unsafe fn sub(self, count: usize) -> Self {
835        Self {
836            inner: self
837                .inner
838                .map(|p| unsafe { NonNull::new_unchecked(p.as_ptr().sub(count)) }),
839        }
840    }
841
842    /// Calculates the offset from a pointer using wrapping arithmetic.
843    ///
844    /// If the pointer is null, this returns a null pointer.
845    ///
846    /// # Examples
847    ///
848    /// ```rust
849    /// use atomic_tagged_ptr::Ptr;
850    /// use std::ptr::NonNull;
851    ///
852    /// let mut arr = [10, 20, 30];
853    /// let ptr = Ptr::new(NonNull::new(&mut arr[0] as *mut i32));
854    /// let offset_ptr = ptr.wrapping_offset(1);
855    /// assert_eq!(unsafe { offset_ptr.read() }, 20);
856    /// ```
857    #[inline]
858    pub fn wrapping_offset(self, count: isize) -> Self {
859        Self {
860            inner: self
861                .inner
862                .map(|p| unsafe { NonNull::new_unchecked(p.as_ptr().wrapping_offset(count)) }),
863        }
864    }
865
866    /// Calculates the offset from a pointer using wrapping arithmetic (positive offset).
867    ///
868    /// If the pointer is null, this returns a null pointer.
869    ///
870    /// # Examples
871    ///
872    /// ```rust
873    /// use atomic_tagged_ptr::Ptr;
874    /// use std::ptr::NonNull;
875    ///
876    /// let mut arr = [10, 20, 30];
877    /// let ptr = Ptr::new(NonNull::new(&mut arr[0] as *mut i32));
878    /// let offset_ptr = ptr.wrapping_add(2);
879    /// assert_eq!(unsafe { offset_ptr.read() }, 30);
880    /// ```
881    #[inline]
882    pub fn wrapping_add(self, count: usize) -> Self {
883        Self {
884            inner: self
885                .inner
886                .map(|p| unsafe { NonNull::new_unchecked(p.as_ptr().wrapping_add(count)) }),
887        }
888    }
889
890    /// Calculates the offset from a pointer using wrapping arithmetic (negative offset).
891    ///
892    /// If the pointer is null, this returns a null pointer.
893    ///
894    /// # Examples
895    ///
896    /// ```rust
897    /// use atomic_tagged_ptr::Ptr;
898    /// use std::ptr::NonNull;
899    ///
900    /// let mut arr = [10, 20, 30];
901    /// let ptr = Ptr::new(NonNull::new(&mut arr[2] as *mut i32));
902    /// let offset_ptr = ptr.wrapping_sub(1);
903    /// assert_eq!(unsafe { offset_ptr.read() }, 20);
904    /// ```
905    #[inline]
906    pub fn wrapping_sub(self, count: usize) -> Self {
907        Self {
908            inner: self
909                .inner
910                .map(|p| unsafe { NonNull::new_unchecked(p.as_ptr().wrapping_sub(count)) }),
911        }
912    }
913}
914
915impl<T> fmt::Pointer for Ptr<T> {
916    #[inline]
917    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
918        fmt::Pointer::fmt(&self.as_ptr(), f)
919    }
920}
921
922impl<T> PartialOrd for Ptr<T> {
923    #[inline]
924    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
925        Some(self.cmp(other))
926    }
927}
928
929impl<T> Ord for Ptr<T> {
930    #[inline]
931    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
932        self.as_ptr().cmp(&other.as_ptr())
933    }
934}
935
936impl<T> From<Ptr<T>> for *const T {
937    #[inline]
938    fn from(ptr: Ptr<T>) -> Self {
939        ptr.as_ptr()
940    }
941}
942
943impl<T> From<Ptr<T>> for *mut T {
944    #[inline]
945    fn from(ptr: Ptr<T>) -> Self {
946        ptr.as_mut_ptr()
947    }
948}
949
950impl<T> From<Ptr<T>> for Option<*const T> {
951    #[inline]
952    fn from(ptr: Ptr<T>) -> Self {
953        ptr.inner.map(|p| p.as_ptr() as *const T)
954    }
955}
956
957impl<T> From<Ptr<T>> for Option<*mut T> {
958    #[inline]
959    fn from(ptr: Ptr<T>) -> Self {
960        ptr.inner.map(|p| p.as_ptr())
961    }
962}
963
964// --- PartialEq implementations to ensure seamless forward compatibility ---
965
966impl<T> PartialEq for Ptr<T> {
967    #[inline]
968    fn eq(&self, other: &Self) -> bool {
969        self.inner == other.inner
970    }
971}
972
973impl<T> Eq for Ptr<T> {}
974
975impl<T> core::hash::Hash for Ptr<T> {
976    #[inline]
977    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
978        self.inner.hash(state);
979    }
980}
981
982impl<T> PartialEq<Option<NonNull<T>>> for Ptr<T> {
983    #[inline]
984    fn eq(&self, other: &Option<NonNull<T>>) -> bool {
985        self.inner == *other
986    }
987}
988
989impl<T> PartialEq<NonNull<T>> for Ptr<T> {
990    #[inline]
991    fn eq(&self, other: &NonNull<T>) -> bool {
992        self.inner == Some(*other)
993    }
994}
995
996impl<T> PartialEq<*const T> for Ptr<T> {
997    #[inline]
998    fn eq(&self, other: &*const T) -> bool {
999        self.as_ptr() == *other
1000    }
1001}
1002
1003impl<T> PartialEq<*mut T> for Ptr<T> {
1004    #[inline]
1005    fn eq(&self, other: &*mut T) -> bool {
1006        self.as_mut_ptr() == *other
1007    }
1008}
1009
1010// --- From / Into conversion implementations for Ptr<T> ---
1011
1012impl<T> From<Option<NonNull<T>>> for Ptr<T> {
1013    #[inline]
1014    fn from(ptr: Option<NonNull<T>>) -> Self {
1015        Self { inner: ptr }
1016    }
1017}
1018
1019impl<T> From<NonNull<T>> for Ptr<T> {
1020    #[inline]
1021    fn from(ptr: NonNull<T>) -> Self {
1022        Self { inner: Some(ptr) }
1023    }
1024}
1025
1026impl<T> From<*const T> for Ptr<T> {
1027    #[inline]
1028    fn from(ptr: *const T) -> Self {
1029        Self {
1030            inner: NonNull::new(ptr as *mut T),
1031        }
1032    }
1033}
1034
1035impl<T> From<*mut T> for Ptr<T> {
1036    #[inline]
1037    fn from(ptr: *mut T) -> Self {
1038        Self {
1039            inner: NonNull::new(ptr),
1040        }
1041    }
1042}
1043
1044impl<T> From<TaggedPtr<T>> for Ptr<T> {
1045    #[inline]
1046    fn from(tagged: TaggedPtr<T>) -> Self {
1047        tagged.ptr
1048    }
1049}
1050
1051impl<T> From<Ptr<T>> for Option<NonNull<T>> {
1052    #[inline]
1053    fn from(ptr: Ptr<T>) -> Self {
1054        ptr.inner
1055    }
1056}