object_collection/
map.rs

1use std::borrow::Borrow;
2use std::collections::hash_map::{IntoIter, Keys, RandomState};
3use std::collections::HashMap;
4use std::hash::{BuildHasher, Hash};
5use std::os::raw::c_void;
6
7#[repr(C)]
8#[derive(Debug)]
9pub struct ObjectMap<K, S = RandomState> {
10    inner: HashMap<K, *mut c_void, S>,
11}
12
13impl<K, S> ObjectMap<K, S> {
14    pub fn keys(&self) -> Keys<'_, K, *mut c_void> {
15        self.inner.keys()
16    }
17
18    pub fn len(&self) -> usize {
19        self.inner.len()
20    }
21
22    pub fn capacity(&self) -> usize {
23        self.inner.capacity()
24    }
25
26    pub fn is_empty(&self) -> bool {
27        self.inner.is_empty()
28    }
29
30    pub fn clear(&mut self) {
31        self.inner.clear()
32    }
33
34    pub fn hasher(&mut self) -> &S {
35        self.inner.hasher()
36    }
37}
38
39impl<K> ObjectMap<K, RandomState> {
40    pub fn new() -> Self {
41        ObjectMap {
42            inner: HashMap::new(),
43        }
44    }
45
46    pub fn with_capacity(capacity: usize) -> Self {
47        ObjectMap {
48            inner: HashMap::with_capacity(capacity),
49        }
50    }
51}
52
53impl<K, S> ObjectMap<K, S>
54where
55    K: Eq + Hash,
56    S: BuildHasher,
57{
58    pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self {
59        ObjectMap {
60            inner: HashMap::with_capacity_and_hasher(capacity, hasher),
61        }
62    }
63
64    pub fn insert<V>(&mut self, k: K, v: V) -> Option<*mut c_void> {
65        let ptr = Box::leak(Box::new(v));
66        self.inner.insert(k, ptr as *mut _ as *mut c_void)
67    }
68
69    pub fn insert_raw(&mut self, k: K, ptr: *mut c_void) -> Option<*mut c_void> {
70        self.inner.insert(k, ptr)
71    }
72
73    pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<*mut c_void>
74    where
75        K: Borrow<Q>,
76        Q: Hash + Eq,
77    {
78        self.inner.remove(k)
79    }
80
81    pub fn get<Q: ?Sized, T>(&self, k: &Q) -> Option<&T>
82    where
83        K: Borrow<Q>,
84        Q: Hash + Eq,
85    {
86        match self.inner.get(k) {
87            Some(v) => unsafe {
88                Some(std::ptr::read_unaligned(
89                    v as *const *mut c_void as *const &T,
90                ))
91            },
92            None => None,
93        }
94    }
95
96    pub fn get_mut<Q: ?Sized, T>(&mut self, k: &Q) -> Option<&mut T>
97    where
98        K: Borrow<Q>,
99        Q: Hash + Eq,
100    {
101        match self.inner.get_mut(k) {
102            Some(v) => unsafe {
103                Some(std::ptr::read_unaligned(
104                    v as *mut *mut c_void as *mut &mut T,
105                ))
106            },
107            None => None,
108        }
109    }
110
111    pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
112    where
113        K: Borrow<Q>,
114        Q: Hash + Eq,
115    {
116        self.inner.contains_key(k)
117    }
118}
119
120impl<K> Default for ObjectMap<K, RandomState> {
121    fn default() -> Self {
122        Self::new()
123    }
124}
125
126impl<K, S> IntoIterator for ObjectMap<K, S> {
127    type Item = (K, *mut c_void);
128    type IntoIter = IntoIter<K, *mut c_void>;
129
130    #[inline]
131    fn into_iter(self) -> IntoIter<K, *mut c_void> {
132        self.inner.into_iter()
133    }
134}
135
136#[cfg(test)]
137mod tests {
138    use crate::ObjectMap;
139
140    #[test]
141    fn test() {
142        let mut map = ObjectMap::new();
143        assert!(map.is_empty());
144        map.insert(1, 2i32);
145        map.insert(2, true);
146        assert!(!map.is_empty());
147        let x: &mut i32 = map.get_mut(&1).unwrap();
148        assert_eq!(&mut 2, x);
149        let y: &mut bool = map.get_mut(&2).unwrap();
150        assert_eq!(&mut true, y);
151    }
152}