orx_concurrent_option/raw.rs
1use crate::{states::*, ConcurrentOption};
2use core::sync::atomic::Ordering;
3
4impl<T> ConcurrentOption<T> {
5 // raw
6
7 /// Returns:
8 /// * a raw `*const T` pointer to the underlying data when the option is of Some variant;
9 /// * `None` otherwise.
10 ///
11 /// See [`get_raw_with_order`] to explicitly set the ordering.
12 ///
13 /// [`get_raw_with_order`]: ConcurrentOption::get_raw_with_order
14 ///
15 /// # Example
16 ///
17 /// ```rust
18 /// use orx_concurrent_option::*;
19 ///
20 /// let x = ConcurrentOption::<String>::none();
21 /// let p = x.get_raw();
22 /// assert!(p.is_none());
23 ///
24 /// let x = ConcurrentOption::some(3.to_string());
25 /// let p = x.get_raw();
26 /// assert!(p.is_some());
27 /// assert_eq!(unsafe { p.unwrap().as_ref() }, Some(&3.to_string()));
28 /// ```
29 pub fn get_raw(&self) -> Option<*const T> {
30 match self.spin_get_handle(SOME, SOME) {
31 Some(_handle) => {
32 let x = unsafe { &*self.value.get() };
33 Some(x.as_ptr())
34 }
35 None => None,
36 }
37 }
38
39 /// Returns:
40 /// * a raw `*mut T` pointer to the underlying data when the option is of Some variant;
41 /// * `None` otherwise.
42 ///
43 /// See [`get_raw_mut_with_order`] to explicitly set the ordering.
44 ///
45 /// [`get_raw_mut_with_order`]: ConcurrentOption::get_raw_mut_with_order
46 ///
47 /// ```rust
48 /// use orx_concurrent_option::*;
49 ///
50 /// let x = ConcurrentOption::<String>::none();
51 /// let p = x.get_raw_mut();
52 /// assert!(p.is_none());
53 ///
54 /// let x = ConcurrentOption::some(3.to_string());
55 /// let p = x.get_raw_mut();
56 /// assert!(p.is_some());
57 /// assert_eq!(unsafe { p.unwrap().as_ref() }, Some(&3.to_string()));
58 ///
59 /// let p = x.get_raw().unwrap();
60 /// assert_eq!(unsafe { p.as_ref() }, Some(&3.to_string()));
61 ///
62 /// let p = x.get_raw_mut();
63 /// let p = p.unwrap();
64 /// let _ = unsafe { p.replace(7.to_string()) }; // only write leads to memory leak
65 /// assert_eq!(unsafe { x.as_ref() }, Some(&7.to_string()));
66 /// ```
67 pub fn get_raw_mut(&self) -> Option<*mut T> {
68 match self.spin_get_handle(SOME, SOME) {
69 Some(_handle) => {
70 let x = unsafe { &mut *self.value.get() };
71 Some(x.as_mut_ptr())
72 }
73 None => None,
74 }
75 }
76
77 // raw with-order
78
79 /// Returns:
80 /// * a raw `*const T` pointer to the underlying data when the option is of Some variant;
81 /// * `None` otherwise.
82 ///
83 /// Depending on requirement of the use case, `Relaxed`, `Acquire` or `SeqCst` can be used as the `order`.
84 ///
85 /// # Example
86 ///
87 /// ```rust
88 /// use orx_concurrent_option::*;
89 /// use core::sync::atomic::Ordering;
90 ///
91 /// let x = ConcurrentOption::<String>::none();
92 /// let p = x.get_raw_with_order(Ordering::SeqCst);
93 /// assert!(p.is_none());
94 ///
95 /// let x = ConcurrentOption::some(3.to_string());
96 /// let p = x.get_raw_with_order(Ordering::Acquire);
97 /// assert!(p.is_some());
98 /// assert_eq!(unsafe { p.unwrap().as_ref() }, Some(&3.to_string()));
99 /// ```
100 pub fn get_raw_with_order(&self, order: Ordering) -> Option<*const T> {
101 match self.state.load(order) {
102 SOME => {
103 let x = unsafe { &*self.value.get() };
104 Some(x.as_ptr())
105 }
106 _ => None,
107 }
108 }
109
110 /// Returns:
111 /// * a raw `*mut T` pointer to the underlying data when the option is of Some variant;
112 /// * `None` otherwise.
113 ///
114 /// Depending on requirement of the use case, `Relaxed`, `Acquire` or `SeqCst` can be used as the `order`.
115 ///
116 /// ```rust
117 /// use orx_concurrent_option::*;
118 /// use core::sync::atomic::Ordering;
119 ///
120 /// let x = ConcurrentOption::<String>::none();
121 /// let p = x.get_raw_mut_with_order(Ordering::SeqCst);
122 /// assert!(p.is_none());
123 ///
124 /// let x = ConcurrentOption::some(3.to_string());
125 /// let p = x.get_raw_mut_with_order(Ordering::Acquire);
126 /// assert!(p.is_some());
127 /// assert_eq!(unsafe { p.unwrap().as_ref() }, Some(&3.to_string()));
128 ///
129 /// let p = x.get_raw_mut_with_order(Ordering::Relaxed).unwrap();
130 /// assert_eq!(unsafe { p.as_ref() }, Some(&3.to_string()));
131 ///
132 /// let p = x.get_raw_mut_with_order(Ordering::Relaxed);
133 /// let p = p.unwrap();
134 /// let _ = unsafe { p.replace(7.to_string()) }; // only write leads to memory leak
135 /// assert_eq!(unsafe { x.as_ref() }, Some(&7.to_string()));
136 /// ```
137 pub fn get_raw_mut_with_order(&self, order: Ordering) -> Option<*mut T> {
138 match self.state.load(order) {
139 SOME => {
140 let x = unsafe { &mut *self.value.get() };
141 Some(x.as_mut_ptr())
142 }
143 _ => None,
144 }
145 }
146}