1use crate::ptr_traits::{ManagedPtr, MutPtr, PtrTraits};
6use crate::sentinel::{is_sentinel_ptr, make_sentinel};
7use crate::size_tracker::{NonTrackingSize, SizeTracker, TrackingSize};
8use crate::tag::DefaultObjectTag;
9use core::cell::UnsafeCell;
10use core::pin::Pin;
11use pin_init::{PinInit, pin_data, pin_init, pinned_drop};
12
13#[repr(C)]
19pub struct DoublyLinkedListNode<T> {
20 pub next: UnsafeCell<*mut T>,
22 pub prev: UnsafeCell<*mut T>,
24 _pin: core::marker::PhantomData<core::marker::PhantomPinned>,
29}
30
31impl<T> DoublyLinkedListNode<T> {
32 #[inline]
34 pub const fn new() -> Self {
35 Self {
36 next: UnsafeCell::new(core::ptr::null_mut()),
37 prev: UnsafeCell::new(core::ptr::null_mut()),
38 _pin: core::marker::PhantomData,
39 }
40 }
41
42 #[inline]
44 pub fn in_container(&self) -> bool {
45 !unsafe { *self.next.get() }.is_null()
48 }
49
50 #[inline]
51 fn get_next(&self) -> *mut T {
52 unsafe { *self.next.get() }
54 }
55
56 #[inline]
57 fn set_next(&self, next: *mut T) {
58 unsafe {
61 *self.next.get() = next;
62 }
63 }
64
65 #[inline]
66 fn get_prev(&self) -> *mut T {
67 unsafe { *self.prev.get() }
69 }
70
71 #[inline]
72 fn set_prev(&self, prev: *mut T) {
73 unsafe {
76 *self.prev.get() = prev;
77 }
78 }
79}
80
81impl<T> core::fmt::Debug for DoublyLinkedListNode<T> {
82 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
83 f.debug_struct("DoublyLinkedListNode").field("in_container", &self.in_container()).finish()
84 }
85}
86
87impl<T> Default for DoublyLinkedListNode<T> {
88 #[inline]
89 fn default() -> Self {
90 Self::new()
91 }
92}
93
94impl<T> Drop for DoublyLinkedListNode<T> {
95 #[inline]
96 fn drop(&mut self) {
97 debug_assert!(!self.in_container(), "Object destroyed while still in container");
98 }
99}
100
101pub trait DoublyLinkedListContainable<T, Tag = DefaultObjectTag> {
103 fn get_node(&self) -> &DoublyLinkedListNode<T>;
105}
106
107#[repr(C)]
257#[pin_data(PinnedDrop)]
258pub struct DoublyLinkedList<P, Tag = DefaultObjectTag, S = NonTrackingSize>
259where
260 P: PtrTraits,
261 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
262 S: SizeTracker,
263{
264 head: *mut P::Target,
285
286 size: S,
289
290 #[pin]
294 _pin: core::marker::PhantomPinned,
295
296 _phantom: core::marker::PhantomData<(P, Tag)>,
297}
298
299impl<P, Tag, S> DoublyLinkedList<P, Tag, S>
300where
301 P: PtrTraits,
302 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
303 S: SizeTracker,
304{
305 #[inline]
307 pub fn new() -> impl PinInit<Self, core::convert::Infallible> {
308 pin_init!(&this in Self {
309 head: make_sentinel(this.as_ptr()),
310 size: S::INIT,
311 _pin: core::marker::PhantomPinned,
312 _phantom: core::marker::PhantomData,
313 })
314 }
315
316 #[inline]
317 fn get_sentinel(&self) -> *mut P::Target {
318 make_sentinel(self as *const Self as *mut Self)
319 }
320
321 #[inline]
322 fn get_tail(&self) -> *mut P::Target {
323 if self.is_empty() {
324 self.get_sentinel()
325 } else {
326 unsafe { *(*self.head).get_node().prev.get() }
330 }
331 }
332
333 #[inline]
337 unsafe fn set_tail(&self, tail: *mut P::Target) {
338 debug_assert!(!self.is_empty());
339 unsafe {
343 *(*self.head).get_node().prev.get() = tail;
344 }
345 }
346
347 #[inline]
352 unsafe fn get_node_ref<'a>(&self, ptr: *mut P::Target) -> &'a DoublyLinkedListNode<P::Target> {
353 let _ = self;
354 unsafe { &(*ptr) }.get_node()
356 }
357
358 #[inline]
360 pub fn is_empty(&self) -> bool {
361 is_sentinel_ptr(self.head)
362 }
363
364 #[inline]
366 pub fn front(&self) -> Option<&P::Target> {
367 if self.is_empty() { None } else { unsafe { Some(&*self.head) } }
368 }
369
370 #[inline]
373 pub fn front_mut(self: Pin<&mut Self>) -> Option<Pin<&mut P::Target>>
374 where
375 P: MutPtr,
376 {
377 if self.is_empty() {
378 None
379 } else {
380 Some(unsafe { Pin::new_unchecked(&mut *self.head) })
384 }
385 }
386
387 #[inline]
389 pub fn back(&self) -> Option<&P::Target> {
390 let tail = self.get_tail();
391 if is_sentinel_ptr(tail) { None } else { unsafe { Some(&*tail) } }
392 }
393
394 #[inline]
397 pub fn back_mut(self: Pin<&mut Self>) -> Option<Pin<&mut P::Target>>
398 where
399 P: MutPtr,
400 {
401 let tail = self.get_tail();
402 if is_sentinel_ptr(tail) {
403 None
404 } else {
405 Some(unsafe { Pin::new_unchecked(&mut *tail) })
409 }
410 }
411
412 #[inline]
415 fn cursor_at_ptr(self: Pin<&mut Self>, current: *mut P::Target) -> CursorMut<'_, P, Tag, S> {
416 CursorMut { list: self, current }
417 }
418
419 #[inline]
425 pub fn push_front(self: Pin<&mut Self>, ptr: P)
426 where
427 P: ManagedPtr,
428 {
429 unsafe { self.push_front_raw(ptr) }
432 }
433
434 #[inline]
450 pub unsafe fn push_front_raw(self: Pin<&mut Self>, ptr: P) {
451 let mut cursor = self.cursor_front_mut();
452 unsafe {
454 cursor.insert_before_raw(ptr);
455 }
456 }
457
458 #[inline]
464 pub fn push_back(self: Pin<&mut Self>, ptr: P)
465 where
466 P: ManagedPtr,
467 {
468 unsafe { self.push_back_raw(ptr) }
471 }
472
473 #[inline]
488 pub unsafe fn push_back_raw(self: Pin<&mut Self>, ptr: P) {
489 let mut cursor = self.cursor_back_mut();
490 unsafe {
492 cursor.insert_before_raw(ptr);
493 }
494 }
495
496 #[inline]
498 pub fn pop_front(self: Pin<&mut Self>) -> Option<P> {
499 self.cursor_front_mut().erase()
500 }
501
502 #[inline]
504 pub fn pop_back(self: Pin<&mut Self>) -> Option<P> {
505 let tail = self.get_tail();
506 self.cursor_at_ptr(tail).erase()
507 }
508
509 pub fn clear(mut self: Pin<&mut Self>) {
511 while self.as_mut().pop_front().is_some() {}
512 }
513
514 #[inline]
521 pub unsafe fn erase(self: Pin<&mut Self>, obj: &P::Target) -> Option<P> {
522 let ptr = obj as *const P::Target as *mut P::Target;
523 let node = obj.get_node();
524
525 if !node.in_container() {
526 return None;
527 }
528
529 self.cursor_at_ptr(ptr).erase()
530 }
531
532 #[inline]
544 pub unsafe fn replace_raw(self: Pin<&mut Self>, obj: &P::Target, replacement: P) -> Option<P> {
545 let ptr = obj as *const P::Target as *mut P::Target;
546 let node = obj.get_node();
547
548 if !node.in_container() {
549 return None;
550 }
551
552 let mut cursor = self.cursor_at_ptr(ptr);
553 unsafe { cursor.replace_raw(replacement) }
555 }
556
557 #[inline]
560 pub fn erase_if<F>(self: Pin<&mut Self>, mut f: F) -> Option<P>
561 where
562 F: FnMut(&P::Target) -> bool,
563 {
564 let mut cursor = self.cursor_front_mut();
565 while let Some(item) = cursor.get() {
566 if f(item) {
567 return cursor.erase();
568 } else {
569 cursor.move_next();
570 }
571 }
572 None
573 }
574
575 #[inline]
577 pub fn find_if<F>(&self, mut f: F) -> Option<&P::Target>
578 where
579 F: FnMut(&P::Target) -> bool,
580 {
581 self.iter().find(|&x| f(x))
582 }
583
584 #[inline]
586 pub fn cursor_front_mut(self: Pin<&mut Self>) -> CursorMut<'_, P, Tag, S> {
587 let head = self.head;
588 self.cursor_at_ptr(head)
589 }
590
591 #[inline]
593 pub fn cursor_back_mut(self: Pin<&mut Self>) -> CursorMut<'_, P, Tag, S> {
594 let sentinel = self.get_sentinel();
595 self.cursor_at_ptr(sentinel)
596 }
597
598 #[inline]
606 pub unsafe fn cursor_at(self: Pin<&mut Self>, obj: &P::Target) -> CursorMut<'_, P, Tag, S> {
607 debug_assert!(obj.get_node().in_container(), "Object must be in a container");
608 self.cursor_at_ptr(obj as *const P::Target as *mut P::Target)
609 }
610
611 #[inline]
617 pub fn splice(self: Pin<&mut Self>, other: Pin<&mut DoublyLinkedList<P, Tag, S>>) {
618 self.cursor_back_mut().splice(other);
619 }
620
621 #[inline]
622 pub fn iter(&self) -> Iterator<'_, P, Tag> {
623 Iterator::new(self)
624 }
625
626 #[inline]
630 pub fn iter_mut(self: Pin<&mut Self>) -> IteratorMut<'_, P, Tag>
631 where
632 P: MutPtr,
633 {
634 IteratorMut::new(self)
635 }
636
637 #[inline]
639 pub fn forward_iter(&self) -> ForwardIterator<'_, P, Tag> {
640 ForwardIterator::new(self.head)
641 }
642
643 #[inline]
647 pub fn forward_iter_mut(self: Pin<&mut Self>) -> ForwardIteratorMut<'_, P, Tag>
648 where
649 P: MutPtr,
650 {
651 ForwardIteratorMut::new(self.head)
652 }
653
654 #[inline]
656 pub fn reverse_iter(&self) -> ReverseIterator<'_, P, Tag> {
657 ReverseIterator::new(self.get_tail())
658 }
659
660 #[inline]
664 pub fn reverse_iter_mut(self: Pin<&mut Self>) -> ReverseIteratorMut<'_, P, Tag>
665 where
666 P: MutPtr,
667 {
668 ReverseIteratorMut::new(self.get_tail(), self.head)
669 }
670}
671
672impl<P, Tag> DoublyLinkedList<P, Tag, TrackingSize>
673where
674 P: PtrTraits,
675 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
676{
677 #[inline]
679 pub fn len(&self) -> usize {
680 self.size.get()
681 }
682}
683
684#[pinned_drop]
685impl<P, Tag, S> PinnedDrop for DoublyLinkedList<P, Tag, S>
686where
687 P: PtrTraits,
688 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
689 S: SizeTracker,
690{
691 fn drop(self: Pin<&mut Self>) {
692 if P::IS_MANAGED {
693 self.clear();
694 } else {
695 debug_assert!(self.is_empty(), "List must be empty on destruction");
696 if S::IS_TRACKING {
697 debug_assert_eq!(self.size.get(), 0, "Size must be zero on destruction");
698 }
699 }
700 }
701}
702
703pub struct CursorMut<'a, P, Tag = DefaultObjectTag, S = NonTrackingSize>
709where
710 P: PtrTraits,
711 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
712 S: SizeTracker,
713{
714 list: Pin<&'a mut DoublyLinkedList<P, Tag, S>>,
715 current: *mut P::Target,
716}
717
718impl<'a, P, Tag, S> CursorMut<'a, P, Tag, S>
719where
720 P: PtrTraits,
721 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
722 S: SizeTracker,
723{
724 #[inline]
725 pub fn get(&self) -> Option<&P::Target> {
726 if is_sentinel_ptr(self.current) { None } else { unsafe { Some(&*self.current) } }
727 }
728
729 #[inline]
732 pub fn get_mut(&mut self) -> Option<Pin<&mut P::Target>>
733 where
734 P: MutPtr,
735 {
736 if is_sentinel_ptr(self.current) {
737 None
738 } else {
739 Some(unsafe { Pin::new_unchecked(&mut *self.current) })
743 }
744 }
745
746 #[inline]
747 pub fn move_next(&mut self) {
748 if !is_sentinel_ptr(self.current) {
749 let node = unsafe { self.list.get_node_ref(self.current) };
751 self.current = node.get_next();
752 }
753 }
754
755 #[inline]
756 pub fn move_prev(&mut self) {
757 if !is_sentinel_ptr(self.current) {
758 let node = unsafe { self.list.get_node_ref(self.current) };
760 let prev = node.get_prev();
761 if self.current == self.list.head {
762 self.current = self.list.get_sentinel(); } else {
764 self.current = prev;
765 }
766 } else {
767 self.current = self.list.get_tail();
769 }
770 }
771
772 #[inline]
779 pub fn insert_after(&mut self, ptr: P)
780 where
781 P: ManagedPtr,
782 {
783 debug_assert!(!ptr.get_ref().get_node().in_container());
784 unsafe { self.insert_after_raw(ptr) }
788 }
789
790 #[inline]
807 pub unsafe fn insert_after_raw(&mut self, ptr: P) {
808 debug_assert!(!is_sentinel_ptr(self.current), "Cannot insert after end sentinel");
809 let raw = P::into_raw(ptr);
810 let node = unsafe { self.list.get_node_ref(raw) };
812 debug_assert!(!node.in_container());
813
814 let current_node = unsafe { self.list.get_node_ref(self.current) };
816 let next = current_node.get_next();
817
818 let current_save = self.current;
819 self.current = next;
820 unsafe {
823 self.insert_chain_before(raw, raw, 1);
824 }
825 self.current = current_save;
826 }
827
828 #[inline]
835 pub fn replace(&mut self, replacement: P) -> Option<P>
836 where
837 P: ManagedPtr,
838 {
839 unsafe { self.replace_raw(replacement) }
842 }
843
844 #[inline]
861 pub unsafe fn replace_raw(&mut self, replacement: P) -> Option<P> {
862 if is_sentinel_ptr(self.current) {
863 return None;
864 }
865 unsafe {
868 self.insert_before_raw(replacement);
869 }
870 self.erase()
871 }
872
873 #[inline]
879 pub fn insert_before(&mut self, ptr: P)
880 where
881 P: ManagedPtr,
882 {
883 debug_assert!(!ptr.get_ref().get_node().in_container());
884 unsafe { self.insert_before_raw(ptr) }
887 }
888
889 #[inline]
905 pub unsafe fn insert_before_raw(&mut self, ptr: P) {
906 let raw = P::into_raw(ptr);
907 let node = unsafe { self.list.get_node_ref(raw) };
909 debug_assert!(!node.in_container());
910
911 unsafe {
913 self.insert_chain_before(raw, raw, 1);
914 }
915 }
916
917 #[inline]
928 unsafe fn insert_chain_before(
929 &mut self,
930 chain_head: *mut P::Target,
931 chain_tail: *mut P::Target,
932 count: usize,
933 ) {
934 let head = self.list.head;
935 let before = self.current;
936 let chain_tail_node = unsafe { self.list.get_node_ref(chain_tail) };
938 let chain_head_node = unsafe { self.list.get_node_ref(chain_head) };
940
941 if is_sentinel_ptr(head) {
942 chain_tail_node.set_next(before);
943 chain_head_node.set_prev(chain_tail);
944 *self.list.as_mut().project().head = chain_head;
945 } else if before == head {
946 let head_node = unsafe { self.list.get_node_ref(head) };
948 let tail = head_node.get_prev();
949 chain_tail_node.set_next(before);
950 chain_head_node.set_prev(tail);
951 head_node.set_prev(chain_tail);
952 *self.list.as_mut().project().head = chain_head;
953 } else if is_sentinel_ptr(before) {
954 let head_node = unsafe { self.list.get_node_ref(head) };
956 let tail = head_node.get_prev();
957 let tail_node = unsafe { self.list.get_node_ref(tail) };
959 chain_tail_node.set_next(before);
960 chain_head_node.set_prev(tail);
961 tail_node.set_next(chain_head);
962 head_node.set_prev(chain_tail);
963 } else {
964 let current_node = unsafe { self.list.get_node_ref(before) };
966 let prev = current_node.get_prev();
967 let prev_node = unsafe { self.list.get_node_ref(prev) };
969 chain_tail_node.set_next(before);
970 chain_head_node.set_prev(prev);
971 prev_node.set_next(chain_head);
972 current_node.set_prev(chain_tail);
973 }
974
975 if S::IS_TRACKING {
976 let new_size = self.list.size.get() + count;
977 self.list.as_mut().project().size.set(new_size);
978 }
979 }
980
981 pub fn splice(&mut self, other: Pin<&mut DoublyLinkedList<P, Tag, S>>) {
995 if other.is_empty() {
996 return;
997 }
998
999 let other_head = other.head;
1000 let other_tail = other.get_tail();
1001 let other_sentinel = other.get_sentinel();
1002 let count = if S::IS_TRACKING { other.size.get() } else { 0 };
1003
1004 unsafe {
1007 self.insert_chain_before(other_head, other_tail, count);
1008 }
1009
1010 let other = other.project();
1011 *other.head = other_sentinel;
1012 if S::IS_TRACKING {
1013 other.size.set(0);
1014 }
1015 }
1016
1017 pub fn split_after(&mut self, dest: &mut CursorMut<'_, P, Tag, S>) {
1030 debug_assert!(!is_sentinel_ptr(self.current), "Cannot split after end sentinel");
1031
1032 let curr_node = unsafe { self.list.get_node_ref(self.current) };
1034 let next_ptr = curr_node.get_next();
1035
1036 if is_sentinel_ptr(next_ptr) {
1038 return;
1039 }
1040
1041 let chain_head = next_ptr;
1042 let chain_tail = self.list.get_tail();
1043
1044 let mut count = 0;
1045 if S::IS_TRACKING {
1046 let mut p = chain_head;
1047 let sentinel = self.list.get_sentinel();
1048 while p != sentinel {
1049 count += 1;
1050 p = unsafe { self.list.get_node_ref(p) }.get_next();
1052 }
1053 let new_size = self.list.size.get() - count;
1054 self.list.as_mut().project().size.set(new_size);
1055 }
1056
1057 curr_node.set_next(self.list.get_sentinel());
1059 unsafe {
1060 self.list.set_tail(self.current);
1061 }
1062
1063 unsafe {
1067 dest.insert_chain_before(chain_head, chain_tail, count);
1068 }
1069 }
1070
1071 pub fn split_before(&mut self, dest: &mut CursorMut<'_, P, Tag, S>) {
1087 if self.current == self.list.head {
1089 return;
1090 }
1091
1092 if is_sentinel_ptr(self.current) {
1094 if self.list.is_empty() {
1095 return;
1096 }
1097 let chain_head = self.list.head;
1098 let chain_tail = self.list.get_tail();
1099 let sentinel = self.list.get_sentinel();
1100 let list = self.list.as_mut().project();
1101 let count = if S::IS_TRACKING {
1102 let c = list.size.get();
1103 list.size.set(0);
1104 c
1105 } else {
1106 0
1107 };
1108
1109 *list.head = sentinel;
1110
1111 unsafe {
1114 dest.insert_chain_before(chain_head, chain_tail, count);
1115 }
1116 return;
1117 }
1118
1119 let b = self.current;
1122 let b_node = unsafe { self.list.get_node_ref(b) };
1123 let chain_head = self.list.head;
1124 let chain_tail = b_node.get_prev();
1125 let old_tail = self.list.get_tail();
1126
1127 let mut count = 0;
1128 if S::IS_TRACKING {
1129 let mut p = chain_head;
1130 while p != b {
1131 count += 1;
1132 p = unsafe { self.list.get_node_ref(p) }.get_next();
1134 }
1135 let new_size = self.list.size.get() - count;
1136 self.list.as_mut().project().size.set(new_size);
1137 }
1138
1139 *self.list.as_mut().project().head = b;
1141 b_node.set_prev(old_tail);
1142
1143 unsafe {
1147 dest.insert_chain_before(chain_head, chain_tail, count);
1148 }
1149 }
1150
1151 #[inline]
1152 pub fn erase(&mut self) -> Option<P> {
1153 let ptr = self.current;
1154 if is_sentinel_ptr(ptr) {
1155 return None;
1156 }
1157 let head = self.list.head;
1158 let node = unsafe { self.list.get_node_ref(ptr) };
1160 let next = node.get_next();
1161 let prev = node.get_prev();
1162
1163 self.list.as_mut().project().size.decrement();
1164
1165 let tgt_prev_node = if is_sentinel_ptr(next) { head } else { next };
1166 unsafe { self.list.get_node_ref(tgt_prev_node) }.set_prev(prev);
1168
1169 if ptr == head {
1170 *self.list.as_mut().project().head = next;
1171 } else {
1172 unsafe { self.list.get_node_ref(prev) }.set_next(next);
1174 }
1175
1176 node.set_prev(core::ptr::null_mut());
1177 node.set_next(core::ptr::null_mut());
1178
1179 self.current = next;
1180 Some(unsafe { P::from_raw(ptr) })
1182 }
1183}
1184
1185pub struct Iterator<'a, P, Tag = DefaultObjectTag>
1187where
1188 P: PtrTraits,
1189 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1190{
1191 front: ForwardIterator<'a, P, Tag>,
1192 back: ReverseIterator<'a, P, Tag>,
1193}
1194
1195impl<'a, P, Tag> Iterator<'a, P, Tag>
1196where
1197 P: PtrTraits,
1198 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1199{
1200 fn new<S: SizeTracker>(list: &'a DoublyLinkedList<P, Tag, S>) -> Self {
1201 if list.is_empty() {
1202 Self {
1203 front: ForwardIterator::new(crate::make_sentinel_null()),
1204 back: ReverseIterator::new(crate::make_sentinel_null()),
1205 }
1206 } else {
1207 Self {
1208 front: ForwardIterator::new(list.head),
1209 back: ReverseIterator::new(list.get_tail()),
1210 }
1211 }
1212 }
1213}
1214
1215impl<'a, P, Tag> core::iter::Iterator for Iterator<'a, P, Tag>
1216where
1217 P: PtrTraits,
1218 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1219{
1220 type Item = &'a P::Target;
1221
1222 fn next(&mut self) -> Option<Self::Item> {
1223 let met = self.front.current == self.back.current;
1224 let item = self.front.next();
1225 if item.is_some() && met {
1226 self.front.current = crate::make_sentinel_null();
1227 self.back.current = crate::make_sentinel_null();
1228 }
1229 item
1230 }
1231}
1232
1233impl<'a, P, Tag> core::iter::DoubleEndedIterator for Iterator<'a, P, Tag>
1234where
1235 P: PtrTraits,
1236 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1237{
1238 fn next_back(&mut self) -> Option<Self::Item> {
1239 let met = self.front.current == self.back.current;
1240 let item = self.back.next();
1241 if item.is_some() && met {
1242 self.front.current = crate::make_sentinel_null();
1243 self.back.current = crate::make_sentinel_null();
1244 }
1245 item
1246 }
1247}
1248
1249pub struct ForwardIterator<'a, P, Tag = DefaultObjectTag>
1251where
1252 P: PtrTraits,
1253 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1254{
1255 current: *mut P::Target,
1256 _phantom: core::marker::PhantomData<&'a (P, Tag)>,
1257}
1258
1259impl<'a, P, Tag> ForwardIterator<'a, P, Tag>
1260where
1261 P: PtrTraits,
1262 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1263{
1264 fn new(current: *mut P::Target) -> Self {
1265 Self { current, _phantom: core::marker::PhantomData }
1266 }
1267}
1268
1269impl<'a, P, Tag> core::iter::Iterator for ForwardIterator<'a, P, Tag>
1270where
1271 P: PtrTraits,
1272 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1273{
1274 type Item = &'a P::Target;
1275
1276 fn next(&mut self) -> Option<Self::Item> {
1277 if is_sentinel_ptr(self.current) {
1278 None
1279 } else {
1280 let current = unsafe { &*self.current };
1284 self.current = current.get_node().get_next();
1285 Some(current)
1286 }
1287 }
1288}
1289
1290pub struct ReverseIterator<'a, P, Tag = DefaultObjectTag>
1292where
1293 P: PtrTraits,
1294 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1295{
1296 current: *mut P::Target,
1297 _phantom: core::marker::PhantomData<&'a (P, Tag)>,
1298}
1299
1300impl<'a, P, Tag> ReverseIterator<'a, P, Tag>
1301where
1302 P: PtrTraits,
1303 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1304{
1305 fn new(current: *mut P::Target) -> Self {
1306 Self { current, _phantom: core::marker::PhantomData }
1307 }
1308}
1309
1310impl<'a, P, Tag> core::iter::Iterator for ReverseIterator<'a, P, Tag>
1311where
1312 P: PtrTraits,
1313 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1314{
1315 type Item = &'a P::Target;
1316
1317 fn next(&mut self) -> Option<Self::Item> {
1318 if is_sentinel_ptr(self.current) {
1319 None
1320 } else {
1321 let current = unsafe { &*self.current };
1325 let prev = current.get_node().get_prev();
1326
1327 let prev_node = unsafe { &*prev }.get_node();
1330 if is_sentinel_ptr(prev_node.get_next()) {
1331 self.current = prev_node.get_next();
1334 } else {
1335 self.current = prev;
1336 }
1337 Some(current)
1338 }
1339 }
1340}
1341
1342pub struct IteratorMut<'a, P, Tag = DefaultObjectTag>
1346where
1347 P: MutPtr,
1348 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1349{
1350 front: ForwardIteratorMut<'a, P, Tag>,
1351 back: ReverseIteratorMut<'a, P, Tag>,
1352}
1353
1354impl<'a, P, Tag> IteratorMut<'a, P, Tag>
1355where
1356 P: MutPtr,
1357 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1358{
1359 fn new<S: SizeTracker>(list: Pin<&'a mut DoublyLinkedList<P, Tag, S>>) -> Self {
1360 if list.is_empty() {
1361 Self {
1362 front: ForwardIteratorMut::new(crate::make_sentinel_null()),
1363 back: ReverseIteratorMut::new(
1364 crate::make_sentinel_null(),
1365 crate::make_sentinel_null(),
1366 ),
1367 }
1368 } else {
1369 let tail = list.get_tail();
1370 Self {
1371 front: ForwardIteratorMut::new(list.head),
1372 back: ReverseIteratorMut::new(tail, list.head),
1373 }
1374 }
1375 }
1376}
1377
1378impl<'a, P, Tag> core::iter::Iterator for IteratorMut<'a, P, Tag>
1379where
1380 P: MutPtr,
1381 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1382{
1383 type Item = Pin<&'a mut P::Target>;
1384
1385 fn next(&mut self) -> Option<Self::Item> {
1386 let met = self.front.current == self.back.current;
1387 let item = self.front.next();
1388 if item.is_some() && met {
1389 self.front.current = crate::make_sentinel_null();
1390 self.back.current = crate::make_sentinel_null();
1391 }
1392 item
1393 }
1394}
1395
1396impl<'a, P, Tag> core::iter::DoubleEndedIterator for IteratorMut<'a, P, Tag>
1397where
1398 P: MutPtr,
1399 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1400{
1401 fn next_back(&mut self) -> Option<Self::Item> {
1402 let met = self.front.current == self.back.current;
1403 let item = self.back.next();
1404 if item.is_some() && met {
1405 self.front.current = crate::make_sentinel_null();
1406 self.back.current = crate::make_sentinel_null();
1407 }
1408 item
1409 }
1410}
1411
1412pub struct ForwardIteratorMut<'a, P, Tag = DefaultObjectTag>
1416where
1417 P: MutPtr,
1418 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1419{
1420 current: *mut P::Target,
1421 _phantom: core::marker::PhantomData<&'a mut (P, Tag)>,
1422}
1423
1424impl<'a, P, Tag> ForwardIteratorMut<'a, P, Tag>
1425where
1426 P: MutPtr,
1427 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1428{
1429 fn new(current: *mut P::Target) -> Self {
1430 Self { current, _phantom: core::marker::PhantomData }
1431 }
1432}
1433
1434impl<'a, P, Tag> core::iter::Iterator for ForwardIteratorMut<'a, P, Tag>
1435where
1436 P: MutPtr,
1437 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1438{
1439 type Item = Pin<&'a mut P::Target>;
1440
1441 fn next(&mut self) -> Option<Self::Item> {
1442 if is_sentinel_ptr(self.current) {
1443 None
1444 } else {
1445 let current_ptr = self.current;
1446 self.current = unsafe { &*current_ptr }.get_node().get_next();
1449 Some(unsafe { Pin::new_unchecked(&mut *current_ptr) })
1455 }
1456 }
1457}
1458
1459pub struct ReverseIteratorMut<'a, P, Tag = DefaultObjectTag>
1463where
1464 P: MutPtr,
1465 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1466{
1467 current: *mut P::Target,
1468 head: *mut P::Target,
1469 _phantom: core::marker::PhantomData<&'a mut (P, Tag)>,
1470}
1471
1472impl<'a, P, Tag> ReverseIteratorMut<'a, P, Tag>
1473where
1474 P: MutPtr,
1475 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1476{
1477 fn new(current: *mut P::Target, head: *mut P::Target) -> Self {
1478 Self { current, head, _phantom: core::marker::PhantomData }
1479 }
1480}
1481
1482impl<'a, P, Tag> core::iter::Iterator for ReverseIteratorMut<'a, P, Tag>
1483where
1484 P: MutPtr,
1485 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1486{
1487 type Item = Pin<&'a mut P::Target>;
1488
1489 fn next(&mut self) -> Option<Self::Item> {
1490 if is_sentinel_ptr(self.current) {
1491 None
1492 } else {
1493 let current_ptr = self.current;
1494 if current_ptr == self.head {
1495 self.current = crate::make_sentinel_null();
1496 } else {
1497 self.current = unsafe { &*current_ptr }.get_node().get_prev();
1500 }
1501 Some(unsafe { Pin::new_unchecked(&mut *current_ptr) })
1507 }
1508 }
1509}
1510
1511#[inline]
1519pub unsafe fn remove_from_container<T, Tag, P>(obj: &T) -> Option<P>
1520where
1521 P: PtrTraits<Target = T>,
1522 T: DoublyLinkedListContainable<T, Tag>,
1523{
1524 let node = obj.get_node();
1525 let next = node.get_next();
1526 if next.is_null() {
1527 return None;
1528 }
1529 let prev = node.get_prev();
1530 debug_assert!(!prev.is_null());
1531
1532 unsafe {
1535 let tgt_prev = if is_sentinel_ptr(next) {
1536 let list_ptr = crate::sentinel::unmake_sentinel::<
1537 DoublyLinkedList<P, Tag, NonTrackingSize>,
1538 T,
1539 >(next);
1540 (*(*list_ptr).head).get_node().prev.get()
1541 } else {
1542 (*next).get_node().prev.get()
1543 };
1544
1545 let prev_node = (*prev).get_node();
1546 let prev_next = prev_node.get_next();
1547 let tgt_next = if is_sentinel_ptr(prev_next) {
1548 let list_ptr = crate::sentinel::unmake_sentinel::<
1549 DoublyLinkedList<P, Tag, NonTrackingSize>,
1550 T,
1551 >(prev_next);
1552 &raw mut (*list_ptr).head
1553 } else {
1554 prev_node.next.get()
1555 };
1556
1557 *tgt_prev = prev;
1558 *tgt_next = next;
1559
1560 node.set_next(core::ptr::null_mut());
1561 node.set_prev(core::ptr::null_mut());
1562
1563 Some(P::from_raw(obj as *const T as *mut T))
1564 }
1565}
1566
1567impl<P, Tag, S> core::fmt::Debug for DoublyLinkedList<P, Tag, S>
1568where
1569 P: PtrTraits,
1570 P::Target: DoublyLinkedListContainable<P::Target, Tag> + core::fmt::Debug,
1571 S: SizeTracker,
1572{
1573 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1574 f.debug_list().entries(self.iter()).finish()
1575 }
1576}
1577
1578#[cfg(test)]
1579mod tests {
1580 extern crate alloc;
1581 use super::*;
1582 use crate::intrusive_container_test_support::*;
1583 use crate::ref_ptr::RefPtr;
1584 use crate::unique_ptr::UniquePtr;
1585 use core::ffi::c_void;
1586 use pin_init::stack_pin_init;
1587
1588 #[derive(crate::DoublyLinkedListContainable, crate::Recyclable)]
1589 #[pin_data]
1590 struct TestObject {
1591 value: i32,
1592 #[pin]
1593 #[dll_node]
1594 node: DoublyLinkedListNode<TestObject>,
1595 }
1596
1597 impl TestObject {
1598 fn new(value: i32) -> Self {
1599 Self { value, node: DoublyLinkedListNode::new() }
1600 }
1601 }
1602
1603 impl TestValue for TestObject {
1604 fn new(value: i32) -> Self {
1605 Self::new(value)
1606 }
1607 }
1608
1609 ::zr::static_assert!(
1610 core::mem::size_of::<DoublyLinkedListNode<TestObject>>()
1611 == 2 * core::mem::size_of::<*mut TestObject>()
1612 );
1613 ::zr::static_assert!(
1614 core::mem::align_of::<DoublyLinkedListNode<TestObject>>()
1615 == core::mem::align_of::<*mut TestObject>()
1616 );
1617
1618 ::zr::static_assert!(
1619 core::mem::size_of::<DoublyLinkedList<*mut TestObject>>()
1620 == core::mem::size_of::<*mut TestObject>()
1621 );
1622 ::zr::static_assert!(
1623 core::mem::align_of::<DoublyLinkedList<*mut TestObject>>()
1624 == core::mem::align_of::<*mut TestObject>()
1625 );
1626
1627 ::zr::static_assert!(
1628 core::mem::size_of::<DoublyLinkedList<*mut TestObject, DefaultObjectTag, TrackingSize>>()
1629 == 2 * core::mem::size_of::<*mut TestObject>()
1630 );
1631 ::zr::static_assert!(
1632 core::mem::align_of::<DoublyLinkedList<*mut TestObject, DefaultObjectTag, TrackingSize>>()
1633 == core::mem::align_of::<*mut TestObject>()
1634 );
1635
1636 ::zr::static_assert!(
1637 core::mem::size_of::<ForwardIterator<'_, *mut TestObject>>()
1638 == core::mem::size_of::<*mut TestObject>()
1639 );
1640 ::zr::static_assert!(
1641 core::mem::align_of::<ForwardIterator<'_, *mut TestObject>>()
1642 == core::mem::align_of::<*mut TestObject>()
1643 );
1644
1645 ::zr::static_assert!(
1646 core::mem::size_of::<ReverseIterator<'_, *mut TestObject>>()
1647 == core::mem::size_of::<*mut TestObject>()
1648 );
1649 ::zr::static_assert!(
1650 core::mem::align_of::<ReverseIterator<'_, *mut TestObject>>()
1651 == core::mem::align_of::<*mut TestObject>()
1652 );
1653
1654 #[derive(crate::DoublyLinkedListContainable, crate::Recyclable)]
1655 #[pin_data]
1656 struct UniqueTestObject {
1657 value: i32,
1658 #[pin]
1659 #[dll_node]
1660 node: DoublyLinkedListNode<UniqueTestObject>,
1661 }
1662
1663 impl UniqueTestObject {
1664 fn new(value: i32) -> Self {
1665 Self { value, node: DoublyLinkedListNode::new() }
1666 }
1667 }
1668
1669 impl TestValue for UniqueTestObject {
1670 fn new(value: i32) -> Self {
1671 Self::new(value)
1672 }
1673 }
1674
1675 #[fbl::ref_counted]
1676 #[derive(crate::DoublyLinkedListContainable, crate::Recyclable)]
1677 #[repr(C)]
1678 pub struct RefTestObject {
1679 value: i32,
1680 #[dll_node]
1681 node: DoublyLinkedListNode<RefTestObject>,
1682 }
1683
1684 impl TestValue for RefTestObject {
1685 fn new_ref_counted(value: i32) -> RefPtr<Self> {
1686 crate::make_ref_counted!(RefTestObject {
1687 value: value,
1688 node: DoublyLinkedListNode::new()
1689 })
1690 .unwrap()
1691 }
1692 }
1693
1694 macro_rules! generate_list_tests {
1695 ($mod_name:ident, $ptr_type:ty, $factory_type:ty, $get_val:expr, $push:expr) => {
1696 mod $mod_name {
1697 use super::*;
1698
1699 #[test]
1700 fn test_basic() {
1701 let mut factory = <$factory_type>::new();
1702 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1703 assert!(list.is_empty());
1704
1705 let obj1 = factory.create(1);
1706 let obj2 = factory.create(2);
1707
1708 $push(list.as_mut(), obj1);
1709 $push(list.as_mut(), obj2);
1710
1711 assert!(!list.is_empty());
1712
1713 let mut iter = list.iter();
1714 assert_eq!(iter.next().unwrap().value, 2);
1715 assert_eq!(iter.next().unwrap().value, 1);
1716 assert!(iter.next().is_none());
1717
1718 list.as_mut().clear();
1719 assert!(list.is_empty());
1720 }
1721
1722 #[test]
1723 fn test_double_ended_iterator() {
1724 let mut factory = <$factory_type>::new();
1725 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1726 let obj1 = factory.create(1);
1727 let obj2 = factory.create(2);
1728 let obj3 = factory.create(3);
1729
1730 $push(list.as_mut(), obj1);
1731 $push(list.as_mut(), obj2);
1732 $push(list.as_mut(), obj3);
1733
1734 let mut iter = list.iter();
1735 assert_eq!(iter.next().unwrap().value, 3);
1736 assert_eq!(iter.next_back().unwrap().value, 1);
1737 assert_eq!(iter.next().unwrap().value, 2);
1738 assert!(iter.next().is_none());
1739 assert!(iter.next_back().is_none());
1740
1741 list.as_mut().clear();
1742 }
1743
1744 #[test]
1745 fn test_explicit_pops() {
1746 let mut factory = <$factory_type>::new();
1747 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1748 let obj1 = factory.create(1);
1749 let obj2 = factory.create(2);
1750
1751 $push(list.as_mut(), obj1);
1752 $push(list.as_mut(), obj2);
1753
1754 let p1 = list.as_mut().pop_front();
1755 assert!(p1.is_some());
1756 let p2 = list.as_mut().pop_front();
1757 assert!(p2.is_some());
1758 assert!(list.as_mut().pop_front().is_none());
1759 }
1760
1761 #[test]
1762 fn test_cursor_move_prev() {
1763 let mut factory = <$factory_type>::new();
1764 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1765 let obj1 = factory.create(1);
1766 let obj2 = factory.create(2);
1767 let obj3 = factory.create(3);
1768
1769 $push(list.as_mut(), obj1);
1770 $push(list.as_mut(), obj2);
1771 $push(list.as_mut(), obj3);
1772
1773 let (a, b, c) = {
1774 let mut iter = list.iter();
1775 (
1776 $get_val(iter.next().unwrap()),
1777 $get_val(iter.next().unwrap()),
1778 $get_val(iter.next().unwrap()),
1779 )
1780 };
1781
1782 let mut cursor = list.as_mut().cursor_front_mut();
1783 assert_eq!($get_val(cursor.get().unwrap()), a);
1784
1785 cursor.move_prev();
1786 assert!(cursor.get().is_none()); cursor.move_prev();
1789 assert_eq!($get_val(cursor.get().unwrap()), c);
1790
1791 cursor.move_prev();
1792 assert_eq!($get_val(cursor.get().unwrap()), b);
1793
1794 cursor.move_prev();
1795 assert_eq!($get_val(cursor.get().unwrap()), a);
1796
1797 list.as_mut().clear();
1798 }
1799
1800 #[test]
1801 fn test_cursor_insert_after() {
1802 let mut factory = <$factory_type>::new();
1803 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1804 let obj1 = factory.create(1);
1805 let obj2 = factory.create(2);
1806 let obj3 = factory.create(3);
1807
1808 $push(list.as_mut(), obj1);
1809
1810 let mut cursor = list.as_mut().cursor_front_mut();
1811 unsafe {
1812 cursor.insert_after_raw(obj3);
1813 cursor.insert_after_raw(obj2);
1814 }
1815
1816 let mut iter = list.iter();
1817 assert_eq!($get_val(iter.next().unwrap()), 1);
1818 assert_eq!($get_val(iter.next().unwrap()), 2);
1819 assert_eq!($get_val(iter.next().unwrap()), 3);
1820 assert!(iter.next().is_none());
1821
1822 list.as_mut().clear();
1823 }
1824
1825 #[test]
1826 fn test_pop_back() {
1827 let mut factory = <$factory_type>::new();
1828 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1829 let obj1 = factory.create(1);
1830 let obj2 = factory.create(2);
1831
1832 $push(list.as_mut(), obj1);
1833 $push(list.as_mut(), obj2);
1834
1835 let p1 = list.as_mut().pop_back();
1836 assert!(p1.is_some());
1837 let p2 = list.as_mut().pop_back();
1838 assert!(p2.is_some());
1839 assert!(list.as_mut().pop_back().is_none());
1840 }
1841
1842 #[test]
1843 fn test_erase() {
1844 let mut factory = <$factory_type>::new();
1845 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1846 let obj1 = factory.create(1);
1847 let obj2 = factory.create(2);
1848 let obj3 = factory.create(3);
1849
1850 $push(list.as_mut(), obj1);
1851 $push(list.as_mut(), obj2);
1852 $push(list.as_mut(), obj3);
1853
1854 let mut cursor = list.as_mut().cursor_front_mut();
1855 cursor.move_next();
1856 let erased = cursor.erase();
1857 assert!(erased.is_some());
1858 factory.cleanup(erased.unwrap());
1859
1860 let mut iter = list.iter();
1861 assert!(iter.next().is_some());
1862 assert!(iter.next().is_some());
1863 assert!(iter.next().is_none());
1864
1865 list.as_mut().clear();
1866 }
1867
1868 #[test]
1869 fn test_erase_if() {
1870 let mut factory = <$factory_type>::new();
1871 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1872 let obj1 = factory.create(1);
1873 let obj2 = factory.create(2);
1874 let obj3 = factory.create(3);
1875
1876 $push(list.as_mut(), obj1);
1877 $push(list.as_mut(), obj2);
1878 $push(list.as_mut(), obj3);
1879
1880 let erased = list.as_mut().erase_if(|o| o.value == 2);
1881 assert!(erased.is_some());
1882 assert_eq!($get_val(erased.unwrap().get_ref()), 2);
1883
1884 let mut iter = list.iter();
1885 assert_eq!($get_val(iter.next().unwrap()), 3);
1886 assert_eq!($get_val(iter.next().unwrap()), 1);
1887 assert!(iter.next().is_none());
1888
1889 list.as_mut().clear();
1890 }
1891
1892 #[test]
1893 fn test_find_if() {
1894 let mut factory = <$factory_type>::new();
1895 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1896 let obj1 = factory.create(1);
1897 let obj2 = factory.create(2);
1898
1899 $push(list.as_mut(), obj1);
1900 $push(list.as_mut(), obj2);
1901
1902 let found = list.find_if(|o| o.value == 1);
1903 assert!(found.is_some());
1904 assert_eq!(found.unwrap().value, 1);
1905
1906 let found = list.find_if(|o| o.value == 3);
1907 assert!(found.is_none());
1908
1909 list.as_mut().clear();
1910 }
1911
1912 #[test]
1913 fn test_complete_reverse_iteration() {
1914 let mut factory = <$factory_type>::new();
1915 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1916 let obj1 = factory.create(1);
1917 let obj2 = factory.create(2);
1918 let obj3 = factory.create(3);
1919
1920 $push(list.as_mut(), obj1);
1921 $push(list.as_mut(), obj2);
1922 $push(list.as_mut(), obj3);
1923
1924 let (a, b, c) = {
1925 let mut iter = list.iter();
1926 (
1927 $get_val(iter.next().unwrap()),
1928 $get_val(iter.next().unwrap()),
1929 $get_val(iter.next().unwrap()),
1930 )
1931 };
1932
1933 let mut iter = list.iter();
1934 assert_eq!($get_val(iter.next_back().unwrap()), c);
1935 assert_eq!($get_val(iter.next_back().unwrap()), b);
1936 assert_eq!($get_val(iter.next_back().unwrap()), a);
1937 assert!(iter.next_back().is_none());
1938
1939 list.as_mut().clear();
1940 }
1941
1942 #[test]
1943 fn test_split_after() {
1944 let mut factory = <$factory_type>::new();
1945 stack_pin_init!(let list1 = DoublyLinkedList::<$ptr_type>::new());
1946 stack_pin_init!(let list2 = DoublyLinkedList::<$ptr_type>::new());
1947
1948 let obj1 = factory.create(1);
1949 let obj2 = factory.create(2);
1950 let obj3 = factory.create(3);
1951 let obj4 = factory.create(4);
1952
1953 $push(list1.as_mut(), obj4);
1954 $push(list1.as_mut(), obj3);
1955 $push(list1.as_mut(), obj2);
1956 $push(list1.as_mut(), obj1);
1957
1958 let mut cursor = list1.as_mut().cursor_front_mut();
1959 cursor.move_next(); let mut dest_cursor = list2.as_mut().cursor_back_mut();
1962 cursor.split_after(&mut dest_cursor);
1963
1964 let mut iter1 = list1.iter();
1965 assert_eq!($get_val(iter1.next().unwrap()), 1);
1966 assert_eq!($get_val(iter1.next().unwrap()), 2);
1967 assert!(iter1.next().is_none());
1968
1969 let mut iter2 = list2.iter();
1970 assert_eq!($get_val(iter2.next().unwrap()), 3);
1971 assert_eq!($get_val(iter2.next().unwrap()), 4);
1972 assert!(iter2.next().is_none());
1973
1974 list1.as_mut().clear();
1975 list2.as_mut().clear();
1976 }
1977
1978 #[test]
1979 fn test_split_before() {
1980 let mut factory = <$factory_type>::new();
1981 stack_pin_init!(let list1 = DoublyLinkedList::<$ptr_type>::new());
1982 stack_pin_init!(let list2 = DoublyLinkedList::<$ptr_type>::new());
1983
1984 let obj1 = factory.create(1);
1985 let obj2 = factory.create(2);
1986 let obj3 = factory.create(3);
1987 let obj4 = factory.create(4);
1988
1989 $push(list1.as_mut(), obj4);
1990 $push(list1.as_mut(), obj3);
1991 $push(list1.as_mut(), obj2);
1992 $push(list1.as_mut(), obj1);
1993
1994 let mut cursor = list1.as_mut().cursor_front_mut();
1995 cursor.move_next();
1996 cursor.move_next(); let mut dest_cursor = list2.as_mut().cursor_back_mut();
1999 cursor.split_before(&mut dest_cursor);
2000
2001 let mut iter2 = list2.iter();
2003 assert_eq!($get_val(iter2.next().unwrap()), 1);
2004 assert_eq!($get_val(iter2.next().unwrap()), 2);
2005 assert!(iter2.next().is_none());
2006
2007 let mut iter1 = list1.iter();
2009 assert_eq!($get_val(iter1.next().unwrap()), 3);
2010 assert_eq!($get_val(iter1.next().unwrap()), 4);
2011 assert!(iter1.next().is_none());
2012
2013 list1.as_mut().clear();
2014 list2.as_mut().clear();
2015 }
2016 }
2017 };
2018 }
2019
2020 generate_list_tests!(
2021 raw_ptr_tests,
2022 *mut TestObject,
2023 RawFactory<TestObject>,
2024 |p: &TestObject| p.value,
2025 |list: Pin<&mut DoublyLinkedList<*mut TestObject>>, obj| {
2026 unsafe { list.push_front_raw(obj) };
2028 }
2029 );
2030
2031 generate_list_tests!(
2032 unique_ptr_tests,
2033 UniquePtr<UniqueTestObject>,
2034 UniqueFactory<UniqueTestObject>,
2035 |p: &UniqueTestObject| p.value,
2036 |list: Pin<&mut DoublyLinkedList<UniquePtr<UniqueTestObject>>>, obj| list.push_front(obj)
2037 );
2038
2039 generate_list_tests!(
2040 ref_ptr_tests,
2041 RefPtr<RefTestObject>,
2042 RefFactory<RefTestObject>,
2043 |p: &RefTestObject| p.value,
2044 |list: Pin<&mut DoublyLinkedList<RefPtr<RefTestObject>>>, obj| list.push_front(obj)
2045 );
2046
2047 #[test]
2048 fn test_tracking_size() {
2049 stack_pin_init!(let list =
2050 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2051
2052 assert_eq!(list.len(), 0);
2053 list.as_mut().push_front(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2054 assert_eq!(list.len(), 1);
2055 list.as_mut().push_front(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2056 assert_eq!(list.len(), 2);
2057 list.as_mut().pop_front();
2058 assert_eq!(list.len(), 1);
2059 list.as_mut().clear();
2060 assert_eq!(list.len(), 0);
2061 }
2062
2063 #[test]
2064 fn test_insert_before() {
2065 stack_pin_init!(let list =
2066 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2067
2068 let mut cursor = list.as_mut().cursor_front_mut();
2069 cursor.insert_before(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2070 assert_eq!(list.len(), 1);
2071 assert_eq!(list.front().unwrap().value, 1);
2072
2073 let mut cursor = list.as_mut().cursor_front_mut();
2074 cursor.insert_before(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2075 assert_eq!(list.len(), 2);
2076 assert_eq!(list.front().unwrap().value, 2);
2077
2078 let mut cursor = list.as_mut().cursor_front_mut();
2079 cursor.move_next(); cursor.insert_before(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2081 assert_eq!(list.len(), 3);
2082
2083 let mut cursor = list.as_mut().cursor_front_mut();
2084 while cursor.get().unwrap().value != 1 {
2085 cursor.move_next();
2086 }
2087 cursor.move_next(); cursor.insert_before(UniquePtr::try_new(UniqueTestObject::new(4)).unwrap());
2089 assert_eq!(list.len(), 4);
2090
2091 let mut iter = list.iter();
2092 assert_eq!(iter.next().unwrap().value, 2);
2093 assert_eq!(iter.next().unwrap().value, 3);
2094 assert_eq!(iter.next().unwrap().value, 1);
2095 assert_eq!(iter.next().unwrap().value, 4);
2096 assert!(iter.next().is_none());
2097
2098 list.as_mut().clear();
2099 }
2100
2101 #[test]
2102 fn test_front_mut_and_back_mut() {
2103 stack_pin_init!(let list =
2104 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2105
2106 assert!(list.as_mut().front_mut().is_none());
2107 assert!(list.as_mut().back_mut().is_none());
2108
2109 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2111 *list.as_mut().front_mut().unwrap().project().value = 2;
2112 assert_eq!(list.as_mut().back_mut().unwrap().value, 2);
2113 *list.as_mut().back_mut().unwrap().project().value = 3;
2114 assert_eq!(list.as_mut().front_mut().unwrap().value, 3);
2115 assert_eq!(list.front().unwrap().value, 3);
2116 assert_eq!(list.back().unwrap().value, 3);
2117 assert_eq!(list.as_mut().pop_front().unwrap().value, 3);
2118 assert!(list.is_empty());
2119
2120 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(10)).unwrap());
2121 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(20)).unwrap());
2122
2123 assert_eq!(list.as_mut().front_mut().unwrap().value, 10);
2124 assert_eq!(list.as_mut().back_mut().unwrap().value, 20);
2125
2126 *list.as_mut().front_mut().unwrap().project().value = 100;
2127 *list.as_mut().back_mut().unwrap().project().value = 200;
2128
2129 assert_eq!(list.front().unwrap().value, 100);
2130 assert_eq!(list.back().unwrap().value, 200);
2131
2132 list.as_mut().clear();
2133 }
2134
2135 macro_rules! assert_not_impl {
2139 ($t:ty: $($trait:tt)+) => {
2140 const _: fn() = || {
2141 trait AmbiguousIfImpl<A> {
2142 fn some_item() {}
2143 }
2144 impl<T: ?Sized> AmbiguousIfImpl<()> for T {}
2145 enum Invalid {}
2146 impl<T: ?Sized + $($trait)+> AmbiguousIfImpl<Invalid> for T {}
2147 let _ = <$t as AmbiguousIfImpl<_>>::some_item;
2148 };
2149 };
2150 }
2151
2152 assert_not_impl!(DoublyLinkedListNode<TestObject>: Unpin);
2154 assert_not_impl!(TestObject: Unpin);
2155 assert_not_impl!(UniqueTestObject: Unpin);
2156 assert_not_impl!(RefTestObject: Unpin);
2157 assert_not_impl!(DoublyLinkedList<*mut TestObject>: Unpin);
2159 assert_not_impl!(RefPtr<RefTestObject>: MutPtr);
2161
2162 #[test]
2163 fn test_iter_mut() {
2164 stack_pin_init!(let list =
2165 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2166
2167 assert!(list.as_mut().iter_mut().next().is_none());
2168 assert!(list.as_mut().iter_mut().next_back().is_none());
2169
2170 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(7)).unwrap());
2172 {
2173 let mut iter = list.as_mut().iter_mut();
2174 let only = iter.next_back().unwrap();
2175 assert_eq!(only.value, 7);
2176 *only.project().value = 8;
2177 assert!(iter.next_back().is_none());
2178 assert!(iter.next().is_none());
2179 }
2180 {
2181 let mut iter = list.as_mut().iter_mut();
2182 assert_eq!(iter.next().unwrap().value, 8);
2183 assert!(iter.next().is_none());
2184 assert!(iter.next_back().is_none());
2185 }
2186 assert_eq!(list.as_mut().pop_front().unwrap().value, 8);
2187 assert!(list.is_empty());
2188
2189 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2190 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2191 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2192
2193 for obj in list.as_mut().iter_mut() {
2194 *obj.project().value *= 10;
2195 }
2196
2197 let mut iter = list.as_mut().iter_mut();
2198 assert_eq!(iter.next().unwrap().value, 10);
2199 let mut last = iter.next_back().unwrap();
2200 assert_eq!(last.value, 30);
2201 *last.as_mut().project().value += 1;
2202 let mut middle = iter.next().unwrap();
2203 *middle.as_mut().project().value += 2;
2204 assert!(iter.next().is_none());
2205 assert!(iter.next_back().is_none());
2206
2207 let values: alloc::vec::Vec<i32> = list.iter().map(|o| o.value).collect();
2208 assert_eq!(values, [10, 22, 31]);
2209 assert_eq!(list.len(), 3);
2210
2211 {
2213 let mut items: alloc::vec::Vec<_> = list.as_mut().iter_mut().collect();
2214 assert_eq!(items.len(), 3);
2215 for item in items.iter_mut() {
2216 *item.as_mut().project().value += 1;
2217 }
2218 *items[0].as_mut().project().value += 100;
2219 *items[2].as_mut().project().value += 200;
2220 }
2221 let values: alloc::vec::Vec<i32> = list.iter().map(|o| o.value).collect();
2222 assert_eq!(values, [111, 23, 232]);
2223
2224 list.as_mut().clear();
2225 assert!(list.is_empty());
2226
2227 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2230 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2231 {
2232 let mut iter = list.as_mut().iter_mut();
2233 let mut first = iter.next().unwrap();
2234 *first.as_mut().project().value = 10;
2235 let mut second = iter.next_back().unwrap();
2236 *first.as_mut().project().value = 11;
2237 *second.as_mut().project().value = 20;
2238 assert!(iter.next().is_none());
2239 assert!(iter.next_back().is_none());
2240 assert_eq!(first.value, 11);
2241 assert_eq!(second.value, 20);
2242 }
2243 let values: alloc::vec::Vec<i32> = list.iter().map(|o| o.value).collect();
2244 assert_eq!(values, [11, 20]);
2245
2246 {
2248 let mut iter = list.as_mut().iter_mut();
2249 let mut last = iter.next_back().unwrap();
2250 *last.as_mut().project().value = 21;
2251 let mut first = iter.next().unwrap();
2252 *last.as_mut().project().value = 22;
2253 *first.as_mut().project().value = 12;
2254 assert!(iter.next().is_none());
2255 assert!(iter.next_back().is_none());
2256 }
2257 let values: alloc::vec::Vec<i32> = list.iter().map(|o| o.value).collect();
2258 assert_eq!(values, [12, 22]);
2259
2260 list.as_mut().clear();
2261 }
2262
2263 #[test]
2264 fn test_forward_and_reverse_iter_mut() {
2265 stack_pin_init!(let list = DoublyLinkedList::<UniquePtr<UniqueTestObject>>::new());
2266
2267 assert!(list.as_mut().forward_iter_mut().next().is_none());
2268 assert!(list.as_mut().reverse_iter_mut().next().is_none());
2269
2270 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(5)).unwrap());
2272 {
2273 let mut r_iter = list.as_mut().reverse_iter_mut();
2274 let only = r_iter.next().unwrap();
2275 assert_eq!(only.value, 5);
2276 *only.project().value = 6;
2277 assert!(r_iter.next().is_none());
2278 }
2279 {
2280 let mut f_iter = list.as_mut().forward_iter_mut();
2281 assert_eq!(f_iter.next().unwrap().value, 6);
2282 assert!(f_iter.next().is_none());
2283 }
2284 assert_eq!(list.as_mut().pop_front().unwrap().value, 6);
2285 assert!(list.is_empty());
2286
2287 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2288 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2289 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2290
2291 for obj in list.as_mut().forward_iter_mut() {
2293 *obj.project().value += 10;
2294 }
2295 let values: alloc::vec::Vec<i32> = list.iter().map(|o| o.value).collect();
2296 assert_eq!(values, [11, 12, 13]);
2297
2298 let mut visited = alloc::vec::Vec::new();
2300 for obj in list.as_mut().reverse_iter_mut() {
2301 visited.push(obj.value);
2302 *obj.project().value *= 2;
2303 }
2304 assert_eq!(visited, [13, 12, 11]);
2305 let values: alloc::vec::Vec<i32> = list.iter().map(|o| o.value).collect();
2306 assert_eq!(values, [22, 24, 26]);
2307
2308 {
2310 let mut items: alloc::vec::Vec<_> = list.as_mut().reverse_iter_mut().collect();
2311 assert_eq!(items.len(), 3);
2312 for item in items.iter_mut() {
2313 *item.as_mut().project().value += 1;
2314 }
2315 *items[0].as_mut().project().value += 100;
2318 *items[2].as_mut().project().value += 200;
2319 assert_eq!(items[0].value, 127);
2320 assert_eq!(items[1].value, 25);
2321 assert_eq!(items[2].value, 223);
2322 }
2323 let values: alloc::vec::Vec<i32> = list.iter().map(|o| o.value).collect();
2324 assert_eq!(values, [223, 25, 127]);
2325
2326 {
2328 let mut items: alloc::vec::Vec<_> = list.as_mut().forward_iter_mut().collect();
2329 assert_eq!(items.len(), 3);
2330 for item in items.iter_mut() {
2331 *item.as_mut().project().value -= 1;
2332 }
2333 *items[2].as_mut().project().value -= 100;
2334 *items[0].as_mut().project().value -= 200;
2335 }
2336 let values: alloc::vec::Vec<i32> = list.iter().map(|o| o.value).collect();
2337 assert_eq!(values, [22, 24, 26]);
2338
2339 list.as_mut().clear();
2340 }
2341
2342 #[test]
2343 fn test_iter_mut_raw_ptr() {
2344 stack_pin_init!(let list = DoublyLinkedList::<*mut TestObject>::new());
2345 let mut obj1 = TestObject::new(1);
2346 let mut obj2 = TestObject::new(2);
2347
2348 unsafe {
2350 list.as_mut().push_back_raw(&mut obj1);
2351 list.as_mut().push_back_raw(&mut obj2);
2352 }
2353
2354 for obj in list.as_mut().iter_mut() {
2355 *obj.project().value += 100;
2356 }
2357 *list.as_mut().front_mut().unwrap().project().value += 1;
2358 *list.as_mut().back_mut().unwrap().project().value += 2;
2359
2360 let values: alloc::vec::Vec<i32> = list.iter().map(|o| o.value).collect();
2361 assert_eq!(values, [102, 104]);
2362
2363 list.as_mut().clear();
2364 }
2365
2366 #[test]
2367 fn test_cursor_get_mut() {
2368 stack_pin_init!(let list =
2369 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2370
2371 assert!(list.as_mut().cursor_front_mut().get_mut().is_none());
2372
2373 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2374 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2375
2376 let mut cursor = list.as_mut().cursor_front_mut();
2377 *cursor.get_mut().unwrap().project().value = 10;
2378 cursor.move_next();
2379 assert_eq!(cursor.get_mut().unwrap().value, 2);
2380 *cursor.get_mut().unwrap().project().value = 20;
2381 cursor.move_next();
2382 assert!(cursor.get_mut().is_none()); let mut iter = list.iter();
2385 assert_eq!(iter.next().unwrap().value, 10);
2386 assert_eq!(iter.next().unwrap().value, 20);
2387 assert!(iter.next().is_none());
2388 assert_eq!(list.len(), 2);
2389
2390 list.as_mut().clear();
2391 }
2392
2393 #[test]
2394 fn test_cursor_front_and_back_mut() {
2395 stack_pin_init!(let list =
2396 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2397
2398 assert!(list.as_mut().cursor_front_mut().get().is_none());
2399 assert!(list.as_mut().cursor_back_mut().get().is_none());
2400
2401 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(10)).unwrap());
2402 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(20)).unwrap());
2403
2404 let mut front_cursor = list.as_mut().cursor_front_mut();
2405 assert_eq!(front_cursor.get().unwrap().value, 10);
2406 front_cursor.move_next();
2407 assert_eq!(front_cursor.get().unwrap().value, 20);
2408
2409 let mut back_cursor = list.as_mut().cursor_back_mut();
2410 assert!(back_cursor.get().is_none());
2411 back_cursor.move_prev();
2412 assert_eq!(back_cursor.get().unwrap().value, 20);
2413
2414 let mut back_cursor = list.as_mut().cursor_back_mut();
2415 back_cursor.insert_before(UniquePtr::try_new(UniqueTestObject::new(30)).unwrap());
2416 assert_eq!(list.len(), 3);
2417 assert_eq!(list.back().unwrap().value, 30);
2418
2419 list.as_mut().clear();
2420 }
2421
2422 #[test]
2423 fn test_splice_middle() {
2424 stack_pin_init!(let list1 =
2425 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2426 stack_pin_init!(let list2 =
2427 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2428
2429 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2430 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2431 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2432 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(4)).unwrap());
2433
2434 let mut cursor = list1.as_mut().cursor_front_mut();
2435 cursor.move_next(); cursor.splice(list2.as_mut());
2438
2439 assert!(list2.is_empty());
2440 assert_eq!(list1.len(), 4);
2441
2442 let mut iter = list1.iter();
2443 assert_eq!(iter.next().unwrap().value, 1);
2444 assert_eq!(iter.next().unwrap().value, 3);
2445 assert_eq!(iter.next().unwrap().value, 4);
2446 assert_eq!(iter.next().unwrap().value, 2);
2447 assert!(iter.next().is_none());
2448
2449 list1.as_mut().clear();
2450 }
2451
2452 #[test]
2453 fn test_splice_head() {
2454 stack_pin_init!(let list1 =
2455 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2456 stack_pin_init!(let list2 =
2457 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2458
2459 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2460 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2461 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2462 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(4)).unwrap());
2463
2464 let mut cursor = list1.as_mut().cursor_front_mut();
2465
2466 cursor.splice(list2.as_mut());
2467
2468 assert!(list2.is_empty());
2469 assert_eq!(list1.len(), 4);
2470
2471 let mut iter = list1.iter();
2472 assert_eq!(iter.next().unwrap().value, 3);
2473 assert_eq!(iter.next().unwrap().value, 4);
2474 assert_eq!(iter.next().unwrap().value, 1);
2475 assert_eq!(iter.next().unwrap().value, 2);
2476 assert!(iter.next().is_none());
2477
2478 list1.as_mut().clear();
2479 }
2480
2481 #[test]
2482 fn test_splice_tail() {
2483 stack_pin_init!(let list1 =
2484 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2485 stack_pin_init!(let list2 =
2486 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2487
2488 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2489 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2490 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2491 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(4)).unwrap());
2492
2493 let mut cursor = list1.as_mut().cursor_front_mut();
2494 cursor.move_next();
2495 cursor.move_next(); cursor.splice(list2.as_mut());
2498
2499 assert!(list2.is_empty());
2500 assert_eq!(list1.len(), 4);
2501
2502 let mut iter = list1.iter();
2503 assert_eq!(iter.next().unwrap().value, 1);
2504 assert_eq!(iter.next().unwrap().value, 2);
2505 assert_eq!(iter.next().unwrap().value, 3);
2506 assert_eq!(iter.next().unwrap().value, 4);
2507 assert!(iter.next().is_none());
2508
2509 list1.as_mut().clear();
2510 }
2511
2512 #[test]
2513 fn test_splice_empty() {
2514 stack_pin_init!(let list1 =
2515 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2516 stack_pin_init!(let list2 =
2517 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2518
2519 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2520 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2521
2522 let mut cursor = list1.as_mut().cursor_front_mut();
2523 cursor.splice(list2.as_mut());
2524
2525 assert!(list2.is_empty());
2526 assert_eq!(list1.len(), 2);
2527
2528 let mut iter = list1.iter();
2529 assert_eq!(iter.next().unwrap().value, 1);
2530 assert_eq!(iter.next().unwrap().value, 2);
2531 assert!(iter.next().is_none());
2532
2533 list1.as_mut().clear();
2534 }
2535
2536 #[test]
2537 fn test_splice_non_tracking() {
2538 stack_pin_init!(let list1 =
2539 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, NonTrackingSize>::new());
2540 stack_pin_init!(let list2 =
2541 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, NonTrackingSize>::new());
2542
2543 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2544 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2545 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2546 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(4)).unwrap());
2547
2548 let mut cursor = list1.as_mut().cursor_front_mut();
2549 cursor.move_next(); cursor.splice(list2.as_mut());
2552
2553 assert!(list2.is_empty());
2554
2555 let mut iter = list1.iter();
2556 assert_eq!(iter.next().unwrap().value, 1);
2557 assert_eq!(iter.next().unwrap().value, 3);
2558 assert_eq!(iter.next().unwrap().value, 4);
2559 assert_eq!(iter.next().unwrap().value, 2);
2560 assert!(iter.next().is_none());
2561
2562 list1.as_mut().clear();
2563 }
2564
2565 #[test]
2566 fn test_list_splice() {
2567 stack_pin_init!(let list1 =
2569 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2570 stack_pin_init!(let list2 =
2571 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2572
2573 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2574 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2575 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2576 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(4)).unwrap());
2577
2578 list1.as_mut().splice(list2.as_mut());
2579
2580 assert!(list2.is_empty());
2581 assert_eq!(list2.len(), 0);
2582 assert_eq!(list1.len(), 4);
2583
2584 let mut iter = list1.iter();
2585 assert_eq!(iter.next().unwrap().value, 1);
2586 assert_eq!(iter.next().unwrap().value, 2);
2587 assert_eq!(iter.next().unwrap().value, 3);
2588 assert_eq!(iter.next().unwrap().value, 4);
2589 assert!(iter.next().is_none());
2590
2591 stack_pin_init!(let list3 =
2593 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2594
2595 list3.as_mut().splice(list1.as_mut());
2596
2597 assert!(list1.is_empty());
2598 assert_eq!(list1.len(), 0);
2599 assert_eq!(list3.len(), 4);
2600
2601 let mut iter = list3.iter();
2602 assert_eq!(iter.next().unwrap().value, 1);
2603 assert_eq!(iter.next().unwrap().value, 2);
2604 assert_eq!(iter.next().unwrap().value, 3);
2605 assert_eq!(iter.next().unwrap().value, 4);
2606 assert!(iter.next().is_none());
2607
2608 list3.as_mut().splice(list1.as_mut());
2610 assert_eq!(list3.len(), 4);
2611 assert!(list1.is_empty());
2612
2613 list3.as_mut().clear();
2614 }
2615
2616 #[test]
2617 fn test_split_after_at_tail() {
2618 stack_pin_init!(let list1 =
2619 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2620 stack_pin_init!(let list2 =
2621 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2622
2623 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2624 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2625
2626 let mut cursor = list1.as_mut().cursor_front_mut();
2627 cursor.move_next(); let mut dest_cursor = list2.as_mut().cursor_back_mut();
2630 cursor.split_after(&mut dest_cursor);
2631
2632 assert!(list2.is_empty());
2633 assert_eq!(list2.len(), 0);
2634 assert_eq!(list1.len(), 2);
2635
2636 list1.as_mut().clear();
2637 }
2638
2639 #[test]
2640 fn test_split_after_at_head() {
2641 stack_pin_init!(let list1 =
2642 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2643 stack_pin_init!(let list2 =
2644 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2645
2646 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2647 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2648 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2649
2650 let mut cursor = list1.as_mut().cursor_front_mut(); let mut dest_cursor = list2.as_mut().cursor_back_mut();
2653 cursor.split_after(&mut dest_cursor);
2654
2655 assert_eq!(list1.len(), 1);
2656 assert_eq!(list2.len(), 2);
2657
2658 let mut iter1 = list1.iter();
2659 assert_eq!(iter1.next().unwrap().value, 1);
2660 assert!(iter1.next().is_none());
2661
2662 let mut iter2 = list2.iter();
2663 assert_eq!(iter2.next().unwrap().value, 2);
2664 assert_eq!(iter2.next().unwrap().value, 3);
2665 assert!(iter2.next().is_none());
2666
2667 list1.as_mut().clear();
2668 list2.as_mut().clear();
2669 }
2670
2671 #[test]
2672 fn test_split_before_at_head() {
2673 stack_pin_init!(let list1 =
2674 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2675 stack_pin_init!(let list2 =
2676 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2677
2678 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2679 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2680
2681 let mut cursor = list1.as_mut().cursor_front_mut(); let mut dest_cursor = list2.as_mut().cursor_back_mut();
2684 cursor.split_before(&mut dest_cursor);
2685
2686 assert!(list2.is_empty());
2687 assert_eq!(list2.len(), 0);
2688 assert_eq!(list1.len(), 2);
2689
2690 list1.as_mut().clear();
2691 }
2692
2693 #[test]
2694 fn test_split_before_at_tail() {
2695 stack_pin_init!(let list1 =
2696 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2697 stack_pin_init!(let list2 =
2698 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2699
2700 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2701 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2702 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2703
2704 let mut cursor = list1.as_mut().cursor_front_mut();
2705 cursor.move_next();
2706 cursor.move_next(); let mut dest_cursor = list2.as_mut().cursor_back_mut();
2709 cursor.split_before(&mut dest_cursor);
2710
2711 assert_eq!(list2.len(), 2);
2712 assert_eq!(list1.len(), 1);
2713
2714 let mut iter2 = list2.iter();
2715 assert_eq!(iter2.next().unwrap().value, 1);
2716 assert_eq!(iter2.next().unwrap().value, 2);
2717 assert!(iter2.next().is_none());
2718
2719 let mut iter1 = list1.iter();
2720 assert_eq!(iter1.next().unwrap().value, 3);
2721 assert!(iter1.next().is_none());
2722
2723 list1.as_mut().clear();
2724 list2.as_mut().clear();
2725 }
2726
2727 #[test]
2728 fn test_split_before_at_sentinel() {
2729 stack_pin_init!(let list1 =
2730 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2731 stack_pin_init!(let list2 =
2732 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2733
2734 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2735 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2736
2737 let mut cursor = list1.as_mut().cursor_back_mut(); let mut dest_cursor = list2.as_mut().cursor_back_mut();
2740 cursor.split_before(&mut dest_cursor);
2741
2742 assert!(list1.is_empty());
2743 assert_eq!(list1.len(), 0);
2744 assert_eq!(list2.len(), 2);
2745
2746 let mut iter2 = list2.iter();
2747 assert_eq!(iter2.next().unwrap().value, 1);
2748 assert_eq!(iter2.next().unwrap().value, 2);
2749 assert!(iter2.next().is_none());
2750
2751 list2.as_mut().clear();
2752 }
2753
2754 #[test]
2755 fn test_split_into_middle_of_dest_list() {
2756 stack_pin_init!(let list1 =
2757 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2758 stack_pin_init!(let list2 =
2759 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2760
2761 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2762 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2763 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2764 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(4)).unwrap());
2765
2766 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(10)).unwrap());
2767 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(20)).unwrap());
2768
2769 let mut cursor1 = list1.as_mut().cursor_front_mut();
2771 cursor1.move_next(); let mut cursor2 = list2.as_mut().cursor_front_mut();
2774 cursor2.move_next(); cursor1.split_after(&mut cursor2);
2777
2778 assert_eq!(list1.len(), 2);
2780 let mut iter1 = list1.iter();
2781 assert_eq!(iter1.next().unwrap().value, 1);
2782 assert_eq!(iter1.next().unwrap().value, 2);
2783 assert!(iter1.next().is_none());
2784
2785 assert_eq!(list2.len(), 4);
2787 let mut iter2 = list2.iter();
2788 assert_eq!(iter2.next().unwrap().value, 10);
2789 assert_eq!(iter2.next().unwrap().value, 3);
2790 assert_eq!(iter2.next().unwrap().value, 4);
2791 assert_eq!(iter2.next().unwrap().value, 20);
2792 assert!(iter2.next().is_none());
2793
2794 list1.as_mut().clear();
2795 list2.as_mut().clear();
2796 }
2797
2798 #[test]
2799 fn test_list_split_methods() {
2800 let mut obj1 = TestObject::new(1);
2801 let mut obj2 = TestObject::new(2);
2802 let mut obj3 = TestObject::new(3);
2803
2804 stack_pin_init!(let list1 = DoublyLinkedList::<*mut TestObject>::new());
2805 stack_pin_init!(let list2 = DoublyLinkedList::<*mut TestObject>::new());
2806
2807 unsafe {
2808 list1.as_mut().push_back_raw(&mut obj1);
2809 list1.as_mut().push_back_raw(&mut obj2);
2810 list1.as_mut().push_back_raw(&mut obj3);
2811
2812 let mut cursor1 = list1.as_mut().cursor_at(&obj1);
2814 let mut cursor2 = list2.as_mut().cursor_back_mut();
2815 cursor1.split_after(&mut cursor2);
2816
2817 assert_eq!(list1.iter().count(), 1);
2818 assert_eq!(list2.iter().count(), 2);
2819
2820 let mut iter1 = list1.iter();
2821 assert_eq!(iter1.next().unwrap().value, 1);
2822 assert!(iter1.next().is_none());
2823
2824 let mut iter2 = list2.iter();
2825 assert_eq!(iter2.next().unwrap().value, 2);
2826 assert_eq!(iter2.next().unwrap().value, 3);
2827 assert!(iter2.next().is_none());
2828
2829 list1.as_mut().splice(list2.as_mut());
2831 assert_eq!(list1.iter().count(), 3);
2832
2833 let mut cursor1 = list1.as_mut().cursor_at(&obj3);
2835 let mut cursor2 = list2.as_mut().cursor_back_mut();
2836 cursor1.split_before(&mut cursor2);
2837
2838 assert_eq!(list2.iter().count(), 2);
2839 assert_eq!(list1.iter().count(), 1);
2840
2841 let mut iter2 = list2.iter();
2842 assert_eq!(iter2.next().unwrap().value, 1);
2843 assert_eq!(iter2.next().unwrap().value, 2);
2844 assert!(iter2.next().is_none());
2845
2846 let mut iter1 = list1.iter();
2847 assert_eq!(iter1.next().unwrap().value, 3);
2848 assert!(iter1.next().is_none());
2849
2850 list1.as_mut().clear();
2851 list2.as_mut().clear();
2852 }
2853 }
2854
2855 #[test]
2856 fn test_cursor_get() {
2857 stack_pin_init!(let list = DoublyLinkedList::<UniquePtr<UniqueTestObject>>::new());
2858
2859 let cursor = list.as_mut().cursor_front_mut();
2860 assert!(cursor.get().is_none());
2861
2862 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(42)).unwrap());
2863
2864 let mut cursor = list.as_mut().cursor_front_mut();
2865 assert!(cursor.get().is_some());
2866 assert_eq!(cursor.get().unwrap().value, 42);
2867
2868 cursor.move_next();
2869 assert!(cursor.get().is_none());
2870
2871 list.as_mut().clear();
2872 }
2873
2874 #[test]
2875 fn test_pop_back() {
2876 stack_pin_init!(let list =
2877 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2878
2879 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2880 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2881
2882 assert_eq!(list.len(), 2);
2883 let popped = list.as_mut().pop_back();
2884 assert!(popped.is_some());
2885 assert_eq!(popped.unwrap().value, 2);
2886 assert_eq!(list.len(), 1);
2887
2888 let popped = list.as_mut().pop_back();
2889 assert!(popped.is_some());
2890 assert_eq!(popped.unwrap().value, 1);
2891 assert_eq!(list.len(), 0);
2892
2893 assert!(list.as_mut().pop_back().is_none());
2894 }
2895
2896 #[test]
2897 fn test_erase() {
2898 stack_pin_init!(let list =
2899 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2900
2901 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2902 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2903 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2904
2905 assert_eq!(list.len(), 3);
2906
2907 let mut cursor = list.as_mut().cursor_front_mut();
2909 cursor.move_next(); let erased = cursor.erase();
2911 assert!(erased.is_some());
2912 assert_eq!(erased.unwrap().value, 2);
2913 assert_eq!(list.len(), 2);
2914
2915 let mut iter = list.iter();
2916 assert_eq!(iter.next().unwrap().value, 1);
2917 assert_eq!(iter.next().unwrap().value, 3);
2918 assert!(iter.next().is_none());
2919
2920 let mut cursor = list.as_mut().cursor_front_mut();
2922 let erased = cursor.erase(); assert!(erased.is_some());
2924 assert_eq!(erased.unwrap().value, 1);
2925 assert_eq!(list.len(), 1);
2926 assert_eq!(list.front().unwrap().value, 3); let mut cursor = list.as_mut().cursor_front_mut();
2930 let erased = cursor.erase(); assert!(erased.is_some());
2932 assert_eq!(erased.unwrap().value, 3);
2933 assert_eq!(list.len(), 0);
2934 assert!(list.is_empty());
2935
2936 list.as_mut().clear();
2937 }
2938
2939 #[test]
2940 fn test_erase_if() {
2941 stack_pin_init!(let list =
2942 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2943
2944 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2945 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2946 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2947
2948 let erased = list.as_mut().erase_if(|obj| obj.value % 2 == 0);
2949 assert!(erased.is_some());
2950 assert_eq!(erased.unwrap().value, 2);
2951
2952 assert_eq!(list.len(), 2);
2953 let mut iter = list.iter();
2954 assert_eq!(iter.next().unwrap().value, 1);
2955 assert_eq!(iter.next().unwrap().value, 3);
2956 assert!(iter.next().is_none());
2957
2958 list.as_mut().clear();
2959 }
2960
2961 #[test]
2962 fn test_erase_by_reference() {
2963 stack_pin_init!(let list =
2964 DoublyLinkedList::<*mut TestObject, DefaultObjectTag, TrackingSize>::new());
2965 let mut obj1 = TestObject::new(1);
2966 let mut obj2 = TestObject::new(2);
2967 let mut obj3 = TestObject::new(3);
2968
2969 unsafe {
2970 list.as_mut().push_back_raw(&mut obj1);
2971 list.as_mut().push_back_raw(&mut obj2);
2972 list.as_mut().push_back_raw(&mut obj3);
2973 }
2974
2975 assert_eq!(list.len(), 3);
2976
2977 let erased = unsafe { list.as_mut().erase(&obj2) };
2979 assert!(erased.is_some());
2980 assert_eq!(unsafe { &*erased.unwrap() }.value, 2);
2981 assert_eq!(list.len(), 2);
2982
2983 let mut iter = list.iter();
2984 assert_eq!(iter.next().unwrap().value, 1);
2985 assert_eq!(iter.next().unwrap().value, 3);
2986 assert!(iter.next().is_none());
2987
2988 list.as_mut().clear();
2989 }
2990
2991 #[test]
2992 fn test_remove_from_container() {
2993 stack_pin_init!(let list = DoublyLinkedList::<*mut TestObject>::new());
2994 let mut obj1 = TestObject::new(1);
2995 let mut obj2 = TestObject::new(2);
2996 let mut obj3 = TestObject::new(3);
2997
2998 let removed = unsafe {
3000 remove_from_container::<TestObject, DefaultObjectTag, *mut TestObject>(&obj1)
3001 };
3002 assert!(removed.is_none());
3003
3004 unsafe {
3005 list.as_mut().push_back_raw(&mut obj1);
3006 list.as_mut().push_back_raw(&mut obj2);
3007 list.as_mut().push_back_raw(&mut obj3);
3008 }
3009
3010 let removed = unsafe {
3012 remove_from_container::<TestObject, DefaultObjectTag, *mut TestObject>(&obj2)
3013 };
3014 assert!(removed.is_some());
3015 assert_eq!(unsafe { &*removed.unwrap() }.value, 2);
3016
3017 let mut iter = list.iter();
3018 assert_eq!(iter.next().unwrap().value, 1);
3019 assert_eq!(iter.next().unwrap().value, 3);
3020 assert!(iter.next().is_none());
3021
3022 let removed = unsafe {
3024 remove_from_container::<TestObject, DefaultObjectTag, *mut TestObject>(&obj1)
3025 };
3026 assert!(removed.is_some());
3027 assert_eq!(unsafe { &*removed.unwrap() }.value, 1);
3028
3029 let mut iter = list.iter();
3030 assert_eq!(iter.next().unwrap().value, 3);
3031 assert!(iter.next().is_none());
3032
3033 let removed = unsafe {
3035 remove_from_container::<TestObject, DefaultObjectTag, *mut TestObject>(&obj3)
3036 };
3037 assert!(removed.is_some());
3038 assert_eq!(unsafe { &*removed.unwrap() }.value, 3);
3039 assert!(list.is_empty());
3040
3041 list.as_mut().clear();
3042 }
3043
3044 #[test]
3045 fn test_replace() {
3046 stack_pin_init!(let list =
3047 DoublyLinkedList::<*mut TestObject, DefaultObjectTag, TrackingSize>::new());
3048 let mut obj1 = TestObject::new(1);
3049 let mut obj2 = TestObject::new(2);
3050 let mut obj3 = TestObject::new(3);
3051
3052 unsafe {
3053 list.as_mut().push_back_raw(&mut obj1);
3054 list.as_mut().push_back_raw(&mut obj2);
3055 }
3056
3057 assert_eq!(list.len(), 2);
3058
3059 let old = unsafe { list.as_mut().replace_raw(&obj2, &mut obj3) };
3060 assert!(old.is_some());
3061 assert_eq!(unsafe { &*old.unwrap() }.value, 2);
3062 assert_eq!(list.len(), 2);
3063
3064 let mut iter = list.iter();
3065 assert_eq!(iter.next().unwrap().value, 1);
3066 assert_eq!(iter.next().unwrap().value, 3);
3067 assert!(iter.next().is_none());
3068
3069 list.as_mut().clear();
3070 }
3071
3072 #[test]
3073 fn test_cursor_replace() {
3074 stack_pin_init!(let list = DoublyLinkedList::<UniquePtr<UniqueTestObject>>::new());
3075
3076 let obj1 = UniquePtr::try_new(UniqueTestObject::new(1)).unwrap();
3077 let obj2 = UniquePtr::try_new(UniqueTestObject::new(2)).unwrap();
3078 let obj3 = UniquePtr::try_new(UniqueTestObject::new(3)).unwrap();
3079
3080 list.as_mut().push_back(obj1);
3081 list.as_mut().push_back(obj2);
3082
3083 let mut cursor = list.as_mut().cursor_front_mut();
3084 cursor.move_next(); let old = cursor.replace(obj3);
3087 assert!(old.is_some());
3088 assert_eq!(old.unwrap().value, 2);
3089
3090 let mut iter = list.iter();
3091 assert_eq!(iter.next().unwrap().value, 1);
3092 assert_eq!(iter.next().unwrap().value, 3);
3093 assert!(iter.next().is_none());
3094
3095 list.as_mut().clear();
3096 }
3097
3098 struct Tag2;
3099
3100 #[fbl::ref_counted]
3101 #[derive(crate::DoublyLinkedListContainable, crate::Recyclable)]
3102 #[repr(C)]
3103 struct MultiListObject {
3104 value: i32,
3105 #[dll_node]
3106 node1: DoublyLinkedListNode<MultiListObject>,
3107 #[dll_node(tag = Tag2)]
3108 node2: DoublyLinkedListNode<MultiListObject>,
3109 }
3110
3111 #[test]
3112 fn test_multiple_containers() {
3113 stack_pin_init!(let list1 =
3114 DoublyLinkedList::<RefPtr<MultiListObject>, DefaultObjectTag>::new());
3115 stack_pin_init!(let list2 = DoublyLinkedList::<RefPtr<MultiListObject>, Tag2>::new());
3116
3117 let obj1 = fbl::make_ref_counted!(MultiListObject {
3118 value: 1,
3119 node1: DoublyLinkedListNode::new(),
3120 node2: DoublyLinkedListNode::new(),
3121 })
3122 .unwrap();
3123
3124 let obj2 = fbl::make_ref_counted!(MultiListObject {
3125 value: 2,
3126 node1: DoublyLinkedListNode::new(),
3127 node2: DoublyLinkedListNode::new(),
3128 })
3129 .unwrap();
3130
3131 list1.as_mut().push_back(obj1.clone());
3132 list1.as_mut().push_back(obj2.clone());
3133
3134 list2.as_mut().push_back(obj2); let mut iter1 = list1.iter();
3137 assert_eq!(iter1.next().unwrap().value, 1);
3138 assert_eq!(iter1.next().unwrap().value, 2);
3139 assert!(iter1.next().is_none());
3140
3141 let mut iter2 = list2.iter();
3142 assert_eq!(iter2.next().unwrap().value, 2);
3143 assert!(iter2.next().is_none());
3144
3145 list1.as_mut().clear();
3146 list2.as_mut().clear();
3147 }
3148
3149 use alloc::sync::Arc;
3150 use core::sync::atomic::{AtomicBool, Ordering};
3151
3152 #[derive(crate::DoublyLinkedListContainable, crate::Recyclable)]
3153 struct LifecycleObject {
3154 destroyed: Arc<AtomicBool>,
3155 #[dll_node]
3156 node: DoublyLinkedListNode<LifecycleObject>,
3157 }
3158
3159 impl LifecycleObject {
3160 fn new(destroyed: Arc<AtomicBool>) -> Self {
3161 Self { destroyed, node: DoublyLinkedListNode::new() }
3162 }
3163 }
3164
3165 impl Drop for LifecycleObject {
3166 fn drop(&mut self) {
3167 self.destroyed.store(true, Ordering::Relaxed);
3168 }
3169 }
3170
3171 #[test]
3172 fn test_lifecycle_on_drop() {
3173 let destroyed1 = Arc::new(AtomicBool::new(false));
3174 let destroyed2 = Arc::new(AtomicBool::new(false));
3175
3176 {
3177 stack_pin_init!(let list = DoublyLinkedList::<UniquePtr<LifecycleObject>>::new());
3178
3179 let obj1 = UniquePtr::try_new(LifecycleObject::new(destroyed1.clone())).unwrap();
3180 let obj2 = UniquePtr::try_new(LifecycleObject::new(destroyed2.clone())).unwrap();
3181
3182 list.as_mut().push_back(obj1);
3183 list.as_mut().push_back(obj2);
3184
3185 assert!(!destroyed1.load(Ordering::Relaxed));
3186 assert!(!destroyed2.load(Ordering::Relaxed));
3187 } assert!(destroyed1.load(Ordering::Relaxed));
3190 assert!(destroyed2.load(Ordering::Relaxed));
3191 }
3192
3193 #[test]
3194 fn test_sized_managed_list() {
3195 stack_pin_init!(let list =
3196 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
3197
3198 assert_eq!(list.len(), 0);
3199
3200 let obj1 = UniquePtr::try_new(UniqueTestObject::new(1)).unwrap();
3201 let obj2 = UniquePtr::try_new(UniqueTestObject::new(2)).unwrap();
3202
3203 list.as_mut().push_back(obj1);
3204 assert_eq!(list.len(), 1);
3205
3206 list.as_mut().push_back(obj2);
3207 assert_eq!(list.len(), 2);
3208
3209 let popped = list.as_mut().pop_front();
3210 assert!(popped.is_some());
3211 assert_eq!(list.len(), 1);
3212
3213 list.as_mut().clear();
3214 assert_eq!(list.len(), 0);
3215 }
3216
3217 #[test]
3218 fn test_unidirectional_iterators() {
3219 stack_pin_init!(let list = DoublyLinkedList::<UniquePtr<UniqueTestObject>>::new());
3220
3221 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
3222 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
3223 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
3224
3225 let mut f_iter = list.forward_iter();
3227 assert_eq!(f_iter.next().unwrap().value, 1);
3228 assert_eq!(f_iter.next().unwrap().value, 2);
3229 assert_eq!(f_iter.next().unwrap().value, 3);
3230 assert!(f_iter.next().is_none());
3231
3232 let mut r_iter = list.reverse_iter();
3234 assert_eq!(r_iter.next().unwrap().value, 3);
3235 assert_eq!(r_iter.next().unwrap().value, 2);
3236 assert_eq!(r_iter.next().unwrap().value, 1);
3237 assert!(r_iter.next().is_none());
3238
3239 list.as_mut().clear();
3240 }
3241
3242 #[test]
3243 fn test_cursor_at() {
3244 stack_pin_init!(let list =
3245 DoublyLinkedList::<*mut TestObject, DefaultObjectTag, TrackingSize>::new());
3246 let mut obj1 = TestObject::new(1);
3247 let mut obj2 = TestObject::new(2);
3248 let mut obj3 = TestObject::new(3);
3249
3250 unsafe {
3251 list.as_mut().push_back_raw(&mut obj1);
3252 list.as_mut().push_back_raw(&mut obj2);
3253 list.as_mut().push_back_raw(&mut obj3);
3254 }
3255
3256 let mut cursor = unsafe { list.as_mut().cursor_at(&obj2) };
3259 assert_eq!(cursor.get().unwrap().value, 2);
3260
3261 cursor.move_next();
3263 assert_eq!(cursor.get().unwrap().value, 3);
3264
3265 let mut cursor = unsafe { list.as_mut().cursor_at(&obj2) };
3268 cursor.move_prev();
3269 assert_eq!(cursor.get().unwrap().value, 1);
3270
3271 let mut cursor = unsafe { list.as_mut().cursor_at(&obj2) };
3274 let erased = cursor.erase().unwrap();
3275 assert_eq!(unsafe { &*erased }.value, 2);
3276
3277 let mut iter = list.iter();
3279 assert_eq!(iter.next().unwrap().value, 1);
3280 assert_eq!(iter.next().unwrap().value, 3);
3281 assert!(iter.next().is_none());
3282
3283 list.as_mut().clear();
3284 }
3285
3286 unsafe extern "C" {
3288 fn cpp_create_unique_list() -> *mut c_void;
3290 fn cpp_destroy_unique_list(list: *mut c_void);
3291 fn cpp_unique_list_push_back(list: *mut c_void, item: *mut c_void);
3292 fn cpp_unique_list_pop_front(list: *mut c_void) -> *mut c_void;
3293 fn cpp_unique_list_is_empty(list: *mut c_void) -> bool;
3294
3295 fn cpp_create_ref_list() -> *mut c_void;
3297 fn cpp_destroy_ref_list(list: *mut c_void);
3298 fn cpp_ref_list_push_back(list: *mut c_void, item: *mut c_void);
3299 fn cpp_ref_list_pop_front(list: *mut c_void) -> *mut c_void;
3300 fn cpp_ref_list_is_empty(list: *mut c_void) -> bool;
3301
3302 fn cpp_create_unique_object(value: i32, destruction_flag: *mut bool) -> *mut c_void;
3304 fn cpp_get_unique_object_value(obj: *mut c_void) -> i32;
3305
3306 fn cpp_create_ref_object(value: i32, destruction_flag: *mut bool) -> *mut c_void;
3308 fn cpp_get_ref_object_value(obj: *mut c_void) -> i32;
3309 }
3310
3311 #[test]
3312 fn test_interop_rust_list_cpp_unique_objects() {
3313 let destroyed1 = AtomicBool::new(false);
3314 let destroyed2 = AtomicBool::new(false);
3315
3316 unsafe {
3317 stack_pin_init!(let list = DoublyLinkedList::<UniquePtr<SharedUniqueObject>>::new());
3318
3319 let cpp_raw1 = cpp_create_unique_object(1, destroyed1.as_ptr() as *mut bool);
3320 let cpp_raw2 = cpp_create_unique_object(2, destroyed2.as_ptr() as *mut bool);
3321
3322 let obj1 = UniquePtr::from_raw(cpp_raw1 as *mut SharedUniqueObject);
3323 let obj2 = UniquePtr::from_raw(cpp_raw2 as *mut SharedUniqueObject);
3324
3325 list.as_mut().push_back(obj1);
3326 list.as_mut().push_back(obj2);
3327
3328 assert!(!destroyed1.load(Ordering::Relaxed));
3329 assert!(!destroyed2.load(Ordering::Relaxed));
3330
3331 let popped = list.as_mut().pop_front();
3333 assert!(popped.is_some());
3334 assert_eq!(popped.as_ref().unwrap().value, 1);
3335
3336 drop(popped);
3338 assert!(destroyed1.load(Ordering::Relaxed));
3339 assert!(!destroyed2.load(Ordering::Relaxed));
3340
3341 }
3343 assert!(destroyed2.load(Ordering::Relaxed));
3344 }
3345
3346 #[test]
3347 fn test_interop_cpp_list_rust_unique_objects() {
3348 let destroyed1 = Arc::new(AtomicBool::new(false));
3349 let destroyed2 = Arc::new(AtomicBool::new(false));
3350
3351 unsafe {
3352 let cpp_list = cpp_create_unique_list();
3353 assert!(cpp_unique_list_is_empty(cpp_list));
3354
3355 let obj1 = UniquePtr::try_new(SharedUniqueObject::new(1)).unwrap();
3356 let obj2 = UniquePtr::try_new(SharedUniqueObject::new(2)).unwrap();
3357
3358 let raw1 = UniquePtr::as_ptr(&obj1) as *mut SharedUniqueObject;
3360 (*raw1).destruction_flag = destroyed1.as_ptr() as *mut bool;
3361 let raw2 = UniquePtr::as_ptr(&obj2) as *mut SharedUniqueObject;
3362 (*raw2).destruction_flag = destroyed2.as_ptr() as *mut bool;
3363
3364 cpp_unique_list_push_back(cpp_list, UniquePtr::into_raw(obj1) as *mut c_void);
3366 cpp_unique_list_push_back(cpp_list, UniquePtr::into_raw(obj2) as *mut c_void);
3367
3368 assert!(!destroyed1.load(Ordering::Relaxed));
3369 assert!(!destroyed2.load(Ordering::Relaxed));
3370
3371 let popped = cpp_unique_list_pop_front(cpp_list);
3373 assert!(!popped.is_null());
3374 assert_eq!(cpp_get_unique_object_value(popped), 1);
3375
3376 let popped_rust = UniquePtr::from_raw(popped as *mut SharedUniqueObject);
3378 drop(popped_rust);
3379 assert!(destroyed1.load(Ordering::Relaxed));
3380 assert!(!destroyed2.load(Ordering::Relaxed));
3381
3382 cpp_destroy_unique_list(cpp_list);
3384 }
3385 assert!(destroyed2.load(Ordering::Relaxed));
3386 }
3387
3388 #[test]
3389 fn test_interop_rust_list_cpp_ref_objects() {
3390 let destroyed1 = AtomicBool::new(false);
3391 let destroyed2 = AtomicBool::new(false);
3392
3393 unsafe {
3394 stack_pin_init!(let list = DoublyLinkedList::<RefPtr<SharedRefObject>>::new());
3395
3396 let cpp_raw1 = cpp_create_ref_object(1, destroyed1.as_ptr() as *mut bool);
3397 let cpp_raw2 = cpp_create_ref_object(2, destroyed2.as_ptr() as *mut bool);
3398
3399 let obj1 = RefPtr::from_raw(cpp_raw1 as *mut SharedRefObject);
3400 let obj2 = RefPtr::from_raw(cpp_raw2 as *mut SharedRefObject);
3401
3402 list.as_mut().push_back(obj1);
3403 list.as_mut().push_back(obj2);
3404
3405 assert!(!destroyed1.load(Ordering::Relaxed));
3406 assert!(!destroyed2.load(Ordering::Relaxed));
3407
3408 let popped = list.as_mut().pop_front();
3410 assert!(popped.is_some());
3411 assert_eq!(popped.as_ref().unwrap().value, 1);
3412
3413 drop(popped);
3415 assert!(destroyed1.load(Ordering::Relaxed));
3416 assert!(!destroyed2.load(Ordering::Relaxed));
3417
3418 }
3420 assert!(destroyed2.load(Ordering::Relaxed));
3421 }
3422
3423 #[test]
3424 fn test_interop_cpp_list_rust_ref_objects() {
3425 let destroyed1 = Arc::new(AtomicBool::new(false));
3426 let destroyed2 = Arc::new(AtomicBool::new(false));
3427
3428 unsafe {
3429 let cpp_list = cpp_create_ref_list();
3430 assert!(cpp_ref_list_is_empty(cpp_list));
3431
3432 let obj1 = SharedRefObject::new_ref_counted(1);
3433 let obj2 = SharedRefObject::new_ref_counted(2);
3434
3435 let raw1 = RefPtr::as_ptr(&obj1) as *mut SharedRefObject;
3437 (*raw1).destruction_flag = destroyed1.as_ptr() as *mut bool;
3438 let raw2 = RefPtr::as_ptr(&obj2) as *mut SharedRefObject;
3439 (*raw2).destruction_flag = destroyed2.as_ptr() as *mut bool;
3440
3441 cpp_ref_list_push_back(
3443 cpp_list,
3444 RefPtr::into_raw(obj1) as *mut SharedRefObject as *mut c_void,
3445 );
3446 cpp_ref_list_push_back(
3447 cpp_list,
3448 RefPtr::into_raw(obj2) as *mut SharedRefObject as *mut c_void,
3449 );
3450
3451 assert!(!destroyed1.load(Ordering::Relaxed));
3452 assert!(!destroyed2.load(Ordering::Relaxed));
3453
3454 let popped = cpp_ref_list_pop_front(cpp_list);
3456 assert!(!popped.is_null());
3457 assert_eq!(cpp_get_ref_object_value(popped), 1);
3458
3459 let popped_rust = RefPtr::from_raw(popped as *mut SharedRefObject);
3461 drop(popped_rust);
3462 assert!(destroyed1.load(Ordering::Relaxed));
3463 assert!(!destroyed2.load(Ordering::Relaxed));
3464
3465 cpp_destroy_ref_list(cpp_list);
3467 }
3468 assert!(destroyed2.load(Ordering::Relaxed));
3469 }
3470}