object_collection/
list.rs

1use std::collections::vec_deque::{Iter, IterMut};
2use std::collections::VecDeque;
3use std::os::raw::c_void;
4use std::ptr;
5
6#[repr(C)]
7#[derive(Debug, PartialEq, Eq)]
8pub struct ObjectList {
9    inner: VecDeque<*mut c_void>,
10}
11
12impl ObjectList {
13    pub fn new() -> Self {
14        ObjectList {
15            inner: VecDeque::new(),
16        }
17    }
18
19    pub fn front<T>(&mut self) -> Option<&T> {
20        match self.inner.front() {
21            Some(value) => unsafe {
22                let result = ptr::read_unaligned(value) as *mut T;
23                Some(&*result)
24            },
25            None => None,
26        }
27    }
28
29    pub fn front_mut<T>(&mut self) -> Option<&mut T> {
30        match self.inner.front_mut() {
31            Some(value) => unsafe {
32                let result = ptr::read_unaligned(value) as *mut T;
33                Some(&mut *result)
34            },
35            None => None,
36        }
37    }
38
39    pub fn front_mut_raw(&mut self) -> Option<*mut c_void> {
40        self.inner
41            .front_mut()
42            .map(|value| unsafe { ptr::read_unaligned(value) })
43    }
44
45    pub fn push_front<T>(&mut self, element: T) {
46        let ptr = Box::leak(Box::new(element));
47        self.inner.push_front(ptr as *mut _ as *mut c_void);
48    }
49
50    pub fn push_front_raw(&mut self, ptr: *mut c_void) {
51        self.inner.push_front(ptr);
52    }
53
54    /// 如果是闭包,还是要获取裸指针再手动转换,不然类型有问题
55    pub fn pop_front_raw(&mut self) -> Option<*mut c_void> {
56        self.inner.pop_front()
57    }
58
59    pub fn back<T>(&mut self) -> Option<&T> {
60        match self.inner.back() {
61            Some(value) => unsafe {
62                let result = ptr::read_unaligned(value) as *mut T;
63                Some(&*result)
64            },
65            None => None,
66        }
67    }
68
69    pub fn back_mut<T>(&mut self) -> Option<&mut T> {
70        match self.inner.back_mut() {
71            Some(value) => unsafe {
72                let result = ptr::read_unaligned(value) as *mut T;
73                Some(&mut *result)
74            },
75            None => None,
76        }
77    }
78
79    pub fn back_mut_raw(&mut self) -> Option<*mut c_void> {
80        self.inner
81            .back_mut()
82            .map(|value| unsafe { ptr::read_unaligned(value) })
83    }
84
85    pub fn push_back<T>(&mut self, element: T) {
86        let ptr = Box::leak(Box::new(element));
87        self.inner.push_back(ptr as *mut _ as *mut c_void);
88    }
89
90    pub fn push_back_raw(&mut self, ptr: *mut c_void) {
91        self.inner.push_back(ptr);
92    }
93
94    /// 如果是闭包,还是要获取裸指针再手动转换,不然类型有问题
95    pub fn pop_back_raw(&mut self) -> Option<*mut c_void> {
96        self.inner.pop_back()
97    }
98
99    pub fn len(&self) -> usize {
100        self.inner.len()
101    }
102
103    pub fn get<T>(&self, index: usize) -> Option<&T> {
104        match self.inner.get(index) {
105            Some(val) => unsafe {
106                let result = ptr::read_unaligned(val) as *mut T;
107                Some(&*result)
108            },
109            None => None,
110        }
111    }
112
113    pub fn get_mut<T>(&mut self, index: usize) -> Option<&mut T> {
114        match self.inner.get_mut(index) {
115            Some(val) => unsafe {
116                let result = ptr::read_unaligned(val) as *mut T;
117                Some(&mut *result)
118            },
119            None => None,
120        }
121    }
122
123    pub fn get_mut_raw(&mut self, index: usize) -> Option<*mut c_void> {
124        self.inner
125            .get_mut(index)
126            .map(|pointer| unsafe { ptr::read_unaligned(pointer) })
127    }
128
129    pub fn is_empty(&self) -> bool {
130        self.inner.is_empty()
131    }
132
133    pub fn move_front_to_back(&mut self) {
134        if let Some(pointer) = self.inner.pop_front() {
135            self.inner.push_back(pointer)
136        }
137    }
138
139    pub fn remove_raw(&mut self, val: *mut c_void) -> Option<*mut c_void> {
140        let index = self
141            .inner
142            .binary_search_by(|x| x.cmp(&val))
143            .unwrap_or_else(|x| x);
144        self.inner.remove(index)
145    }
146
147    pub fn iter_mut(&mut self) -> IterMut<'_, *mut c_void> {
148        self.inner.iter_mut()
149    }
150
151    pub fn iter(&self) -> Iter<'_, *mut c_void> {
152        self.inner.iter()
153    }
154}
155
156impl Default for ObjectList {
157    fn default() -> Self {
158        Self::new()
159    }
160}
161
162impl AsRef<ObjectList> for ObjectList {
163    fn as_ref(&self) -> &ObjectList {
164        self
165    }
166}
167
168impl AsMut<ObjectList> for ObjectList {
169    fn as_mut(&mut self) -> &mut ObjectList {
170        &mut *self
171    }
172}
173
174#[cfg(test)]
175mod tests {
176    use crate::ObjectList;
177    use std::ffi::c_void;
178
179    #[test]
180    fn test() {
181        let mut list = ObjectList::new();
182        assert!(list.is_empty());
183        list.push_back(1);
184        assert_eq!(&1, list.front().unwrap());
185        assert_eq!(&1, list.front().unwrap());
186        assert!(!list.is_empty());
187        list.push_back(true);
188        assert_eq!(&true, list.back().unwrap());
189        assert_eq!(&true, list.back().unwrap());
190
191        assert_eq!(&1, list.get(0).unwrap());
192        assert_eq!(&1, list.get(0).unwrap());
193        assert_eq!(&true, list.get_mut(1).unwrap());
194        assert_eq!(&true, list.get_mut(1).unwrap());
195
196        unsafe {
197            let b = list.pop_back_raw().unwrap() as *mut _ as *mut bool;
198            assert_eq!(true, *b);
199            let n = list.pop_back_raw().unwrap() as *mut _ as *mut i32;
200            assert_eq!(1, *n);
201        }
202    }
203
204    #[test]
205    fn test_remove_raw() {
206        let mut list = ObjectList::new();
207        list.push_back_raw(1 as *mut c_void);
208        list.push_back_raw(2 as *mut c_void);
209        list.push_back_raw(3 as *mut c_void);
210        list.remove_raw(2 as *mut c_void);
211        assert_eq!(1 as *mut c_void, list.pop_front_raw().unwrap());
212        assert_eq!(3 as *mut c_void, list.pop_back_raw().unwrap());
213    }
214}