1use crate::Pointer;
58use std::marker::PhantomData;
59use std::{fmt, mem, ptr::null};
60
61pub unsafe trait ListItem<Tag>: Sized {
72 fn get_node(&self) -> &mut ListNode<Self, Tag>;
73}
74
75pub struct ListNode<T: Sized, Tag> {
77 prev: *const T,
78 next: *const T,
79 _phan: PhantomData<fn(&Tag)>,
80}
81
82unsafe impl<T, Tag> Send for ListNode<T, Tag> {}
83
84impl<T: ListItem<Tag>, Tag> ListNode<T, Tag> {
85 #[inline]
86 fn get_prev<'a>(&self) -> Option<&'a mut ListNode<T, Tag>> {
87 if self.prev.is_null() { None } else { unsafe { Some((*self.prev).get_node()) } }
88 }
89
90 #[inline]
91 fn get_next<'a>(&self) -> Option<&'a mut ListNode<T, Tag>> {
92 if self.next.is_null() { None } else { unsafe { Some((*self.next).get_node()) } }
93 }
94}
95
96impl<T, Tag> Default for ListNode<T, Tag> {
97 #[inline(always)]
98 fn default() -> Self {
99 Self { prev: null(), next: null(), _phan: Default::default() }
100 }
101}
102
103impl<T: ListItem<Tag> + fmt::Debug, Tag> fmt::Debug for ListNode<T, Tag> {
104 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105 write!(f, "(")?;
106 if !self.prev.is_null() {
107 write!(f, "prev: {:p} ", self.prev)?;
108 } else {
109 write!(f, "prev: none ")?;
110 }
111 if !self.next.is_null() {
112 write!(f, "next: {:p} ", self.next)?;
113 } else {
114 write!(f, "next: none ")?;
115 }
116 write!(f, ")")
117 }
118}
119
120pub struct DLinkedList<P, Tag>
124where
125 P: Pointer,
126 P::Target: ListItem<Tag>,
127{
128 length: u64,
129 head: *const P::Target,
130 tail: *const P::Target,
131 _phan: PhantomData<fn(&Tag)>,
132}
133
134unsafe impl<P, Tag> Send for DLinkedList<P, Tag>
135where
136 P: Pointer,
137 P::Target: ListItem<Tag>,
138{
139}
140
141impl<P: fmt::Debug, Tag> fmt::Debug for DLinkedList<P, Tag>
142where
143 P: Pointer,
144 P::Target: ListItem<Tag>,
145{
146 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
147 write!(f, "{{ length: {} ", self.length)?;
148 if !self.head.is_null() {
149 write!(f, "head: {:?} ", self.head)?;
150 } else {
151 write!(f, "head: none ")?;
152 }
153 if !self.tail.is_null() {
154 write!(f, "tail: {:?} ", self.tail)?;
155 } else {
156 write!(f, "tail: none ")?;
157 }
158 write!(f, "}}")
159 }
160}
161
162impl<P, Tag> DLinkedList<P, Tag>
163where
164 P: Pointer,
165 P::Target: ListItem<Tag>,
166{
167 #[inline(always)]
169 pub fn new() -> Self {
170 DLinkedList { length: 0, head: null(), tail: null(), _phan: Default::default() }
171 }
172
173 #[inline]
176 pub fn clear(&mut self) {
177 self.length = 0;
178 self.head = null();
179 self.tail = null();
180 }
181
182 #[inline(always)]
184 pub fn get_length(&self) -> u64 {
185 return self.length;
186 }
187
188 #[inline(always)]
190 pub fn len(&self) -> usize {
191 return self.length as usize;
192 }
193
194 #[inline(always)]
196 pub fn is_empty(&self) -> bool {
197 self.length == 0
198 }
199
200 #[inline(always)]
201 fn remove_node(&mut self, item: &P::Target) {
202 let node = item.get_node();
203 if let Some(prev) = node.get_prev() {
204 prev.next = node.next;
205 } else {
206 self.head = node.next;
207 }
208 if let Some(next) = node.get_next() {
209 next.prev = node.prev;
210 } else {
211 self.tail = node.prev;
212 }
213 node.next = null();
214 node.prev = null();
215 self.length -= 1;
216 }
217
218 #[inline(always)]
224 pub unsafe fn peak(&mut self, ptr: *mut P::Target) {
225 assert!(!self.head.is_null());
226 let item = unsafe { &(*ptr) };
227 if !self.head.is_null() {
228 let head_node = unsafe { (*self.head).get_node() } as *const ListNode<P::Target, Tag>;
229 if head_node == item.get_node() as *const ListNode<P::Target, Tag> {
230 return;
231 }
232 }
233 self.remove_node(item);
234 self.push_front_ptr(ptr);
235 }
236
237 #[inline]
239 pub fn push_front(&mut self, item: P) {
240 let ptr = item.into_raw();
241 self.push_front_ptr(ptr);
242 }
243
244 #[inline]
245 fn push_front_ptr(&mut self, ptr: *const P::Target) {
246 let node = unsafe { (*ptr).get_node() };
247 let head = self.head;
248 node.next = head;
249 node.prev = null();
250
251 if head.is_null() {
252 self.tail = ptr;
253 } else {
254 unsafe {
255 (*head).get_node().prev = ptr;
256 }
257 }
258 self.head = ptr;
259 self.length += 1;
260 }
261
262 #[inline]
264 pub fn push_back(&mut self, item: P) {
265 let node = item.as_ref().get_node();
266 let tail = self.tail;
267 node.prev = tail;
268 node.next = null();
269
270 let ptr = item.into_raw();
271 if tail.is_null() {
272 self.head = ptr;
273 } else {
274 unsafe {
275 (*tail).get_node().next = ptr;
276 }
277 }
278 self.tail = ptr;
279 self.length += 1;
280 }
281
282 pub fn pop_front(&mut self) -> Option<P> {
284 if self.head.is_null() {
285 None
286 } else {
287 let head_ptr = self.head;
288 let item = unsafe { &(*head_ptr) };
289 self.remove_node(item);
290 Some(unsafe { P::from_raw(head_ptr) })
291 }
292 }
293
294 #[inline]
296 pub fn pop_back(&mut self) -> Option<P> {
297 if self.tail.is_null() {
298 None
299 } else {
300 let tail_ptr = self.tail;
301 let item = unsafe { &(*tail_ptr) };
302 self.remove_node(item);
303 Some(unsafe { P::from_raw(tail_ptr) })
304 }
305 }
306
307 #[inline]
309 pub fn get_front(&self) -> Option<&P::Target> {
310 if self.head.is_null() { None } else { unsafe { Some(&(*self.head)) } }
311 }
312
313 #[inline]
315 pub fn get_back(&self) -> Option<&P::Target> {
316 if self.tail.is_null() { None } else { unsafe { Some(&(*self.tail)) } }
317 }
318
319 #[inline(always)]
321 pub fn is_front(&self, node: &P::Target) -> bool {
322 if self.head.is_null() {
323 false
324 } else {
325 self.head == node as *const P::Target
330 }
331 }
332
333 pub fn print<U: std::fmt::Debug>(&self) {
334 println!("print list begin! length={}", self.length);
335 let mut ptr = self.head;
336 while !ptr.is_null() {
337 unsafe {
338 ptr = (*ptr).get_node().next;
344 }
345 }
346 println!("print list end:");
347 }
348
349 #[inline(always)]
352 pub fn iter<'a>(&'a self) -> DLinkedListIterator<'a, P, Tag> {
353 DLinkedListIterator { list: self, cur: null() }
354 }
355
356 #[inline(always)]
359 pub fn drain<'a>(&'a mut self) -> DLinkedListDrainer<'a, P, Tag> {
360 DLinkedListDrainer { list: self }
361 }
362}
363
364impl<P, Tag> Drop for DLinkedList<P, Tag>
365where
366 P: Pointer,
367 P::Target: ListItem<Tag>,
368{
369 fn drop(&mut self) {
370 if mem::needs_drop::<P>() {
374 self.drain().for_each(drop);
375 }
376 }
377}
378
379pub struct DLinkedListIterator<'a, P, Tag>
380where
381 P: Pointer,
382 P::Target: ListItem<Tag>,
383{
384 list: &'a DLinkedList<P, Tag>,
385 cur: *const P::Target,
386}
387
388unsafe impl<'a, P, Tag> Send for DLinkedListIterator<'a, P, Tag>
389where
390 P: Pointer,
391 P::Target: ListItem<Tag>,
392{
393}
394
395impl<'a, P, Tag> Iterator for DLinkedListIterator<'a, P, Tag>
396where
397 P: Pointer,
398 P::Target: ListItem<Tag>,
399{
400 type Item = &'a P::Target;
401
402 fn next(&mut self) -> Option<Self::Item> {
403 if self.cur.is_null() {
404 if self.list.head.is_null() {
405 return None;
406 } else {
407 self.cur = self.list.head;
408 }
409 } else {
410 let next = unsafe { (*self.cur).get_node().next };
411 if next.is_null() {
412 return None;
413 } else {
414 self.cur = next;
415 }
416 }
417 unsafe { Some(&(*self.cur)) }
418 }
419}
420
421pub struct DLinkedListDrainer<'a, P, Tag>
422where
423 P: Pointer,
424 P::Target: ListItem<Tag>,
425{
426 list: &'a mut DLinkedList<P, Tag>,
427}
428
429unsafe impl<'a, P, Tag> Send for DLinkedListDrainer<'a, P, Tag>
430where
431 P: Pointer,
432 P::Target: ListItem<Tag>,
433{
434}
435
436impl<'a, P, Tag> Iterator for DLinkedListDrainer<'a, P, Tag>
437where
438 P: Pointer,
439 P::Target: ListItem<Tag>,
440{
441 type Item = P;
442
443 #[inline]
444 fn next(&mut self) -> Option<P> {
445 self.list.pop_back()
446 }
447}
448
449#[cfg(test)]
450mod tests {
451 use super::*;
452 use std::cell::UnsafeCell;
453 use std::ptr::NonNull;
454 use std::sync::Arc;
455 use std::sync::atomic::{AtomicUsize, Ordering};
456
457 pub struct TestTag;
458
459 #[derive(Debug)]
460 pub struct TestNode {
461 pub value: i64,
462 pub node: UnsafeCell<ListNode<Self, TestTag>>,
463 pub drop_detector: usize, }
465
466 static NEXT_DROP_ID: AtomicUsize = AtomicUsize::new(0);
467 static ACTIVE_NODE_COUNT: AtomicUsize = AtomicUsize::new(0);
468
469 impl Drop for TestNode {
470 fn drop(&mut self) {
471 ACTIVE_NODE_COUNT.fetch_sub(1, Ordering::SeqCst);
472 }
473 }
474
475 unsafe impl Send for TestNode {}
476
477 unsafe impl ListItem<TestTag> for TestNode {
478 fn get_node(&self) -> &mut ListNode<Self, TestTag> {
479 unsafe { &mut *self.node.get() }
480 }
481 }
482
483 fn new_node(v: i64) -> TestNode {
484 ACTIVE_NODE_COUNT.fetch_add(1, Ordering::SeqCst);
485 TestNode {
486 value: v,
487 node: UnsafeCell::new(ListNode::default()),
488 drop_detector: NEXT_DROP_ID.fetch_add(1, Ordering::SeqCst),
489 }
490 }
491
492 #[test]
493 fn test_push_back_box() {
494 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
495
496 let node1 = Box::new(new_node(1));
497 l.push_back(node1);
498
499 let node2 = Box::new(new_node(2));
500 l.push_back(node2);
501
502 let node3 = Box::new(new_node(3));
503 l.push_back(node3);
504
505 assert_eq!(3, l.get_length());
506
507 let mut iter = l.iter();
508 assert_eq!(iter.next().unwrap().value, 1);
509 assert_eq!(iter.next().unwrap().value, 2);
510 assert_eq!(iter.next().unwrap().value, 3);
511 assert!(iter.next().is_none());
512
513 {
514 let mut drain = l.drain();
515 assert_eq!(drain.next().unwrap().value, 3);
516 assert_eq!(drain.next().unwrap().value, 2);
517 assert_eq!(drain.next().unwrap().value, 1);
518 assert!(drain.next().is_none());
519 }
520 assert_eq!(l.get_length(), 0);
521 }
522
523 #[test]
524 fn test_push_back_arc() {
525 let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
526
527 let node1 = Arc::new(new_node(1));
528 l.push_back(node1);
529
530 let node2 = Arc::new(new_node(2));
531 l.push_back(node2);
532
533 let node3 = Arc::new(new_node(3));
534 l.push_back(node3);
535
536 assert_eq!(3, l.get_length());
537
538 let mut iter = l.iter();
539 assert_eq!(iter.next().unwrap().value, 1);
540 assert_eq!(iter.next().unwrap().value, 2);
541 assert_eq!(iter.next().unwrap().value, 3);
542 assert!(iter.next().is_none());
543
544 {
545 let mut drain = l.drain();
546 assert_eq!(drain.next().unwrap().value, 3);
547 assert_eq!(drain.next().unwrap().value, 2);
548 assert_eq!(drain.next().unwrap().value, 1);
549 assert!(drain.next().is_none());
550 }
551 assert_eq!(l.get_length(), 0);
552 }
553
554 #[test]
555 fn test_push_front_box() {
556 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
557
558 let node3 = Box::new(new_node(3));
559 l.push_front(node3);
560
561 let node2 = Box::new(new_node(2));
562 l.push_front(node2);
563
564 let node1 = Box::new(new_node(1));
565 l.push_front(node1);
566
567 assert_eq!(3, l.get_length());
568
569 let mut iter = l.iter();
570 assert_eq!(iter.next().unwrap().value, 1);
571 assert_eq!(iter.next().unwrap().value, 2);
572 assert_eq!(iter.next().unwrap().value, 3);
573 assert!(iter.next().is_none());
574
575 {
576 let mut drain = l.drain();
577 assert_eq!(drain.next().unwrap().value, 3);
578 assert_eq!(drain.next().unwrap().value, 2);
579 assert_eq!(drain.next().unwrap().value, 1);
580 assert!(drain.next().is_none());
581 }
582 assert_eq!(l.get_length(), 0);
583 }
584
585 #[test]
586 fn test_push_front_arc() {
587 let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
588
589 let node3 = Arc::new(new_node(3));
590 l.push_front(node3);
591
592 let node2 = Arc::new(new_node(2));
593 l.push_front(node2);
594
595 let node1 = Arc::new(new_node(1));
596 l.push_front(node1);
597
598 assert_eq!(3, l.get_length());
599
600 let mut iter = l.iter();
601 assert_eq!(iter.next().unwrap().value, 1);
602 assert_eq!(iter.next().unwrap().value, 2);
603 assert_eq!(iter.next().unwrap().value, 3);
604 assert!(iter.next().is_none());
605
606 {
607 let mut drain = l.drain();
608 assert_eq!(drain.next().unwrap().value, 3);
609 assert_eq!(drain.next().unwrap().value, 2);
610 assert_eq!(drain.next().unwrap().value, 1);
611 assert!(drain.next().is_none());
612 }
613 assert_eq!(l.get_length(), 0);
614 }
615
616 #[test]
617 fn test_pop_back_box() {
618 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
619
620 let node1 = Box::new(new_node(1));
621 l.push_back(node1);
622
623 let node2 = Box::new(new_node(2));
624 l.push_back(node2);
625
626 let node3 = Box::new(new_node(3));
627 l.push_back(node3);
628
629 let mut iter = l.iter();
630 assert_eq!(iter.next().unwrap().value, 1);
631 assert_eq!(iter.next().unwrap().value, 2);
632 assert_eq!(iter.next().unwrap().value, 3);
633 assert!(iter.next().is_none());
634
635 let del_node = l.pop_back();
636 assert_eq!(2, l.get_length());
637 assert!(del_node.is_some());
638 assert_eq!(del_node.unwrap().value, 3);
639
640 let mut iter_remaining = l.iter();
641 assert_eq!(iter_remaining.next().unwrap().value, 1);
642 assert_eq!(iter_remaining.next().unwrap().value, 2);
643 assert!(iter_remaining.next().is_none());
644
645 {
646 let mut drain = l.drain();
647 assert_eq!(drain.next().unwrap().value, 2);
648 assert_eq!(drain.next().unwrap().value, 1);
649 assert!(drain.next().is_none());
650 }
651 assert_eq!(l.get_length(), 0);
652 }
653
654 #[test]
655 fn test_pop_back_arc() {
656 let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
657
658 let node1 = Arc::new(new_node(1));
659 l.push_back(node1);
660
661 let node2 = Arc::new(new_node(2));
662 l.push_back(node2);
663
664 let node3 = Arc::new(new_node(3));
665 l.push_back(node3);
666
667 let mut iter = l.iter();
668 assert_eq!(iter.next().unwrap().value, 1);
669 assert_eq!(iter.next().unwrap().value, 2);
670 assert_eq!(iter.next().unwrap().value, 3);
671 assert!(iter.next().is_none());
672
673 let del_node = l.pop_back();
674 assert_eq!(2, l.get_length());
675 assert!(del_node.is_some());
676 assert!(del_node.is_some());
678
679 let mut iter = l.iter();
681 assert_eq!(iter.next().unwrap().value, 1);
682 assert_eq!(iter.next().unwrap().value, 2);
683 assert!(iter.next().is_none());
684
685 {
686 let mut drain = l.drain();
687 assert_eq!(drain.next().unwrap().value, 2);
688 assert_eq!(drain.next().unwrap().value, 1);
689 assert!(drain.next().is_none());
690 }
691 assert_eq!(l.get_length(), 0);
692 }
693
694 #[test]
695 fn test_iter_box() {
696 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
697
698 let mut count = 0;
699 for _item in l.iter() {
700 count += 1;
701 }
702 assert_eq!(count, 0);
703
704 let node1 = Box::new(new_node(1));
705 l.push_back(node1);
706
707 let node2 = Box::new(new_node(2));
708 l.push_back(node2);
709
710 let node3 = Box::new(new_node(3));
711 l.push_back(node3);
712
713 count = 0;
714 for item in l.iter() {
715 count += 1;
716 println!("{}", item.value);
717 }
718 assert_eq!(count, 3);
719
720 {
721 let mut drain = l.drain();
722 assert_eq!(drain.next().unwrap().value, 3);
723 assert_eq!(drain.next().unwrap().value, 2);
724 assert_eq!(drain.next().unwrap().value, 1);
725 assert!(drain.next().is_none());
726 }
727 assert_eq!(l.get_length(), 0);
728 }
729
730 #[test]
731 fn test_iter_arc() {
732 let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
733
734 let mut count = 0;
735 for _item in l.iter() {
736 count += 1;
737 }
738 assert_eq!(count, 0);
739
740 let node1 = Arc::new(new_node(1));
741 l.push_back(node1);
742
743 let node2 = Arc::new(new_node(2));
744 l.push_back(node2);
745
746 let node3 = Arc::new(new_node(3));
747 l.push_back(node3);
748
749 let mut iter = l.iter();
751 assert_eq!(iter.next().unwrap().value, 1);
752 assert_eq!(iter.next().unwrap().value, 2);
753 assert_eq!(iter.next().unwrap().value, 3);
754 assert!(iter.next().is_none());
755
756 {
757 let mut drain = l.drain();
758 assert_eq!(drain.next().unwrap().value, 3);
759 assert_eq!(drain.next().unwrap().value, 2);
760 assert_eq!(drain.next().unwrap().value, 1);
761 assert!(drain.next().is_none());
762 }
763 assert_eq!(l.get_length(), 0);
764 }
765
766 #[test]
767 fn test_single_element_box() {
768 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
769 let node1 = Box::new(new_node(1));
770 l.push_front(node1);
771 let del_node = l.pop_back();
772 assert!(del_node.is_some());
773 assert_eq!(del_node.unwrap().value, 1);
774 assert_eq!(0, l.get_length());
775 assert!(l.pop_back().is_none());
776
777 let mut l2 = DLinkedList::<Box<TestNode>, TestTag>::new();
778 let node2 = Box::new(new_node(2));
779 l2.push_back(node2);
780 let del_node2 = l2.pop_back();
781 assert!(del_node2.is_some());
782 assert_eq!(del_node2.unwrap().value, 2);
783 assert_eq!(0, l2.get_length());
784 assert!(l2.pop_back().is_none());
785
786 {
787 let mut drain = l.drain();
788 assert!(drain.next().is_none());
789 }
790 assert_eq!(l.get_length(), 0);
791
792 {
793 let mut drain = l2.drain();
794 assert!(drain.next().is_none());
795 }
796 assert_eq!(l2.get_length(), 0);
797 }
798
799 #[test]
800 fn test_single_element_arc() {
801 let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
802 let node1 = Arc::new(new_node(1));
803 l.push_front(node1);
804 let del_node = l.pop_back();
805 assert!(del_node.is_some());
806 assert_eq!(0, l.get_length());
807 assert!(l.pop_back().is_none());
808
809 let mut l2 = DLinkedList::<Arc<TestNode>, TestTag>::new();
810 let node2 = Arc::new(new_node(2));
811 l2.push_back(node2);
812 let del_node2 = l2.pop_back();
813 assert!(del_node2.is_some());
814 assert_eq!(0, l2.get_length());
815 assert!(l2.pop_back().is_none());
816
817 {
818 let mut drain = l.drain();
819 assert!(drain.next().is_none());
820 }
821 assert_eq!(l.get_length(), 0);
822
823 {
824 let mut drain = l2.drain();
825 assert!(drain.next().is_none());
826 }
827 assert_eq!(l2.get_length(), 0);
828 }
829
830 #[test]
831 fn test_drop_box_implementation() {
832 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
834
835 {
836 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
837
838 let node1 = Box::new(new_node(1));
839 l.push_back(node1);
840
841 let node2 = Box::new(new_node(2));
842 l.push_back(node2);
843
844 let node3 = Box::new(new_node(3));
845 l.push_back(node3);
846
847 assert_eq!(l.get_length(), 3);
848 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 3);
849 } assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
853 }
854
855 #[test]
856 fn test_raw_pointer_list() {
857 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
859
860 let node1 = Box::into_raw(Box::new(new_node(10)));
862 let node2 = Box::into_raw(Box::new(new_node(20)));
863
864 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
865
866 {
867 let mut l = DLinkedList::<*const TestNode, TestTag>::new();
868 l.push_back(node1);
869 l.push_back(node2);
870
871 let mut iter = l.iter();
872 assert_eq!(iter.next().unwrap().value, 10);
873 assert_eq!(iter.next().unwrap().value, 20);
874 assert!(iter.next().is_none());
875 } assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
879
880 unsafe {
881 assert_eq!((*node1).value, 10);
883 assert_eq!((*node2).value, 20);
884
885 drop(Box::from_raw(node1));
887 drop(Box::from_raw(node2));
888 }
889
890 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
891 }
892
893 #[test]
894 fn test_non_null_list() {
895 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
897
898 let node1 = Box::leak(Box::new(new_node(100)));
901 let node2 = Box::leak(Box::new(new_node(200)));
902
903 let ptr1 = NonNull::from(node1);
904 let ptr2 = NonNull::from(node2);
905
906 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
907
908 {
909 let mut l = DLinkedList::<NonNull<TestNode>, TestTag>::new();
910 l.push_back(ptr1);
911 l.push_back(ptr2);
912
913 let mut iter = l.iter();
914 assert_eq!(iter.next().unwrap().value, 100);
915 assert_eq!(iter.next().unwrap().value, 200);
916 assert!(iter.next().is_none());
917 } assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
921
922 unsafe {
923 drop(Box::from_raw(ptr1.as_ptr()));
925 drop(Box::from_raw(ptr2.as_ptr()));
926 }
927
928 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
929 }
930}