Skip to main content

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}