tagged_pointer_as_enum/
lib.rs1#![doc = include_str!("../README.md")]
2
3#[cfg(not(target_pointer_width = "64"))]
4compile_error!("Pointer size must be 64 bits");
5
6mod tagged_pointer;
7pub use tagged_pointer::TaggedPointer;
8
9mod tagged_pointer_value;
10pub use tagged_pointer_value::TaggedPointerValue;
11
12#[macro_use]
13mod macros;
14
15impl TaggedPointerValue for bool {}
16
17impl TaggedPointerValue for u8 {}
18impl TaggedPointerValue for u16 {}
19impl TaggedPointerValue for u32 {}
20impl TaggedPointerValue for i8 {}
21impl TaggedPointerValue for i16 {}
22impl TaggedPointerValue for i32 {}
23
24impl<T> TaggedPointerValue for Box<T> {}
25impl<T> TaggedPointerValue for Option<Box<T>> {}
26
27#[cfg(test)]
28mod test {
29 use super::*;
30
31 const TEST_BITS: u8 = 5;
32 const BOOL_TAG: usize = 1;
33 const U8_TAG: usize = 2;
34 const BOX_STRING_TAG: usize = 3;
35 const OPTION_BOX_STRING_TAG: usize = 4;
36
37 #[test]
38 fn test_bool() {
39 let ptr_true = TaggedPointer::<TEST_BITS>::new::<bool, BOOL_TAG>(true);
40 assert_eq!(ptr_true.tag(), BOOL_TAG);
41 assert!(ptr_true.is::<BOOL_TAG>());
42 assert!(!ptr_true.is::<U8_TAG>());
43 assert_eq!(ptr_true.unwrap::<bool>(), true);
44
45 let ptr_false = TaggedPointer::<TEST_BITS>::new::<bool, BOOL_TAG>(false);
46 assert_eq!(ptr_false.tag(), BOOL_TAG);
47 assert!(ptr_false.is::<BOOL_TAG>());
48 assert!(!ptr_false.is::<U8_TAG>());
49 assert_eq!(ptr_false.unwrap::<bool>(), false);
50 }
51
52 #[test]
53 fn test_u8() {
54 let ptr42 = TaggedPointer::<TEST_BITS>::new::<u8, U8_TAG>(42);
55 assert_eq!(ptr42.tag(), U8_TAG);
56 assert!(ptr42.is::<U8_TAG>());
57 assert!(!ptr42.is::<BOOL_TAG>());
58 assert_eq!(ptr42.unwrap::<u8>(), 42);
59 }
60
61 #[test]
62 fn test_box() {
63 let ptr = Box::new(String::from("foo"));
64 let ptr_s = TaggedPointer::<TEST_BITS>::new::<Box<String>, BOX_STRING_TAG>(ptr);
65 assert_eq!(ptr_s.tag(), BOX_STRING_TAG);
66 assert!(ptr_s.is::<BOX_STRING_TAG>());
67 assert!(!ptr_s.is::<BOOL_TAG>());
68 assert_eq!(
69 ptr_s.borrow_value::<Box<String>, String>(),
70 &String::from("foo")
71 );
72 assert_eq!(ptr_s.unwrap::<Box<String>>(), Box::new(String::from("foo")));
73 }
74
75 #[test]
76 fn test_option_box() {
77 let some_ptr = Some(Box::new(String::from("foo")));
78 let ptr_s =
79 TaggedPointer::<TEST_BITS>::new::<Option<Box<String>>, OPTION_BOX_STRING_TAG>(some_ptr);
80 assert_eq!(ptr_s.tag(), OPTION_BOX_STRING_TAG);
81 assert!(ptr_s.is::<OPTION_BOX_STRING_TAG>());
82 assert!(!ptr_s.is::<BOOL_TAG>());
83 assert_eq!(
84 ptr_s.unwrap::<Option<Box<String>>>(),
85 Some(Box::new(String::from("foo")))
86 );
87 }
88
89 #[test]
90 fn test_drop() {
91 let mut ptr = TaggedPointer::<TEST_BITS>::new::<bool, BOOL_TAG>(true);
92 ptr.drop_as::<bool>();
93
94 let mut ptr = TaggedPointer::<TEST_BITS>::new::<u8, U8_TAG>(42);
95 ptr.drop_as::<u8>();
96
97 let mut ptr = TaggedPointer::<TEST_BITS>::new::<Box<String>, BOX_STRING_TAG>(Box::new(
98 String::from("foo"),
99 ));
100 ptr.drop_as::<Box<String>>();
101 }
102}