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]
298 _pin: core::marker::PhantomData<core::marker::PhantomPinned>,
299
300 _phantom: core::marker::PhantomData<(P, Tag)>,
301}
302
303impl<P, Tag, S> DoublyLinkedList<P, Tag, S>
304where
305 P: PtrTraits,
306 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
307 S: SizeTracker,
308{
309 #[inline]
311 pub fn new() -> impl PinInit<Self, core::convert::Infallible> {
312 pin_init!(&this in Self {
313 head: make_sentinel(this.as_ptr()),
314 size: S::INIT,
315 _pin: core::marker::PhantomData,
316 _phantom: core::marker::PhantomData,
317 })
318 }
319
320 #[inline]
321 fn get_sentinel(&self) -> *mut P::Target {
322 make_sentinel(self as *const Self as *mut Self)
323 }
324
325 #[inline]
326 fn get_tail(&self) -> *mut P::Target {
327 if self.is_empty() {
328 self.get_sentinel()
329 } else {
330 unsafe { *(*self.head).get_node().prev.get() }
334 }
335 }
336
337 #[inline]
341 unsafe fn set_tail(&self, tail: *mut P::Target) {
342 debug_assert!(!self.is_empty());
343 unsafe {
347 *(*self.head).get_node().prev.get() = tail;
348 }
349 }
350
351 #[inline]
356 unsafe fn get_node_ref<'a>(&self, ptr: *mut P::Target) -> &'a DoublyLinkedListNode<P::Target> {
357 let _ = self;
358 unsafe { &(*ptr) }.get_node()
360 }
361
362 #[inline]
364 pub fn is_empty(&self) -> bool {
365 is_sentinel_ptr(self.head)
366 }
367
368 #[inline]
370 pub fn front(&self) -> Option<&P::Target> {
371 if self.is_empty() { None } else { unsafe { Some(&*self.head) } }
372 }
373
374 #[inline]
377 pub fn front_mut(self: Pin<&mut Self>) -> Option<Pin<&mut P::Target>>
378 where
379 P: MutPtr,
380 {
381 if self.is_empty() {
382 None
383 } else {
384 Some(unsafe { Pin::new_unchecked(&mut *self.head) })
388 }
389 }
390
391 #[inline]
393 pub fn back(&self) -> Option<&P::Target> {
394 let tail = self.get_tail();
395 if is_sentinel_ptr(tail) { None } else { unsafe { Some(&*tail) } }
396 }
397
398 #[inline]
401 pub fn back_mut(self: Pin<&mut Self>) -> Option<Pin<&mut P::Target>>
402 where
403 P: MutPtr,
404 {
405 let tail = self.get_tail();
406 if is_sentinel_ptr(tail) {
407 None
408 } else {
409 Some(unsafe { Pin::new_unchecked(&mut *tail) })
413 }
414 }
415
416 #[inline]
419 fn cursor_at_ptr(self: Pin<&mut Self>, current: *mut P::Target) -> CursorMut<'_, P, Tag, S> {
420 CursorMut { list: self, current }
421 }
422
423 #[inline]
429 pub fn push_front(self: Pin<&mut Self>, ptr: P)
430 where
431 P: ManagedPtr,
432 {
433 unsafe { self.push_front_raw(ptr) }
436 }
437
438 #[inline]
454 pub unsafe fn push_front_raw(self: Pin<&mut Self>, ptr: P) {
455 let mut cursor = self.cursor_front_mut();
456 unsafe {
458 cursor.insert_before_raw(ptr);
459 }
460 }
461
462 #[inline]
468 pub fn push_back(self: Pin<&mut Self>, ptr: P)
469 where
470 P: ManagedPtr,
471 {
472 unsafe { self.push_back_raw(ptr) }
475 }
476
477 #[inline]
492 pub unsafe fn push_back_raw(self: Pin<&mut Self>, ptr: P) {
493 let mut cursor = self.cursor_back_mut();
494 unsafe {
496 cursor.insert_before_raw(ptr);
497 }
498 }
499
500 #[inline]
502 pub fn pop_front(self: Pin<&mut Self>) -> Option<P> {
503 self.cursor_front_mut().erase()
504 }
505
506 #[inline]
508 pub fn pop_back(self: Pin<&mut Self>) -> Option<P> {
509 let tail = self.get_tail();
510 self.cursor_at_ptr(tail).erase()
511 }
512
513 pub fn clear(mut self: Pin<&mut Self>) {
515 while self.as_mut().pop_front().is_some() {}
516 }
517
518 #[inline]
542 pub unsafe fn clear_unsafe(self: Pin<&mut Self>) {
543 const {
544 assert!(
545 !P::IS_MANAGED,
546 "clear_unsafe is not allowed for containers of managed pointers",
547 );
548 }
549
550 let sentinel = self.get_sentinel();
551 let this = self.project();
552 *this.head = sentinel;
553
554 if S::IS_TRACKING {
556 this.size.set(0);
557 }
558 }
559
560 #[inline]
567 pub unsafe fn erase(self: Pin<&mut Self>, obj: &P::Target) -> Option<P> {
568 let ptr = obj as *const P::Target as *mut P::Target;
569 let node = obj.get_node();
570
571 if !node.in_container() {
572 return None;
573 }
574
575 self.cursor_at_ptr(ptr).erase()
576 }
577
578 #[inline]
590 pub unsafe fn replace_raw(self: Pin<&mut Self>, obj: &P::Target, replacement: P) -> Option<P> {
591 let ptr = obj as *const P::Target as *mut P::Target;
592 let node = obj.get_node();
593
594 if !node.in_container() {
595 return None;
596 }
597
598 let mut cursor = self.cursor_at_ptr(ptr);
599 unsafe { cursor.replace_raw(replacement) }
601 }
602
603 #[inline]
606 pub fn erase_if<F>(self: Pin<&mut Self>, mut f: F) -> Option<P>
607 where
608 F: FnMut(&P::Target) -> bool,
609 {
610 let mut cursor = self.cursor_front_mut();
611 while let Some(item) = cursor.get() {
612 if f(item) {
613 return cursor.erase();
614 } else {
615 cursor.move_next();
616 }
617 }
618 None
619 }
620
621 #[inline]
623 pub fn find_if<F>(&self, mut f: F) -> Option<&P::Target>
624 where
625 F: FnMut(&P::Target) -> bool,
626 {
627 self.iter().find(|&x| f(x))
628 }
629
630 #[inline]
632 pub fn cursor_front_mut(self: Pin<&mut Self>) -> CursorMut<'_, P, Tag, S> {
633 let head = self.head;
634 self.cursor_at_ptr(head)
635 }
636
637 #[inline]
639 pub fn cursor_back_mut(self: Pin<&mut Self>) -> CursorMut<'_, P, Tag, S> {
640 let sentinel = self.get_sentinel();
641 self.cursor_at_ptr(sentinel)
642 }
643
644 #[inline]
652 pub unsafe fn cursor_at(self: Pin<&mut Self>, obj: &P::Target) -> CursorMut<'_, P, Tag, S> {
653 debug_assert!(obj.get_node().in_container(), "Object must be in a container");
654 self.cursor_at_ptr(obj as *const P::Target as *mut P::Target)
655 }
656
657 #[inline]
663 pub fn splice(self: Pin<&mut Self>, other: Pin<&mut DoublyLinkedList<P, Tag, S>>) {
664 self.cursor_back_mut().splice(other);
665 }
666
667 #[inline]
668 pub fn iter(&self) -> Iterator<'_, P, Tag> {
669 Iterator::new(self)
670 }
671
672 #[inline]
676 pub fn iter_mut(self: Pin<&mut Self>) -> IteratorMut<'_, P, Tag>
677 where
678 P: MutPtr,
679 {
680 IteratorMut::new(self)
681 }
682
683 #[inline]
685 pub fn forward_iter(&self) -> ForwardIterator<'_, P, Tag> {
686 ForwardIterator::new(self.head)
687 }
688
689 #[inline]
693 pub fn forward_iter_mut(self: Pin<&mut Self>) -> ForwardIteratorMut<'_, P, Tag>
694 where
695 P: MutPtr,
696 {
697 ForwardIteratorMut::new(self.head)
698 }
699
700 #[inline]
702 pub fn reverse_iter(&self) -> ReverseIterator<'_, P, Tag> {
703 ReverseIterator::new(self.get_tail())
704 }
705
706 #[inline]
710 pub fn reverse_iter_mut(self: Pin<&mut Self>) -> ReverseIteratorMut<'_, P, Tag>
711 where
712 P: MutPtr,
713 {
714 ReverseIteratorMut::new(self.get_tail(), self.head)
715 }
716}
717
718impl<P, Tag> DoublyLinkedList<P, Tag, TrackingSize>
719where
720 P: PtrTraits,
721 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
722{
723 #[inline]
725 pub fn len(&self) -> usize {
726 self.size.get()
727 }
728}
729
730#[pinned_drop]
731impl<P, Tag, S> PinnedDrop for DoublyLinkedList<P, Tag, S>
732where
733 P: PtrTraits,
734 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
735 S: SizeTracker,
736{
737 fn drop(self: Pin<&mut Self>) {
738 if P::IS_MANAGED {
739 self.clear();
740 } else {
741 debug_assert!(self.is_empty(), "List must be empty on destruction");
742 if S::IS_TRACKING {
743 debug_assert_eq!(self.size.get(), 0, "Size must be zero on destruction");
744 }
745 }
746 }
747}
748
749pub struct CursorMut<'a, P, Tag = DefaultObjectTag, S = NonTrackingSize>
755where
756 P: PtrTraits,
757 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
758 S: SizeTracker,
759{
760 list: Pin<&'a mut DoublyLinkedList<P, Tag, S>>,
761 current: *mut P::Target,
762}
763
764impl<'a, P, Tag, S> CursorMut<'a, P, Tag, S>
765where
766 P: PtrTraits,
767 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
768 S: SizeTracker,
769{
770 #[inline]
771 pub fn get(&self) -> Option<&P::Target> {
772 if is_sentinel_ptr(self.current) { None } else { unsafe { Some(&*self.current) } }
773 }
774
775 #[inline]
778 pub fn get_mut(&mut self) -> Option<Pin<&mut P::Target>>
779 where
780 P: MutPtr,
781 {
782 if is_sentinel_ptr(self.current) {
783 None
784 } else {
785 Some(unsafe { Pin::new_unchecked(&mut *self.current) })
789 }
790 }
791
792 #[inline]
793 pub fn move_next(&mut self) {
794 if !is_sentinel_ptr(self.current) {
795 let node = unsafe { self.list.get_node_ref(self.current) };
797 self.current = node.get_next();
798 }
799 }
800
801 #[inline]
802 pub fn move_prev(&mut self) {
803 if !is_sentinel_ptr(self.current) {
804 let node = unsafe { self.list.get_node_ref(self.current) };
806 let prev = node.get_prev();
807 if self.current == self.list.head {
808 self.current = self.list.get_sentinel(); } else {
810 self.current = prev;
811 }
812 } else {
813 self.current = self.list.get_tail();
815 }
816 }
817
818 #[inline]
825 pub fn insert_after(&mut self, ptr: P)
826 where
827 P: ManagedPtr,
828 {
829 debug_assert!(!ptr.get_ref().get_node().in_container());
830 unsafe { self.insert_after_raw(ptr) }
834 }
835
836 #[inline]
853 pub unsafe fn insert_after_raw(&mut self, ptr: P) {
854 debug_assert!(!is_sentinel_ptr(self.current), "Cannot insert after end sentinel");
855 let raw = P::into_raw(ptr);
856 let node = unsafe { self.list.get_node_ref(raw) };
858 debug_assert!(!node.in_container());
859
860 let current_node = unsafe { self.list.get_node_ref(self.current) };
862 let next = current_node.get_next();
863
864 let current_save = self.current;
865 self.current = next;
866 unsafe {
869 self.insert_chain_before(raw, raw, 1);
870 }
871 self.current = current_save;
872 }
873
874 #[inline]
881 pub fn replace(&mut self, replacement: P) -> Option<P>
882 where
883 P: ManagedPtr,
884 {
885 unsafe { self.replace_raw(replacement) }
888 }
889
890 #[inline]
907 pub unsafe fn replace_raw(&mut self, replacement: P) -> Option<P> {
908 if is_sentinel_ptr(self.current) {
909 return None;
910 }
911 unsafe {
914 self.insert_before_raw(replacement);
915 }
916 self.erase()
917 }
918
919 #[inline]
925 pub fn insert_before(&mut self, ptr: P)
926 where
927 P: ManagedPtr,
928 {
929 debug_assert!(!ptr.get_ref().get_node().in_container());
930 unsafe { self.insert_before_raw(ptr) }
933 }
934
935 #[inline]
951 pub unsafe fn insert_before_raw(&mut self, ptr: P) {
952 let raw = P::into_raw(ptr);
953 let node = unsafe { self.list.get_node_ref(raw) };
955 debug_assert!(!node.in_container());
956
957 unsafe {
959 self.insert_chain_before(raw, raw, 1);
960 }
961 }
962
963 #[inline]
974 unsafe fn insert_chain_before(
975 &mut self,
976 chain_head: *mut P::Target,
977 chain_tail: *mut P::Target,
978 count: usize,
979 ) {
980 let head = self.list.head;
981 let before = self.current;
982 let chain_tail_node = unsafe { self.list.get_node_ref(chain_tail) };
984 let chain_head_node = unsafe { self.list.get_node_ref(chain_head) };
986
987 if is_sentinel_ptr(head) {
988 chain_tail_node.set_next(before);
989 chain_head_node.set_prev(chain_tail);
990 *self.list.as_mut().project().head = chain_head;
991 } else if before == head {
992 let head_node = unsafe { self.list.get_node_ref(head) };
994 let tail = head_node.get_prev();
995 chain_tail_node.set_next(before);
996 chain_head_node.set_prev(tail);
997 head_node.set_prev(chain_tail);
998 *self.list.as_mut().project().head = chain_head;
999 } else if is_sentinel_ptr(before) {
1000 let head_node = unsafe { self.list.get_node_ref(head) };
1002 let tail = head_node.get_prev();
1003 let tail_node = unsafe { self.list.get_node_ref(tail) };
1005 chain_tail_node.set_next(before);
1006 chain_head_node.set_prev(tail);
1007 tail_node.set_next(chain_head);
1008 head_node.set_prev(chain_tail);
1009 } else {
1010 let current_node = unsafe { self.list.get_node_ref(before) };
1012 let prev = current_node.get_prev();
1013 let prev_node = unsafe { self.list.get_node_ref(prev) };
1015 chain_tail_node.set_next(before);
1016 chain_head_node.set_prev(prev);
1017 prev_node.set_next(chain_head);
1018 current_node.set_prev(chain_tail);
1019 }
1020
1021 if S::IS_TRACKING {
1022 let new_size = self.list.size.get() + count;
1023 self.list.as_mut().project().size.set(new_size);
1024 }
1025 }
1026
1027 pub fn splice(&mut self, other: Pin<&mut DoublyLinkedList<P, Tag, S>>) {
1041 if other.is_empty() {
1042 return;
1043 }
1044
1045 let other_head = other.head;
1046 let other_tail = other.get_tail();
1047 let other_sentinel = other.get_sentinel();
1048 let count = if S::IS_TRACKING { other.size.get() } else { 0 };
1049
1050 unsafe {
1053 self.insert_chain_before(other_head, other_tail, count);
1054 }
1055
1056 let other = other.project();
1057 *other.head = other_sentinel;
1058 if S::IS_TRACKING {
1059 other.size.set(0);
1060 }
1061 }
1062
1063 pub fn split_after(&mut self, dest: &mut CursorMut<'_, P, Tag, S>) {
1076 debug_assert!(!is_sentinel_ptr(self.current), "Cannot split after end sentinel");
1077
1078 let curr_node = unsafe { self.list.get_node_ref(self.current) };
1080 let next_ptr = curr_node.get_next();
1081
1082 if is_sentinel_ptr(next_ptr) {
1084 return;
1085 }
1086
1087 let chain_head = next_ptr;
1088 let chain_tail = self.list.get_tail();
1089
1090 let mut count = 0;
1091 if S::IS_TRACKING {
1092 let mut p = chain_head;
1093 let sentinel = self.list.get_sentinel();
1094 while p != sentinel {
1095 count += 1;
1096 p = unsafe { self.list.get_node_ref(p) }.get_next();
1098 }
1099 let new_size = self.list.size.get() - count;
1100 self.list.as_mut().project().size.set(new_size);
1101 }
1102
1103 curr_node.set_next(self.list.get_sentinel());
1105 unsafe {
1106 self.list.set_tail(self.current);
1107 }
1108
1109 unsafe {
1113 dest.insert_chain_before(chain_head, chain_tail, count);
1114 }
1115 }
1116
1117 pub fn split_before(&mut self, dest: &mut CursorMut<'_, P, Tag, S>) {
1133 if self.current == self.list.head {
1135 return;
1136 }
1137
1138 if is_sentinel_ptr(self.current) {
1140 if self.list.is_empty() {
1141 return;
1142 }
1143 let chain_head = self.list.head;
1144 let chain_tail = self.list.get_tail();
1145 let sentinel = self.list.get_sentinel();
1146 let list = self.list.as_mut().project();
1147 let count = if S::IS_TRACKING {
1148 let c = list.size.get();
1149 list.size.set(0);
1150 c
1151 } else {
1152 0
1153 };
1154
1155 *list.head = sentinel;
1156
1157 unsafe {
1160 dest.insert_chain_before(chain_head, chain_tail, count);
1161 }
1162 return;
1163 }
1164
1165 let b = self.current;
1168 let b_node = unsafe { self.list.get_node_ref(b) };
1169 let chain_head = self.list.head;
1170 let chain_tail = b_node.get_prev();
1171 let old_tail = self.list.get_tail();
1172
1173 let mut count = 0;
1174 if S::IS_TRACKING {
1175 let mut p = chain_head;
1176 while p != b {
1177 count += 1;
1178 p = unsafe { self.list.get_node_ref(p) }.get_next();
1180 }
1181 let new_size = self.list.size.get() - count;
1182 self.list.as_mut().project().size.set(new_size);
1183 }
1184
1185 *self.list.as_mut().project().head = b;
1187 b_node.set_prev(old_tail);
1188
1189 unsafe {
1193 dest.insert_chain_before(chain_head, chain_tail, count);
1194 }
1195 }
1196
1197 #[inline]
1198 pub fn erase(&mut self) -> Option<P> {
1199 let ptr = self.current;
1200 if is_sentinel_ptr(ptr) {
1201 return None;
1202 }
1203 let head = self.list.head;
1204 let node = unsafe { self.list.get_node_ref(ptr) };
1206 let next = node.get_next();
1207 let prev = node.get_prev();
1208
1209 self.list.as_mut().project().size.decrement();
1210
1211 let tgt_prev_node = if is_sentinel_ptr(next) { head } else { next };
1212 unsafe { self.list.get_node_ref(tgt_prev_node) }.set_prev(prev);
1214
1215 if ptr == head {
1216 *self.list.as_mut().project().head = next;
1217 } else {
1218 unsafe { self.list.get_node_ref(prev) }.set_next(next);
1220 }
1221
1222 node.set_prev(core::ptr::null_mut());
1223 node.set_next(core::ptr::null_mut());
1224
1225 self.current = next;
1226 Some(unsafe { P::from_raw(ptr) })
1228 }
1229}
1230
1231pub struct Iterator<'a, P, Tag = DefaultObjectTag>
1233where
1234 P: PtrTraits,
1235 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1236{
1237 front: ForwardIterator<'a, P, Tag>,
1238 back: ReverseIterator<'a, P, Tag>,
1239}
1240
1241impl<'a, P, Tag> Iterator<'a, P, Tag>
1242where
1243 P: PtrTraits,
1244 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1245{
1246 fn new<S: SizeTracker>(list: &'a DoublyLinkedList<P, Tag, S>) -> Self {
1247 if list.is_empty() {
1248 Self {
1249 front: ForwardIterator::new(crate::make_sentinel_null()),
1250 back: ReverseIterator::new(crate::make_sentinel_null()),
1251 }
1252 } else {
1253 Self {
1254 front: ForwardIterator::new(list.head),
1255 back: ReverseIterator::new(list.get_tail()),
1256 }
1257 }
1258 }
1259}
1260
1261impl<'a, P, Tag> core::iter::Iterator for Iterator<'a, P, Tag>
1262where
1263 P: PtrTraits,
1264 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1265{
1266 type Item = &'a P::Target;
1267
1268 fn next(&mut self) -> Option<Self::Item> {
1269 let met = self.front.current == self.back.current;
1270 let item = self.front.next();
1271 if item.is_some() && met {
1272 self.front.current = crate::make_sentinel_null();
1273 self.back.current = crate::make_sentinel_null();
1274 }
1275 item
1276 }
1277}
1278
1279impl<'a, P, Tag> core::iter::DoubleEndedIterator for Iterator<'a, P, Tag>
1280where
1281 P: PtrTraits,
1282 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1283{
1284 fn next_back(&mut self) -> Option<Self::Item> {
1285 let met = self.front.current == self.back.current;
1286 let item = self.back.next();
1287 if item.is_some() && met {
1288 self.front.current = crate::make_sentinel_null();
1289 self.back.current = crate::make_sentinel_null();
1290 }
1291 item
1292 }
1293}
1294
1295pub struct ForwardIterator<'a, P, Tag = DefaultObjectTag>
1297where
1298 P: PtrTraits,
1299 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1300{
1301 current: *mut P::Target,
1302 _phantom: core::marker::PhantomData<&'a (P, Tag)>,
1303}
1304
1305impl<'a, P, Tag> ForwardIterator<'a, P, Tag>
1306where
1307 P: PtrTraits,
1308 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1309{
1310 fn new(current: *mut P::Target) -> Self {
1311 Self { current, _phantom: core::marker::PhantomData }
1312 }
1313}
1314
1315impl<'a, P, Tag> core::iter::Iterator for ForwardIterator<'a, P, Tag>
1316where
1317 P: PtrTraits,
1318 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1319{
1320 type Item = &'a P::Target;
1321
1322 fn next(&mut self) -> Option<Self::Item> {
1323 if is_sentinel_ptr(self.current) {
1324 None
1325 } else {
1326 let current = unsafe { &*self.current };
1330 self.current = current.get_node().get_next();
1331 Some(current)
1332 }
1333 }
1334}
1335
1336pub struct ReverseIterator<'a, P, Tag = DefaultObjectTag>
1338where
1339 P: PtrTraits,
1340 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1341{
1342 current: *mut P::Target,
1343 _phantom: core::marker::PhantomData<&'a (P, Tag)>,
1344}
1345
1346impl<'a, P, Tag> ReverseIterator<'a, P, Tag>
1347where
1348 P: PtrTraits,
1349 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1350{
1351 fn new(current: *mut P::Target) -> Self {
1352 Self { current, _phantom: core::marker::PhantomData }
1353 }
1354}
1355
1356impl<'a, P, Tag> core::iter::Iterator for ReverseIterator<'a, P, Tag>
1357where
1358 P: PtrTraits,
1359 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1360{
1361 type Item = &'a P::Target;
1362
1363 fn next(&mut self) -> Option<Self::Item> {
1364 if is_sentinel_ptr(self.current) {
1365 None
1366 } else {
1367 let current = unsafe { &*self.current };
1371 let prev = current.get_node().get_prev();
1372
1373 let prev_node = unsafe { &*prev }.get_node();
1376 if is_sentinel_ptr(prev_node.get_next()) {
1377 self.current = prev_node.get_next();
1380 } else {
1381 self.current = prev;
1382 }
1383 Some(current)
1384 }
1385 }
1386}
1387
1388pub struct IteratorMut<'a, P, Tag = DefaultObjectTag>
1392where
1393 P: MutPtr,
1394 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1395{
1396 front: ForwardIteratorMut<'a, P, Tag>,
1397 back: ReverseIteratorMut<'a, P, Tag>,
1398}
1399
1400impl<'a, P, Tag> IteratorMut<'a, P, Tag>
1401where
1402 P: MutPtr,
1403 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1404{
1405 fn new<S: SizeTracker>(list: Pin<&'a mut DoublyLinkedList<P, Tag, S>>) -> Self {
1406 if list.is_empty() {
1407 Self {
1408 front: ForwardIteratorMut::new(crate::make_sentinel_null()),
1409 back: ReverseIteratorMut::new(
1410 crate::make_sentinel_null(),
1411 crate::make_sentinel_null(),
1412 ),
1413 }
1414 } else {
1415 let tail = list.get_tail();
1416 Self {
1417 front: ForwardIteratorMut::new(list.head),
1418 back: ReverseIteratorMut::new(tail, list.head),
1419 }
1420 }
1421 }
1422}
1423
1424impl<'a, P, Tag> core::iter::Iterator for IteratorMut<'a, P, Tag>
1425where
1426 P: MutPtr,
1427 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1428{
1429 type Item = Pin<&'a mut P::Target>;
1430
1431 fn next(&mut self) -> Option<Self::Item> {
1432 let met = self.front.current == self.back.current;
1433 let item = self.front.next();
1434 if item.is_some() && met {
1435 self.front.current = crate::make_sentinel_null();
1436 self.back.current = crate::make_sentinel_null();
1437 }
1438 item
1439 }
1440}
1441
1442impl<'a, P, Tag> core::iter::DoubleEndedIterator for IteratorMut<'a, P, Tag>
1443where
1444 P: MutPtr,
1445 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1446{
1447 fn next_back(&mut self) -> Option<Self::Item> {
1448 let met = self.front.current == self.back.current;
1449 let item = self.back.next();
1450 if item.is_some() && met {
1451 self.front.current = crate::make_sentinel_null();
1452 self.back.current = crate::make_sentinel_null();
1453 }
1454 item
1455 }
1456}
1457
1458pub struct ForwardIteratorMut<'a, P, Tag = DefaultObjectTag>
1462where
1463 P: MutPtr,
1464 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1465{
1466 current: *mut P::Target,
1467 _phantom: core::marker::PhantomData<&'a mut (P, Tag)>,
1468}
1469
1470impl<'a, P, Tag> ForwardIteratorMut<'a, P, Tag>
1471where
1472 P: MutPtr,
1473 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1474{
1475 fn new(current: *mut P::Target) -> Self {
1476 Self { current, _phantom: core::marker::PhantomData }
1477 }
1478}
1479
1480impl<'a, P, Tag> core::iter::Iterator for ForwardIteratorMut<'a, P, Tag>
1481where
1482 P: MutPtr,
1483 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1484{
1485 type Item = Pin<&'a mut P::Target>;
1486
1487 fn next(&mut self) -> Option<Self::Item> {
1488 if is_sentinel_ptr(self.current) {
1489 None
1490 } else {
1491 let current_ptr = self.current;
1492 self.current = unsafe { &*current_ptr }.get_node().get_next();
1495 Some(unsafe { Pin::new_unchecked(&mut *current_ptr) })
1501 }
1502 }
1503}
1504
1505pub struct ReverseIteratorMut<'a, P, Tag = DefaultObjectTag>
1509where
1510 P: MutPtr,
1511 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1512{
1513 current: *mut P::Target,
1514 head: *mut P::Target,
1515 _phantom: core::marker::PhantomData<&'a mut (P, Tag)>,
1516}
1517
1518impl<'a, P, Tag> ReverseIteratorMut<'a, P, Tag>
1519where
1520 P: MutPtr,
1521 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1522{
1523 fn new(current: *mut P::Target, head: *mut P::Target) -> Self {
1524 Self { current, head, _phantom: core::marker::PhantomData }
1525 }
1526}
1527
1528impl<'a, P, Tag> core::iter::Iterator for ReverseIteratorMut<'a, P, Tag>
1529where
1530 P: MutPtr,
1531 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1532{
1533 type Item = Pin<&'a mut P::Target>;
1534
1535 fn next(&mut self) -> Option<Self::Item> {
1536 if is_sentinel_ptr(self.current) {
1537 None
1538 } else {
1539 let current_ptr = self.current;
1540 if current_ptr == self.head {
1541 self.current = crate::make_sentinel_null();
1542 } else {
1543 self.current = unsafe { &*current_ptr }.get_node().get_prev();
1546 }
1547 Some(unsafe { Pin::new_unchecked(&mut *current_ptr) })
1553 }
1554 }
1555}
1556
1557#[inline]
1565pub unsafe fn remove_from_container<T, Tag, P>(obj: &T) -> Option<P>
1566where
1567 P: PtrTraits<Target = T>,
1568 T: DoublyLinkedListContainable<T, Tag>,
1569{
1570 let node = obj.get_node();
1571 let next = node.get_next();
1572 if next.is_null() {
1573 return None;
1574 }
1575 let prev = node.get_prev();
1576 debug_assert!(!prev.is_null());
1577
1578 unsafe {
1581 let tgt_prev = if is_sentinel_ptr(next) {
1582 let list_ptr = crate::sentinel::unmake_sentinel::<
1583 DoublyLinkedList<P, Tag, NonTrackingSize>,
1584 T,
1585 >(next);
1586 (*(*list_ptr).head).get_node().prev.get()
1587 } else {
1588 (*next).get_node().prev.get()
1589 };
1590
1591 let prev_node = (*prev).get_node();
1592 let prev_next = prev_node.get_next();
1593 let tgt_next = if is_sentinel_ptr(prev_next) {
1594 let list_ptr = crate::sentinel::unmake_sentinel::<
1595 DoublyLinkedList<P, Tag, NonTrackingSize>,
1596 T,
1597 >(prev_next);
1598 &raw mut (*list_ptr).head
1599 } else {
1600 prev_node.next.get()
1601 };
1602
1603 *tgt_prev = prev;
1604 *tgt_next = next;
1605
1606 node.set_next(core::ptr::null_mut());
1607 node.set_prev(core::ptr::null_mut());
1608
1609 Some(P::from_raw(obj as *const T as *mut T))
1610 }
1611}
1612
1613impl<P, Tag, S> core::fmt::Debug for DoublyLinkedList<P, Tag, S>
1614where
1615 P: PtrTraits,
1616 P::Target: DoublyLinkedListContainable<P::Target, Tag> + core::fmt::Debug,
1617 S: SizeTracker,
1618{
1619 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1620 f.debug_list().entries(self.iter()).finish()
1621 }
1622}
1623
1624#[cfg(test)]
1625mod tests {
1626 extern crate alloc;
1627 use super::*;
1628 use crate::intrusive_container_test_support::*;
1629 use crate::ref_ptr::RefPtr;
1630 use crate::unique_ptr::UniquePtr;
1631 use core::ffi::c_void;
1632 use pin_init::stack_pin_init;
1633
1634 #[derive(crate::DoublyLinkedListContainable, crate::Recyclable)]
1635 #[pin_data]
1636 struct TestObject {
1637 value: i32,
1638 #[pin]
1639 #[dll_node]
1640 node: DoublyLinkedListNode<TestObject>,
1641 }
1642
1643 impl TestObject {
1644 fn new(value: i32) -> Self {
1645 Self { value, node: DoublyLinkedListNode::new() }
1646 }
1647 }
1648
1649 impl TestValue for TestObject {
1650 fn new(value: i32) -> Self {
1651 Self::new(value)
1652 }
1653 }
1654
1655 ::zr::static_assert!(
1656 core::mem::size_of::<DoublyLinkedListNode<TestObject>>()
1657 == 2 * core::mem::size_of::<*mut TestObject>()
1658 );
1659 ::zr::static_assert!(
1660 core::mem::align_of::<DoublyLinkedListNode<TestObject>>()
1661 == core::mem::align_of::<*mut TestObject>()
1662 );
1663
1664 ::zr::static_assert!(
1665 core::mem::size_of::<DoublyLinkedList<*mut TestObject>>()
1666 == core::mem::size_of::<*mut TestObject>()
1667 );
1668 ::zr::static_assert!(
1669 core::mem::align_of::<DoublyLinkedList<*mut TestObject>>()
1670 == core::mem::align_of::<*mut TestObject>()
1671 );
1672
1673 ::zr::static_assert!(
1674 core::mem::size_of::<DoublyLinkedList<*mut TestObject, DefaultObjectTag, TrackingSize>>()
1675 == 2 * core::mem::size_of::<*mut TestObject>()
1676 );
1677 ::zr::static_assert!(
1678 core::mem::align_of::<DoublyLinkedList<*mut TestObject, DefaultObjectTag, TrackingSize>>()
1679 == core::mem::align_of::<*mut TestObject>()
1680 );
1681
1682 ::zr::static_assert!(
1683 core::mem::size_of::<ForwardIterator<'_, *mut TestObject>>()
1684 == core::mem::size_of::<*mut TestObject>()
1685 );
1686 ::zr::static_assert!(
1687 core::mem::align_of::<ForwardIterator<'_, *mut TestObject>>()
1688 == core::mem::align_of::<*mut TestObject>()
1689 );
1690
1691 ::zr::static_assert!(
1692 core::mem::size_of::<ReverseIterator<'_, *mut TestObject>>()
1693 == core::mem::size_of::<*mut TestObject>()
1694 );
1695 ::zr::static_assert!(
1696 core::mem::align_of::<ReverseIterator<'_, *mut TestObject>>()
1697 == core::mem::align_of::<*mut TestObject>()
1698 );
1699
1700 #[derive(crate::DoublyLinkedListContainable, crate::Recyclable)]
1701 #[pin_data]
1702 struct UniqueTestObject {
1703 value: i32,
1704 #[pin]
1705 #[dll_node]
1706 node: DoublyLinkedListNode<UniqueTestObject>,
1707 }
1708
1709 impl UniqueTestObject {
1710 fn new(value: i32) -> Self {
1711 Self { value, node: DoublyLinkedListNode::new() }
1712 }
1713 }
1714
1715 impl TestValue for UniqueTestObject {
1716 fn new(value: i32) -> Self {
1717 Self::new(value)
1718 }
1719 }
1720
1721 #[fbl::ref_counted]
1722 #[derive(crate::DoublyLinkedListContainable, crate::Recyclable)]
1723 #[repr(C)]
1724 pub struct RefTestObject {
1725 value: i32,
1726 #[dll_node]
1727 node: DoublyLinkedListNode<RefTestObject>,
1728 }
1729
1730 impl TestValue for RefTestObject {
1731 fn new_ref_counted(value: i32) -> RefPtr<Self> {
1732 crate::make_ref_counted!(RefTestObject {
1733 value: value,
1734 node: DoublyLinkedListNode::new()
1735 })
1736 .unwrap()
1737 }
1738 }
1739
1740 macro_rules! generate_list_tests {
1741 ($mod_name:ident, $ptr_type:ty, $factory_type:ty, $get_val:expr, $push:expr) => {
1742 mod $mod_name {
1743 use super::*;
1744
1745 #[test]
1746 fn test_basic() {
1747 let mut factory = <$factory_type>::new();
1748 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1749 assert!(list.is_empty());
1750
1751 let obj1 = factory.create(1);
1752 let obj2 = factory.create(2);
1753
1754 $push(list.as_mut(), obj1);
1755 $push(list.as_mut(), obj2);
1756
1757 assert!(!list.is_empty());
1758
1759 let mut iter = list.iter();
1760 assert_eq!(iter.next().unwrap().value, 2);
1761 assert_eq!(iter.next().unwrap().value, 1);
1762 assert!(iter.next().is_none());
1763
1764 list.as_mut().clear();
1765 assert!(list.is_empty());
1766 }
1767
1768 #[test]
1769 fn test_double_ended_iterator() {
1770 let mut factory = <$factory_type>::new();
1771 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1772 let obj1 = factory.create(1);
1773 let obj2 = factory.create(2);
1774 let obj3 = factory.create(3);
1775
1776 $push(list.as_mut(), obj1);
1777 $push(list.as_mut(), obj2);
1778 $push(list.as_mut(), obj3);
1779
1780 let mut iter = list.iter();
1781 assert_eq!(iter.next().unwrap().value, 3);
1782 assert_eq!(iter.next_back().unwrap().value, 1);
1783 assert_eq!(iter.next().unwrap().value, 2);
1784 assert!(iter.next().is_none());
1785 assert!(iter.next_back().is_none());
1786
1787 list.as_mut().clear();
1788 }
1789
1790 #[test]
1791 fn test_explicit_pops() {
1792 let mut factory = <$factory_type>::new();
1793 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1794 let obj1 = factory.create(1);
1795 let obj2 = factory.create(2);
1796
1797 $push(list.as_mut(), obj1);
1798 $push(list.as_mut(), obj2);
1799
1800 let p1 = list.as_mut().pop_front();
1801 assert!(p1.is_some());
1802 let p2 = list.as_mut().pop_front();
1803 assert!(p2.is_some());
1804 assert!(list.as_mut().pop_front().is_none());
1805 }
1806
1807 #[test]
1808 fn test_cursor_move_prev() {
1809 let mut factory = <$factory_type>::new();
1810 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1811 let obj1 = factory.create(1);
1812 let obj2 = factory.create(2);
1813 let obj3 = factory.create(3);
1814
1815 $push(list.as_mut(), obj1);
1816 $push(list.as_mut(), obj2);
1817 $push(list.as_mut(), obj3);
1818
1819 let (a, b, c) = {
1820 let mut iter = list.iter();
1821 (
1822 $get_val(iter.next().unwrap()),
1823 $get_val(iter.next().unwrap()),
1824 $get_val(iter.next().unwrap()),
1825 )
1826 };
1827
1828 let mut cursor = list.as_mut().cursor_front_mut();
1829 assert_eq!($get_val(cursor.get().unwrap()), a);
1830
1831 cursor.move_prev();
1832 assert!(cursor.get().is_none()); cursor.move_prev();
1835 assert_eq!($get_val(cursor.get().unwrap()), c);
1836
1837 cursor.move_prev();
1838 assert_eq!($get_val(cursor.get().unwrap()), b);
1839
1840 cursor.move_prev();
1841 assert_eq!($get_val(cursor.get().unwrap()), a);
1842
1843 list.as_mut().clear();
1844 }
1845
1846 #[test]
1847 fn test_cursor_insert_after() {
1848 let mut factory = <$factory_type>::new();
1849 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1850 let obj1 = factory.create(1);
1851 let obj2 = factory.create(2);
1852 let obj3 = factory.create(3);
1853
1854 $push(list.as_mut(), obj1);
1855
1856 let mut cursor = list.as_mut().cursor_front_mut();
1857 unsafe {
1858 cursor.insert_after_raw(obj3);
1859 cursor.insert_after_raw(obj2);
1860 }
1861
1862 let mut iter = list.iter();
1863 assert_eq!($get_val(iter.next().unwrap()), 1);
1864 assert_eq!($get_val(iter.next().unwrap()), 2);
1865 assert_eq!($get_val(iter.next().unwrap()), 3);
1866 assert!(iter.next().is_none());
1867
1868 list.as_mut().clear();
1869 }
1870
1871 #[test]
1872 fn test_pop_back() {
1873 let mut factory = <$factory_type>::new();
1874 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1875 let obj1 = factory.create(1);
1876 let obj2 = factory.create(2);
1877
1878 $push(list.as_mut(), obj1);
1879 $push(list.as_mut(), obj2);
1880
1881 let p1 = list.as_mut().pop_back();
1882 assert!(p1.is_some());
1883 let p2 = list.as_mut().pop_back();
1884 assert!(p2.is_some());
1885 assert!(list.as_mut().pop_back().is_none());
1886 }
1887
1888 #[test]
1889 fn test_erase() {
1890 let mut factory = <$factory_type>::new();
1891 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1892 let obj1 = factory.create(1);
1893 let obj2 = factory.create(2);
1894 let obj3 = factory.create(3);
1895
1896 $push(list.as_mut(), obj1);
1897 $push(list.as_mut(), obj2);
1898 $push(list.as_mut(), obj3);
1899
1900 let mut cursor = list.as_mut().cursor_front_mut();
1901 cursor.move_next();
1902 let erased = cursor.erase();
1903 assert!(erased.is_some());
1904 factory.cleanup(erased.unwrap());
1905
1906 let mut iter = list.iter();
1907 assert!(iter.next().is_some());
1908 assert!(iter.next().is_some());
1909 assert!(iter.next().is_none());
1910
1911 list.as_mut().clear();
1912 }
1913
1914 #[test]
1915 fn test_erase_if() {
1916 let mut factory = <$factory_type>::new();
1917 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1918 let obj1 = factory.create(1);
1919 let obj2 = factory.create(2);
1920 let obj3 = factory.create(3);
1921
1922 $push(list.as_mut(), obj1);
1923 $push(list.as_mut(), obj2);
1924 $push(list.as_mut(), obj3);
1925
1926 let erased = list.as_mut().erase_if(|o| o.value == 2);
1927 assert!(erased.is_some());
1928 assert_eq!($get_val(erased.unwrap().get_ref()), 2);
1929
1930 let mut iter = list.iter();
1931 assert_eq!($get_val(iter.next().unwrap()), 3);
1932 assert_eq!($get_val(iter.next().unwrap()), 1);
1933 assert!(iter.next().is_none());
1934
1935 list.as_mut().clear();
1936 }
1937
1938 #[test]
1939 fn test_find_if() {
1940 let mut factory = <$factory_type>::new();
1941 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1942 let obj1 = factory.create(1);
1943 let obj2 = factory.create(2);
1944
1945 $push(list.as_mut(), obj1);
1946 $push(list.as_mut(), obj2);
1947
1948 let found = list.find_if(|o| o.value == 1);
1949 assert!(found.is_some());
1950 assert_eq!(found.unwrap().value, 1);
1951
1952 let found = list.find_if(|o| o.value == 3);
1953 assert!(found.is_none());
1954
1955 list.as_mut().clear();
1956 }
1957
1958 #[test]
1959 fn test_complete_reverse_iteration() {
1960 let mut factory = <$factory_type>::new();
1961 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1962 let obj1 = factory.create(1);
1963 let obj2 = factory.create(2);
1964 let obj3 = factory.create(3);
1965
1966 $push(list.as_mut(), obj1);
1967 $push(list.as_mut(), obj2);
1968 $push(list.as_mut(), obj3);
1969
1970 let (a, b, c) = {
1971 let mut iter = list.iter();
1972 (
1973 $get_val(iter.next().unwrap()),
1974 $get_val(iter.next().unwrap()),
1975 $get_val(iter.next().unwrap()),
1976 )
1977 };
1978
1979 let mut iter = list.iter();
1980 assert_eq!($get_val(iter.next_back().unwrap()), c);
1981 assert_eq!($get_val(iter.next_back().unwrap()), b);
1982 assert_eq!($get_val(iter.next_back().unwrap()), a);
1983 assert!(iter.next_back().is_none());
1984
1985 list.as_mut().clear();
1986 }
1987
1988 #[test]
1989 fn test_split_after() {
1990 let mut factory = <$factory_type>::new();
1991 stack_pin_init!(let list1 = DoublyLinkedList::<$ptr_type>::new());
1992 stack_pin_init!(let list2 = DoublyLinkedList::<$ptr_type>::new());
1993
1994 let obj1 = factory.create(1);
1995 let obj2 = factory.create(2);
1996 let obj3 = factory.create(3);
1997 let obj4 = factory.create(4);
1998
1999 $push(list1.as_mut(), obj4);
2000 $push(list1.as_mut(), obj3);
2001 $push(list1.as_mut(), obj2);
2002 $push(list1.as_mut(), obj1);
2003
2004 let mut cursor = list1.as_mut().cursor_front_mut();
2005 cursor.move_next(); let mut dest_cursor = list2.as_mut().cursor_back_mut();
2008 cursor.split_after(&mut dest_cursor);
2009
2010 let mut iter1 = list1.iter();
2011 assert_eq!($get_val(iter1.next().unwrap()), 1);
2012 assert_eq!($get_val(iter1.next().unwrap()), 2);
2013 assert!(iter1.next().is_none());
2014
2015 let mut iter2 = list2.iter();
2016 assert_eq!($get_val(iter2.next().unwrap()), 3);
2017 assert_eq!($get_val(iter2.next().unwrap()), 4);
2018 assert!(iter2.next().is_none());
2019
2020 list1.as_mut().clear();
2021 list2.as_mut().clear();
2022 }
2023
2024 #[test]
2025 fn test_split_before() {
2026 let mut factory = <$factory_type>::new();
2027 stack_pin_init!(let list1 = DoublyLinkedList::<$ptr_type>::new());
2028 stack_pin_init!(let list2 = DoublyLinkedList::<$ptr_type>::new());
2029
2030 let obj1 = factory.create(1);
2031 let obj2 = factory.create(2);
2032 let obj3 = factory.create(3);
2033 let obj4 = factory.create(4);
2034
2035 $push(list1.as_mut(), obj4);
2036 $push(list1.as_mut(), obj3);
2037 $push(list1.as_mut(), obj2);
2038 $push(list1.as_mut(), obj1);
2039
2040 let mut cursor = list1.as_mut().cursor_front_mut();
2041 cursor.move_next();
2042 cursor.move_next(); let mut dest_cursor = list2.as_mut().cursor_back_mut();
2045 cursor.split_before(&mut dest_cursor);
2046
2047 let mut iter2 = list2.iter();
2049 assert_eq!($get_val(iter2.next().unwrap()), 1);
2050 assert_eq!($get_val(iter2.next().unwrap()), 2);
2051 assert!(iter2.next().is_none());
2052
2053 let mut iter1 = list1.iter();
2055 assert_eq!($get_val(iter1.next().unwrap()), 3);
2056 assert_eq!($get_val(iter1.next().unwrap()), 4);
2057 assert!(iter1.next().is_none());
2058
2059 list1.as_mut().clear();
2060 list2.as_mut().clear();
2061 }
2062 }
2063 };
2064 }
2065
2066 generate_list_tests!(
2067 raw_ptr_tests,
2068 *mut TestObject,
2069 RawFactory<TestObject>,
2070 |p: &TestObject| p.value,
2071 |list: Pin<&mut DoublyLinkedList<*mut TestObject>>, obj| {
2072 unsafe { list.push_front_raw(obj) };
2074 }
2075 );
2076
2077 generate_list_tests!(
2078 unique_ptr_tests,
2079 UniquePtr<UniqueTestObject>,
2080 UniqueFactory<UniqueTestObject>,
2081 |p: &UniqueTestObject| p.value,
2082 |list: Pin<&mut DoublyLinkedList<UniquePtr<UniqueTestObject>>>, obj| list.push_front(obj)
2083 );
2084
2085 generate_list_tests!(
2086 ref_ptr_tests,
2087 RefPtr<RefTestObject>,
2088 RefFactory<RefTestObject>,
2089 |p: &RefTestObject| p.value,
2090 |list: Pin<&mut DoublyLinkedList<RefPtr<RefTestObject>>>, obj| list.push_front(obj)
2091 );
2092
2093 #[test]
2094 fn test_tracking_size() {
2095 stack_pin_init!(let list =
2096 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2097
2098 assert_eq!(list.len(), 0);
2099 list.as_mut().push_front(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2100 assert_eq!(list.len(), 1);
2101 list.as_mut().push_front(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2102 assert_eq!(list.len(), 2);
2103 list.as_mut().pop_front();
2104 assert_eq!(list.len(), 1);
2105 list.as_mut().clear();
2106 assert_eq!(list.len(), 0);
2107 }
2108
2109 #[test]
2110 fn test_insert_before() {
2111 stack_pin_init!(let list =
2112 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2113
2114 let mut cursor = list.as_mut().cursor_front_mut();
2115 cursor.insert_before(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2116 assert_eq!(list.len(), 1);
2117 assert_eq!(list.front().unwrap().value, 1);
2118
2119 let mut cursor = list.as_mut().cursor_front_mut();
2120 cursor.insert_before(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2121 assert_eq!(list.len(), 2);
2122 assert_eq!(list.front().unwrap().value, 2);
2123
2124 let mut cursor = list.as_mut().cursor_front_mut();
2125 cursor.move_next(); cursor.insert_before(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2127 assert_eq!(list.len(), 3);
2128
2129 let mut cursor = list.as_mut().cursor_front_mut();
2130 while cursor.get().unwrap().value != 1 {
2131 cursor.move_next();
2132 }
2133 cursor.move_next(); cursor.insert_before(UniquePtr::try_new(UniqueTestObject::new(4)).unwrap());
2135 assert_eq!(list.len(), 4);
2136
2137 let mut iter = list.iter();
2138 assert_eq!(iter.next().unwrap().value, 2);
2139 assert_eq!(iter.next().unwrap().value, 3);
2140 assert_eq!(iter.next().unwrap().value, 1);
2141 assert_eq!(iter.next().unwrap().value, 4);
2142 assert!(iter.next().is_none());
2143
2144 list.as_mut().clear();
2145 }
2146
2147 #[test]
2148 fn test_front_mut_and_back_mut() {
2149 stack_pin_init!(let list =
2150 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2151
2152 assert!(list.as_mut().front_mut().is_none());
2153 assert!(list.as_mut().back_mut().is_none());
2154
2155 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2157 *list.as_mut().front_mut().unwrap().project().value = 2;
2158 assert_eq!(list.as_mut().back_mut().unwrap().value, 2);
2159 *list.as_mut().back_mut().unwrap().project().value = 3;
2160 assert_eq!(list.as_mut().front_mut().unwrap().value, 3);
2161 assert_eq!(list.front().unwrap().value, 3);
2162 assert_eq!(list.back().unwrap().value, 3);
2163 assert_eq!(list.as_mut().pop_front().unwrap().value, 3);
2164 assert!(list.is_empty());
2165
2166 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(10)).unwrap());
2167 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(20)).unwrap());
2168
2169 assert_eq!(list.as_mut().front_mut().unwrap().value, 10);
2170 assert_eq!(list.as_mut().back_mut().unwrap().value, 20);
2171
2172 *list.as_mut().front_mut().unwrap().project().value = 100;
2173 *list.as_mut().back_mut().unwrap().project().value = 200;
2174
2175 assert_eq!(list.front().unwrap().value, 100);
2176 assert_eq!(list.back().unwrap().value, 200);
2177
2178 list.as_mut().clear();
2179 }
2180
2181 macro_rules! assert_not_impl {
2185 ($t:ty: $($trait:tt)+) => {
2186 const _: fn() = || {
2187 trait AmbiguousIfImpl<A> {
2188 fn some_item() {}
2189 }
2190 impl<T: ?Sized> AmbiguousIfImpl<()> for T {}
2191 enum Invalid {}
2192 impl<T: ?Sized + $($trait)+> AmbiguousIfImpl<Invalid> for T {}
2193 let _ = <$t as AmbiguousIfImpl<_>>::some_item;
2194 };
2195 };
2196 }
2197
2198 assert_not_impl!(DoublyLinkedListNode<TestObject>: Unpin);
2200 assert_not_impl!(TestObject: Unpin);
2201 assert_not_impl!(UniqueTestObject: Unpin);
2202 assert_not_impl!(RefTestObject: Unpin);
2203 assert_not_impl!(DoublyLinkedList<*mut TestObject>: Unpin);
2205 assert_not_impl!(RefPtr<RefTestObject>: MutPtr);
2207
2208 #[test]
2209 fn test_iter_mut() {
2210 stack_pin_init!(let list =
2211 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2212
2213 assert!(list.as_mut().iter_mut().next().is_none());
2214 assert!(list.as_mut().iter_mut().next_back().is_none());
2215
2216 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(7)).unwrap());
2218 {
2219 let mut iter = list.as_mut().iter_mut();
2220 let only = iter.next_back().unwrap();
2221 assert_eq!(only.value, 7);
2222 *only.project().value = 8;
2223 assert!(iter.next_back().is_none());
2224 assert!(iter.next().is_none());
2225 }
2226 {
2227 let mut iter = list.as_mut().iter_mut();
2228 assert_eq!(iter.next().unwrap().value, 8);
2229 assert!(iter.next().is_none());
2230 assert!(iter.next_back().is_none());
2231 }
2232 assert_eq!(list.as_mut().pop_front().unwrap().value, 8);
2233 assert!(list.is_empty());
2234
2235 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2236 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2237 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2238
2239 for obj in list.as_mut().iter_mut() {
2240 *obj.project().value *= 10;
2241 }
2242
2243 let mut iter = list.as_mut().iter_mut();
2244 assert_eq!(iter.next().unwrap().value, 10);
2245 let mut last = iter.next_back().unwrap();
2246 assert_eq!(last.value, 30);
2247 *last.as_mut().project().value += 1;
2248 let mut middle = iter.next().unwrap();
2249 *middle.as_mut().project().value += 2;
2250 assert!(iter.next().is_none());
2251 assert!(iter.next_back().is_none());
2252
2253 let values: alloc::vec::Vec<i32> = list.iter().map(|o| o.value).collect();
2254 assert_eq!(values, [10, 22, 31]);
2255 assert_eq!(list.len(), 3);
2256
2257 {
2259 let mut items: alloc::vec::Vec<_> = list.as_mut().iter_mut().collect();
2260 assert_eq!(items.len(), 3);
2261 for item in items.iter_mut() {
2262 *item.as_mut().project().value += 1;
2263 }
2264 *items[0].as_mut().project().value += 100;
2265 *items[2].as_mut().project().value += 200;
2266 }
2267 let values: alloc::vec::Vec<i32> = list.iter().map(|o| o.value).collect();
2268 assert_eq!(values, [111, 23, 232]);
2269
2270 list.as_mut().clear();
2271 assert!(list.is_empty());
2272
2273 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2276 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2277 {
2278 let mut iter = list.as_mut().iter_mut();
2279 let mut first = iter.next().unwrap();
2280 *first.as_mut().project().value = 10;
2281 let mut second = iter.next_back().unwrap();
2282 *first.as_mut().project().value = 11;
2283 *second.as_mut().project().value = 20;
2284 assert!(iter.next().is_none());
2285 assert!(iter.next_back().is_none());
2286 assert_eq!(first.value, 11);
2287 assert_eq!(second.value, 20);
2288 }
2289 let values: alloc::vec::Vec<i32> = list.iter().map(|o| o.value).collect();
2290 assert_eq!(values, [11, 20]);
2291
2292 {
2294 let mut iter = list.as_mut().iter_mut();
2295 let mut last = iter.next_back().unwrap();
2296 *last.as_mut().project().value = 21;
2297 let mut first = iter.next().unwrap();
2298 *last.as_mut().project().value = 22;
2299 *first.as_mut().project().value = 12;
2300 assert!(iter.next().is_none());
2301 assert!(iter.next_back().is_none());
2302 }
2303 let values: alloc::vec::Vec<i32> = list.iter().map(|o| o.value).collect();
2304 assert_eq!(values, [12, 22]);
2305
2306 list.as_mut().clear();
2307 }
2308
2309 #[test]
2310 fn test_forward_and_reverse_iter_mut() {
2311 stack_pin_init!(let list = DoublyLinkedList::<UniquePtr<UniqueTestObject>>::new());
2312
2313 assert!(list.as_mut().forward_iter_mut().next().is_none());
2314 assert!(list.as_mut().reverse_iter_mut().next().is_none());
2315
2316 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(5)).unwrap());
2318 {
2319 let mut r_iter = list.as_mut().reverse_iter_mut();
2320 let only = r_iter.next().unwrap();
2321 assert_eq!(only.value, 5);
2322 *only.project().value = 6;
2323 assert!(r_iter.next().is_none());
2324 }
2325 {
2326 let mut f_iter = list.as_mut().forward_iter_mut();
2327 assert_eq!(f_iter.next().unwrap().value, 6);
2328 assert!(f_iter.next().is_none());
2329 }
2330 assert_eq!(list.as_mut().pop_front().unwrap().value, 6);
2331 assert!(list.is_empty());
2332
2333 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2334 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2335 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2336
2337 for obj in list.as_mut().forward_iter_mut() {
2339 *obj.project().value += 10;
2340 }
2341 let values: alloc::vec::Vec<i32> = list.iter().map(|o| o.value).collect();
2342 assert_eq!(values, [11, 12, 13]);
2343
2344 let mut visited = alloc::vec::Vec::new();
2346 for obj in list.as_mut().reverse_iter_mut() {
2347 visited.push(obj.value);
2348 *obj.project().value *= 2;
2349 }
2350 assert_eq!(visited, [13, 12, 11]);
2351 let values: alloc::vec::Vec<i32> = list.iter().map(|o| o.value).collect();
2352 assert_eq!(values, [22, 24, 26]);
2353
2354 {
2356 let mut items: alloc::vec::Vec<_> = list.as_mut().reverse_iter_mut().collect();
2357 assert_eq!(items.len(), 3);
2358 for item in items.iter_mut() {
2359 *item.as_mut().project().value += 1;
2360 }
2361 *items[0].as_mut().project().value += 100;
2364 *items[2].as_mut().project().value += 200;
2365 assert_eq!(items[0].value, 127);
2366 assert_eq!(items[1].value, 25);
2367 assert_eq!(items[2].value, 223);
2368 }
2369 let values: alloc::vec::Vec<i32> = list.iter().map(|o| o.value).collect();
2370 assert_eq!(values, [223, 25, 127]);
2371
2372 {
2374 let mut items: alloc::vec::Vec<_> = list.as_mut().forward_iter_mut().collect();
2375 assert_eq!(items.len(), 3);
2376 for item in items.iter_mut() {
2377 *item.as_mut().project().value -= 1;
2378 }
2379 *items[2].as_mut().project().value -= 100;
2380 *items[0].as_mut().project().value -= 200;
2381 }
2382 let values: alloc::vec::Vec<i32> = list.iter().map(|o| o.value).collect();
2383 assert_eq!(values, [22, 24, 26]);
2384
2385 list.as_mut().clear();
2386 }
2387
2388 #[test]
2389 fn test_iter_mut_raw_ptr() {
2390 stack_pin_init!(let list = DoublyLinkedList::<*mut TestObject>::new());
2391 let mut obj1 = TestObject::new(1);
2392 let mut obj2 = TestObject::new(2);
2393
2394 unsafe {
2396 list.as_mut().push_back_raw(&mut obj1);
2397 list.as_mut().push_back_raw(&mut obj2);
2398 }
2399
2400 for obj in list.as_mut().iter_mut() {
2401 *obj.project().value += 100;
2402 }
2403 *list.as_mut().front_mut().unwrap().project().value += 1;
2404 *list.as_mut().back_mut().unwrap().project().value += 2;
2405
2406 let values: alloc::vec::Vec<i32> = list.iter().map(|o| o.value).collect();
2407 assert_eq!(values, [102, 104]);
2408
2409 list.as_mut().clear();
2410 }
2411
2412 #[test]
2413 fn test_cursor_get_mut() {
2414 stack_pin_init!(let list =
2415 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2416
2417 assert!(list.as_mut().cursor_front_mut().get_mut().is_none());
2418
2419 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2420 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2421
2422 let mut cursor = list.as_mut().cursor_front_mut();
2423 *cursor.get_mut().unwrap().project().value = 10;
2424 cursor.move_next();
2425 assert_eq!(cursor.get_mut().unwrap().value, 2);
2426 *cursor.get_mut().unwrap().project().value = 20;
2427 cursor.move_next();
2428 assert!(cursor.get_mut().is_none()); let mut iter = list.iter();
2431 assert_eq!(iter.next().unwrap().value, 10);
2432 assert_eq!(iter.next().unwrap().value, 20);
2433 assert!(iter.next().is_none());
2434 assert_eq!(list.len(), 2);
2435
2436 list.as_mut().clear();
2437 }
2438
2439 #[test]
2440 fn test_cursor_front_and_back_mut() {
2441 stack_pin_init!(let list =
2442 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2443
2444 assert!(list.as_mut().cursor_front_mut().get().is_none());
2445 assert!(list.as_mut().cursor_back_mut().get().is_none());
2446
2447 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(10)).unwrap());
2448 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(20)).unwrap());
2449
2450 let mut front_cursor = list.as_mut().cursor_front_mut();
2451 assert_eq!(front_cursor.get().unwrap().value, 10);
2452 front_cursor.move_next();
2453 assert_eq!(front_cursor.get().unwrap().value, 20);
2454
2455 let mut back_cursor = list.as_mut().cursor_back_mut();
2456 assert!(back_cursor.get().is_none());
2457 back_cursor.move_prev();
2458 assert_eq!(back_cursor.get().unwrap().value, 20);
2459
2460 let mut back_cursor = list.as_mut().cursor_back_mut();
2461 back_cursor.insert_before(UniquePtr::try_new(UniqueTestObject::new(30)).unwrap());
2462 assert_eq!(list.len(), 3);
2463 assert_eq!(list.back().unwrap().value, 30);
2464
2465 list.as_mut().clear();
2466 }
2467
2468 #[test]
2469 fn test_splice_middle() {
2470 stack_pin_init!(let list1 =
2471 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2472 stack_pin_init!(let list2 =
2473 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2474
2475 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2476 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2477 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2478 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(4)).unwrap());
2479
2480 let mut cursor = list1.as_mut().cursor_front_mut();
2481 cursor.move_next(); cursor.splice(list2.as_mut());
2484
2485 assert!(list2.is_empty());
2486 assert_eq!(list1.len(), 4);
2487
2488 let mut iter = list1.iter();
2489 assert_eq!(iter.next().unwrap().value, 1);
2490 assert_eq!(iter.next().unwrap().value, 3);
2491 assert_eq!(iter.next().unwrap().value, 4);
2492 assert_eq!(iter.next().unwrap().value, 2);
2493 assert!(iter.next().is_none());
2494
2495 list1.as_mut().clear();
2496 }
2497
2498 #[test]
2499 fn test_splice_head() {
2500 stack_pin_init!(let list1 =
2501 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2502 stack_pin_init!(let list2 =
2503 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2504
2505 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2506 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2507 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2508 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(4)).unwrap());
2509
2510 let mut cursor = list1.as_mut().cursor_front_mut();
2511
2512 cursor.splice(list2.as_mut());
2513
2514 assert!(list2.is_empty());
2515 assert_eq!(list1.len(), 4);
2516
2517 let mut iter = list1.iter();
2518 assert_eq!(iter.next().unwrap().value, 3);
2519 assert_eq!(iter.next().unwrap().value, 4);
2520 assert_eq!(iter.next().unwrap().value, 1);
2521 assert_eq!(iter.next().unwrap().value, 2);
2522 assert!(iter.next().is_none());
2523
2524 list1.as_mut().clear();
2525 }
2526
2527 #[test]
2528 fn test_splice_tail() {
2529 stack_pin_init!(let list1 =
2530 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2531 stack_pin_init!(let list2 =
2532 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2533
2534 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2535 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2536 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2537 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(4)).unwrap());
2538
2539 let mut cursor = list1.as_mut().cursor_front_mut();
2540 cursor.move_next();
2541 cursor.move_next(); cursor.splice(list2.as_mut());
2544
2545 assert!(list2.is_empty());
2546 assert_eq!(list1.len(), 4);
2547
2548 let mut iter = list1.iter();
2549 assert_eq!(iter.next().unwrap().value, 1);
2550 assert_eq!(iter.next().unwrap().value, 2);
2551 assert_eq!(iter.next().unwrap().value, 3);
2552 assert_eq!(iter.next().unwrap().value, 4);
2553 assert!(iter.next().is_none());
2554
2555 list1.as_mut().clear();
2556 }
2557
2558 #[test]
2559 fn test_splice_empty() {
2560 stack_pin_init!(let list1 =
2561 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2562 stack_pin_init!(let list2 =
2563 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2564
2565 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2566 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2567
2568 let mut cursor = list1.as_mut().cursor_front_mut();
2569 cursor.splice(list2.as_mut());
2570
2571 assert!(list2.is_empty());
2572 assert_eq!(list1.len(), 2);
2573
2574 let mut iter = list1.iter();
2575 assert_eq!(iter.next().unwrap().value, 1);
2576 assert_eq!(iter.next().unwrap().value, 2);
2577 assert!(iter.next().is_none());
2578
2579 list1.as_mut().clear();
2580 }
2581
2582 #[test]
2583 fn test_splice_non_tracking() {
2584 stack_pin_init!(let list1 =
2585 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, NonTrackingSize>::new());
2586 stack_pin_init!(let list2 =
2587 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, NonTrackingSize>::new());
2588
2589 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2590 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2591 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2592 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(4)).unwrap());
2593
2594 let mut cursor = list1.as_mut().cursor_front_mut();
2595 cursor.move_next(); cursor.splice(list2.as_mut());
2598
2599 assert!(list2.is_empty());
2600
2601 let mut iter = list1.iter();
2602 assert_eq!(iter.next().unwrap().value, 1);
2603 assert_eq!(iter.next().unwrap().value, 3);
2604 assert_eq!(iter.next().unwrap().value, 4);
2605 assert_eq!(iter.next().unwrap().value, 2);
2606 assert!(iter.next().is_none());
2607
2608 list1.as_mut().clear();
2609 }
2610
2611 #[test]
2612 fn test_list_splice() {
2613 stack_pin_init!(let list1 =
2615 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2616 stack_pin_init!(let list2 =
2617 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2618
2619 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2620 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2621 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2622 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(4)).unwrap());
2623
2624 list1.as_mut().splice(list2.as_mut());
2625
2626 assert!(list2.is_empty());
2627 assert_eq!(list2.len(), 0);
2628 assert_eq!(list1.len(), 4);
2629
2630 let mut iter = list1.iter();
2631 assert_eq!(iter.next().unwrap().value, 1);
2632 assert_eq!(iter.next().unwrap().value, 2);
2633 assert_eq!(iter.next().unwrap().value, 3);
2634 assert_eq!(iter.next().unwrap().value, 4);
2635 assert!(iter.next().is_none());
2636
2637 stack_pin_init!(let list3 =
2639 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2640
2641 list3.as_mut().splice(list1.as_mut());
2642
2643 assert!(list1.is_empty());
2644 assert_eq!(list1.len(), 0);
2645 assert_eq!(list3.len(), 4);
2646
2647 let mut iter = list3.iter();
2648 assert_eq!(iter.next().unwrap().value, 1);
2649 assert_eq!(iter.next().unwrap().value, 2);
2650 assert_eq!(iter.next().unwrap().value, 3);
2651 assert_eq!(iter.next().unwrap().value, 4);
2652 assert!(iter.next().is_none());
2653
2654 list3.as_mut().splice(list1.as_mut());
2656 assert_eq!(list3.len(), 4);
2657 assert!(list1.is_empty());
2658
2659 list3.as_mut().clear();
2660 }
2661
2662 #[test]
2663 fn test_split_after_at_tail() {
2664 stack_pin_init!(let list1 =
2665 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2666 stack_pin_init!(let list2 =
2667 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2668
2669 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2670 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2671
2672 let mut cursor = list1.as_mut().cursor_front_mut();
2673 cursor.move_next(); let mut dest_cursor = list2.as_mut().cursor_back_mut();
2676 cursor.split_after(&mut dest_cursor);
2677
2678 assert!(list2.is_empty());
2679 assert_eq!(list2.len(), 0);
2680 assert_eq!(list1.len(), 2);
2681
2682 list1.as_mut().clear();
2683 }
2684
2685 #[test]
2686 fn test_split_after_at_head() {
2687 stack_pin_init!(let list1 =
2688 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2689 stack_pin_init!(let list2 =
2690 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2691
2692 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2693 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2694 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2695
2696 let mut cursor = list1.as_mut().cursor_front_mut(); let mut dest_cursor = list2.as_mut().cursor_back_mut();
2699 cursor.split_after(&mut dest_cursor);
2700
2701 assert_eq!(list1.len(), 1);
2702 assert_eq!(list2.len(), 2);
2703
2704 let mut iter1 = list1.iter();
2705 assert_eq!(iter1.next().unwrap().value, 1);
2706 assert!(iter1.next().is_none());
2707
2708 let mut iter2 = list2.iter();
2709 assert_eq!(iter2.next().unwrap().value, 2);
2710 assert_eq!(iter2.next().unwrap().value, 3);
2711 assert!(iter2.next().is_none());
2712
2713 list1.as_mut().clear();
2714 list2.as_mut().clear();
2715 }
2716
2717 #[test]
2718 fn test_split_before_at_head() {
2719 stack_pin_init!(let list1 =
2720 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2721 stack_pin_init!(let list2 =
2722 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2723
2724 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2725 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2726
2727 let mut cursor = list1.as_mut().cursor_front_mut(); let mut dest_cursor = list2.as_mut().cursor_back_mut();
2730 cursor.split_before(&mut dest_cursor);
2731
2732 assert!(list2.is_empty());
2733 assert_eq!(list2.len(), 0);
2734 assert_eq!(list1.len(), 2);
2735
2736 list1.as_mut().clear();
2737 }
2738
2739 #[test]
2740 fn test_split_before_at_tail() {
2741 stack_pin_init!(let list1 =
2742 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2743 stack_pin_init!(let list2 =
2744 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2745
2746 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2747 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2748 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2749
2750 let mut cursor = list1.as_mut().cursor_front_mut();
2751 cursor.move_next();
2752 cursor.move_next(); let mut dest_cursor = list2.as_mut().cursor_back_mut();
2755 cursor.split_before(&mut dest_cursor);
2756
2757 assert_eq!(list2.len(), 2);
2758 assert_eq!(list1.len(), 1);
2759
2760 let mut iter2 = list2.iter();
2761 assert_eq!(iter2.next().unwrap().value, 1);
2762 assert_eq!(iter2.next().unwrap().value, 2);
2763 assert!(iter2.next().is_none());
2764
2765 let mut iter1 = list1.iter();
2766 assert_eq!(iter1.next().unwrap().value, 3);
2767 assert!(iter1.next().is_none());
2768
2769 list1.as_mut().clear();
2770 list2.as_mut().clear();
2771 }
2772
2773 #[test]
2774 fn test_split_before_at_sentinel() {
2775 stack_pin_init!(let list1 =
2776 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2777 stack_pin_init!(let list2 =
2778 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2779
2780 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2781 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2782
2783 let mut cursor = list1.as_mut().cursor_back_mut(); let mut dest_cursor = list2.as_mut().cursor_back_mut();
2786 cursor.split_before(&mut dest_cursor);
2787
2788 assert!(list1.is_empty());
2789 assert_eq!(list1.len(), 0);
2790 assert_eq!(list2.len(), 2);
2791
2792 let mut iter2 = list2.iter();
2793 assert_eq!(iter2.next().unwrap().value, 1);
2794 assert_eq!(iter2.next().unwrap().value, 2);
2795 assert!(iter2.next().is_none());
2796
2797 list2.as_mut().clear();
2798 }
2799
2800 #[test]
2801 fn test_split_into_middle_of_dest_list() {
2802 stack_pin_init!(let list1 =
2803 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2804 stack_pin_init!(let list2 =
2805 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2806
2807 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2808 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2809 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2810 list1.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(4)).unwrap());
2811
2812 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(10)).unwrap());
2813 list2.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(20)).unwrap());
2814
2815 let mut cursor1 = list1.as_mut().cursor_front_mut();
2817 cursor1.move_next(); let mut cursor2 = list2.as_mut().cursor_front_mut();
2820 cursor2.move_next(); cursor1.split_after(&mut cursor2);
2823
2824 assert_eq!(list1.len(), 2);
2826 let mut iter1 = list1.iter();
2827 assert_eq!(iter1.next().unwrap().value, 1);
2828 assert_eq!(iter1.next().unwrap().value, 2);
2829 assert!(iter1.next().is_none());
2830
2831 assert_eq!(list2.len(), 4);
2833 let mut iter2 = list2.iter();
2834 assert_eq!(iter2.next().unwrap().value, 10);
2835 assert_eq!(iter2.next().unwrap().value, 3);
2836 assert_eq!(iter2.next().unwrap().value, 4);
2837 assert_eq!(iter2.next().unwrap().value, 20);
2838 assert!(iter2.next().is_none());
2839
2840 list1.as_mut().clear();
2841 list2.as_mut().clear();
2842 }
2843
2844 #[test]
2845 fn test_list_split_methods() {
2846 let mut obj1 = TestObject::new(1);
2847 let mut obj2 = TestObject::new(2);
2848 let mut obj3 = TestObject::new(3);
2849
2850 stack_pin_init!(let list1 = DoublyLinkedList::<*mut TestObject>::new());
2851 stack_pin_init!(let list2 = DoublyLinkedList::<*mut TestObject>::new());
2852
2853 unsafe {
2854 list1.as_mut().push_back_raw(&mut obj1);
2855 list1.as_mut().push_back_raw(&mut obj2);
2856 list1.as_mut().push_back_raw(&mut obj3);
2857
2858 let mut cursor1 = list1.as_mut().cursor_at(&obj1);
2860 let mut cursor2 = list2.as_mut().cursor_back_mut();
2861 cursor1.split_after(&mut cursor2);
2862
2863 assert_eq!(list1.iter().count(), 1);
2864 assert_eq!(list2.iter().count(), 2);
2865
2866 let mut iter1 = list1.iter();
2867 assert_eq!(iter1.next().unwrap().value, 1);
2868 assert!(iter1.next().is_none());
2869
2870 let mut iter2 = list2.iter();
2871 assert_eq!(iter2.next().unwrap().value, 2);
2872 assert_eq!(iter2.next().unwrap().value, 3);
2873 assert!(iter2.next().is_none());
2874
2875 list1.as_mut().splice(list2.as_mut());
2877 assert_eq!(list1.iter().count(), 3);
2878
2879 let mut cursor1 = list1.as_mut().cursor_at(&obj3);
2881 let mut cursor2 = list2.as_mut().cursor_back_mut();
2882 cursor1.split_before(&mut cursor2);
2883
2884 assert_eq!(list2.iter().count(), 2);
2885 assert_eq!(list1.iter().count(), 1);
2886
2887 let mut iter2 = list2.iter();
2888 assert_eq!(iter2.next().unwrap().value, 1);
2889 assert_eq!(iter2.next().unwrap().value, 2);
2890 assert!(iter2.next().is_none());
2891
2892 let mut iter1 = list1.iter();
2893 assert_eq!(iter1.next().unwrap().value, 3);
2894 assert!(iter1.next().is_none());
2895
2896 list1.as_mut().clear();
2897 list2.as_mut().clear();
2898 }
2899 }
2900
2901 #[test]
2902 fn test_cursor_get() {
2903 stack_pin_init!(let list = DoublyLinkedList::<UniquePtr<UniqueTestObject>>::new());
2904
2905 let cursor = list.as_mut().cursor_front_mut();
2906 assert!(cursor.get().is_none());
2907
2908 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(42)).unwrap());
2909
2910 let mut cursor = list.as_mut().cursor_front_mut();
2911 assert!(cursor.get().is_some());
2912 assert_eq!(cursor.get().unwrap().value, 42);
2913
2914 cursor.move_next();
2915 assert!(cursor.get().is_none());
2916
2917 list.as_mut().clear();
2918 }
2919
2920 #[test]
2921 fn test_pop_back() {
2922 stack_pin_init!(let list =
2923 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2924
2925 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2926 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2927
2928 assert_eq!(list.len(), 2);
2929 let popped = list.as_mut().pop_back();
2930 assert!(popped.is_some());
2931 assert_eq!(popped.unwrap().value, 2);
2932 assert_eq!(list.len(), 1);
2933
2934 let popped = list.as_mut().pop_back();
2935 assert!(popped.is_some());
2936 assert_eq!(popped.unwrap().value, 1);
2937 assert_eq!(list.len(), 0);
2938
2939 assert!(list.as_mut().pop_back().is_none());
2940 }
2941
2942 #[test]
2943 fn test_erase() {
2944 stack_pin_init!(let list =
2945 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2946
2947 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2948 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2949 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2950
2951 assert_eq!(list.len(), 3);
2952
2953 let mut cursor = list.as_mut().cursor_front_mut();
2955 cursor.move_next(); let erased = cursor.erase();
2957 assert!(erased.is_some());
2958 assert_eq!(erased.unwrap().value, 2);
2959 assert_eq!(list.len(), 2);
2960
2961 let mut iter = list.iter();
2962 assert_eq!(iter.next().unwrap().value, 1);
2963 assert_eq!(iter.next().unwrap().value, 3);
2964 assert!(iter.next().is_none());
2965
2966 let mut cursor = list.as_mut().cursor_front_mut();
2968 let erased = cursor.erase(); assert!(erased.is_some());
2970 assert_eq!(erased.unwrap().value, 1);
2971 assert_eq!(list.len(), 1);
2972 assert_eq!(list.front().unwrap().value, 3); let mut cursor = list.as_mut().cursor_front_mut();
2976 let erased = cursor.erase(); assert!(erased.is_some());
2978 assert_eq!(erased.unwrap().value, 3);
2979 assert_eq!(list.len(), 0);
2980 assert!(list.is_empty());
2981
2982 list.as_mut().clear();
2983 }
2984
2985 #[test]
2986 fn test_erase_if() {
2987 stack_pin_init!(let list =
2988 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2989
2990 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2991 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2992 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2993
2994 let erased = list.as_mut().erase_if(|obj| obj.value % 2 == 0);
2995 assert!(erased.is_some());
2996 assert_eq!(erased.unwrap().value, 2);
2997
2998 assert_eq!(list.len(), 2);
2999 let mut iter = list.iter();
3000 assert_eq!(iter.next().unwrap().value, 1);
3001 assert_eq!(iter.next().unwrap().value, 3);
3002 assert!(iter.next().is_none());
3003
3004 list.as_mut().clear();
3005 }
3006
3007 #[test]
3008 fn test_erase_by_reference() {
3009 stack_pin_init!(let list =
3010 DoublyLinkedList::<*mut TestObject, DefaultObjectTag, TrackingSize>::new());
3011 let mut obj1 = TestObject::new(1);
3012 let mut obj2 = TestObject::new(2);
3013 let mut obj3 = TestObject::new(3);
3014
3015 unsafe {
3016 list.as_mut().push_back_raw(&mut obj1);
3017 list.as_mut().push_back_raw(&mut obj2);
3018 list.as_mut().push_back_raw(&mut obj3);
3019 }
3020
3021 assert_eq!(list.len(), 3);
3022
3023 let erased = unsafe { list.as_mut().erase(&obj2) };
3025 assert!(erased.is_some());
3026 assert_eq!(unsafe { &*erased.unwrap() }.value, 2);
3027 assert_eq!(list.len(), 2);
3028
3029 let mut iter = list.iter();
3030 assert_eq!(iter.next().unwrap().value, 1);
3031 assert_eq!(iter.next().unwrap().value, 3);
3032 assert!(iter.next().is_none());
3033
3034 list.as_mut().clear();
3035 }
3036
3037 #[test]
3038 fn test_remove_from_container() {
3039 stack_pin_init!(let list = DoublyLinkedList::<*mut TestObject>::new());
3040 let mut obj1 = TestObject::new(1);
3041 let mut obj2 = TestObject::new(2);
3042 let mut obj3 = TestObject::new(3);
3043
3044 let removed = unsafe {
3046 remove_from_container::<TestObject, DefaultObjectTag, *mut TestObject>(&obj1)
3047 };
3048 assert!(removed.is_none());
3049
3050 unsafe {
3051 list.as_mut().push_back_raw(&mut obj1);
3052 list.as_mut().push_back_raw(&mut obj2);
3053 list.as_mut().push_back_raw(&mut obj3);
3054 }
3055
3056 let removed = unsafe {
3058 remove_from_container::<TestObject, DefaultObjectTag, *mut TestObject>(&obj2)
3059 };
3060 assert!(removed.is_some());
3061 assert_eq!(unsafe { &*removed.unwrap() }.value, 2);
3062
3063 let mut iter = list.iter();
3064 assert_eq!(iter.next().unwrap().value, 1);
3065 assert_eq!(iter.next().unwrap().value, 3);
3066 assert!(iter.next().is_none());
3067
3068 let removed = unsafe {
3070 remove_from_container::<TestObject, DefaultObjectTag, *mut TestObject>(&obj1)
3071 };
3072 assert!(removed.is_some());
3073 assert_eq!(unsafe { &*removed.unwrap() }.value, 1);
3074
3075 let mut iter = list.iter();
3076 assert_eq!(iter.next().unwrap().value, 3);
3077 assert!(iter.next().is_none());
3078
3079 let removed = unsafe {
3081 remove_from_container::<TestObject, DefaultObjectTag, *mut TestObject>(&obj3)
3082 };
3083 assert!(removed.is_some());
3084 assert_eq!(unsafe { &*removed.unwrap() }.value, 3);
3085 assert!(list.is_empty());
3086
3087 list.as_mut().clear();
3088 }
3089
3090 #[test]
3091 fn test_replace() {
3092 stack_pin_init!(let list =
3093 DoublyLinkedList::<*mut TestObject, DefaultObjectTag, TrackingSize>::new());
3094 let mut obj1 = TestObject::new(1);
3095 let mut obj2 = TestObject::new(2);
3096 let mut obj3 = TestObject::new(3);
3097
3098 unsafe {
3099 list.as_mut().push_back_raw(&mut obj1);
3100 list.as_mut().push_back_raw(&mut obj2);
3101 }
3102
3103 assert_eq!(list.len(), 2);
3104
3105 let old = unsafe { list.as_mut().replace_raw(&obj2, &mut obj3) };
3106 assert!(old.is_some());
3107 assert_eq!(unsafe { &*old.unwrap() }.value, 2);
3108 assert_eq!(list.len(), 2);
3109
3110 let mut iter = list.iter();
3111 assert_eq!(iter.next().unwrap().value, 1);
3112 assert_eq!(iter.next().unwrap().value, 3);
3113 assert!(iter.next().is_none());
3114
3115 list.as_mut().clear();
3116 }
3117
3118 #[test]
3119 fn test_cursor_replace() {
3120 stack_pin_init!(let list = DoublyLinkedList::<UniquePtr<UniqueTestObject>>::new());
3121
3122 let obj1 = UniquePtr::try_new(UniqueTestObject::new(1)).unwrap();
3123 let obj2 = UniquePtr::try_new(UniqueTestObject::new(2)).unwrap();
3124 let obj3 = UniquePtr::try_new(UniqueTestObject::new(3)).unwrap();
3125
3126 list.as_mut().push_back(obj1);
3127 list.as_mut().push_back(obj2);
3128
3129 let mut cursor = list.as_mut().cursor_front_mut();
3130 cursor.move_next(); let old = cursor.replace(obj3);
3133 assert!(old.is_some());
3134 assert_eq!(old.unwrap().value, 2);
3135
3136 let mut iter = list.iter();
3137 assert_eq!(iter.next().unwrap().value, 1);
3138 assert_eq!(iter.next().unwrap().value, 3);
3139 assert!(iter.next().is_none());
3140
3141 list.as_mut().clear();
3142 }
3143
3144 struct Tag2;
3145
3146 #[fbl::ref_counted]
3147 #[derive(crate::DoublyLinkedListContainable, crate::Recyclable)]
3148 #[repr(C)]
3149 struct MultiListObject {
3150 value: i32,
3151 #[dll_node]
3152 node1: DoublyLinkedListNode<MultiListObject>,
3153 #[dll_node(tag = Tag2)]
3154 node2: DoublyLinkedListNode<MultiListObject>,
3155 }
3156
3157 #[test]
3158 fn test_multiple_containers() {
3159 stack_pin_init!(let list1 =
3160 DoublyLinkedList::<RefPtr<MultiListObject>, DefaultObjectTag>::new());
3161 stack_pin_init!(let list2 = DoublyLinkedList::<RefPtr<MultiListObject>, Tag2>::new());
3162
3163 let obj1 = fbl::make_ref_counted!(MultiListObject {
3164 value: 1,
3165 node1: DoublyLinkedListNode::new(),
3166 node2: DoublyLinkedListNode::new(),
3167 })
3168 .unwrap();
3169
3170 let obj2 = fbl::make_ref_counted!(MultiListObject {
3171 value: 2,
3172 node1: DoublyLinkedListNode::new(),
3173 node2: DoublyLinkedListNode::new(),
3174 })
3175 .unwrap();
3176
3177 list1.as_mut().push_back(obj1.clone());
3178 list1.as_mut().push_back(obj2.clone());
3179
3180 list2.as_mut().push_back(obj2); let mut iter1 = list1.iter();
3183 assert_eq!(iter1.next().unwrap().value, 1);
3184 assert_eq!(iter1.next().unwrap().value, 2);
3185 assert!(iter1.next().is_none());
3186
3187 let mut iter2 = list2.iter();
3188 assert_eq!(iter2.next().unwrap().value, 2);
3189 assert!(iter2.next().is_none());
3190
3191 list1.as_mut().clear();
3192 list2.as_mut().clear();
3193 }
3194
3195 use alloc::sync::Arc;
3196 use core::sync::atomic::{AtomicBool, Ordering};
3197
3198 #[derive(crate::DoublyLinkedListContainable, crate::Recyclable)]
3199 struct LifecycleObject {
3200 destroyed: Arc<AtomicBool>,
3201 #[dll_node]
3202 node: DoublyLinkedListNode<LifecycleObject>,
3203 }
3204
3205 impl LifecycleObject {
3206 fn new(destroyed: Arc<AtomicBool>) -> Self {
3207 Self { destroyed, node: DoublyLinkedListNode::new() }
3208 }
3209 }
3210
3211 impl Drop for LifecycleObject {
3212 fn drop(&mut self) {
3213 self.destroyed.store(true, Ordering::Relaxed);
3214 }
3215 }
3216
3217 #[test]
3218 fn test_lifecycle_on_drop() {
3219 let destroyed1 = Arc::new(AtomicBool::new(false));
3220 let destroyed2 = Arc::new(AtomicBool::new(false));
3221
3222 {
3223 stack_pin_init!(let list = DoublyLinkedList::<UniquePtr<LifecycleObject>>::new());
3224
3225 let obj1 = UniquePtr::try_new(LifecycleObject::new(destroyed1.clone())).unwrap();
3226 let obj2 = UniquePtr::try_new(LifecycleObject::new(destroyed2.clone())).unwrap();
3227
3228 list.as_mut().push_back(obj1);
3229 list.as_mut().push_back(obj2);
3230
3231 assert!(!destroyed1.load(Ordering::Relaxed));
3232 assert!(!destroyed2.load(Ordering::Relaxed));
3233 } assert!(destroyed1.load(Ordering::Relaxed));
3236 assert!(destroyed2.load(Ordering::Relaxed));
3237 }
3238
3239 #[test]
3240 fn test_sized_managed_list() {
3241 stack_pin_init!(let list =
3242 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
3243
3244 assert_eq!(list.len(), 0);
3245
3246 let obj1 = UniquePtr::try_new(UniqueTestObject::new(1)).unwrap();
3247 let obj2 = UniquePtr::try_new(UniqueTestObject::new(2)).unwrap();
3248
3249 list.as_mut().push_back(obj1);
3250 assert_eq!(list.len(), 1);
3251
3252 list.as_mut().push_back(obj2);
3253 assert_eq!(list.len(), 2);
3254
3255 let popped = list.as_mut().pop_front();
3256 assert!(popped.is_some());
3257 assert_eq!(list.len(), 1);
3258
3259 list.as_mut().clear();
3260 assert_eq!(list.len(), 0);
3261 }
3262
3263 #[test]
3264 fn test_unidirectional_iterators() {
3265 stack_pin_init!(let list = DoublyLinkedList::<UniquePtr<UniqueTestObject>>::new());
3266
3267 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
3268 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
3269 list.as_mut().push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
3270
3271 let mut f_iter = list.forward_iter();
3273 assert_eq!(f_iter.next().unwrap().value, 1);
3274 assert_eq!(f_iter.next().unwrap().value, 2);
3275 assert_eq!(f_iter.next().unwrap().value, 3);
3276 assert!(f_iter.next().is_none());
3277
3278 let mut r_iter = list.reverse_iter();
3280 assert_eq!(r_iter.next().unwrap().value, 3);
3281 assert_eq!(r_iter.next().unwrap().value, 2);
3282 assert_eq!(r_iter.next().unwrap().value, 1);
3283 assert!(r_iter.next().is_none());
3284
3285 list.as_mut().clear();
3286 }
3287
3288 #[test]
3289 fn test_cursor_at() {
3290 stack_pin_init!(let list =
3291 DoublyLinkedList::<*mut TestObject, DefaultObjectTag, TrackingSize>::new());
3292 let mut obj1 = TestObject::new(1);
3293 let mut obj2 = TestObject::new(2);
3294 let mut obj3 = TestObject::new(3);
3295
3296 unsafe {
3297 list.as_mut().push_back_raw(&mut obj1);
3298 list.as_mut().push_back_raw(&mut obj2);
3299 list.as_mut().push_back_raw(&mut obj3);
3300 }
3301
3302 let mut cursor = unsafe { list.as_mut().cursor_at(&obj2) };
3305 assert_eq!(cursor.get().unwrap().value, 2);
3306
3307 cursor.move_next();
3309 assert_eq!(cursor.get().unwrap().value, 3);
3310
3311 let mut cursor = unsafe { list.as_mut().cursor_at(&obj2) };
3314 cursor.move_prev();
3315 assert_eq!(cursor.get().unwrap().value, 1);
3316
3317 let mut cursor = unsafe { list.as_mut().cursor_at(&obj2) };
3320 let erased = cursor.erase().unwrap();
3321 assert_eq!(unsafe { &*erased }.value, 2);
3322
3323 let mut iter = list.iter();
3325 assert_eq!(iter.next().unwrap().value, 1);
3326 assert_eq!(iter.next().unwrap().value, 3);
3327 assert!(iter.next().is_none());
3328
3329 list.as_mut().clear();
3330 }
3331
3332 #[test]
3333 fn test_clear_unsafe() {
3334 use core::mem::ManuallyDrop;
3335 use core::ptr::NonNull;
3336
3337 stack_pin_init!(
3338 let list =
3339 DoublyLinkedList::<*mut TestObject, DefaultObjectTag, TrackingSize>::new()
3340 );
3341
3342 unsafe {
3345 list.as_mut().clear_unsafe();
3346 }
3347 assert!(list.is_empty());
3348 assert_eq!(list.len(), 0);
3349
3350 let mut obj1 = ManuallyDrop::new(TestObject::new(10));
3353 let mut obj2 = ManuallyDrop::new(TestObject::new(20));
3354 let mut obj3 = ManuallyDrop::new(TestObject::new(30));
3355
3356 unsafe {
3359 list.as_mut().push_back_raw(&mut *obj1);
3360 list.as_mut().push_back_raw(&mut *obj2);
3361 list.as_mut().push_back_raw(&mut *obj3);
3362 }
3363
3364 assert!(!list.is_empty());
3365 assert_eq!(list.len(), 3);
3366
3367 unsafe {
3370 list.as_mut().clear_unsafe();
3371 }
3372
3373 assert!(list.is_empty());
3374 assert_eq!(list.len(), 0);
3375 assert!(list.front().is_none());
3376 assert!(list.back().is_none());
3377 assert!(list.iter().next().is_none());
3378
3379 assert!(obj1.get_node().in_container());
3381 assert!(obj2.get_node().in_container());
3382 assert!(obj3.get_node().in_container());
3383
3384 let mut fresh1 = TestObject::new(40);
3386 let mut fresh2 = TestObject::new(50);
3387 unsafe {
3389 list.as_mut().push_back_raw(&mut fresh1);
3390 list.as_mut().push_back_raw(&mut fresh2);
3391 }
3392 assert!(!list.is_empty());
3393 assert_eq!(list.len(), 2);
3394 let mut iter = list.iter();
3395 assert_eq!(iter.next().unwrap().value, 40);
3396 assert_eq!(iter.next().unwrap().value, 50);
3397 assert!(iter.next().is_none());
3398 list.as_mut().clear();
3399 assert!(list.is_empty());
3400 assert_eq!(list.len(), 0);
3401
3402 stack_pin_init!(let nn_list = DoublyLinkedList::<NonNull<TestObject>>::new());
3404 unsafe {
3406 nn_list.as_mut().clear_unsafe();
3407 }
3408 assert!(nn_list.is_empty());
3409
3410 let mut nn_obj1 = ManuallyDrop::new(TestObject::new(1));
3411 let mut nn_obj2 = ManuallyDrop::new(TestObject::new(2));
3412 unsafe {
3415 nn_list.as_mut().push_front_raw(NonNull::from(&mut *nn_obj1));
3416 nn_list.as_mut().push_front_raw(NonNull::from(&mut *nn_obj2));
3417 assert!(!nn_list.is_empty());
3418 nn_list.as_mut().clear_unsafe();
3419 }
3420 assert!(nn_list.is_empty());
3421 assert!(nn_obj1.get_node().in_container());
3422 assert!(nn_obj2.get_node().in_container());
3423 }
3424
3425 unsafe extern "C" {
3427 fn cpp_create_unique_list() -> *mut c_void;
3429 fn cpp_destroy_unique_list(list: *mut c_void);
3430 fn cpp_unique_list_push_back(list: *mut c_void, item: *mut c_void);
3431 fn cpp_unique_list_pop_front(list: *mut c_void) -> *mut c_void;
3432 fn cpp_unique_list_is_empty(list: *mut c_void) -> bool;
3433
3434 fn cpp_create_ref_list() -> *mut c_void;
3436 fn cpp_destroy_ref_list(list: *mut c_void);
3437 fn cpp_ref_list_push_back(list: *mut c_void, item: *mut c_void);
3438 fn cpp_ref_list_pop_front(list: *mut c_void) -> *mut c_void;
3439 fn cpp_ref_list_is_empty(list: *mut c_void) -> bool;
3440
3441 fn cpp_create_unique_object(value: i32, destruction_flag: *mut bool) -> *mut c_void;
3443 fn cpp_get_unique_object_value(obj: *mut c_void) -> i32;
3444
3445 fn cpp_create_ref_object(value: i32, destruction_flag: *mut bool) -> *mut c_void;
3447 fn cpp_get_ref_object_value(obj: *mut c_void) -> i32;
3448 }
3449
3450 #[test]
3451 fn test_interop_rust_list_cpp_unique_objects() {
3452 let destroyed1 = AtomicBool::new(false);
3453 let destroyed2 = AtomicBool::new(false);
3454
3455 unsafe {
3456 stack_pin_init!(let list = DoublyLinkedList::<UniquePtr<SharedUniqueObject>>::new());
3457
3458 let cpp_raw1 = cpp_create_unique_object(1, destroyed1.as_ptr() as *mut bool);
3459 let cpp_raw2 = cpp_create_unique_object(2, destroyed2.as_ptr() as *mut bool);
3460
3461 let obj1 = UniquePtr::from_raw(cpp_raw1 as *mut SharedUniqueObject);
3462 let obj2 = UniquePtr::from_raw(cpp_raw2 as *mut SharedUniqueObject);
3463
3464 list.as_mut().push_back(obj1);
3465 list.as_mut().push_back(obj2);
3466
3467 assert!(!destroyed1.load(Ordering::Relaxed));
3468 assert!(!destroyed2.load(Ordering::Relaxed));
3469
3470 let popped = list.as_mut().pop_front();
3472 assert!(popped.is_some());
3473 assert_eq!(popped.as_ref().unwrap().value, 1);
3474
3475 drop(popped);
3477 assert!(destroyed1.load(Ordering::Relaxed));
3478 assert!(!destroyed2.load(Ordering::Relaxed));
3479
3480 }
3482 assert!(destroyed2.load(Ordering::Relaxed));
3483 }
3484
3485 #[test]
3486 fn test_interop_cpp_list_rust_unique_objects() {
3487 let destroyed1 = Arc::new(AtomicBool::new(false));
3488 let destroyed2 = Arc::new(AtomicBool::new(false));
3489
3490 unsafe {
3491 let cpp_list = cpp_create_unique_list();
3492 assert!(cpp_unique_list_is_empty(cpp_list));
3493
3494 let obj1 = UniquePtr::try_new(SharedUniqueObject::new(1)).unwrap();
3495 let obj2 = UniquePtr::try_new(SharedUniqueObject::new(2)).unwrap();
3496
3497 let raw1 = UniquePtr::as_ptr(&obj1) as *mut SharedUniqueObject;
3499 (*raw1).destruction_flag = destroyed1.as_ptr() as *mut bool;
3500 let raw2 = UniquePtr::as_ptr(&obj2) as *mut SharedUniqueObject;
3501 (*raw2).destruction_flag = destroyed2.as_ptr() as *mut bool;
3502
3503 cpp_unique_list_push_back(cpp_list, UniquePtr::into_raw(obj1) as *mut c_void);
3505 cpp_unique_list_push_back(cpp_list, UniquePtr::into_raw(obj2) as *mut c_void);
3506
3507 assert!(!destroyed1.load(Ordering::Relaxed));
3508 assert!(!destroyed2.load(Ordering::Relaxed));
3509
3510 let popped = cpp_unique_list_pop_front(cpp_list);
3512 assert!(!popped.is_null());
3513 assert_eq!(cpp_get_unique_object_value(popped), 1);
3514
3515 let popped_rust = UniquePtr::from_raw(popped as *mut SharedUniqueObject);
3517 drop(popped_rust);
3518 assert!(destroyed1.load(Ordering::Relaxed));
3519 assert!(!destroyed2.load(Ordering::Relaxed));
3520
3521 cpp_destroy_unique_list(cpp_list);
3523 }
3524 assert!(destroyed2.load(Ordering::Relaxed));
3525 }
3526
3527 #[test]
3528 fn test_interop_rust_list_cpp_ref_objects() {
3529 let destroyed1 = AtomicBool::new(false);
3530 let destroyed2 = AtomicBool::new(false);
3531
3532 unsafe {
3533 stack_pin_init!(let list = DoublyLinkedList::<RefPtr<SharedRefObject>>::new());
3534
3535 let cpp_raw1 = cpp_create_ref_object(1, destroyed1.as_ptr() as *mut bool);
3536 let cpp_raw2 = cpp_create_ref_object(2, destroyed2.as_ptr() as *mut bool);
3537
3538 let obj1 = RefPtr::from_raw(cpp_raw1 as *mut SharedRefObject);
3539 let obj2 = RefPtr::from_raw(cpp_raw2 as *mut SharedRefObject);
3540
3541 list.as_mut().push_back(obj1);
3542 list.as_mut().push_back(obj2);
3543
3544 assert!(!destroyed1.load(Ordering::Relaxed));
3545 assert!(!destroyed2.load(Ordering::Relaxed));
3546
3547 let popped = list.as_mut().pop_front();
3549 assert!(popped.is_some());
3550 assert_eq!(popped.as_ref().unwrap().value, 1);
3551
3552 drop(popped);
3554 assert!(destroyed1.load(Ordering::Relaxed));
3555 assert!(!destroyed2.load(Ordering::Relaxed));
3556
3557 }
3559 assert!(destroyed2.load(Ordering::Relaxed));
3560 }
3561
3562 #[test]
3563 fn test_interop_cpp_list_rust_ref_objects() {
3564 let destroyed1 = Arc::new(AtomicBool::new(false));
3565 let destroyed2 = Arc::new(AtomicBool::new(false));
3566
3567 unsafe {
3568 let cpp_list = cpp_create_ref_list();
3569 assert!(cpp_ref_list_is_empty(cpp_list));
3570
3571 let obj1 = SharedRefObject::new_ref_counted(1);
3572 let obj2 = SharedRefObject::new_ref_counted(2);
3573
3574 let raw1 = RefPtr::as_ptr(&obj1) as *mut SharedRefObject;
3576 (*raw1).destruction_flag = destroyed1.as_ptr() as *mut bool;
3577 let raw2 = RefPtr::as_ptr(&obj2) as *mut SharedRefObject;
3578 (*raw2).destruction_flag = destroyed2.as_ptr() as *mut bool;
3579
3580 cpp_ref_list_push_back(
3582 cpp_list,
3583 RefPtr::into_raw(obj1) as *mut SharedRefObject as *mut c_void,
3584 );
3585 cpp_ref_list_push_back(
3586 cpp_list,
3587 RefPtr::into_raw(obj2) as *mut SharedRefObject as *mut c_void,
3588 );
3589
3590 assert!(!destroyed1.load(Ordering::Relaxed));
3591 assert!(!destroyed2.load(Ordering::Relaxed));
3592
3593 let popped = cpp_ref_list_pop_front(cpp_list);
3595 assert!(!popped.is_null());
3596 assert_eq!(cpp_get_ref_object_value(popped), 1);
3597
3598 let popped_rust = RefPtr::from_raw(popped as *mut SharedRefObject);
3600 drop(popped_rust);
3601 assert!(destroyed1.load(Ordering::Relaxed));
3602 assert!(!destroyed2.load(Ordering::Relaxed));
3603
3604 cpp_destroy_ref_list(cpp_list);
3606 }
3607 assert!(destroyed2.load(Ordering::Relaxed));
3608 }
3609}