1use crate::Pointer;
56use core::fmt;
57use core::marker::PhantomData;
58use core::mem;
59use core::ptr::{self, null};
60
61pub unsafe trait SListItem<Tag>: Sized {
71 fn get_node(&self) -> &mut SListNode<Self, Tag>;
72}
73
74#[repr(C)]
77pub struct SListNode<T: Sized, Tag> {
78 next: *const T,
79 _phan: PhantomData<fn(&Tag)>,
80}
81
82unsafe impl<T, Tag> Send for SListNode<T, Tag> {}
83
84impl<T: SListItem<Tag>, Tag> SListNode<T, Tag> {}
85
86impl<T, Tag> Default for SListNode<T, Tag> {
87 #[inline(always)]
88 fn default() -> Self {
89 Self { next: null(), _phan: Default::default() }
90 }
91}
92
93impl<T: SListItem<Tag> + fmt::Debug, Tag> fmt::Debug for SListNode<T, Tag> {
94 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
95 write!(f, "(")?;
96 if !self.next.is_null() {
97 write!(f, "next: {:p} ", self.next)?;
98 } else {
99 write!(f, "next: none ")?;
100 }
101 write!(f, ")")
102 }
103}
104
105#[repr(C)]
109pub struct SLinkedList<P, Tag>
110where
111 P: Pointer,
112 P::Target: SListItem<Tag>,
113{
114 length: usize,
115 head: *const P::Target,
116 tail: *const P::Target,
117 _phan: PhantomData<fn(&Tag)>,
118}
119
120unsafe impl<P, Tag> Send for SLinkedList<P, Tag>
121where
122 P: Pointer,
123 P::Target: SListItem<Tag>,
124{
125}
126
127impl<P: fmt::Debug, Tag> fmt::Debug for SLinkedList<P, Tag>
128where
129 P: Pointer,
130 P::Target: SListItem<Tag>,
131{
132 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
133 write!(f, "{{ length: {} ", self.length)?;
134 if !self.head.is_null() {
135 write!(f, "head: {:?} ", self.head)?;
136 } else {
137 write!(f, "head: none ")?;
138 }
139 if !self.tail.is_null() {
140 write!(f, "tail: {:?} ", self.tail)?;
141 } else {
142 write!(f, "tail: none ")?;
143 }
144 write!(f, "}}")
145 }
146}
147
148impl<P, Tag> SLinkedList<P, Tag>
149where
150 P: Pointer,
151 P::Target: SListItem<Tag>,
152{
153 #[inline(always)]
155 pub fn new() -> Self {
156 SLinkedList { length: 0, head: null(), tail: null(), _phan: Default::default() }
157 }
158
159 #[inline]
161 pub fn clear(&mut self) {
162 while self.pop_front().is_some() {}
166 }
167
168 #[inline(always)]
170 pub fn len(&self) -> usize {
171 self.length
172 }
173
174 #[inline(always)]
176 pub fn is_empty(&self) -> bool {
177 self.length == 0
178 }
179
180 #[inline]
182 pub fn push_back(&mut self, item: P) {
183 let node = item.as_ref().get_node();
184 node.next = null();
185 let ptr = item.into_raw();
186 if self.tail.is_null() {
187 self.head = ptr;
189 } else {
190 unsafe {
192 (*self.tail).get_node().next = ptr;
193 }
194 }
195 self.tail = ptr;
196 self.length += 1;
197 }
198
199 #[inline]
201 pub fn push_front(&mut self, item: P) {
202 let ptr = item.into_raw();
203 let node = unsafe { (*ptr).get_node() };
204 node.next = self.head;
205 if self.head.is_null() {
206 self.tail = ptr;
208 }
209 self.head = ptr;
210 self.length += 1;
211 }
212
213 pub fn pop_front(&mut self) -> Option<P> {
215 if self.head.is_null() {
216 None
217 } else {
218 let head_ptr = self.head;
219 let node = unsafe { (*head_ptr).get_node() };
220 let next_ptr = node.next;
221
222 self.head = next_ptr;
224
225 if self.head.is_null() {
227 self.tail = null();
228 }
229
230 node.next = null();
232 self.length -= 1;
233
234 Some(unsafe { P::from_raw(head_ptr) })
235 }
236 }
237
238 #[inline]
240 pub fn get_front(&self) -> Option<&P::Target> {
241 if self.head.is_null() { None } else { unsafe { Some(&(*self.head)) } }
242 }
243
244 #[inline]
246 pub fn get_back(&self) -> Option<&P::Target> {
247 if self.tail.is_null() { None } else { unsafe { Some(&(*self.tail)) } }
248 }
249
250 #[inline(always)]
252 pub fn is_front(&self, node: &P::Target) -> bool {
253 if self.head.is_null() { false } else { ptr::eq(self.head, node) }
254 }
255
256 #[inline(always)]
268 pub fn iter<'a>(&'a self) -> SLinkedListIterator<'a, P, Tag> {
269 SLinkedListIterator { list: self, cur: null() }
270 }
271
272 #[inline(always)]
274 pub fn drain<'a>(&'a mut self) -> SLinkedListDrainer<'a, P, Tag> {
275 SLinkedListDrainer { list: self }
276 }
277}
278
279impl<P, Tag> Drop for SLinkedList<P, Tag>
280where
281 P: Pointer,
282 P::Target: SListItem<Tag>,
283{
284 fn drop(&mut self) {
285 if mem::needs_drop::<P>() {
286 self.drain().for_each(drop);
287 }
288 }
289}
290
291pub struct SLinkedListIterator<'a, P, Tag>
292where
293 P: Pointer,
294 P::Target: SListItem<Tag>,
295{
296 list: &'a SLinkedList<P, Tag>,
297 cur: *const P::Target,
298}
299
300unsafe impl<'a, P, Tag> Send for SLinkedListIterator<'a, P, Tag>
301where
302 P: Pointer,
303 P::Target: SListItem<Tag>,
304{
305}
306
307impl<'a, P, Tag> Iterator for SLinkedListIterator<'a, P, Tag>
308where
309 P: Pointer,
310 P::Target: SListItem<Tag>,
311{
312 type Item = &'a P::Target;
313
314 fn next(&mut self) -> Option<Self::Item> {
315 if self.cur.is_null() {
316 if self.list.head.is_null() {
317 return None;
318 } else {
319 self.cur = self.list.head;
320 }
321 } else {
322 let next = unsafe { (*self.cur).get_node().next };
323 if next.is_null() {
324 return None;
325 } else {
326 self.cur = next;
327 }
328 }
329 unsafe { Some(&(*self.cur)) }
330 }
331}
332
333pub struct SLinkedListDrainer<'a, P, Tag>
334where
335 P: Pointer,
336 P::Target: SListItem<Tag>,
337{
338 list: &'a mut SLinkedList<P, Tag>,
339}
340
341unsafe impl<'a, P, Tag> Send for SLinkedListDrainer<'a, P, Tag>
342where
343 P: Pointer,
344 P::Target: SListItem<Tag>,
345{
346}
347
348impl<'a, P, Tag> Iterator for SLinkedListDrainer<'a, P, Tag>
349where
350 P: Pointer,
351 P::Target: SListItem<Tag>,
352{
353 type Item = P;
354
355 #[inline]
356 fn next(&mut self) -> Option<P> {
357 self.list.pop_front()
358 }
359}
360
361#[cfg(test)]
362mod tests {
363 use super::*;
364 use std::cell::UnsafeCell;
365 use std::sync::atomic::{AtomicUsize, Ordering};
366
367 pub struct TestTag;
368
369 #[derive(Debug)]
370 pub struct TestNode {
371 pub value: i64,
372 pub node: UnsafeCell<SListNode<Self, TestTag>>,
373 }
374
375 static ACTIVE_NODE_COUNT: AtomicUsize = AtomicUsize::new(0);
376
377 impl Drop for TestNode {
378 fn drop(&mut self) {
379 ACTIVE_NODE_COUNT.fetch_sub(1, Ordering::SeqCst);
380 }
381 }
382
383 unsafe impl Send for TestNode {}
384
385 unsafe impl SListItem<TestTag> for TestNode {
386 fn get_node(&self) -> &mut SListNode<Self, TestTag> {
387 unsafe { &mut *self.node.get() }
388 }
389 }
390
391 fn new_node(v: i64) -> TestNode {
392 ACTIVE_NODE_COUNT.fetch_add(1, Ordering::SeqCst);
393 TestNode { value: v, node: UnsafeCell::new(SListNode::default()) }
394 }
395
396 #[test]
397 fn test_push_back_pop_front_box() {
398 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
399 let mut l = SLinkedList::<Box<TestNode>, TestTag>::new();
400
401 let node1 = Box::new(new_node(1));
402 l.push_back(node1);
403
404 let node2 = Box::new(new_node(2));
405 l.push_back(node2);
406
407 let node3 = Box::new(new_node(3));
408 l.push_back(node3);
409
410 assert_eq!(3, l.len());
411 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 3);
412
413 let mut iter = l.iter();
415 assert_eq!(iter.next().unwrap().value, 1);
416 assert_eq!(iter.next().unwrap().value, 2);
417 assert_eq!(iter.next().unwrap().value, 3);
418 assert!(iter.next().is_none());
419
420 let n1 = l.pop_front();
422 assert!(n1.is_some());
423 assert_eq!(n1.unwrap().value, 1);
424 assert_eq!(l.len(), 2);
425
426 let n2 = l.pop_front();
427 assert!(n2.is_some());
428 assert_eq!(n2.unwrap().value, 2);
429 assert_eq!(l.len(), 1);
430
431 let n3 = l.pop_front();
432 assert!(n3.is_some());
433 assert_eq!(n3.unwrap().value, 3);
434 assert_eq!(l.len(), 0);
435
436 assert!(l.pop_front().is_none());
437 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
438 }
439
440 #[test]
441 fn test_push_front_box() {
442 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
443 let mut l = SLinkedList::<Box<TestNode>, TestTag>::new();
444
445 let node1 = Box::new(new_node(1));
446 l.push_front(node1); let node2 = Box::new(new_node(2));
449 l.push_front(node2); let node3 = Box::new(new_node(3));
452 l.push_front(node3); assert_eq!(3, l.len());
455 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 3);
456
457 let mut iter = l.iter();
459 assert_eq!(iter.next().unwrap().value, 3);
460 assert_eq!(iter.next().unwrap().value, 2);
461 assert_eq!(iter.next().unwrap().value, 1);
462 assert!(iter.next().is_none());
463
464 let n1 = l.pop_front();
466 assert!(n1.is_some());
467 assert_eq!(n1.unwrap().value, 3);
468 assert_eq!(l.len(), 2);
469
470 let n2 = l.pop_front();
471 assert!(n2.is_some());
472 assert_eq!(n2.unwrap().value, 2);
473 assert_eq!(l.len(), 1);
474
475 let n3 = l.pop_front();
476 assert!(n3.is_some());
477 assert_eq!(n3.unwrap().value, 1);
478 assert_eq!(l.len(), 0);
479
480 assert!(l.pop_front().is_none());
481 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
482 }
483
484 #[test]
485 fn test_drain() {
486 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
487 let mut l = SLinkedList::<Box<TestNode>, TestTag>::new();
488
489 l.push_back(Box::new(new_node(10)));
490 l.push_back(Box::new(new_node(20)));
491 l.push_back(Box::new(new_node(30)));
492
493 assert_eq!(l.len(), 3);
494 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 3);
495
496 {
497 let mut drain = l.drain();
498 assert_eq!(drain.next().unwrap().value, 10);
499 assert_eq!(drain.next().unwrap().value, 20);
500 assert_eq!(drain.next().unwrap().value, 30);
501 assert!(drain.next().is_none());
502 }
503
504 assert_eq!(l.len(), 0);
505 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
506 }
507
508 #[test]
509 fn test_clear() {
510 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
511 let mut l = SLinkedList::<Box<TestNode>, TestTag>::new();
512
513 l.push_back(Box::new(new_node(1)));
514 l.push_back(Box::new(new_node(2)));
515 assert_eq!(l.len(), 2);
516 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
517
518 l.clear();
519
520 assert!(l.is_empty());
521 assert_eq!(l.len(), 0);
522 assert!(l.get_front().is_none());
523 assert!(l.get_back().is_none());
524 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
525
526 l.push_back(Box::new(new_node(3)));
528 assert_eq!(l.len(), 1);
529 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 1);
530 }
531}