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}