1use crate::Pointer;
85use core::fmt;
86use core::marker::PhantomData;
87use core::mem;
88use core::ptr::{self, null};
89
90pub unsafe trait SListItem<Tag>: Sized {
100 fn get_node(&self) -> &mut SListNode<Self, Tag>;
101}
102
103#[repr(C)]
106pub struct SListNode<T: Sized, Tag> {
107 next: *const T,
108 _phan: PhantomData<fn(&Tag)>,
109}
110
111unsafe impl<T, Tag> Send for SListNode<T, Tag> {}
112
113impl<T: SListItem<Tag>, Tag> SListNode<T, Tag> {}
114
115impl<T, Tag> Default for SListNode<T, Tag> {
116 #[inline(always)]
117 fn default() -> Self {
118 Self { next: null(), _phan: Default::default() }
119 }
120}
121
122impl<T: SListItem<Tag> + fmt::Debug, Tag> fmt::Debug for SListNode<T, Tag> {
123 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
124 write!(f, "(")?;
125 if !self.next.is_null() {
126 write!(f, "next: {:p} ", self.next)?;
127 } else {
128 write!(f, "next: none ")?;
129 }
130 write!(f, ")")
131 }
132}
133
134#[repr(C)]
138pub struct SLinkedList<P, Tag>
139where
140 P: Pointer,
141 P::Target: SListItem<Tag>,
142{
143 length: usize,
144 head: *const P::Target,
145 tail: *const P::Target,
146 _phan: PhantomData<fn(&Tag)>,
147}
148
149unsafe impl<P, Tag> Send for SLinkedList<P, Tag>
150where
151 P: Pointer,
152 P::Target: SListItem<Tag>,
153{
154}
155
156impl<P: fmt::Debug, Tag> fmt::Debug for SLinkedList<P, Tag>
157where
158 P: Pointer,
159 P::Target: SListItem<Tag>,
160{
161 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
162 write!(f, "{{ length: {} ", self.length)?;
163 if !self.head.is_null() {
164 write!(f, "head: {:?} ", self.head)?;
165 } else {
166 write!(f, "head: none ")?;
167 }
168 if !self.tail.is_null() {
169 write!(f, "tail: {:?} ", self.tail)?;
170 } else {
171 write!(f, "tail: none ")?;
172 }
173 write!(f, "}}")
174 }
175}
176
177impl<P, Tag> SLinkedList<P, Tag>
178where
179 P: Pointer,
180 P::Target: SListItem<Tag>,
181{
182 #[inline(always)]
184 pub fn new() -> Self {
185 SLinkedList { length: 0, head: null(), tail: null(), _phan: Default::default() }
186 }
187
188 #[inline]
190 pub fn clear(&mut self) {
191 while self.pop_front().is_some() {}
195 }
196
197 #[inline(always)]
199 pub fn len(&self) -> usize {
200 self.length
201 }
202
203 #[inline(always)]
205 pub fn is_empty(&self) -> bool {
206 self.length == 0
207 }
208
209 #[inline]
211 pub fn push_back(&mut self, item: P) {
212 let node = item.as_ref().get_node();
213 node.next = null();
214 let ptr = item.into_raw();
215 if self.tail.is_null() {
216 self.head = ptr;
218 } else {
219 unsafe {
221 (*self.tail).get_node().next = ptr;
222 }
223 }
224 self.tail = ptr;
225 self.length += 1;
226 }
227
228 #[inline]
230 pub fn push_front(&mut self, item: P) {
231 let ptr = item.into_raw();
232 let node = unsafe { (*ptr).get_node() };
233 node.next = self.head;
234 if self.head.is_null() {
235 self.tail = ptr;
237 }
238 self.head = ptr;
239 self.length += 1;
240 }
241
242 pub fn pop_front(&mut self) -> Option<P> {
244 if self.head.is_null() {
245 None
246 } else {
247 let head_ptr = self.head;
248 let node = unsafe { (*head_ptr).get_node() };
249 let next_ptr = node.next;
250
251 self.head = next_ptr;
253
254 if self.head.is_null() {
256 self.tail = null();
257 }
258
259 node.next = null();
261 self.length -= 1;
262
263 Some(unsafe { P::from_raw(head_ptr) })
264 }
265 }
266
267 #[inline]
269 pub fn get_front(&self) -> Option<&P::Target> {
270 if self.head.is_null() { None } else { unsafe { Some(&(*self.head)) } }
271 }
272
273 #[inline]
275 pub fn get_back(&self) -> Option<&P::Target> {
276 if self.tail.is_null() { None } else { unsafe { Some(&(*self.tail)) } }
277 }
278
279 #[inline(always)]
281 pub fn is_front(&self, node: &P::Target) -> bool {
282 if self.head.is_null() { false } else { ptr::eq(self.head, node) }
283 }
284
285 #[inline(always)]
297 pub fn iter<'a>(&'a self) -> SLinkedListIterator<'a, P, Tag> {
298 SLinkedListIterator { list: self, cur: null() }
299 }
300
301 #[inline(always)]
303 pub fn drain<'a>(&'a mut self) -> SLinkedListDrainer<'a, P, Tag> {
304 SLinkedListDrainer { list: self }
305 }
306}
307
308impl<P, Tag> Drop for SLinkedList<P, Tag>
309where
310 P: Pointer,
311 P::Target: SListItem<Tag>,
312{
313 fn drop(&mut self) {
314 if mem::needs_drop::<P>() {
315 self.drain().for_each(drop);
316 }
317 }
318}
319
320pub struct SLinkedListIterator<'a, P, Tag>
321where
322 P: Pointer,
323 P::Target: SListItem<Tag>,
324{
325 list: &'a SLinkedList<P, Tag>,
326 cur: *const P::Target,
327}
328
329unsafe impl<'a, P, Tag> Send for SLinkedListIterator<'a, P, Tag>
330where
331 P: Pointer,
332 P::Target: SListItem<Tag>,
333{
334}
335
336impl<'a, P, Tag> Iterator for SLinkedListIterator<'a, P, Tag>
337where
338 P: Pointer,
339 P::Target: SListItem<Tag>,
340{
341 type Item = &'a P::Target;
342
343 fn next(&mut self) -> Option<Self::Item> {
344 if self.cur.is_null() {
345 if self.list.head.is_null() {
346 return None;
347 } else {
348 self.cur = self.list.head;
349 }
350 } else {
351 let next = unsafe { (*self.cur).get_node().next };
352 if next.is_null() {
353 return None;
354 } else {
355 self.cur = next;
356 }
357 }
358 unsafe { Some(&(*self.cur)) }
359 }
360}
361
362pub struct SLinkedListDrainer<'a, P, Tag>
363where
364 P: Pointer,
365 P::Target: SListItem<Tag>,
366{
367 list: &'a mut SLinkedList<P, Tag>,
368}
369
370unsafe impl<'a, P, Tag> Send for SLinkedListDrainer<'a, P, Tag>
371where
372 P: Pointer,
373 P::Target: SListItem<Tag>,
374{
375}
376
377impl<'a, P, Tag> Iterator for SLinkedListDrainer<'a, P, Tag>
378where
379 P: Pointer,
380 P::Target: SListItem<Tag>,
381{
382 type Item = P;
383
384 #[inline]
385 fn next(&mut self) -> Option<P> {
386 self.list.pop_front()
387 }
388}
389
390#[cfg(test)]
391mod tests {
392 use super::*;
393 use std::cell::UnsafeCell;
394 use std::sync::atomic::{AtomicUsize, Ordering};
395
396 pub struct TestTag;
397
398 #[derive(Debug)]
399 pub struct TestNode {
400 pub value: i64,
401 pub node: UnsafeCell<SListNode<Self, TestTag>>,
402 }
403
404 static ACTIVE_NODE_COUNT: AtomicUsize = AtomicUsize::new(0);
405
406 impl Drop for TestNode {
407 fn drop(&mut self) {
408 ACTIVE_NODE_COUNT.fetch_sub(1, Ordering::SeqCst);
409 }
410 }
411
412 unsafe impl Send for TestNode {}
413
414 unsafe impl SListItem<TestTag> for TestNode {
415 fn get_node(&self) -> &mut SListNode<Self, TestTag> {
416 unsafe { &mut *self.node.get() }
417 }
418 }
419
420 fn new_node(v: i64) -> TestNode {
421 ACTIVE_NODE_COUNT.fetch_add(1, Ordering::SeqCst);
422 TestNode { value: v, node: UnsafeCell::new(SListNode::default()) }
423 }
424
425 #[test]
426 fn test_push_back_pop_front_box() {
427 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
428 let mut l = SLinkedList::<Box<TestNode>, TestTag>::new();
429
430 let node1 = Box::new(new_node(1));
431 l.push_back(node1);
432
433 let node2 = Box::new(new_node(2));
434 l.push_back(node2);
435
436 let node3 = Box::new(new_node(3));
437 l.push_back(node3);
438
439 assert_eq!(3, l.len());
440 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 3);
441
442 let mut iter = l.iter();
444 assert_eq!(iter.next().unwrap().value, 1);
445 assert_eq!(iter.next().unwrap().value, 2);
446 assert_eq!(iter.next().unwrap().value, 3);
447 assert!(iter.next().is_none());
448
449 let n1 = l.pop_front();
451 assert!(n1.is_some());
452 assert_eq!(n1.unwrap().value, 1);
453 assert_eq!(l.len(), 2);
454
455 let n2 = l.pop_front();
456 assert!(n2.is_some());
457 assert_eq!(n2.unwrap().value, 2);
458 assert_eq!(l.len(), 1);
459
460 let n3 = l.pop_front();
461 assert!(n3.is_some());
462 assert_eq!(n3.unwrap().value, 3);
463 assert_eq!(l.len(), 0);
464
465 assert!(l.pop_front().is_none());
466 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
467 }
468
469 #[test]
470 fn test_push_front_box() {
471 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
472 let mut l = SLinkedList::<Box<TestNode>, TestTag>::new();
473
474 let node1 = Box::new(new_node(1));
475 l.push_front(node1); let node2 = Box::new(new_node(2));
478 l.push_front(node2); let node3 = Box::new(new_node(3));
481 l.push_front(node3); assert_eq!(3, l.len());
484 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 3);
485
486 let mut iter = l.iter();
488 assert_eq!(iter.next().unwrap().value, 3);
489 assert_eq!(iter.next().unwrap().value, 2);
490 assert_eq!(iter.next().unwrap().value, 1);
491 assert!(iter.next().is_none());
492
493 let n1 = l.pop_front();
495 assert!(n1.is_some());
496 assert_eq!(n1.unwrap().value, 3);
497 assert_eq!(l.len(), 2);
498
499 let n2 = l.pop_front();
500 assert!(n2.is_some());
501 assert_eq!(n2.unwrap().value, 2);
502 assert_eq!(l.len(), 1);
503
504 let n3 = l.pop_front();
505 assert!(n3.is_some());
506 assert_eq!(n3.unwrap().value, 1);
507 assert_eq!(l.len(), 0);
508
509 assert!(l.pop_front().is_none());
510 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
511 }
512
513 #[test]
514 fn test_drain() {
515 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
516 let mut l = SLinkedList::<Box<TestNode>, TestTag>::new();
517
518 l.push_back(Box::new(new_node(10)));
519 l.push_back(Box::new(new_node(20)));
520 l.push_back(Box::new(new_node(30)));
521
522 assert_eq!(l.len(), 3);
523 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 3);
524
525 {
526 let mut drain = l.drain();
527 assert_eq!(drain.next().unwrap().value, 10);
528 assert_eq!(drain.next().unwrap().value, 20);
529 assert_eq!(drain.next().unwrap().value, 30);
530 assert!(drain.next().is_none());
531 }
532
533 assert_eq!(l.len(), 0);
534 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
535 }
536
537 #[test]
538 fn test_clear() {
539 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
540 let mut l = SLinkedList::<Box<TestNode>, TestTag>::new();
541
542 l.push_back(Box::new(new_node(1)));
543 l.push_back(Box::new(new_node(2)));
544 assert_eq!(l.len(), 2);
545 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
546
547 l.clear();
548
549 assert!(l.is_empty());
550 assert_eq!(l.len(), 0);
551 assert!(l.get_front().is_none());
552 assert!(l.get_back().is_none());
553 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
554
555 l.push_back(Box::new(new_node(3)));
557 assert_eq!(l.len(), 1);
558 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 1);
559 }
560}