plux_rs/utils/
ptr.rs

1use std::{
2    marker::PhantomData,
3    sync::atomic::{AtomicPtr, Ordering},
4};
5
6/// A thread-safe pointer wrapper for shared mutable access.
7///
8/// Ptr provides a way to safely share mutable references across threads using atomic operations.
9/// It wraps an `AtomicPtr` and provides methods to access the underlying data safely.
10///
11/// # Type Parameters
12///
13/// * `'a` - Lifetime parameter for the reference
14/// * `T` - Type of the data being pointed to
15///
16/// # Safety
17///
18/// This type uses unsafe operations internally but provides a safe interface.
19/// The caller must ensure that the pointer remains valid for the lifetime `'a`.
20///
21/// # Example
22///
23/// ```rust
24/// use plux_rs::utils::Ptr;
25///
26/// let mut data = 42;
27/// let ptr = Ptr::new(&mut data);
28///
29/// // Access as immutable reference
30/// let value = ptr.as_ref();
31/// assert_eq!(*value, 42);
32///
33/// // Access as mutable reference
34/// let mut_ref = ptr.as_mut();
35/// *mut_ref = 24;
36/// assert_eq!(*ptr.as_ref(), 24);
37/// ```
38#[derive(Debug)]
39pub struct Ptr<'a, T: 'a> {
40    value: AtomicPtr<T>,
41    marker: PhantomData<&'a T>,
42}
43
44impl<'a, T> Ptr<'a, T> {
45    /// Creates a new Ptr from a mutable pointer.
46    ///
47    /// # Parameters
48    ///
49    /// * `value` - Raw mutable pointer to the data
50    ///
51    /// # Returns
52    ///
53    /// Returns a new Ptr instance.
54    ///
55    /// # Safety
56    ///
57    /// The caller must ensure that the pointer remains valid for the lifetime `'a`
58    /// and that no other mutable references to the same data exist.
59    pub const fn new(value: *mut T) -> Self {
60        Self {
61            value: AtomicPtr::new(value),
62            marker: PhantomData,
63        }
64    }
65
66    /// Returns the raw pointer.
67    ///
68    /// # Returns
69    ///
70    /// Returns the underlying `*mut T` pointer.
71    pub fn as_ptr(&self) -> *mut T {
72        self.value.load(Ordering::Relaxed)
73    }
74
75    /// Returns an immutable reference to the data.
76    ///
77    /// # Returns
78    ///
79    /// Returns `&T` to the underlying data.
80    ///
81    /// # Safety
82    ///
83    /// This method is safe as long as the original pointer was valid and no mutable
84    /// references are being used concurrently.
85    pub fn as_ref(&self) -> &T {
86        unsafe { &*self.value.load(Ordering::Relaxed) }
87    }
88
89    /// Returns a mutable reference to the data.
90    ///
91    /// # Returns
92    ///
93    /// Returns `&mut T` to the underlying data.
94    ///
95    /// # Safety
96    ///
97    /// This method is safe as long as the original pointer was valid and no other
98    /// references (mutable or immutable) are being used concurrently.
99    pub fn as_mut(&self) -> &mut T {
100        unsafe { &mut *self.value.load(Ordering::Relaxed) }
101    }
102}