object_collection/
list.rs1use 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 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 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}