1use crate::Pointer;
87use core::marker::PhantomData;
88use core::{
89 fmt, mem,
90 ptr::{self, null},
91};
92
93pub unsafe trait DListItem<Tag>: Sized {
105 fn get_node(&self) -> &mut DListNode<Self, Tag>;
106}
107
108#[repr(C)]
110pub struct DListNode<T: Sized, Tag> {
111 prev: *const T,
112 next: *const T,
113 _phan: PhantomData<fn(&Tag)>,
114}
115
116unsafe impl<T, Tag> Send for DListNode<T, Tag> {}
117
118impl<T: DListItem<Tag>, Tag> DListNode<T, Tag> {
119 #[inline]
120 fn get_prev<'a>(&self) -> Option<&'a mut DListNode<T, Tag>> {
121 if self.prev.is_null() { None } else { unsafe { Some((*self.prev).get_node()) } }
122 }
123
124 #[inline]
125 fn get_next<'a>(&self) -> Option<&'a mut DListNode<T, Tag>> {
126 if self.next.is_null() { None } else { unsafe { Some((*self.next).get_node()) } }
127 }
128}
129
130impl<T, Tag> Default for DListNode<T, Tag> {
131 #[inline(always)]
132 fn default() -> Self {
133 Self { prev: null(), next: null(), _phan: Default::default() }
134 }
135}
136
137impl<T: DListItem<Tag> + fmt::Debug, Tag> fmt::Debug for DListNode<T, Tag> {
138 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
139 write!(f, "(")?;
140 if !self.prev.is_null() {
141 write!(f, "prev: {:p} ", self.prev)?;
142 } else {
143 write!(f, "prev: none ")?;
144 }
145 if !self.next.is_null() {
146 write!(f, "next: {:p} ", self.next)?;
147 } else {
148 write!(f, "next: none ")?;
149 }
150 write!(f, ")")
151 }
152}
153
154#[repr(C)]
158pub struct DLinkedList<P, Tag>
159where
160 P: Pointer,
161 P::Target: DListItem<Tag>,
162{
163 length: usize,
164 head: *const P::Target,
165 tail: *const P::Target,
166 _phan: PhantomData<fn(&Tag)>,
167}
168
169unsafe impl<P, Tag> Send for DLinkedList<P, Tag>
170where
171 P: Pointer,
172 P::Target: DListItem<Tag>,
173{
174}
175
176impl<P: fmt::Debug, Tag> fmt::Debug for DLinkedList<P, Tag>
177where
178 P: Pointer,
179 P::Target: DListItem<Tag>,
180{
181 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
182 write!(f, "{{ length: {} ", self.length)?;
183 if !self.head.is_null() {
184 write!(f, "head: {:?} ", self.head)?;
185 } else {
186 write!(f, "head: none ")?;
187 }
188 if !self.tail.is_null() {
189 write!(f, "tail: {:?} ", self.tail)?;
190 } else {
191 write!(f, "tail: none ")?;
192 }
193 write!(f, "}}")
194 }
195}
196
197impl<P, Tag> DLinkedList<P, Tag>
198where
199 P: Pointer,
200 P::Target: DListItem<Tag>,
201{
202 #[inline(always)]
204 pub fn new() -> Self {
205 DLinkedList { length: 0, head: null(), tail: null(), _phan: Default::default() }
206 }
207
208 #[inline]
210 pub fn clear(&mut self) {
211 while self.pop_front().is_some() {}
215 }
216
217 #[inline(always)]
219 pub fn len(&self) -> usize {
220 self.length
221 }
222
223 #[inline(always)]
225 pub fn is_empty(&self) -> bool {
226 self.length == 0
227 }
228
229 #[inline(always)]
237 pub unsafe fn remove_node(&mut self, item: &P::Target) {
238 let node = item.get_node();
239 if let Some(prev) = node.get_prev() {
240 prev.next = node.next;
241 } else {
242 self.head = node.next;
243 }
244 if let Some(next) = node.get_next() {
245 next.prev = node.prev;
246 } else {
247 self.tail = node.prev;
248 }
249 node.next = null();
250 node.prev = null();
251 self.length -= 1;
252 }
253
254 #[inline(always)]
262 pub unsafe fn peak(&mut self, item: &P::Target) {
263 assert!(!self.head.is_null());
264 if !self.head.is_null() {
265 let head_node = unsafe { (*self.head).get_node() } as *const DListNode<P::Target, Tag>;
266 if ptr::eq(head_node, item.get_node()) {
267 return;
268 }
269 }
270 unsafe { self.remove_node(item) };
271 self.push_front_ptr(item as *const P::Target);
272 }
273
274 #[inline]
276 pub fn push_front(&mut self, item: P) {
277 let ptr = item.into_raw();
278 self.push_front_ptr(ptr);
279 }
280
281 #[inline]
282 fn push_front_ptr(&mut self, ptr: *const P::Target) {
283 let node = unsafe { (*ptr).get_node() };
284 let head = self.head;
285 node.next = head;
286 node.prev = null();
287
288 if head.is_null() {
289 self.tail = ptr;
290 } else {
291 unsafe {
292 (*head).get_node().prev = ptr;
293 }
294 }
295 self.head = ptr;
296 self.length += 1;
297 }
298
299 #[inline]
301 pub fn push_back(&mut self, item: P) {
302 let node = item.as_ref().get_node();
303 let tail = self.tail;
304 node.prev = tail;
305 node.next = null();
306
307 let ptr = item.into_raw();
308 if tail.is_null() {
309 self.head = ptr;
310 } else {
311 unsafe {
312 (*tail).get_node().next = ptr;
313 }
314 }
315 self.tail = ptr;
316 self.length += 1;
317 }
318
319 pub fn pop_front(&mut self) -> Option<P> {
321 if self.head.is_null() {
322 None
323 } else {
324 let head_ptr = self.head;
325 unsafe {
326 let item = &(*head_ptr);
327 self.remove_node(item);
328 Some(P::from_raw(head_ptr))
329 }
330 }
331 }
332
333 #[inline]
335 pub fn pop_back(&mut self) -> Option<P> {
336 if self.tail.is_null() {
337 None
338 } else {
339 let tail_ptr = self.tail;
340 unsafe {
341 let item = &(*tail_ptr);
342 self.remove_node(item);
343 Some(P::from_raw(tail_ptr))
344 }
345 }
346 }
347
348 #[inline]
350 pub fn get_front(&self) -> Option<&P::Target> {
351 if self.head.is_null() { None } else { unsafe { Some(&(*self.head)) } }
352 }
353
354 #[inline]
356 pub fn get_back(&self) -> Option<&P::Target> {
357 if self.tail.is_null() { None } else { unsafe { Some(&(*self.tail)) } }
358 }
359
360 #[inline(always)]
362 pub fn is_front(&self, node: &P::Target) -> bool {
363 if self.head.is_null() {
364 false
365 } else {
366 ptr::eq(self.head, node)
371 }
372 }
373
374 #[cfg(feature = "std")]
375 pub fn print<U: std::fmt::Debug>(&self) {
376 println!("print list begin! length={}", self.length);
377 let mut ptr = self.head;
378 while !ptr.is_null() {
379 unsafe {
380 ptr = (*ptr).get_node().next;
386 }
387 }
388 println!("print list end:");
389 }
390
391 #[inline(always)]
403 pub fn iter<'a>(&'a self) -> DLinkedListIterator<'a, P, Tag> {
404 DLinkedListIterator { list: self, cur: null() }
405 }
406
407 #[inline(always)]
414 pub fn drain<'a>(&'a mut self) -> DLinkedListDrainer<'a, P, Tag> {
415 DLinkedListDrainer { list: self }
416 }
417}
418
419impl<P, Tag> Drop for DLinkedList<P, Tag>
420where
421 P: Pointer,
422 P::Target: DListItem<Tag>,
423{
424 fn drop(&mut self) {
425 if mem::needs_drop::<P>() {
429 self.drain().for_each(drop);
430 }
431 }
432}
433
434pub struct DLinkedListIterator<'a, P, Tag>
435where
436 P: Pointer,
437 P::Target: DListItem<Tag>,
438{
439 list: &'a DLinkedList<P, Tag>,
440 cur: *const P::Target,
441}
442
443unsafe impl<'a, P, Tag> Send for DLinkedListIterator<'a, P, Tag>
444where
445 P: Pointer,
446 P::Target: DListItem<Tag>,
447{
448}
449
450impl<'a, P, Tag> Iterator for DLinkedListIterator<'a, P, Tag>
451where
452 P: Pointer,
453 P::Target: DListItem<Tag>,
454{
455 type Item = &'a P::Target;
456
457 fn next(&mut self) -> Option<Self::Item> {
458 if self.cur.is_null() {
459 if self.list.head.is_null() {
460 return None;
461 } else {
462 self.cur = self.list.head;
463 }
464 } else {
465 let next = unsafe { (*self.cur).get_node().next };
466 if next.is_null() {
467 return None;
468 } else {
469 self.cur = next;
470 }
471 }
472 unsafe { Some(&(*self.cur)) }
473 }
474}
475
476pub struct DLinkedListDrainer<'a, P, Tag>
477where
478 P: Pointer,
479 P::Target: DListItem<Tag>,
480{
481 list: &'a mut DLinkedList<P, Tag>,
482}
483
484unsafe impl<'a, P, Tag> Send for DLinkedListDrainer<'a, P, Tag>
485where
486 P: Pointer,
487 P::Target: DListItem<Tag>,
488{
489}
490
491impl<'a, P, Tag> Iterator for DLinkedListDrainer<'a, P, Tag>
492where
493 P: Pointer,
494 P::Target: DListItem<Tag>,
495{
496 type Item = P;
497
498 #[inline]
499 fn next(&mut self) -> Option<P> {
500 self.list.pop_front()
501 }
502}
503
504#[cfg(test)]
505mod tests {
506 use super::*;
507 use std::cell::UnsafeCell;
508 use std::ptr::NonNull;
509 use std::sync::Arc;
510 use std::sync::atomic::{AtomicUsize, Ordering};
511
512 pub struct TestTag;
513
514 #[derive(Debug)]
515 pub struct TestNode {
516 pub value: i64,
517 pub node: UnsafeCell<DListNode<Self, TestTag>>,
518 }
519
520 static ACTIVE_NODE_COUNT: AtomicUsize = AtomicUsize::new(0);
521
522 impl Drop for TestNode {
523 fn drop(&mut self) {
524 ACTIVE_NODE_COUNT.fetch_sub(1, Ordering::SeqCst);
525 }
526 }
527
528 unsafe impl Send for TestNode {}
529
530 unsafe impl DListItem<TestTag> for TestNode {
531 fn get_node(&self) -> &mut DListNode<Self, TestTag> {
532 unsafe { &mut *self.node.get() }
533 }
534 }
535
536 fn new_node(v: i64) -> TestNode {
537 ACTIVE_NODE_COUNT.fetch_add(1, Ordering::SeqCst);
538 TestNode { value: v, node: UnsafeCell::new(DListNode::default()) }
539 }
540
541 #[test]
542 fn test_push_back_box() {
543 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
544
545 let node1 = Box::new(new_node(1));
546 l.push_back(node1);
547
548 let node2 = Box::new(new_node(2));
549 l.push_back(node2);
550
551 let node3 = Box::new(new_node(3));
552 l.push_back(node3);
553
554 assert_eq!(3, l.len());
555
556 let mut iter = l.iter();
557 assert_eq!(iter.next().unwrap().value, 1);
558 assert_eq!(iter.next().unwrap().value, 2);
559 assert_eq!(iter.next().unwrap().value, 3);
560 assert!(iter.next().is_none());
561
562 {
563 let mut drain = l.drain();
564 assert_eq!(drain.next().unwrap().value, 1);
565 assert_eq!(drain.next().unwrap().value, 2);
566 assert_eq!(drain.next().unwrap().value, 3);
567 assert!(drain.next().is_none());
568 }
569 assert_eq!(l.len(), 0);
570 }
571
572 #[test]
573 fn test_push_back_arc() {
574 let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
575
576 let node1 = Arc::new(new_node(1));
577 l.push_back(node1);
578
579 let node2 = Arc::new(new_node(2));
580 l.push_back(node2);
581
582 let node3 = Arc::new(new_node(3));
583 l.push_back(node3);
584
585 assert_eq!(3, l.len());
586
587 let mut iter = l.iter();
588 assert_eq!(iter.next().unwrap().value, 1);
589 assert_eq!(iter.next().unwrap().value, 2);
590 assert_eq!(iter.next().unwrap().value, 3);
591 assert!(iter.next().is_none());
592
593 {
594 let mut drain = l.drain();
595 assert_eq!(drain.next().unwrap().value, 1);
596 assert_eq!(drain.next().unwrap().value, 2);
597 assert_eq!(drain.next().unwrap().value, 3);
598 assert!(drain.next().is_none());
599 }
600 assert_eq!(l.len(), 0);
601 }
602
603 #[test]
604 fn test_push_front_box() {
605 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
606
607 let node3 = Box::new(new_node(3));
608 l.push_front(node3);
609
610 let node2 = Box::new(new_node(2));
611 l.push_front(node2);
612
613 let node1 = Box::new(new_node(1));
614 l.push_front(node1);
615
616 assert_eq!(3, l.len());
617
618 let mut iter = l.iter();
619 assert_eq!(iter.next().unwrap().value, 1);
620 assert_eq!(iter.next().unwrap().value, 2);
621 assert_eq!(iter.next().unwrap().value, 3);
622 assert!(iter.next().is_none());
623
624 {
625 let mut drain = l.drain();
626 assert_eq!(drain.next().unwrap().value, 1);
627 assert_eq!(drain.next().unwrap().value, 2);
628 assert_eq!(drain.next().unwrap().value, 3);
629 assert!(drain.next().is_none());
630 }
631 assert_eq!(l.len(), 0);
632 }
633
634 #[test]
635 fn test_push_front_arc() {
636 let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
637
638 let node3 = Arc::new(new_node(3));
639 l.push_front(node3);
640
641 let node2 = Arc::new(new_node(2));
642 l.push_front(node2);
643
644 let node1 = Arc::new(new_node(1));
645 l.push_front(node1);
646
647 assert_eq!(3, l.len());
648
649 let mut iter = l.iter();
650 assert_eq!(iter.next().unwrap().value, 1);
651 assert_eq!(iter.next().unwrap().value, 2);
652 assert_eq!(iter.next().unwrap().value, 3);
653 assert!(iter.next().is_none());
654
655 {
656 let mut drain = l.drain();
657 assert_eq!(drain.next().unwrap().value, 1);
658 assert_eq!(drain.next().unwrap().value, 2);
659 assert_eq!(drain.next().unwrap().value, 3);
660 assert!(drain.next().is_none());
661 }
662 assert_eq!(l.len(), 0);
663 }
664
665 #[test]
666 fn test_pop_back_box() {
667 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
668
669 let node1 = Box::new(new_node(1));
670 l.push_back(node1);
671
672 let node2 = Box::new(new_node(2));
673 l.push_back(node2);
674
675 let node3 = Box::new(new_node(3));
676 l.push_back(node3);
677
678 let mut iter = l.iter();
679 assert_eq!(iter.next().unwrap().value, 1);
680 assert_eq!(iter.next().unwrap().value, 2);
681 assert_eq!(iter.next().unwrap().value, 3);
682 assert!(iter.next().is_none());
683
684 let del_node = l.pop_back();
685 assert_eq!(2, l.len());
686 assert!(del_node.is_some());
687 assert_eq!(del_node.unwrap().value, 3);
688
689 let mut iter_remaining = l.iter();
690 assert_eq!(iter_remaining.next().unwrap().value, 1);
691 assert_eq!(iter_remaining.next().unwrap().value, 2);
692 assert!(iter_remaining.next().is_none());
693
694 {
695 let mut drain = l.drain();
696 assert_eq!(drain.next().unwrap().value, 1);
697 assert_eq!(drain.next().unwrap().value, 2);
698 assert!(drain.next().is_none());
699 }
700 assert_eq!(l.len(), 0);
701 }
702
703 #[test]
704 fn test_pop_back_arc() {
705 let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
706
707 let node1 = Arc::new(new_node(1));
708 l.push_back(node1);
709
710 let node2 = Arc::new(new_node(2));
711 l.push_back(node2);
712
713 let node3 = Arc::new(new_node(3));
714 l.push_back(node3);
715
716 let mut iter = l.iter();
717 assert_eq!(iter.next().unwrap().value, 1);
718 assert_eq!(iter.next().unwrap().value, 2);
719 assert_eq!(iter.next().unwrap().value, 3);
720 assert!(iter.next().is_none());
721
722 let del_node = l.pop_back();
723 assert_eq!(2, l.len());
724 assert!(del_node.is_some());
725 assert!(del_node.is_some());
727
728 let mut iter = l.iter();
730 assert_eq!(iter.next().unwrap().value, 1);
731 assert_eq!(iter.next().unwrap().value, 2);
732 assert!(iter.next().is_none());
733
734 {
735 let mut drain = l.drain();
736 assert_eq!(drain.next().unwrap().value, 1);
737 assert_eq!(drain.next().unwrap().value, 2);
738 assert!(drain.next().is_none());
739 }
740 assert_eq!(l.len(), 0);
741 }
742
743 #[test]
744 fn test_iter_box() {
745 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
746
747 let mut count = 0;
748 for _item in l.iter() {
749 count += 1;
750 }
751 assert_eq!(count, 0);
752
753 let node1 = Box::new(new_node(1));
754 l.push_back(node1);
755
756 let node2 = Box::new(new_node(2));
757 l.push_back(node2);
758
759 let node3 = Box::new(new_node(3));
760 l.push_back(node3);
761
762 count = 0;
763 for item in l.iter() {
764 count += 1;
765 println!("{}", item.value);
766 }
767 assert_eq!(count, 3);
768
769 {
770 let mut drain = l.drain();
771 assert_eq!(drain.next().unwrap().value, 1);
772 assert_eq!(drain.next().unwrap().value, 2);
773 assert_eq!(drain.next().unwrap().value, 3);
774 assert!(drain.next().is_none());
775 }
776 assert_eq!(l.len(), 0);
777 }
778
779 #[test]
780 fn test_iter_arc() {
781 let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
782
783 let mut count = 0;
784 for _item in l.iter() {
785 count += 1;
786 }
787 assert_eq!(count, 0);
788
789 let node1 = Arc::new(new_node(1));
790 l.push_back(node1);
791
792 let node2 = Arc::new(new_node(2));
793 l.push_back(node2);
794
795 let node3 = Arc::new(new_node(3));
796 l.push_back(node3);
797
798 let mut iter = l.iter();
800 assert_eq!(iter.next().unwrap().value, 1);
801 assert_eq!(iter.next().unwrap().value, 2);
802 assert_eq!(iter.next().unwrap().value, 3);
803 assert!(iter.next().is_none());
804
805 {
806 let mut drain = l.drain();
807 assert_eq!(drain.next().unwrap().value, 1);
808 assert_eq!(drain.next().unwrap().value, 2);
809 assert_eq!(drain.next().unwrap().value, 3);
810 assert!(drain.next().is_none());
811 }
812 assert_eq!(l.len(), 0);
813 }
814
815 #[test]
816 fn test_single_element_box() {
817 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
818 let node1 = Box::new(new_node(1));
819 l.push_front(node1);
820 let del_node = l.pop_back();
821 assert!(del_node.is_some());
822 assert_eq!(del_node.unwrap().value, 1);
823 assert_eq!(0, l.len());
824 assert!(l.pop_back().is_none());
825
826 let mut l2 = DLinkedList::<Box<TestNode>, TestTag>::new();
827 let node2 = Box::new(new_node(2));
828 l2.push_back(node2);
829 let del_node2 = l2.pop_back();
830 assert!(del_node2.is_some());
831 assert_eq!(del_node2.unwrap().value, 2);
832 assert_eq!(0, l2.len());
833 assert!(l2.pop_back().is_none());
834
835 {
836 let mut drain = l.drain();
837 assert!(drain.next().is_none());
838 }
839 assert_eq!(l.len(), 0);
840
841 {
842 let mut drain = l2.drain();
843 assert!(drain.next().is_none());
844 }
845 assert_eq!(l2.len(), 0);
846 }
847
848 #[test]
849 fn test_single_element_arc() {
850 let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
851 let node1 = Arc::new(new_node(1));
852 l.push_front(node1);
853 let del_node = l.pop_back();
854 assert!(del_node.is_some());
855 assert_eq!(0, l.len());
856 assert!(l.pop_back().is_none());
857
858 let mut l2 = DLinkedList::<Arc<TestNode>, TestTag>::new();
859 let node2 = Arc::new(new_node(2));
860 l2.push_back(node2);
861 let del_node2 = l2.pop_back();
862 assert!(del_node2.is_some());
863 assert_eq!(0, l2.len());
864 assert!(l2.pop_back().is_none());
865
866 {
867 let mut drain = l.drain();
868 assert!(drain.next().is_none());
869 }
870 assert_eq!(l.len(), 0);
871
872 {
873 let mut drain = l2.drain();
874 assert!(drain.next().is_none());
875 }
876 assert_eq!(l2.len(), 0);
877 }
878
879 #[test]
880 fn test_drop_box_implementation() {
881 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
883
884 {
885 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
886
887 let node1 = Box::new(new_node(1));
888 l.push_back(node1);
889
890 let node2 = Box::new(new_node(2));
891 l.push_back(node2);
892
893 let node3 = Box::new(new_node(3));
894 l.push_back(node3);
895
896 assert_eq!(l.len(), 3);
897 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 3);
898 } assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
902 }
903
904 #[test]
905 fn test_raw_pointer_list() {
906 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
908
909 let node1 = Box::into_raw(Box::new(new_node(10)));
911 let node2 = Box::into_raw(Box::new(new_node(20)));
912
913 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
914
915 {
916 let mut l = DLinkedList::<*const TestNode, TestTag>::new();
917 l.push_back(node1);
918 l.push_back(node2);
919
920 let mut iter = l.iter();
921 assert_eq!(iter.next().unwrap().value, 10);
922 assert_eq!(iter.next().unwrap().value, 20);
923 assert!(iter.next().is_none());
924 } assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
928
929 unsafe {
930 assert_eq!((*node1).value, 10);
932 assert_eq!((*node2).value, 20);
933
934 drop(Box::from_raw(node1));
936 drop(Box::from_raw(node2));
937 }
938 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
939 }
940
941 #[test]
942 fn test_non_null_list() {
943 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
945
946 let node1 = Box::leak(Box::new(new_node(100)));
949 let node2 = Box::leak(Box::new(new_node(200)));
950
951 let ptr1 = NonNull::from(node1);
952 let ptr2 = NonNull::from(node2);
953
954 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
955
956 {
957 let mut l = DLinkedList::<NonNull<TestNode>, TestTag>::new();
958 l.push_back(ptr1);
959 l.push_back(ptr2);
960
961 let mut iter = l.iter();
962 assert_eq!(iter.next().unwrap().value, 100);
963 assert_eq!(iter.next().unwrap().value, 200);
964 assert!(iter.next().is_none());
965 } assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
969
970 unsafe {
971 drop(Box::from_raw(ptr1.as_ptr()));
973 drop(Box::from_raw(ptr2.as_ptr()));
974 }
975
976 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
977 }
978
979 #[test]
980 fn test_clear() {
981 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
982 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
983
984 l.push_back(Box::new(new_node(1)));
985 l.push_back(Box::new(new_node(2)));
986 assert_eq!(l.len(), 2);
987 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
988
989 l.clear();
990
991 assert!(l.is_empty());
992 assert_eq!(l.len(), 0);
993 assert!(l.get_front().is_none());
994 assert!(l.get_back().is_none());
995 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
996
997 l.push_back(Box::new(new_node(3)));
999 assert_eq!(l.len(), 1);
1000 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 1);
1001 }
1002}