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