rostl_primitives/
ooption.rs1use crate::traits::Cmov;
4use bytemuck::{Pod, Zeroable};
5
6#[repr(C)]
10#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Zeroable)]
11pub struct OOption<T>
12where
13 T: Cmov + Pod + Zeroable,
14{
15 pub value: T,
17 pub is_some: bool,
19}
20unsafe impl<T> Pod for OOption<T> where T: Cmov + Pod + Zeroable {}
21
22impl<T> OOption<T>
23where
24 T: Cmov + Pod + Zeroable,
25{
26 pub const fn new(value: T, is_some: bool) -> Self {
28 Self { value, is_some }
29 }
30
31 pub const fn is_some(&self) -> bool {
33 self.is_some
34 }
35
36 pub fn unwrap(&self) -> T {
38 assert!(self.is_some(), "Called `unwrap` on an `OOption` that is `None`.");
39 let mut ret = T::zeroed();
40 ret.cmov(&self.value, self.is_some);
41 ret
42 }
43}
44
45impl<T> OOption<T>
46where
47 T: Cmov + Pod + Zeroable + Default,
48{
49 pub fn unwrap_or_default(&self) -> T {
51 let mut ret = T::default();
52 ret.cmov(&self.value, self.is_some);
53 ret
54 }
55}
56
57impl<T> Cmov for OOption<T>
58where
59 T: Cmov + Pod + Zeroable,
60{
61 fn cmov(&mut self, other: &Self, choice: bool) {
62 self.value.cmov(&other.value, choice);
63 self.is_some.cmov(&other.is_some, choice);
64 }
65
66 fn cxchg(&mut self, other: &mut Self, choice: bool) {
67 let tmp_value = self.value;
68 self.value.cmov(&other.value, choice);
69 other.value.cmov(&tmp_value, choice);
70
71 let tmp_is_some = self.is_some;
72 self.is_some.cmov(&other.is_some, choice);
73 other.is_some.cmov(&tmp_is_some, choice);
74 }
75}