1use crate::Pointer;
58use core::marker::PhantomData;
59use core::{
60 fmt, mem,
61 ptr::{self, null},
62};
63
64pub unsafe trait DListItem<Tag>: Sized {
76 fn get_node(&self) -> &mut DListNode<Self, Tag>;
77}
78
79#[repr(C)]
81pub struct DListNode<T: Sized, Tag> {
82 prev: *const T,
83 next: *const T,
84 _phan: PhantomData<fn(&Tag)>,
85}
86
87unsafe impl<T, Tag> Send for DListNode<T, Tag> {}
88
89impl<T: DListItem<Tag>, Tag> DListNode<T, Tag> {
90 #[inline]
91 fn get_prev<'a>(&self) -> Option<&'a mut DListNode<T, Tag>> {
92 if self.prev.is_null() { None } else { unsafe { Some((*self.prev).get_node()) } }
93 }
94
95 #[inline]
96 fn get_next<'a>(&self) -> Option<&'a mut DListNode<T, Tag>> {
97 if self.next.is_null() { None } else { unsafe { Some((*self.next).get_node()) } }
98 }
99}
100
101impl<T, Tag> Default for DListNode<T, Tag> {
102 #[inline(always)]
103 fn default() -> Self {
104 Self { prev: null(), next: null(), _phan: Default::default() }
105 }
106}
107
108impl<T: DListItem<Tag> + fmt::Debug, Tag> fmt::Debug for DListNode<T, Tag> {
109 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
110 write!(f, "(")?;
111 if !self.prev.is_null() {
112 write!(f, "prev: {:p} ", self.prev)?;
113 } else {
114 write!(f, "prev: none ")?;
115 }
116 if !self.next.is_null() {
117 write!(f, "next: {:p} ", self.next)?;
118 } else {
119 write!(f, "next: none ")?;
120 }
121 write!(f, ")")
122 }
123}
124
125#[repr(C)]
129pub struct DLinkedList<P, Tag>
130where
131 P: Pointer,
132 P::Target: DListItem<Tag>,
133{
134 length: usize,
135 head: *const P::Target,
136 tail: *const P::Target,
137 _phan: PhantomData<fn(&Tag)>,
138}
139
140unsafe impl<P, Tag> Send for DLinkedList<P, Tag>
141where
142 P: Pointer,
143 P::Target: DListItem<Tag>,
144{
145}
146
147impl<P: fmt::Debug, Tag> fmt::Debug for DLinkedList<P, Tag>
148where
149 P: Pointer,
150 P::Target: DListItem<Tag>,
151{
152 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
153 write!(f, "{{ length: {} ", self.length)?;
154 if !self.head.is_null() {
155 write!(f, "head: {:?} ", self.head)?;
156 } else {
157 write!(f, "head: none ")?;
158 }
159 if !self.tail.is_null() {
160 write!(f, "tail: {:?} ", self.tail)?;
161 } else {
162 write!(f, "tail: none ")?;
163 }
164 write!(f, "}}")
165 }
166}
167
168impl<P, Tag> DLinkedList<P, Tag>
169where
170 P: Pointer,
171 P::Target: DListItem<Tag>,
172{
173 #[inline(always)]
175 pub fn new() -> Self {
176 DLinkedList { length: 0, head: null(), tail: null(), _phan: Default::default() }
177 }
178
179 #[inline]
181 pub fn clear(&mut self) {
182 while self.pop_front().is_some() {}
186 }
187
188 #[inline(always)]
190 pub fn len(&self) -> usize {
191 self.length
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 DListNode<P::Target, Tag>;
229 if ptr::eq(head_node, item.get_node()) {
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 ptr::eq(self.head, node)
330 }
331 }
332
333 #[cfg(feature = "std")]
334 pub fn print<U: std::fmt::Debug>(&self) {
335 println!("print list begin! length={}", self.length);
336 let mut ptr = self.head;
337 while !ptr.is_null() {
338 unsafe {
339 ptr = (*ptr).get_node().next;
345 }
346 }
347 println!("print list end:");
348 }
349
350 #[inline(always)]
362 pub fn iter<'a>(&'a self) -> DLinkedListIterator<'a, P, Tag> {
363 DLinkedListIterator { list: self, cur: null() }
364 }
365
366 #[inline(always)]
373 pub fn drain<'a>(&'a mut self) -> DLinkedListDrainer<'a, P, Tag> {
374 DLinkedListDrainer { list: self }
375 }
376}
377
378impl<P, Tag> Drop for DLinkedList<P, Tag>
379where
380 P: Pointer,
381 P::Target: DListItem<Tag>,
382{
383 fn drop(&mut self) {
384 if mem::needs_drop::<P>() {
388 self.drain().for_each(drop);
389 }
390 }
391}
392
393pub struct DLinkedListIterator<'a, P, Tag>
394where
395 P: Pointer,
396 P::Target: DListItem<Tag>,
397{
398 list: &'a DLinkedList<P, Tag>,
399 cur: *const P::Target,
400}
401
402unsafe impl<'a, P, Tag> Send for DLinkedListIterator<'a, P, Tag>
403where
404 P: Pointer,
405 P::Target: DListItem<Tag>,
406{
407}
408
409impl<'a, P, Tag> Iterator for DLinkedListIterator<'a, P, Tag>
410where
411 P: Pointer,
412 P::Target: DListItem<Tag>,
413{
414 type Item = &'a P::Target;
415
416 fn next(&mut self) -> Option<Self::Item> {
417 if self.cur.is_null() {
418 if self.list.head.is_null() {
419 return None;
420 } else {
421 self.cur = self.list.head;
422 }
423 } else {
424 let next = unsafe { (*self.cur).get_node().next };
425 if next.is_null() {
426 return None;
427 } else {
428 self.cur = next;
429 }
430 }
431 unsafe { Some(&(*self.cur)) }
432 }
433}
434
435pub struct DLinkedListDrainer<'a, P, Tag>
436where
437 P: Pointer,
438 P::Target: DListItem<Tag>,
439{
440 list: &'a mut DLinkedList<P, Tag>,
441}
442
443unsafe impl<'a, P, Tag> Send for DLinkedListDrainer<'a, P, Tag>
444where
445 P: Pointer,
446 P::Target: DListItem<Tag>,
447{
448}
449
450impl<'a, P, Tag> Iterator for DLinkedListDrainer<'a, P, Tag>
451where
452 P: Pointer,
453 P::Target: DListItem<Tag>,
454{
455 type Item = P;
456
457 #[inline]
458 fn next(&mut self) -> Option<P> {
459 self.list.pop_front()
460 }
461}
462
463#[cfg(test)]
464mod tests {
465 use super::*;
466 use std::cell::UnsafeCell;
467 use std::ptr::NonNull;
468 use std::sync::Arc;
469 use std::sync::atomic::{AtomicUsize, Ordering};
470
471 pub struct TestTag;
472
473 #[derive(Debug)]
474 pub struct TestNode {
475 pub value: i64,
476 pub node: UnsafeCell<DListNode<Self, TestTag>>,
477 }
478
479 static ACTIVE_NODE_COUNT: AtomicUsize = AtomicUsize::new(0);
480
481 impl Drop for TestNode {
482 fn drop(&mut self) {
483 ACTIVE_NODE_COUNT.fetch_sub(1, Ordering::SeqCst);
484 }
485 }
486
487 unsafe impl Send for TestNode {}
488
489 unsafe impl DListItem<TestTag> for TestNode {
490 fn get_node(&self) -> &mut DListNode<Self, TestTag> {
491 unsafe { &mut *self.node.get() }
492 }
493 }
494
495 fn new_node(v: i64) -> TestNode {
496 ACTIVE_NODE_COUNT.fetch_add(1, Ordering::SeqCst);
497 TestNode { value: v, node: UnsafeCell::new(DListNode::default()) }
498 }
499
500 #[test]
501 fn test_push_back_box() {
502 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
503
504 let node1 = Box::new(new_node(1));
505 l.push_back(node1);
506
507 let node2 = Box::new(new_node(2));
508 l.push_back(node2);
509
510 let node3 = Box::new(new_node(3));
511 l.push_back(node3);
512
513 assert_eq!(3, l.len());
514
515 let mut iter = l.iter();
516 assert_eq!(iter.next().unwrap().value, 1);
517 assert_eq!(iter.next().unwrap().value, 2);
518 assert_eq!(iter.next().unwrap().value, 3);
519 assert!(iter.next().is_none());
520
521 {
522 let mut drain = l.drain();
523 assert_eq!(drain.next().unwrap().value, 1);
524 assert_eq!(drain.next().unwrap().value, 2);
525 assert_eq!(drain.next().unwrap().value, 3);
526 assert!(drain.next().is_none());
527 }
528 assert_eq!(l.len(), 0);
529 }
530
531 #[test]
532 fn test_push_back_arc() {
533 let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
534
535 let node1 = Arc::new(new_node(1));
536 l.push_back(node1);
537
538 let node2 = Arc::new(new_node(2));
539 l.push_back(node2);
540
541 let node3 = Arc::new(new_node(3));
542 l.push_back(node3);
543
544 assert_eq!(3, l.len());
545
546 let mut iter = l.iter();
547 assert_eq!(iter.next().unwrap().value, 1);
548 assert_eq!(iter.next().unwrap().value, 2);
549 assert_eq!(iter.next().unwrap().value, 3);
550 assert!(iter.next().is_none());
551
552 {
553 let mut drain = l.drain();
554 assert_eq!(drain.next().unwrap().value, 1);
555 assert_eq!(drain.next().unwrap().value, 2);
556 assert_eq!(drain.next().unwrap().value, 3);
557 assert!(drain.next().is_none());
558 }
559 assert_eq!(l.len(), 0);
560 }
561
562 #[test]
563 fn test_push_front_box() {
564 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
565
566 let node3 = Box::new(new_node(3));
567 l.push_front(node3);
568
569 let node2 = Box::new(new_node(2));
570 l.push_front(node2);
571
572 let node1 = Box::new(new_node(1));
573 l.push_front(node1);
574
575 assert_eq!(3, l.len());
576
577 let mut iter = l.iter();
578 assert_eq!(iter.next().unwrap().value, 1);
579 assert_eq!(iter.next().unwrap().value, 2);
580 assert_eq!(iter.next().unwrap().value, 3);
581 assert!(iter.next().is_none());
582
583 {
584 let mut drain = l.drain();
585 assert_eq!(drain.next().unwrap().value, 1);
586 assert_eq!(drain.next().unwrap().value, 2);
587 assert_eq!(drain.next().unwrap().value, 3);
588 assert!(drain.next().is_none());
589 }
590 assert_eq!(l.len(), 0);
591 }
592
593 #[test]
594 fn test_push_front_arc() {
595 let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
596
597 let node3 = Arc::new(new_node(3));
598 l.push_front(node3);
599
600 let node2 = Arc::new(new_node(2));
601 l.push_front(node2);
602
603 let node1 = Arc::new(new_node(1));
604 l.push_front(node1);
605
606 assert_eq!(3, l.len());
607
608 let mut iter = l.iter();
609 assert_eq!(iter.next().unwrap().value, 1);
610 assert_eq!(iter.next().unwrap().value, 2);
611 assert_eq!(iter.next().unwrap().value, 3);
612 assert!(iter.next().is_none());
613
614 {
615 let mut drain = l.drain();
616 assert_eq!(drain.next().unwrap().value, 1);
617 assert_eq!(drain.next().unwrap().value, 2);
618 assert_eq!(drain.next().unwrap().value, 3);
619 assert!(drain.next().is_none());
620 }
621 assert_eq!(l.len(), 0);
622 }
623
624 #[test]
625 fn test_pop_back_box() {
626 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
627
628 let node1 = Box::new(new_node(1));
629 l.push_back(node1);
630
631 let node2 = Box::new(new_node(2));
632 l.push_back(node2);
633
634 let node3 = Box::new(new_node(3));
635 l.push_back(node3);
636
637 let mut iter = l.iter();
638 assert_eq!(iter.next().unwrap().value, 1);
639 assert_eq!(iter.next().unwrap().value, 2);
640 assert_eq!(iter.next().unwrap().value, 3);
641 assert!(iter.next().is_none());
642
643 let del_node = l.pop_back();
644 assert_eq!(2, l.len());
645 assert!(del_node.is_some());
646 assert_eq!(del_node.unwrap().value, 3);
647
648 let mut iter_remaining = l.iter();
649 assert_eq!(iter_remaining.next().unwrap().value, 1);
650 assert_eq!(iter_remaining.next().unwrap().value, 2);
651 assert!(iter_remaining.next().is_none());
652
653 {
654 let mut drain = l.drain();
655 assert_eq!(drain.next().unwrap().value, 1);
656 assert_eq!(drain.next().unwrap().value, 2);
657 assert!(drain.next().is_none());
658 }
659 assert_eq!(l.len(), 0);
660 }
661
662 #[test]
663 fn test_pop_back_arc() {
664 let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
665
666 let node1 = Arc::new(new_node(1));
667 l.push_back(node1);
668
669 let node2 = Arc::new(new_node(2));
670 l.push_back(node2);
671
672 let node3 = Arc::new(new_node(3));
673 l.push_back(node3);
674
675 let mut iter = l.iter();
676 assert_eq!(iter.next().unwrap().value, 1);
677 assert_eq!(iter.next().unwrap().value, 2);
678 assert_eq!(iter.next().unwrap().value, 3);
679 assert!(iter.next().is_none());
680
681 let del_node = l.pop_back();
682 assert_eq!(2, l.len());
683 assert!(del_node.is_some());
684 assert!(del_node.is_some());
686
687 let mut iter = l.iter();
689 assert_eq!(iter.next().unwrap().value, 1);
690 assert_eq!(iter.next().unwrap().value, 2);
691 assert!(iter.next().is_none());
692
693 {
694 let mut drain = l.drain();
695 assert_eq!(drain.next().unwrap().value, 1);
696 assert_eq!(drain.next().unwrap().value, 2);
697 assert!(drain.next().is_none());
698 }
699 assert_eq!(l.len(), 0);
700 }
701
702 #[test]
703 fn test_iter_box() {
704 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
705
706 let mut count = 0;
707 for _item in l.iter() {
708 count += 1;
709 }
710 assert_eq!(count, 0);
711
712 let node1 = Box::new(new_node(1));
713 l.push_back(node1);
714
715 let node2 = Box::new(new_node(2));
716 l.push_back(node2);
717
718 let node3 = Box::new(new_node(3));
719 l.push_back(node3);
720
721 count = 0;
722 for item in l.iter() {
723 count += 1;
724 println!("{}", item.value);
725 }
726 assert_eq!(count, 3);
727
728 {
729 let mut drain = l.drain();
730 assert_eq!(drain.next().unwrap().value, 1);
731 assert_eq!(drain.next().unwrap().value, 2);
732 assert_eq!(drain.next().unwrap().value, 3);
733 assert!(drain.next().is_none());
734 }
735 assert_eq!(l.len(), 0);
736 }
737
738 #[test]
739 fn test_iter_arc() {
740 let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
741
742 let mut count = 0;
743 for _item in l.iter() {
744 count += 1;
745 }
746 assert_eq!(count, 0);
747
748 let node1 = Arc::new(new_node(1));
749 l.push_back(node1);
750
751 let node2 = Arc::new(new_node(2));
752 l.push_back(node2);
753
754 let node3 = Arc::new(new_node(3));
755 l.push_back(node3);
756
757 let mut iter = l.iter();
759 assert_eq!(iter.next().unwrap().value, 1);
760 assert_eq!(iter.next().unwrap().value, 2);
761 assert_eq!(iter.next().unwrap().value, 3);
762 assert!(iter.next().is_none());
763
764 {
765 let mut drain = l.drain();
766 assert_eq!(drain.next().unwrap().value, 1);
767 assert_eq!(drain.next().unwrap().value, 2);
768 assert_eq!(drain.next().unwrap().value, 3);
769 assert!(drain.next().is_none());
770 }
771 assert_eq!(l.len(), 0);
772 }
773
774 #[test]
775 fn test_single_element_box() {
776 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
777 let node1 = Box::new(new_node(1));
778 l.push_front(node1);
779 let del_node = l.pop_back();
780 assert!(del_node.is_some());
781 assert_eq!(del_node.unwrap().value, 1);
782 assert_eq!(0, l.len());
783 assert!(l.pop_back().is_none());
784
785 let mut l2 = DLinkedList::<Box<TestNode>, TestTag>::new();
786 let node2 = Box::new(new_node(2));
787 l2.push_back(node2);
788 let del_node2 = l2.pop_back();
789 assert!(del_node2.is_some());
790 assert_eq!(del_node2.unwrap().value, 2);
791 assert_eq!(0, l2.len());
792 assert!(l2.pop_back().is_none());
793
794 {
795 let mut drain = l.drain();
796 assert!(drain.next().is_none());
797 }
798 assert_eq!(l.len(), 0);
799
800 {
801 let mut drain = l2.drain();
802 assert!(drain.next().is_none());
803 }
804 assert_eq!(l2.len(), 0);
805 }
806
807 #[test]
808 fn test_single_element_arc() {
809 let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
810 let node1 = Arc::new(new_node(1));
811 l.push_front(node1);
812 let del_node = l.pop_back();
813 assert!(del_node.is_some());
814 assert_eq!(0, l.len());
815 assert!(l.pop_back().is_none());
816
817 let mut l2 = DLinkedList::<Arc<TestNode>, TestTag>::new();
818 let node2 = Arc::new(new_node(2));
819 l2.push_back(node2);
820 let del_node2 = l2.pop_back();
821 assert!(del_node2.is_some());
822 assert_eq!(0, l2.len());
823 assert!(l2.pop_back().is_none());
824
825 {
826 let mut drain = l.drain();
827 assert!(drain.next().is_none());
828 }
829 assert_eq!(l.len(), 0);
830
831 {
832 let mut drain = l2.drain();
833 assert!(drain.next().is_none());
834 }
835 assert_eq!(l2.len(), 0);
836 }
837
838 #[test]
839 fn test_drop_box_implementation() {
840 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
842
843 {
844 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
845
846 let node1 = Box::new(new_node(1));
847 l.push_back(node1);
848
849 let node2 = Box::new(new_node(2));
850 l.push_back(node2);
851
852 let node3 = Box::new(new_node(3));
853 l.push_back(node3);
854
855 assert_eq!(l.len(), 3);
856 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 3);
857 } assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
861 }
862
863 #[test]
864 fn test_raw_pointer_list() {
865 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
867
868 let node1 = Box::into_raw(Box::new(new_node(10)));
870 let node2 = Box::into_raw(Box::new(new_node(20)));
871
872 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
873
874 {
875 let mut l = DLinkedList::<*const TestNode, TestTag>::new();
876 l.push_back(node1);
877 l.push_back(node2);
878
879 let mut iter = l.iter();
880 assert_eq!(iter.next().unwrap().value, 10);
881 assert_eq!(iter.next().unwrap().value, 20);
882 assert!(iter.next().is_none());
883 } assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
887
888 unsafe {
889 assert_eq!((*node1).value, 10);
891 assert_eq!((*node2).value, 20);
892
893 drop(Box::from_raw(node1));
895 drop(Box::from_raw(node2));
896 }
897
898 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
899 }
900
901 #[test]
902 fn test_non_null_list() {
903 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
905
906 let node1 = Box::leak(Box::new(new_node(100)));
909 let node2 = Box::leak(Box::new(new_node(200)));
910
911 let ptr1 = NonNull::from(node1);
912 let ptr2 = NonNull::from(node2);
913
914 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
915
916 {
917 let mut l = DLinkedList::<NonNull<TestNode>, TestTag>::new();
918 l.push_back(ptr1);
919 l.push_back(ptr2);
920
921 let mut iter = l.iter();
922 assert_eq!(iter.next().unwrap().value, 100);
923 assert_eq!(iter.next().unwrap().value, 200);
924 assert!(iter.next().is_none());
925 } assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
929
930 unsafe {
931 drop(Box::from_raw(ptr1.as_ptr()));
933 drop(Box::from_raw(ptr2.as_ptr()));
934 }
935
936 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
937 }
938
939 #[test]
940 fn test_clear() {
941 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
942 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
943
944 l.push_back(Box::new(new_node(1)));
945 l.push_back(Box::new(new_node(2)));
946 assert_eq!(l.len(), 2);
947 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
948
949 l.clear();
950
951 assert!(l.is_empty());
952 assert_eq!(l.len(), 0);
953 assert!(l.get_front().is_none());
954 assert!(l.get_back().is_none());
955 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
956
957 l.push_back(Box::new(new_node(3)));
959 assert_eq!(l.len(), 1);
960 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 1);
961 }
962}