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;
242#[cfg(any(feature = "std", test))]
243extern crate std;
244
245use core::marker::PhantomData;
246use core::{
247 borrow::BorrowMut,
248 fmt,
249 mem::{self, MaybeUninit},
250 ptr::{self, null, null_mut},
251};
252use pointers::Pointer;
253
254pub unsafe trait DListItem<Tag>: Sized {
266 fn get_node(&self) -> &mut DListNode<Tag>;
267
268 #[allow(unsafe_op_in_unsafe_fn)]
275 #[inline(always)]
276 unsafe fn get_node_from_ptr<'a>(p: *mut u8) -> &'a mut DListNode<Tag>
277 where
278 Self: 'a,
279 {
280 debug_assert!(!p.is_null());
281 (*(p as *const Self)).get_node()
282 }
283}
284
285#[repr(C)]
287pub struct DListNode<Tag> {
288 prev: *mut u8,
289 next: *mut u8,
290 _phan: PhantomData<fn(&Tag)>,
291}
292
293unsafe impl<Tag> Send for DListNode<Tag> {}
294
295impl<Tag> Default for DListNode<Tag> {
296 #[inline(always)]
297 fn default() -> Self {
298 Self { prev: null_mut(), next: null_mut(), _phan: Default::default() }
299 }
300}
301
302impl<Tag> fmt::Debug for DListNode<Tag> {
303 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
304 write!(f, "(")?;
305 if !self.prev.is_null() {
306 write!(f, "prev: {:p} ", self.prev)?;
307 } else {
308 write!(f, "prev: none ")?;
309 }
310 if !self.next.is_null() {
311 write!(f, "next: {:p} ", self.next)?;
312 } else {
313 write!(f, "next: none ")?;
314 }
315 write!(f, ")")
316 }
317}
318
319#[repr(C)]
323pub struct DLinkedList<P, Tag>
324where
325 P: Pointer,
326 P::Target: DListItem<Tag>,
327{
328 length: usize,
329 head: *mut u8,
330 tail: *mut u8,
331 _phan: PhantomData<fn(&P, &Tag)>,
332}
333
334unsafe impl<P, Tag> Send for DLinkedList<P, Tag>
335where
336 P: Pointer,
337 P::Target: DListItem<Tag>,
338{
339}
340
341impl<P: fmt::Debug, Tag> fmt::Debug for DLinkedList<P, Tag>
342where
343 P: Pointer,
344 P::Target: DListItem<Tag>,
345{
346 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
347 write!(f, "{{ length: {} ", self.length)?;
348 if !self.head.is_null() {
349 write!(f, "head: {:?} ", self.head)?;
350 } else {
351 write!(f, "head: none ")?;
352 }
353 if !self.tail.is_null() {
354 write!(f, "tail: {:?} ", self.tail)?;
355 } else {
356 write!(f, "tail: none ")?;
357 }
358 write!(f, "}}")
359 }
360}
361
362impl<P, Tag> DLinkedList<P, Tag>
363where
364 P: Pointer,
365 P::Target: DListItem<Tag>,
366{
367 #[inline(always)]
369 pub fn new() -> Self {
370 DLinkedList { length: 0, head: null_mut(), tail: null_mut(), _phan: Default::default() }
371 }
372
373 #[inline]
375 pub fn clear(&mut self) {
376 while self.pop_front().is_some() {}
380 }
381
382 #[inline(always)]
384 pub fn len(&self) -> usize {
385 self.length
386 }
387
388 #[inline(always)]
390 pub fn is_empty(&self) -> bool {
391 self.length == 0
392 }
393
394 #[inline(always)]
395 fn _remove_node(&mut self, item: *mut u8) -> bool {
396 let mut removed = false;
397 unsafe {
398 let node = <P::Target as DListItem<Tag>>::get_node_from_ptr(item);
399 if !node.prev.is_null() {
400 <P::Target as DListItem<Tag>>::get_node_from_ptr(node.prev).next = node.next;
401 removed = true;
402 } else if self.head == item {
403 self.head = node.next;
404 removed = true;
405 }
406 if !node.next.is_null() {
407 <P::Target as DListItem<Tag>>::get_node_from_ptr(node.next).prev = node.prev;
408 removed = true;
409 } else if self.tail == item {
410 self.tail = node.prev;
411 removed = true;
412 }
413 if removed {
414 node.next = null_mut();
415 node.prev = null_mut();
416 self.length -= 1;
417 }
418 }
419 removed
420 }
421
422 #[inline(always)]
480 pub unsafe fn remove_node(&mut self, item: *const P::Target) -> Option<P> {
481 unsafe { if self._remove_node(item as *mut u8) { Some(P::from_raw(item)) } else { None } }
482 }
483
484 #[inline(always)]
492 pub unsafe fn remove_node_raw(&mut self, item: *const P::Target) -> *const P::Target {
493 if self._remove_node(item as *mut u8) { item } else { null() }
494 }
495
496 #[inline(always)]
504 pub unsafe fn peak(&mut self, item: *const P::Target) {
505 assert!(!self.head.is_null());
506 if !ptr::eq(self.head, item as *mut u8) {
507 assert!(self._remove_node(item as *mut u8), "item is not in the list");
508 self.push_front_ptr(item);
509 }
510 }
511
512 #[inline]
514 pub fn push_front(&mut self, item: P) {
515 let ptr = item.into_raw();
516 self.push_front_ptr(ptr);
517 }
518
519 #[inline]
520 fn push_front_ptr(&mut self, ptr: *const P::Target) {
521 let node = unsafe { <P::Target as DListItem<Tag>>::get_node_from_ptr(ptr as *mut u8) };
522 let head = self.head;
523 node.next = head;
524 node.prev = null_mut();
525
526 if head.is_null() {
527 self.tail = ptr as *mut u8;
528 } else {
529 unsafe {
530 <P::Target as DListItem<Tag>>::get_node_from_ptr(head).prev = ptr as *mut u8;
531 }
532 }
533 self.head = ptr as *mut u8;
534 self.length += 1;
535 }
536
537 #[inline]
539 pub fn push_back(&mut self, item: P) {
540 let tail = self.tail;
541 let ptr = item.into_raw() as *mut u8;
542 unsafe {
543 let node = <P::Target as DListItem<Tag>>::get_node_from_ptr(ptr);
544 node.prev = tail;
545 node.next = null_mut();
546 if tail.is_null() {
547 self.head = ptr;
548 } else {
549 <P::Target as DListItem<Tag>>::get_node_from_ptr(tail).next = ptr;
550 }
551 }
552 self.tail = ptr;
553 self.length += 1;
554 }
555
556 pub fn pop_front(&mut self) -> Option<P> {
558 if !self.head.is_null() {
559 let head_ptr = self.head;
560 unsafe {
561 self._remove_node(head_ptr);
562 Some(P::from_raw(head_ptr as *const P::Target))
563 }
564 } else {
565 None
566 }
567 }
568
569 #[inline]
571 pub fn pop_back(&mut self) -> Option<P> {
572 if !self.tail.is_null() {
573 let tail_ptr = self.tail;
574 unsafe {
575 self._remove_node(tail_ptr);
576 Some(P::from_raw(tail_ptr as *const P::Target))
577 }
578 } else {
579 None
580 }
581 }
582
583 #[inline]
584 pub fn get_front_ptr(&self) -> *const P::Target {
585 self.head as *const P::Target
586 }
587
588 #[inline]
590 pub fn get_front(&self) -> Option<&P::Target> {
591 unsafe {
592 if !self.head.is_null() { Some(&(*(self.head as *const P::Target))) } else { None }
593 }
594 }
595
596 #[inline]
597 pub fn get_back_ptr(&self) -> *const P::Target {
598 self.tail as *const P::Target
599 }
600
601 #[inline]
603 pub fn get_back(&self) -> Option<&P::Target> {
604 unsafe {
605 if !self.tail.is_null() { Some(&(*(self.tail as *const P::Target))) } else { None }
606 }
607 }
608
609 #[inline(always)]
611 pub fn is_front(&self, node: &P::Target) -> bool {
612 if self.head.is_null() {
613 false
614 } else {
615 ptr::eq(self.head, node as *const P::Target as *mut u8)
620 }
621 }
622
623 #[inline(always)]
635 pub fn iter<'a>(&'a self) -> DLinkedListIter<'a, P, Tag> {
636 DLinkedListIter {
637 next_p: self.head,
638 len: self.len(),
639 _phan: Default::default(),
640 cur: MaybeUninit::uninit(),
641 }
642 }
643
644 #[inline(always)]
651 pub fn drain<'a>(&'a mut self) -> DLinkedListDrainer<'a, P, Tag> {
652 DLinkedListDrainer { list: self, _phan: Default::default() }
653 }
654}
655
656impl<P, Tag> Drop for DLinkedList<P, Tag>
657where
658 P: Pointer,
659 P::Target: DListItem<Tag>,
660{
661 fn drop(&mut self) {
662 if mem::needs_drop::<P>() {
666 self.drain().for_each(drop);
667 }
668 }
669}
670
671pub struct DLinkedListIter<'a, P, Tag>
672where
673 P: Pointer,
674 P::Target: DListItem<Tag>,
675{
676 next_p: *mut u8,
677 cur: MaybeUninit<P>,
678 len: usize,
679 _phan: PhantomData<&'a DLinkedList<P, Tag>>,
680}
681
682unsafe impl<'a, P, Tag> Send for DLinkedListIter<'a, P, Tag>
683where
684 P: Pointer,
685 P::Target: DListItem<Tag>,
686{
687}
688
689impl<'a, P, Tag> Iterator for DLinkedListIter<'a, P, Tag>
690where
691 P: Pointer,
692 P::Target: DListItem<Tag>,
693{
694 type Item = &'a P;
695
696 #[inline]
697 fn next(&mut self) -> Option<&'a P> {
698 if !self.next_p.is_null() {
699 self.len -= 1;
700 let cur = self.next_p;
701 unsafe {
702 self.next_p = <P::Target as DListItem<Tag>>::get_node_from_ptr(cur).next;
703 self.cur.write(P::from_raw(cur as *const P::Target));
704 return Some(mem::transmute::<&P, &P>(self.cur.assume_init_ref()));
706 }
707 }
708 None
709 }
710
711 #[inline]
712 fn size_hint(&self) -> (usize, Option<usize>) {
713 (self.len, Some(self.len))
714 }
715}
716
717impl<'a, P, Tag> ExactSizeIterator for DLinkedListIter<'a, P, Tag>
718where
719 P: Pointer,
720 P::Target: DListItem<Tag>,
721{
722}
723
724pub type DLinkedListDrainer<'a, P, Tag> = Drainer<&'a mut DLinkedList<P, Tag>, P, Tag>;
725pub type DLinkedListIntoIter<P, Tag> = Drainer<DLinkedList<P, Tag>, P, Tag>;
726
727pub struct Drainer<L, P, Tag>
728where
729 L: BorrowMut<DLinkedList<P, Tag>>,
730 P: Pointer,
731 P::Target: DListItem<Tag>,
732{
733 list: L,
734 _phan: PhantomData<(P, Tag)>,
735}
736
737impl<L, P, Tag> Iterator for Drainer<L, P, Tag>
738where
739 L: BorrowMut<DLinkedList<P, Tag>>,
740 P: Pointer,
741 P::Target: DListItem<Tag>,
742{
743 type Item = P;
744
745 #[inline]
746 fn next(&mut self) -> Option<P> {
747 self.list.borrow_mut().pop_front()
748 }
749
750 #[inline]
751 fn size_hint(&self) -> (usize, Option<usize>) {
752 let l = self.list.borrow().len();
753 (l, Some(l))
754 }
755}
756
757impl<L, P, Tag> ExactSizeIterator for Drainer<L, P, Tag>
758where
759 L: BorrowMut<DLinkedList<P, Tag>>,
760 P: Pointer,
761 P::Target: DListItem<Tag>,
762{
763}
764
765impl<'a, P, Tag> IntoIterator for &'a DLinkedList<P, Tag>
766where
767 P: Pointer,
768 P::Target: DListItem<Tag>,
769{
770 type Item = &'a P;
771 type IntoIter = DLinkedListIter<'a, P, Tag>;
772
773 #[inline]
774 fn into_iter(self) -> Self::IntoIter {
775 self.iter()
776 }
777}
778
779impl<P, Tag> IntoIterator for DLinkedList<P, Tag>
780where
781 P: Pointer,
782 P::Target: DListItem<Tag>,
783{
784 type Item = P;
785 type IntoIter = DLinkedListIntoIter<P, Tag>;
786
787 #[inline]
788 fn into_iter(self) -> Self::IntoIter {
789 Drainer { list: self, _phan: Default::default() }
790 }
791}
792
793#[cfg(test)]
794mod tests {
795 use super::*;
796 use std::boxed::Box;
797 use std::cell::UnsafeCell;
798 use std::println;
799 use std::ptr::NonNull;
800 use std::sync::Arc;
801 use std::sync::atomic::{AtomicUsize, Ordering};
802
803 pub struct TestTag;
804
805 #[derive(Debug)]
806 pub struct TestNode {
807 pub value: i64,
808 pub node: UnsafeCell<DListNode<TestTag>>,
809 }
810
811 static ACTIVE_NODE_COUNT: AtomicUsize = AtomicUsize::new(0);
812
813 impl Drop for TestNode {
814 fn drop(&mut self) {
815 ACTIVE_NODE_COUNT.fetch_sub(1, Ordering::SeqCst);
816 }
817 }
818
819 unsafe impl Send for TestNode {}
820
821 unsafe impl DListItem<TestTag> for TestNode {
822 fn get_node(&self) -> &mut DListNode<TestTag> {
823 unsafe { &mut *self.node.get() }
824 }
825 }
826
827 fn new_node(v: i64) -> TestNode {
828 ACTIVE_NODE_COUNT.fetch_add(1, Ordering::SeqCst);
829 TestNode { value: v, node: UnsafeCell::new(DListNode::default()) }
830 }
831
832 #[test]
833 fn test_push_back_box() {
834 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
835
836 let node1 = Box::new(new_node(1));
837 l.push_back(node1);
838
839 let node2 = Box::new(new_node(2));
840 l.push_back(node2);
841
842 let node3 = Box::new(new_node(3));
843 l.push_back(node3);
844
845 assert_eq!(3, l.len());
846
847 let mut iter = l.iter();
848 assert_eq!(iter.next().unwrap().value, 1);
849 assert_eq!(iter.next().unwrap().value, 2);
850 assert_eq!(iter.next().unwrap().value, 3);
851 assert!(iter.next().is_none());
852
853 {
854 let mut drain = l.drain();
855 assert_eq!(drain.next().unwrap().value, 1);
856 assert_eq!(drain.next().unwrap().value, 2);
857 assert_eq!(drain.next().unwrap().value, 3);
858 assert!(drain.next().is_none());
859 }
860 assert_eq!(l.len(), 0);
861 }
862
863 #[test]
864 fn test_push_back_arc() {
865 let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
866
867 let node1 = Arc::new(new_node(1));
868 l.push_back(node1);
869
870 let node2 = Arc::new(new_node(2));
871 l.push_back(node2);
872
873 let node3 = Arc::new(new_node(3));
874 l.push_back(node3);
875
876 assert_eq!(3, l.len());
877
878 let mut iter = l.iter();
879 assert_eq!(iter.next().unwrap().value, 1);
880 assert_eq!(iter.next().unwrap().value, 2);
881 assert_eq!(iter.next().unwrap().value, 3);
882 assert!(iter.next().is_none());
883
884 {
885 let mut drain = l.drain();
886 assert_eq!(drain.next().unwrap().value, 1);
887 assert_eq!(drain.next().unwrap().value, 2);
888 assert_eq!(drain.next().unwrap().value, 3);
889 assert!(drain.next().is_none());
890 }
891 assert_eq!(l.len(), 0);
892 }
893
894 #[test]
895 fn test_push_front_box() {
896 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
897
898 let node3 = Box::new(new_node(3));
899 l.push_front(node3);
900
901 let node2 = Box::new(new_node(2));
902 l.push_front(node2);
903
904 let node1 = Box::new(new_node(1));
905 l.push_front(node1);
906
907 assert_eq!(3, l.len());
908
909 let mut iter = l.iter();
910 assert_eq!(iter.next().unwrap().value, 1);
911 assert_eq!(iter.next().unwrap().value, 2);
912 assert_eq!(iter.next().unwrap().value, 3);
913 assert!(iter.next().is_none());
914
915 {
916 let mut drain = l.drain();
917 assert_eq!(drain.next().unwrap().value, 1);
918 assert_eq!(drain.next().unwrap().value, 2);
919 assert_eq!(drain.next().unwrap().value, 3);
920 assert!(drain.next().is_none());
921 }
922 assert_eq!(l.len(), 0);
923 }
924
925 #[test]
926 fn test_push_front_arc() {
927 let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
928
929 let node3 = Arc::new(new_node(3));
930 l.push_front(node3);
931
932 let node2 = Arc::new(new_node(2));
933 l.push_front(node2);
934
935 let node1 = Arc::new(new_node(1));
936 l.push_front(node1);
937
938 assert_eq!(3, l.len());
939
940 let mut iter = l.iter();
941 assert_eq!(iter.next().unwrap().value, 1);
942 assert_eq!(iter.next().unwrap().value, 2);
943 assert_eq!(iter.next().unwrap().value, 3);
944 assert!(iter.next().is_none());
945
946 {
947 let mut drain = l.drain();
948 assert_eq!(drain.next().unwrap().value, 1);
949 assert_eq!(drain.next().unwrap().value, 2);
950 assert_eq!(drain.next().unwrap().value, 3);
951 assert!(drain.next().is_none());
952 }
953 assert_eq!(l.len(), 0);
954 }
955
956 #[test]
957 fn test_pop_back_box() {
958 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
959
960 let node1 = Box::new(new_node(1));
961 l.push_back(node1);
962
963 let node2 = Box::new(new_node(2));
964 l.push_back(node2);
965
966 let node3 = Box::new(new_node(3));
967 l.push_back(node3);
968
969 let mut iter = l.iter();
970 assert_eq!(iter.next().unwrap().value, 1);
971 assert_eq!(iter.next().unwrap().value, 2);
972 assert_eq!(iter.next().unwrap().value, 3);
973 assert!(iter.next().is_none());
974
975 let del_node = l.pop_back();
976 assert_eq!(2, l.len());
977 assert!(del_node.is_some());
978 assert_eq!(del_node.unwrap().value, 3);
979
980 let mut iter_remaining = l.iter();
981 assert_eq!(iter_remaining.next().unwrap().value, 1);
982 assert_eq!(iter_remaining.next().unwrap().value, 2);
983 assert!(iter_remaining.next().is_none());
984
985 {
986 let mut drain = l.drain();
987 assert_eq!(drain.next().unwrap().value, 1);
988 assert_eq!(drain.next().unwrap().value, 2);
989 assert!(drain.next().is_none());
990 }
991 assert_eq!(l.len(), 0);
992 }
993
994 #[test]
995 fn test_pop_back_arc() {
996 let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
997
998 let node1 = Arc::new(new_node(1));
999 l.push_back(node1);
1000
1001 let node2 = Arc::new(new_node(2));
1002 l.push_back(node2);
1003
1004 let node3 = Arc::new(new_node(3));
1005 l.push_back(node3);
1006
1007 let mut iter = l.iter();
1008 assert_eq!(iter.next().unwrap().value, 1);
1009 assert_eq!(iter.next().unwrap().value, 2);
1010 assert_eq!(iter.next().unwrap().value, 3);
1011 assert!(iter.next().is_none());
1012
1013 let del_node = l.pop_back();
1014 assert_eq!(2, l.len());
1015 assert!(del_node.is_some());
1016 assert!(del_node.is_some());
1018
1019 let mut iter = l.iter();
1021 assert_eq!(iter.next().unwrap().value, 1);
1022 assert_eq!(iter.next().unwrap().value, 2);
1023 assert!(iter.next().is_none());
1024
1025 {
1026 let mut drain = l.drain();
1027 assert_eq!(drain.next().unwrap().value, 1);
1028 assert_eq!(drain.next().unwrap().value, 2);
1029 assert!(drain.next().is_none());
1030 }
1031 assert_eq!(l.len(), 0);
1032 }
1033
1034 #[test]
1035 fn test_pop_front_arc() {
1036 let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
1037
1038 let node1 = Arc::new(new_node(1));
1039 l.push_front(node1);
1040
1041 let node2 = Arc::new(new_node(2));
1042 l.push_front(node2);
1043
1044 let node3 = Arc::new(new_node(3));
1045 l.push_front(node3);
1046
1047 let mut iter = l.iter();
1048 assert_eq!(iter.next().unwrap().value, 3);
1049 assert_eq!(iter.next().unwrap().value, 2);
1050 assert_eq!(iter.next().unwrap().value, 1);
1051 assert!(iter.next().is_none());
1052
1053 let del_node = l.pop_front();
1054 assert_eq!(2, l.len());
1055 assert!(del_node.is_some());
1056 assert!(del_node.is_some());
1058
1059 let mut iter = l.iter();
1061 assert_eq!(iter.next().unwrap().value, 2);
1062 assert_eq!(iter.next().unwrap().value, 1);
1063 assert!(iter.next().is_none());
1064
1065 {
1066 assert_eq!(l.pop_front().unwrap().value, 2);
1067 assert_eq!(l.pop_front().unwrap().value, 1);
1068 assert!(l.pop_front().is_none());
1069 assert!(l.pop_back().is_none());
1070 }
1071 assert_eq!(l.len(), 0);
1072 }
1073
1074 #[test]
1075 fn test_iter_box() {
1076 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
1077
1078 let mut count = 0;
1079 for _item in l.iter() {
1080 count += 1;
1081 }
1082 assert_eq!(count, 0);
1083
1084 let node1 = Box::new(new_node(1));
1085 l.push_back(node1);
1086
1087 let node2 = Box::new(new_node(2));
1088 l.push_back(node2);
1089
1090 let node3 = Box::new(new_node(3));
1091 l.push_back(node3);
1092
1093 count = 0;
1094 for item in l.iter() {
1095 count += 1;
1096 println!("{}", item.value);
1097 }
1098 assert_eq!(count, 3);
1099
1100 {
1101 let mut drain = l.drain();
1102 assert_eq!(drain.next().unwrap().value, 1);
1103 assert_eq!(drain.next().unwrap().value, 2);
1104 assert_eq!(drain.next().unwrap().value, 3);
1105 assert!(drain.next().is_none());
1106 }
1107 assert_eq!(l.len(), 0);
1108 }
1109
1110 #[test]
1111 fn test_iter_arc() {
1112 let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
1113
1114 let mut count = 0;
1115 for _item in l.iter() {
1116 count += 1;
1117 }
1118 assert_eq!(count, 0);
1119
1120 let node1 = Arc::new(new_node(1));
1121 l.push_back(node1);
1122
1123 let node2 = Arc::new(new_node(2));
1124 l.push_back(node2);
1125
1126 let node3 = Arc::new(new_node(3));
1127 l.push_back(node3);
1128
1129 let mut iter = l.iter();
1131 assert_eq!(iter.next().unwrap().value, 1);
1132 assert_eq!(iter.next().unwrap().value, 2);
1133 assert_eq!(iter.next().unwrap().value, 3);
1134 assert!(iter.next().is_none());
1135
1136 {
1137 let mut drain = l.drain();
1138 assert_eq!(drain.next().unwrap().value, 1);
1139 assert_eq!(drain.next().unwrap().value, 2);
1140 assert_eq!(drain.next().unwrap().value, 3);
1141 assert!(drain.next().is_none());
1142 }
1143 assert_eq!(l.len(), 0);
1144 }
1145
1146 #[test]
1147 fn test_single_element_box() {
1148 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
1149 let node1 = Box::new(new_node(1));
1150 l.push_front(node1);
1151 let del_node = l.pop_back();
1152 assert!(del_node.is_some());
1153 assert_eq!(del_node.unwrap().value, 1);
1154 assert_eq!(0, l.len());
1155 assert!(l.pop_back().is_none());
1156
1157 let mut l2 = DLinkedList::<Box<TestNode>, TestTag>::new();
1158 let node2 = Box::new(new_node(2));
1159 l2.push_back(node2);
1160 let del_node2 = l2.pop_back();
1161 assert!(del_node2.is_some());
1162 assert_eq!(del_node2.unwrap().value, 2);
1163 assert_eq!(0, l2.len());
1164 assert!(l2.pop_back().is_none());
1165
1166 {
1167 let mut drain = l.drain();
1168 assert!(drain.next().is_none());
1169 }
1170 assert_eq!(l.len(), 0);
1171
1172 {
1173 let mut drain = l2.drain();
1174 assert!(drain.next().is_none());
1175 }
1176 assert_eq!(l2.len(), 0);
1177 }
1178
1179 #[test]
1180 fn test_single_element_arc() {
1181 let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
1182 let node1 = Arc::new(new_node(1));
1183 l.push_front(node1);
1184 let del_node = l.pop_back();
1185 assert!(del_node.is_some());
1186 assert_eq!(0, l.len());
1187 assert!(l.pop_back().is_none());
1188
1189 let mut l2 = DLinkedList::<Arc<TestNode>, TestTag>::new();
1190 let node2 = Arc::new(new_node(2));
1191 l2.push_back(node2);
1192 let del_node2 = l2.pop_back();
1193 assert!(del_node2.is_some());
1194 assert_eq!(0, l2.len());
1195 assert!(l2.pop_back().is_none());
1196
1197 {
1198 let mut drain = l.drain();
1199 assert!(drain.next().is_none());
1200 }
1201 assert_eq!(l.len(), 0);
1202
1203 {
1204 let mut drain = l2.drain();
1205 assert!(drain.next().is_none());
1206 }
1207 assert_eq!(l2.len(), 0);
1208 }
1209
1210 #[test]
1211 fn test_drop_box_implementation() {
1212 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
1214
1215 {
1216 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
1217
1218 let node1 = Box::new(new_node(1));
1219 l.push_back(node1);
1220
1221 let node2 = Box::new(new_node(2));
1222 l.push_back(node2);
1223
1224 let node3 = Box::new(new_node(3));
1225 l.push_back(node3);
1226
1227 assert_eq!(l.len(), 3);
1228 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 3);
1229 } assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
1233 }
1234
1235 #[test]
1236 fn test_raw_pointer_list() {
1237 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
1239
1240 let node1 = Box::into_raw(Box::new(new_node(10)));
1242 let node2 = Box::into_raw(Box::new(new_node(20)));
1243
1244 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
1245
1246 unsafe {
1247 let mut l = DLinkedList::<*const TestNode, TestTag>::new();
1248 l.push_back(node1);
1249 l.push_back(node2);
1250
1251 let mut iter = l.iter();
1252 let item = iter.next().unwrap();
1253 assert_eq!((**item).value, 10);
1254 let item = iter.next().unwrap();
1255 assert_eq!((**item).value, 20);
1256 assert!(iter.next().is_none());
1257 } assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
1261
1262 unsafe {
1263 assert_eq!((*node1).value, 10);
1265 assert_eq!((*node2).value, 20);
1266
1267 drop(Box::from_raw(node1));
1269 drop(Box::from_raw(node2));
1270 }
1271 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
1272 }
1273
1274 #[test]
1275 fn test_non_null_list() {
1276 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
1278
1279 let node1 = Box::leak(Box::new(new_node(100)));
1282 let node2 = Box::leak(Box::new(new_node(200)));
1283
1284 let ptr1 = NonNull::from(node1);
1285 let ptr2 = NonNull::from(node2);
1286
1287 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
1288
1289 unsafe {
1290 let mut l = DLinkedList::<NonNull<TestNode>, TestTag>::new();
1291 l.push_back(ptr1);
1292 l.push_back(ptr2);
1293
1294 let mut iter = l.iter();
1295 assert_eq!(iter.next().unwrap().as_ref().value, 100);
1296 assert_eq!(iter.next().unwrap().as_ref().value, 200);
1297 assert!(iter.next().is_none());
1298 } assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
1302
1303 unsafe {
1304 drop(Box::from_raw(ptr1.as_ptr()));
1306 drop(Box::from_raw(ptr2.as_ptr()));
1307 }
1308
1309 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
1310 }
1311
1312 #[test]
1313 fn test_clear() {
1314 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
1315 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
1316
1317 l.push_back(Box::new(new_node(1)));
1318 l.push_back(Box::new(new_node(2)));
1319 assert_eq!(l.len(), 2);
1320 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 2);
1321
1322 l.clear();
1323
1324 assert!(l.is_empty());
1325 assert_eq!(l.len(), 0);
1326 assert!(l.get_front().is_none());
1327 assert!(l.get_back().is_none());
1328 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
1329
1330 l.push_back(Box::new(new_node(3)));
1332 assert_eq!(l.len(), 1);
1333 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 1);
1334 }
1335
1336 #[test]
1337 fn test_remove_middle() {
1338 ACTIVE_NODE_COUNT.store(0, Ordering::SeqCst);
1340 {
1341 let mut l = DLinkedList::<Box<TestNode>, TestTag>::new();
1342
1343 let node1 = Box::new(new_node(1));
1344 l.push_back(node1);
1345
1346 let node2 = Box::new(new_node(2));
1347
1348 let node2_p = Box::into_raw(node2);
1351 l.push_back(unsafe { Box::from_raw(node2_p) });
1352
1353 let node3 = Box::new(new_node(3));
1354 l.push_back(node3);
1355
1356 assert_eq!(l.len(), 3);
1357 assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 3);
1358
1359 let node2 = unsafe { l.remove_node(node2_p).unwrap() };
1360 assert_eq!(l.len(), 2);
1361 assert_eq!(node2.value, 2);
1362
1363 let node4 = Box::new(new_node(4));
1364
1365 let node4_p = Box::into_raw(node4);
1366 assert!(unsafe { l.remove_node(node4_p) }.is_none());
1367 unsafe {
1368 let _ = Box::from_raw(node4_p);
1369 }
1370 } assert_eq!(ACTIVE_NODE_COUNT.load(Ordering::SeqCst), 0);
1374 }
1375
1376 #[test]
1377 fn test_peak_arc() {
1378 let mut l = DLinkedList::<Arc<TestNode>, TestTag>::new();
1379
1380 let node1 = Arc::new(new_node(1));
1381 l.push_back(node1);
1382
1383 let node2 = Arc::new(new_node(2));
1384 l.push_back(node2);
1385
1386 let node3 = Arc::new(new_node(3));
1387 l.push_back(node3.clone());
1388
1389 let mut iter = l.iter();
1390 assert_eq!(iter.next().unwrap().value, 1);
1391 assert_eq!(iter.next().unwrap().value, 2);
1392 assert_eq!(iter.next().unwrap().value, 3);
1393 assert!(iter.next().is_none());
1394
1395 let node3_p = Arc::as_ptr(&node3);
1396
1397 unsafe { l.peak(node3_p) };
1398
1399 let mut iter = l.iter();
1401 assert_eq!(iter.next().unwrap().value, 3);
1402 assert_eq!(iter.next().unwrap().value, 1);
1403 assert_eq!(iter.next().unwrap().value, 2);
1404 assert!(iter.next().is_none());
1405
1406 {
1407 let mut drain = l.drain();
1408 assert_eq!(drain.next().unwrap().value, 3);
1409 assert_eq!(drain.next().unwrap().value, 1);
1410 assert_eq!(drain.next().unwrap().value, 2);
1411 assert!(drain.next().is_none());
1412 }
1413 assert_eq!(l.len(), 0);
1414 }
1415}