shape_value/v2/
typed_option.rs1#[repr(C)]
20pub struct PrimitiveOption<T: Copy> {
21 pub has_value: u8,
23 pub _pad: [u8; 7],
25 pub value: T,
27}
28
29impl<T: Copy> PrimitiveOption<T> {
30 #[inline]
32 pub fn some(value: T) -> Self {
33 Self {
34 has_value: 1,
35 _pad: [0; 7],
36 value,
37 }
38 }
39
40 #[inline]
45 pub fn none() -> Self
46 where
47 T: Default,
48 {
49 Self {
50 has_value: 0,
51 _pad: [0; 7],
52 value: T::default(),
53 }
54 }
55
56 #[inline]
58 pub fn is_some(&self) -> bool {
59 self.has_value != 0
60 }
61
62 #[inline]
64 pub fn is_none(&self) -> bool {
65 self.has_value == 0
66 }
67
68 #[inline]
70 pub fn get(&self) -> Option<T> {
71 if self.is_some() {
72 Some(self.value)
73 } else {
74 None
75 }
76 }
77}
78
79pub type HeapOption<T> = *const T;
85
86#[inline]
88pub fn heap_option_is_none<T>(ptr: *const T) -> bool {
89 ptr.is_null()
90}
91
92#[inline]
94pub fn heap_option_is_some<T>(ptr: *const T) -> bool {
95 !ptr.is_null()
96}
97
98pub const PRIMITIVE_OPTION_OFFSET_HAS_VALUE: usize = 0;
100pub const PRIMITIVE_OPTION_OFFSET_VALUE: usize = 8;
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105
106 #[test]
107 fn test_primitive_option_f64_some() {
108 let opt = PrimitiveOption::some(3.14f64);
109 assert!(opt.is_some());
110 assert!(!opt.is_none());
111 assert_eq!(opt.get(), Some(3.14f64));
112 }
113
114 #[test]
115 fn test_primitive_option_f64_none() {
116 let opt = PrimitiveOption::<f64>::none();
117 assert!(opt.is_none());
118 assert!(!opt.is_some());
119 assert_eq!(opt.get(), None);
120 }
121
122 #[test]
123 fn test_primitive_option_i64_some() {
124 let opt = PrimitiveOption::some(42i64);
125 assert!(opt.is_some());
126 assert_eq!(opt.get(), Some(42i64));
127 }
128
129 #[test]
130 fn test_primitive_option_i64_none() {
131 let opt = PrimitiveOption::<i64>::none();
132 assert!(opt.is_none());
133 assert_eq!(opt.get(), None);
134 }
135
136 #[test]
137 fn test_primitive_option_i32_some() {
138 let opt = PrimitiveOption::some(99i32);
139 assert!(opt.is_some());
140 assert_eq!(opt.get(), Some(99i32));
141 }
142
143 #[test]
144 fn test_primitive_option_i32_none() {
145 let opt = PrimitiveOption::<i32>::none();
146 assert!(opt.is_none());
147 assert_eq!(opt.get(), None);
148 }
149
150 #[test]
151 fn test_primitive_option_bool_some() {
152 let opt = PrimitiveOption::some(true);
153 assert!(opt.is_some());
154 assert_eq!(opt.get(), Some(true));
155
156 let opt_false = PrimitiveOption::some(false);
157 assert!(opt_false.is_some());
158 assert_eq!(opt_false.get(), Some(false));
159 }
160
161 #[test]
162 fn test_primitive_option_bool_none() {
163 let opt = PrimitiveOption::<bool>::none();
164 assert!(opt.is_none());
165 assert_eq!(opt.get(), None);
166 }
167
168 #[test]
169 fn test_size_of_primitive_option_f64() {
170 assert_eq!(std::mem::size_of::<PrimitiveOption<f64>>(), 16);
171 }
172
173 #[test]
174 fn test_size_of_primitive_option_i64() {
175 assert_eq!(std::mem::size_of::<PrimitiveOption<i64>>(), 16);
176 }
177
178 #[test]
179 fn test_size_of_primitive_option_i32() {
180 assert_eq!(std::mem::size_of::<PrimitiveOption<i32>>(), 12);
183 }
184
185 #[test]
186 fn test_size_of_primitive_option_bool() {
187 assert_eq!(std::mem::size_of::<PrimitiveOption<bool>>(), 9);
189 }
190
191 #[test]
192 fn test_field_offsets_f64() {
193 let opt = PrimitiveOption::some(1.0f64);
194 let base = &opt as *const _ as usize;
195 let has_value_offset = &opt.has_value as *const _ as usize - base;
196 let value_offset = &opt.value as *const _ as usize - base;
197
198 assert_eq!(has_value_offset, PRIMITIVE_OPTION_OFFSET_HAS_VALUE);
199 assert_eq!(value_offset, PRIMITIVE_OPTION_OFFSET_VALUE);
200 }
201
202 #[test]
203 fn test_heap_option_none() {
204 let ptr: HeapOption<u8> = std::ptr::null();
205 assert!(heap_option_is_none(ptr));
206 assert!(!heap_option_is_some(ptr));
207 }
208
209 #[test]
210 fn test_heap_option_some() {
211 let val: u8 = 42;
212 let ptr: HeapOption<u8> = &val as *const u8;
213 assert!(heap_option_is_some(ptr));
214 assert!(!heap_option_is_none(ptr));
215 }
216
217 #[test]
218 fn test_heap_option_is_pointer_sized() {
219 assert_eq!(std::mem::size_of::<HeapOption<u8>>(), 8);
221 assert_eq!(std::mem::size_of::<HeapOption<f64>>(), 8);
222 }
223}