orx_selfref_col/references/node_ptr.rs
1use crate::{MemoryPolicy, Node, SelfRefCol, Variant};
2use core::fmt::Debug;
3use orx_pinned_vec::PinnedVec;
4
5/// A wrapper around a node pointer.
6pub struct NodePtr<V: Variant> {
7 ptr: *mut Node<V>,
8}
9
10// Despite holding pointer to a Node, `NodePtr` implements `Send` since it does not provide access
11// to the pointer with the safe api. Unsafe api can be used to access the node. Safety of such access
12// can be verified by the `is_valid_for` method.
13unsafe impl<V: Variant> Send for NodePtr<V> where V::Item: Send {}
14
15// Despite holding pointer to a Node, `NodePtr` implements `Sync` since it does not provide access
16// to the pointer with the safe api. Unsafe api can be used to access the node. Safety of such access
17// can be verified by the `is_valid_for` method.
18unsafe impl<V: Variant> Sync for NodePtr<V> where V::Item: Sync {}
19
20impl<V: Variant> PartialEq for NodePtr<V> {
21 fn eq(&self, other: &Self) -> bool {
22 self.ptr == other.ptr
23 }
24}
25
26impl<V: Variant> Debug for NodePtr<V> {
27 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
28 f.debug_struct("NodeIdx")
29 .field("ptr", &(self.ptr as usize))
30 .finish()
31 }
32}
33
34impl<V: Variant> Copy for NodePtr<V> {}
35
36impl<V: Variant> Clone for NodePtr<V> {
37 fn clone(&self) -> Self {
38 *self
39 }
40}
41
42impl<V: Variant> NodePtr<V> {
43 /// Creates a new node pointer by wrapping the given `ptr`.
44 pub fn new(ptr: *const Node<V>) -> Self {
45 Self {
46 ptr: ptr as *mut Node<V>,
47 }
48 }
49
50 /// Returns true if:
51 ///
52 /// * `collection` owns this `NodePtr`, and
53 /// * the node, or corresponding element of the `collection`, that this pointer
54 /// is pointing at is still active;
55 ///
56 /// false otherwise.
57 ///
58 /// It is safe to use the unsafe methods of `NodePtr` if `is_valid_for(col)`
59 /// returns true where `col` is the collection that the pointer is created from.
60 #[inline(always)]
61 pub fn is_valid_for<M, P>(self, collection: &SelfRefCol<V, M, P>) -> bool
62 where
63 M: MemoryPolicy<V>,
64 P: PinnedVec<Node<V>>,
65 {
66 collection.nodes().contains_ptr(self.ptr) && unsafe { &*self.ptr }.is_active()
67 }
68
69 /// Returns the const raw pointer to the node.
70 ///
71 /// # SAFETY
72 ///
73 /// This method is unsafe as `NodePtr` implements `Send` and `Sync`.
74 ///
75 /// It is safe dereference the received pointer if we know that `is_valid_for(col)` would
76 /// return `true` where `col` is the collection that this pointer is created from.
77 #[inline(always)]
78 pub unsafe fn ptr(self) -> *const Node<V> {
79 self.ptr
80 }
81
82 /// Returns the mutable raw pointer to the node.
83 ///
84 /// # SAFETY
85 ///
86 /// This method is unsafe as `NodePtr` implements `Send` and `Sync`.
87 ///
88 /// It is safe dereference the received pointer if we know that `is_valid_for(col)` would
89 /// return `true` where `col` is the collection that this pointer is created from.
90 #[inline(always)]
91 pub unsafe fn ptr_mut(self) -> *mut Node<V> {
92 self.ptr
93 }
94
95 /// Returns a reference to the node.
96 ///
97 /// # Safety
98 ///
99 /// It is safe to directly access the underlying node if we know that `is_valid_for(col)` would
100 /// return `true` where `col` is the collection that this pointer is created from.
101 #[inline]
102 pub unsafe fn node<'a>(self) -> &'a Node<V> {
103 unsafe { &*self.ptr }
104 }
105
106 /// Returns a mutable reference to the node.
107 ///
108 /// # Safety
109 ///
110 /// It is safe to directly access the underlying node if we know that `is_valid_for(col)` would
111 /// return `true` where `col` is the collection that this pointer is created from.
112 #[inline]
113 #[allow(clippy::mut_from_ref)]
114 pub unsafe fn node_mut<'a>(self) -> &'a mut Node<V> {
115 unsafe { &mut *self.ptr }
116 }
117}