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}