toolbox_rs/
linked_list.rs1use std::marker::PhantomData;
19use std::ptr::NonNull;
20
21pub struct LinkedList<T> {
22 front: Link<T>,
23 back: Link<T>,
24 len: usize,
25 _ghost: PhantomData<T>,
26}
27pub type ListCursor<T> = NonNull<Node<T>>;
28type Link<T> = Option<ListCursor<T>>;
29
30pub struct Node<T> {
31 next: Link<T>,
32 prev: Link<T>,
33 elem: T,
34}
35
36impl<T> LinkedList<T> {
37 pub fn new() -> Self {
38 Self {
39 front: None,
40 back: None,
41 len: 0,
42 _ghost: PhantomData,
43 }
44 }
45
46 pub fn push_front(&mut self, elem: T) -> ListCursor<T> {
47 unsafe {
49 let new = NonNull::new_unchecked(Box::into_raw(Box::new(Node {
50 next: None,
51 prev: None,
52 elem,
53 })));
54 if let Some(old) = self.front {
55 (*old.as_ptr()).next = Some(new);
57 (*new.as_ptr()).prev = Some(old);
58 } else {
59 self.back = Some(new);
62 }
63 self.front = Some(new);
65 self.len += 1;
66
67 new
68 }
69 }
70
71 pub fn move_to_front(&mut self, b: &ListCursor<T>) {
72 if self.is_empty() {
73 return;
74 }
75
76 if let Some(front) = self.front {
77 if front == *b {
79 return;
80 }
81 }
82
83 unsafe {
85 let a = (*b.as_ptr()).next;
87 (*a.unwrap().as_ptr()).prev = (*b.as_ptr()).prev;
88 if let Some(c) = (*b.as_ptr()).prev {
89 (*c.as_ptr()).next = (*b.as_ptr()).next;
90 }
91
92 if self.back.unwrap() == *b {
94 debug_assert!((*b.as_ptr()).prev.is_none());
95 self.back = a;
96 }
97 }
98
99 unsafe {
101 let x = self.front;
103
104 (*b.as_ptr()).prev = x;
105 (*b.as_ptr()).next = None;
106 (*x.unwrap().as_ptr()).next = Some(*b);
107 self.front = Some(*b);
108 }
109 }
110
111 pub fn pop_back(&mut self) -> Option<T> {
112 unsafe {
113 self.back.map(|node| {
115 let boxed_node = Box::from_raw(node.as_ptr());
118 let result = boxed_node.elem;
119
120 self.back = boxed_node.next;
122 if let Some(new) = self.back {
123 (*new.as_ptr()).prev = None;
125 } else {
126 self.front = None;
128 }
129
130 self.len -= 1;
131 result
132 })
134 }
135 }
136
137 pub fn len(&self) -> usize {
138 self.len
139 }
140
141 pub fn is_empty(&self) -> bool {
142 self.len == 0
143 }
144
145 pub fn clear(&mut self) {
146 while self.pop_back().is_some() {}
148 }
149
150 pub fn get_front(&self) -> &T {
151 unsafe { &self.front.unwrap().as_ref().elem }
153 }
154
155 pub fn get_front_mut(&mut self) -> &mut T {
156 unsafe { &mut self.front.unwrap().as_mut().elem }
158 }
159}
160
161impl<T> Drop for LinkedList<T> {
162 fn drop(&mut self) {
163 self.clear()
164 }
165}
166
167impl<T> Default for LinkedList<T> {
168 fn default() -> Self {
169 Self::new()
170 }
171}
172
173#[cfg(test)]
174mod test {
175 use super::LinkedList;
176
177 #[test]
178 fn default_init_cursor_noop() {
179 let mut list = LinkedList::default();
180
181 assert_eq!(list.len(), 0);
182 assert_eq!(list.pop_back(), None);
183 assert_eq!(list.len(), 0);
184 let cursor = list.push_front(10);
185 assert_eq!(list.len(), 1);
186 assert_eq!(list.pop_back(), Some(10));
187 list.move_to_front(&cursor); }
189
190 #[test]
191 fn test_basic_front() {
192 let mut list = LinkedList::new();
193
194 assert_eq!(list.len(), 0);
195 assert_eq!(list.pop_back(), None);
196 assert_eq!(list.len(), 0);
197
198 list.push_front(10);
199 assert_eq!(list.len(), 1);
200 assert_eq!(list.pop_back(), Some(10));
201 assert_eq!(list.len(), 0);
202 assert_eq!(list.pop_back(), None);
203 assert_eq!(list.len(), 0);
204
205 list.push_front(10);
206 assert_eq!(list.len(), 1);
207 list.push_front(20);
208 assert_eq!(list.len(), 2);
209 list.push_front(30);
210 assert_eq!(list.len(), 3);
211 assert_eq!(list.pop_back(), Some(10));
212 assert_eq!(list.len(), 2);
213 list.push_front(40);
214 assert_eq!(list.len(), 3);
215 assert_eq!(list.pop_back(), Some(20));
216 assert_eq!(list.len(), 2);
217 assert_eq!(list.pop_back(), Some(30));
218 assert_eq!(list.len(), 1);
219 assert_eq!(list.pop_back(), Some(40));
220 assert_eq!(list.len(), 0);
221 assert_eq!(list.pop_back(), None);
222 assert_eq!(list.len(), 0);
223 assert_eq!(list.pop_back(), None);
224 assert_eq!(list.len(), 0);
225 }
226
227 #[test]
228 fn basic_move_to_front() {
229 let mut list = LinkedList::new();
230
231 assert_eq!(list.len(), 0);
232 let first_inserted = list.push_front(1);
233 list.move_to_front(&first_inserted);
234
235 list.push_front(5);
236 list.push_front(4);
237 list.push_front(3);
238 list.push_front(2);
239
240 list.move_to_front(&first_inserted);
241
242 list.push_front(0);
243
244 let mut result = Vec::new();
245 while let Some(element) = list.pop_back() {
246 result.push(element);
247 }
248
249 assert_eq!(result, vec![5, 4, 3, 2, 1, 0]);
250 }
251
252 #[test]
253 fn push_sort_move() {
254 let mut list = LinkedList::new();
260 let mut handles = Vec::new();
261 assert_eq!(list.len(), 0);
262 handles.push(list.push_front(1));
263 handles.push(list.push_front(5));
264 handles.push(list.push_front(2));
265 handles.push(list.push_front(4));
266 handles.push(list.push_front(3));
267
268 handles.sort_by_key(|h| unsafe { h.as_ref().elem });
269
270 handles.iter().for_each(|handle| {
271 list.move_to_front(handle);
272 });
273
274 let mut result = Vec::new();
275 while let Some(element) = list.pop_back() {
276 result.push(element);
277 }
278
279 assert_eq!(result, vec![1, 2, 3, 4, 5]);
280 }
281
282 #[test]
283 #[should_panic]
284 fn test_get_front_mut_empty() {
285 let mut list: LinkedList<i32> = LinkedList::new();
286 let _result = list.get_front_mut(); }
288
289 #[test]
290 fn test_get_front_mut() {
291 let mut list = LinkedList::new();
292
293 list.push_front(10);
295 {
296 let front = list.get_front_mut();
297 *front = 20;
298 }
299 assert_eq!(list.get_front(), &20);
300
301 list.push_front(30);
303 list.push_front(40);
304 {
305 let front = list.get_front_mut();
306 *front = 50;
307 }
308 assert_eq!(list.get_front(), &50);
309
310 assert_eq!(list.pop_back(), Some(20));
312 }
313}