1use crate::ptr_traits::{ManagedPtr, 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)]
15pub struct DoublyLinkedListNode<T> {
16 pub next: UnsafeCell<*mut T>,
18 pub prev: UnsafeCell<*mut T>,
20}
21
22impl<T> DoublyLinkedListNode<T> {
23 pub const fn new() -> Self {
25 Self {
26 next: UnsafeCell::new(core::ptr::null_mut()),
27 prev: UnsafeCell::new(core::ptr::null_mut()),
28 }
29 }
30
31 pub fn in_container(&self) -> bool {
33 !unsafe { *self.next.get() }.is_null()
36 }
37
38 fn get_next(&self) -> *mut T {
39 unsafe { *self.next.get() }
41 }
42
43 fn set_next(&self, next: *mut T) {
44 unsafe {
47 *self.next.get() = next;
48 }
49 }
50
51 fn get_prev(&self) -> *mut T {
52 unsafe { *self.prev.get() }
54 }
55
56 fn set_prev(&self, prev: *mut T) {
57 unsafe {
60 *self.prev.get() = prev;
61 }
62 }
63}
64
65impl<T> core::fmt::Debug for DoublyLinkedListNode<T> {
66 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
67 f.debug_struct("DoublyLinkedListNode").field("in_container", &self.in_container()).finish()
68 }
69}
70
71impl<T> Default for DoublyLinkedListNode<T> {
72 fn default() -> Self {
73 Self::new()
74 }
75}
76
77impl<T> Drop for DoublyLinkedListNode<T> {
78 fn drop(&mut self) {
79 debug_assert!(!self.in_container(), "Object destroyed while still in container");
80 }
81}
82
83pub trait DoublyLinkedListContainable<T, Tag = DefaultObjectTag> {
85 fn get_node(&self) -> &DoublyLinkedListNode<T>;
87}
88
89#[repr(C)]
241#[pin_data(PinnedDrop)]
242pub struct DoublyLinkedList<P, Tag = DefaultObjectTag, S = NonTrackingSize>
243where
244 P: PtrTraits,
245 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
246 S: SizeTracker,
247{
248 head: *mut P::Target,
269
270 size: S,
273
274 #[pin]
278 _pin: core::marker::PhantomPinned,
279
280 _phantom: core::marker::PhantomData<(P, Tag)>,
281}
282
283impl<P, Tag, S> DoublyLinkedList<P, Tag, S>
284where
285 P: PtrTraits,
286 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
287 S: SizeTracker,
288{
289 pub fn new() -> impl PinInit<Self, core::convert::Infallible> {
291 pin_init!(&this in Self {
292 head: make_sentinel(this.as_ptr()),
293 size: S::INIT,
294 _pin: core::marker::PhantomPinned,
295 _phantom: core::marker::PhantomData,
296 })
297 }
298
299 fn get_sentinel(&self) -> *mut P::Target {
300 make_sentinel(self as *const Self as *mut Self)
301 }
302
303 fn get_tail(&self) -> *mut P::Target {
304 if self.is_empty() {
305 self.get_sentinel()
306 } else {
307 unsafe { *(*self.head).get_node().prev.get() }
311 }
312 }
313
314 unsafe fn set_tail(&self, tail: *mut P::Target) {
318 debug_assert!(!self.is_empty());
319 unsafe {
323 *(*self.head).get_node().prev.get() = tail;
324 }
325 }
326
327 unsafe fn get_node_ref<'a>(&self, ptr: *mut P::Target) -> &'a DoublyLinkedListNode<P::Target> {
332 let _ = self;
333 unsafe { &(*ptr) }.get_node()
335 }
336
337 pub fn is_empty(&self) -> bool {
339 is_sentinel_ptr(self.head)
340 }
341
342 pub fn front(&self) -> Option<&P::Target> {
344 if self.is_empty() { None } else { unsafe { Some(&*self.head) } }
345 }
346
347 pub fn front_mut(&mut self) -> Option<&mut P::Target> {
349 if self.is_empty() { None } else { unsafe { Some(&mut *self.head) } }
350 }
351
352 pub fn back(&self) -> Option<&P::Target> {
354 let tail = self.get_tail();
355 if is_sentinel_ptr(tail) { None } else { unsafe { Some(&*tail) } }
356 }
357
358 pub fn back_mut(&mut self) -> Option<&mut P::Target> {
360 let tail = self.get_tail();
361 if is_sentinel_ptr(tail) { None } else { unsafe { Some(&mut *tail) } }
362 }
363
364 pub fn push_front(&mut self, ptr: P)
370 where
371 P: ManagedPtr,
372 {
373 unsafe { self.push_front_raw(ptr) }
376 }
377
378 pub unsafe fn push_front_raw(&mut self, ptr: P) {
389 let head = self.head;
390 let mut cursor = CursorMut { list: self, current: head };
391 unsafe {
393 cursor.insert_before_raw(ptr);
394 }
395 }
396
397 pub fn push_back(&mut self, ptr: P)
403 where
404 P: ManagedPtr,
405 {
406 unsafe { self.push_back_raw(ptr) }
409 }
410
411 pub unsafe fn push_back_raw(&mut self, ptr: P) {
422 let sentinel = self.get_sentinel();
423 let mut cursor = CursorMut { list: self, current: sentinel };
424 unsafe {
426 cursor.insert_before_raw(ptr);
427 }
428 }
429
430 pub fn pop_front(&mut self) -> Option<P> {
432 if self.is_empty() {
433 return None;
434 }
435 let head = self.head;
436 let mut cursor = CursorMut { list: self, current: head };
437 cursor.erase()
438 }
439
440 pub fn pop_back(&mut self) -> Option<P> {
442 if self.is_empty() {
443 return None;
444 }
445 let tail = self.get_tail();
446 let mut cursor = CursorMut { list: self, current: tail };
447 cursor.erase()
448 }
449
450 pub fn clear(&mut self) {
452 while let Some(_) = self.pop_front() {}
453 }
454
455 pub unsafe fn erase(&mut self, obj: &P::Target) -> Option<P> {
462 let ptr = obj as *const P::Target as *mut P::Target;
463 let node = obj.get_node();
464
465 if !node.in_container() {
466 return None;
467 }
468
469 let mut cursor = self.cursor_front_mut();
470 cursor.current = ptr;
471 cursor.erase()
472 }
473
474 pub unsafe fn replace_raw(&mut self, obj: &P::Target, replacement: P) -> Option<P> {
481 let ptr = obj as *const P::Target as *mut P::Target;
482 let node = obj.get_node();
483
484 if !node.in_container() {
485 return None;
486 }
487
488 let mut cursor = self.cursor_front_mut();
489 cursor.current = ptr;
490 unsafe { cursor.replace_raw(replacement) }
492 }
493
494 pub fn erase_if<F>(&mut self, mut f: F) -> Option<P>
497 where
498 F: FnMut(&P::Target) -> bool,
499 {
500 let mut cursor = self.cursor_front_mut();
501 while let Some(item) = cursor.get() {
502 if f(item) {
503 return cursor.erase();
504 } else {
505 cursor.move_next();
506 }
507 }
508 None
509 }
510
511 pub fn find_if<F>(&self, mut f: F) -> Option<&P::Target>
513 where
514 F: FnMut(&P::Target) -> bool,
515 {
516 self.iter().find(|&x| f(x))
517 }
518
519 pub fn cursor_front_mut(&mut self) -> CursorMut<'_, P, Tag, S> {
521 let head = self.head;
522 CursorMut { list: self, current: head }
523 }
524
525 pub fn cursor_back_mut(&mut self) -> CursorMut<'_, P, Tag, S> {
527 let sentinel = self.get_sentinel();
528 CursorMut { list: self, current: sentinel }
529 }
530
531 pub unsafe fn cursor_at(&mut self, obj: &P::Target) -> CursorMut<'_, P, Tag, S> {
539 assert!(obj.get_node().in_container(), "Object must be in a container");
540 CursorMut { list: self, current: obj as *const P::Target as *mut P::Target }
541 }
542
543 pub fn splice(&mut self, other: &mut DoublyLinkedList<P, Tag, S>) {
549 self.cursor_back_mut().splice(other);
550 }
551
552 pub fn iter(&self) -> Iterator<'_, P, Tag> {
553 Iterator::new(self)
554 }
555
556 pub fn iter_mut(&mut self) -> IteratorMut<'_, P, Tag> {
558 IteratorMut::new(self)
559 }
560
561 pub fn forward_iter(&self) -> ForwardIterator<'_, P, Tag> {
563 ForwardIterator::new(self.head)
564 }
565
566 pub fn forward_iter_mut(&mut self) -> ForwardIteratorMut<'_, P, Tag> {
568 ForwardIteratorMut::new(self.head)
569 }
570
571 pub fn reverse_iter(&self) -> ReverseIterator<'_, P, Tag> {
573 ReverseIterator::new(self.get_tail())
574 }
575
576 pub fn reverse_iter_mut(&mut self) -> ReverseIteratorMut<'_, P, Tag> {
578 ReverseIteratorMut::new(self.get_tail())
579 }
580}
581
582impl<P, Tag> DoublyLinkedList<P, Tag, TrackingSize>
583where
584 P: PtrTraits,
585 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
586{
587 pub fn len(&self) -> usize {
589 self.size.get()
590 }
591}
592
593#[pinned_drop]
594impl<P, Tag, S> PinnedDrop for DoublyLinkedList<P, Tag, S>
595where
596 P: PtrTraits,
597 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
598 S: SizeTracker,
599{
600 fn drop(self: Pin<&mut Self>) {
601 if P::IS_MANAGED {
602 let me = unsafe { self.get_unchecked_mut() };
604 me.clear();
605 } else {
606 debug_assert!(self.is_empty(), "List must be empty on destruction");
607 if S::IS_TRACKING {
608 debug_assert_eq!(self.size.get(), 0, "Size must be zero on destruction");
609 }
610 }
611 }
612}
613
614pub struct CursorMut<'a, P, Tag = DefaultObjectTag, S = NonTrackingSize>
616where
617 P: PtrTraits,
618 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
619 S: SizeTracker,
620{
621 list: &'a mut DoublyLinkedList<P, Tag, S>,
622 current: *mut P::Target,
623}
624
625impl<'a, P, Tag, S> CursorMut<'a, P, Tag, S>
626where
627 P: PtrTraits,
628 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
629 S: SizeTracker,
630{
631 pub fn get(&self) -> Option<&P::Target> {
632 if is_sentinel_ptr(self.current) { None } else { unsafe { Some(&*self.current) } }
633 }
634
635 pub fn get_mut(&mut self) -> Option<&mut P::Target> {
636 if is_sentinel_ptr(self.current) { None } else { unsafe { Some(&mut *self.current) } }
637 }
638
639 pub fn move_next(&mut self) {
640 if !is_sentinel_ptr(self.current) {
641 let node = unsafe { self.list.get_node_ref(self.current) };
643 self.current = node.get_next();
644 }
645 }
646
647 pub fn move_prev(&mut self) {
648 if !is_sentinel_ptr(self.current) {
649 let node = unsafe { self.list.get_node_ref(self.current) };
651 let prev = node.get_prev();
652 if self.current == self.list.head {
653 self.current = self.list.get_sentinel(); } else {
655 self.current = prev;
656 }
657 } else {
658 self.current = self.list.get_tail();
660 }
661 }
662
663 pub fn insert_after(&mut self, ptr: P)
670 where
671 P: ManagedPtr,
672 {
673 unsafe { self.insert_after_raw(ptr) }
677 }
678
679 pub unsafe fn insert_after_raw(&mut self, ptr: P) {
690 assert!(!is_sentinel_ptr(self.current), "Cannot insert after end sentinel");
691 let raw = P::into_raw(ptr);
692 let node = unsafe { self.list.get_node_ref(raw) };
694 assert!(!node.in_container());
695
696 let current_node = unsafe { self.list.get_node_ref(self.current) };
698 let next = current_node.get_next();
699
700 let current_save = self.current;
701 self.current = next;
702 unsafe {
705 self.insert_chain_before(raw, raw, 1);
706 }
707 self.current = current_save;
708 }
709
710 pub fn replace(&mut self, replacement: P) -> Option<P>
717 where
718 P: ManagedPtr,
719 {
720 unsafe { self.replace_raw(replacement) }
723 }
724
725 pub unsafe fn replace_raw(&mut self, replacement: P) -> Option<P> {
737 if is_sentinel_ptr(self.current) {
738 return None;
739 }
740 unsafe {
743 self.insert_before_raw(replacement);
744 }
745 self.erase()
746 }
747
748 pub fn insert_before(&mut self, ptr: P)
754 where
755 P: ManagedPtr,
756 {
757 unsafe { self.insert_before_raw(ptr) }
760 }
761
762 pub unsafe fn insert_before_raw(&mut self, ptr: P) {
773 let raw = P::into_raw(ptr);
774 let node = unsafe { self.list.get_node_ref(raw) };
776 assert!(!node.in_container());
777
778 unsafe {
780 self.insert_chain_before(raw, raw, 1);
781 }
782 }
783
784 unsafe fn insert_chain_before(
795 &mut self,
796 chain_head: *mut P::Target,
797 chain_tail: *mut P::Target,
798 count: usize,
799 ) {
800 let chain_tail_node = unsafe { self.list.get_node_ref(chain_tail) };
802 chain_tail_node.set_next(self.current);
803
804 if self.list.is_empty() {
805 let chain_head_node = unsafe { self.list.get_node_ref(chain_head) };
807 chain_head_node.set_prev(chain_tail);
808 self.list.head = chain_head;
809 } else {
810 let prev = if self.current == self.list.head || is_sentinel_ptr(self.current) {
811 self.list.get_tail()
812 } else {
813 let current_node = unsafe { self.list.get_node_ref(self.current) };
815 current_node.get_prev()
816 };
817
818 let chain_head_node = unsafe { self.list.get_node_ref(chain_head) };
820 chain_head_node.set_prev(prev);
821
822 if self.current != self.list.head {
824 let prev_node = unsafe { self.list.get_node_ref(prev) };
826 prev_node.set_next(chain_head);
827 }
828
829 if !is_sentinel_ptr(self.current) {
831 let current_node = unsafe { self.list.get_node_ref(self.current) };
833 current_node.set_prev(chain_tail);
834 }
835
836 if self.current == self.list.head {
838 self.list.head = chain_head;
839 }
840
841 if is_sentinel_ptr(self.current) {
843 unsafe {
845 self.list.set_tail(chain_tail);
846 }
847 }
848 }
849
850 if S::IS_TRACKING {
851 self.list.size.set(self.list.size.get() + count);
852 }
853 }
854
855 pub fn splice(&mut self, other: &mut DoublyLinkedList<P, Tag, S>) {
869 if other.is_empty() {
870 return;
871 }
872
873 let other_head = other.head;
874 let other_tail = other.get_tail();
875 let count = if S::IS_TRACKING { other.size.get() } else { 0 };
876
877 unsafe {
880 self.insert_chain_before(other_head, other_tail, count);
881 }
882
883 other.head = other.get_sentinel();
884 if S::IS_TRACKING {
885 other.size.set(0);
886 }
887 }
888
889 pub fn split_after(&mut self, dest: &mut CursorMut<'_, P, Tag, S>) {
902 assert!(!is_sentinel_ptr(self.current), "Cannot split after end sentinel");
903
904 let curr_node = unsafe { self.list.get_node_ref(self.current) };
906 let next_ptr = curr_node.get_next();
907
908 if is_sentinel_ptr(next_ptr) {
910 return;
911 }
912
913 let chain_head = next_ptr;
914 let chain_tail = self.list.get_tail();
915
916 let mut count = 0;
917 if S::IS_TRACKING {
918 let mut p = chain_head;
919 let sentinel = self.list.get_sentinel();
920 while p != sentinel {
921 count += 1;
922 p = unsafe { self.list.get_node_ref(p) }.get_next();
924 }
925 self.list.size.set(self.list.size.get() - count);
926 }
927
928 curr_node.set_next(self.list.get_sentinel());
930 unsafe {
931 self.list.set_tail(self.current);
932 }
933
934 unsafe {
938 dest.insert_chain_before(chain_head, chain_tail, count);
939 }
940 }
941
942 pub fn split_before(&mut self, dest: &mut CursorMut<'_, P, Tag, S>) {
958 if self.current == self.list.head {
960 return;
961 }
962
963 if is_sentinel_ptr(self.current) {
965 if self.list.is_empty() {
966 return;
967 }
968 let chain_head = self.list.head;
969 let chain_tail = self.list.get_tail();
970 let count = if S::IS_TRACKING {
971 let c = self.list.size.get();
972 self.list.size.set(0);
973 c
974 } else {
975 0
976 };
977
978 self.list.head = self.list.get_sentinel();
979
980 unsafe {
983 dest.insert_chain_before(chain_head, chain_tail, count);
984 }
985 return;
986 }
987
988 let b = self.current;
991 let b_node = unsafe { self.list.get_node_ref(b) };
992 let chain_head = self.list.head;
993 let chain_tail = b_node.get_prev();
994 let old_tail = self.list.get_tail();
995
996 let mut count = 0;
997 if S::IS_TRACKING {
998 let mut p = chain_head;
999 while p != b {
1000 count += 1;
1001 p = unsafe { self.list.get_node_ref(p) }.get_next();
1003 }
1004 self.list.size.set(self.list.size.get() - count);
1005 }
1006
1007 self.list.head = b;
1009 b_node.set_prev(old_tail);
1010
1011 unsafe {
1015 dest.insert_chain_before(chain_head, chain_tail, count);
1016 }
1017 }
1018
1019 pub fn erase(&mut self) -> Option<P> {
1020 if is_sentinel_ptr(self.current) {
1021 return None;
1022 }
1023 let ptr = self.current;
1024 let node = unsafe { self.list.get_node_ref(ptr) };
1026 let next = node.get_next();
1027 let prev = node.get_prev();
1028
1029 self.list.size.decrement();
1030
1031 if self.list.head == ptr && is_sentinel_ptr(next) {
1032 self.list.head = self.list.get_sentinel();
1033 } else {
1034 if self.current != self.list.head {
1036 let prev_node = unsafe { self.list.get_node_ref(prev) };
1038 prev_node.set_next(next);
1039 }
1040
1041 if !is_sentinel_ptr(next) {
1043 let next_node = unsafe { self.list.get_node_ref(next) };
1045 next_node.set_prev(prev);
1046 }
1047
1048 if self.current == self.list.head {
1050 self.list.head = next;
1051 }
1052
1053 if is_sentinel_ptr(next) {
1055 unsafe {
1057 self.list.set_tail(prev);
1058 }
1059 }
1060 }
1061
1062 node.set_next(core::ptr::null_mut());
1063 node.set_prev(core::ptr::null_mut());
1064
1065 self.current = next;
1066 Some(unsafe { P::from_raw(ptr) })
1068 }
1069}
1070
1071pub struct Iterator<'a, P, Tag = DefaultObjectTag>
1073where
1074 P: PtrTraits,
1075 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1076{
1077 front: ForwardIterator<'a, P, Tag>,
1078 back: ReverseIterator<'a, P, Tag>,
1079}
1080
1081impl<'a, P, Tag> Iterator<'a, P, Tag>
1082where
1083 P: PtrTraits,
1084 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1085{
1086 fn new<S: SizeTracker>(list: &'a DoublyLinkedList<P, Tag, S>) -> Self {
1087 if list.is_empty() {
1088 Self {
1089 front: ForwardIterator::new(crate::make_sentinel_null()),
1090 back: ReverseIterator::new(crate::make_sentinel_null()),
1091 }
1092 } else {
1093 Self {
1094 front: ForwardIterator::new(list.head),
1095 back: ReverseIterator::new(list.get_tail()),
1096 }
1097 }
1098 }
1099}
1100
1101impl<'a, P, Tag> core::iter::Iterator for Iterator<'a, P, Tag>
1102where
1103 P: PtrTraits,
1104 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1105{
1106 type Item = &'a P::Target;
1107
1108 fn next(&mut self) -> Option<Self::Item> {
1109 let met = self.front.current == self.back.current;
1110 let item = self.front.next();
1111 if item.is_some() {
1112 if met {
1113 self.front.current = crate::make_sentinel_null();
1114 self.back.current = crate::make_sentinel_null();
1115 }
1116 }
1117 item
1118 }
1119}
1120
1121impl<'a, P, Tag> core::iter::DoubleEndedIterator for Iterator<'a, P, Tag>
1122where
1123 P: PtrTraits,
1124 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1125{
1126 fn next_back(&mut self) -> Option<Self::Item> {
1127 let met = self.front.current == self.back.current;
1128 let item = self.back.next();
1129 if item.is_some() {
1130 if met {
1131 self.front.current = crate::make_sentinel_null();
1132 self.back.current = crate::make_sentinel_null();
1133 }
1134 }
1135 item
1136 }
1137}
1138
1139pub struct ForwardIterator<'a, P, Tag = DefaultObjectTag>
1141where
1142 P: PtrTraits,
1143 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1144{
1145 current: *mut P::Target,
1146 _phantom: core::marker::PhantomData<&'a (P, Tag)>,
1147}
1148
1149impl<'a, P, Tag> ForwardIterator<'a, P, Tag>
1150where
1151 P: PtrTraits,
1152 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1153{
1154 fn new(current: *mut P::Target) -> Self {
1155 Self { current, _phantom: core::marker::PhantomData }
1156 }
1157
1158 pub fn from_element(obj: &'a P::Target) -> Self {
1164 assert!(obj.get_node().in_container(), "Object must be in a container");
1165 Self { current: obj as *const _ as *mut _, _phantom: core::marker::PhantomData }
1166 }
1167}
1168
1169impl<'a, P, Tag> core::iter::Iterator for ForwardIterator<'a, P, Tag>
1170where
1171 P: PtrTraits,
1172 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1173{
1174 type Item = &'a P::Target;
1175
1176 fn next(&mut self) -> Option<Self::Item> {
1177 if is_sentinel_ptr(self.current) {
1178 None
1179 } else {
1180 let current = unsafe { &*self.current };
1184 self.current = current.get_node().get_next();
1185 Some(current)
1186 }
1187 }
1188}
1189
1190pub struct ReverseIterator<'a, P, Tag = DefaultObjectTag>
1192where
1193 P: PtrTraits,
1194 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1195{
1196 current: *mut P::Target,
1197 _phantom: core::marker::PhantomData<&'a (P, Tag)>,
1198}
1199
1200impl<'a, P, Tag> ReverseIterator<'a, P, Tag>
1201where
1202 P: PtrTraits,
1203 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1204{
1205 fn new(current: *mut P::Target) -> Self {
1206 Self { current, _phantom: core::marker::PhantomData }
1207 }
1208
1209 pub fn from_element(obj: &'a P::Target) -> Self {
1215 assert!(obj.get_node().in_container(), "Object must be in a container");
1216 Self { current: obj as *const _ as *mut _, _phantom: core::marker::PhantomData }
1217 }
1218}
1219
1220impl<'a, P, Tag> core::iter::Iterator for ReverseIterator<'a, P, Tag>
1221where
1222 P: PtrTraits,
1223 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1224{
1225 type Item = &'a P::Target;
1226
1227 fn next(&mut self) -> Option<Self::Item> {
1228 if is_sentinel_ptr(self.current) {
1229 None
1230 } else {
1231 let current = unsafe { &*self.current };
1235 let prev = current.get_node().get_prev();
1236
1237 let prev_node = unsafe { &*prev }.get_node();
1240 if is_sentinel_ptr(prev_node.get_next()) {
1241 self.current = prev_node.get_next();
1244 } else {
1245 self.current = prev;
1246 }
1247 Some(current)
1248 }
1249 }
1250}
1251
1252pub struct IteratorMut<'a, P, Tag = DefaultObjectTag>
1254where
1255 P: PtrTraits,
1256 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1257{
1258 front: ForwardIteratorMut<'a, P, Tag>,
1259 back: ReverseIteratorMut<'a, P, Tag>,
1260}
1261
1262impl<'a, P, Tag> IteratorMut<'a, P, Tag>
1263where
1264 P: PtrTraits,
1265 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1266{
1267 fn new<S: SizeTracker>(list: &'a mut DoublyLinkedList<P, Tag, S>) -> Self {
1268 if list.is_empty() {
1269 Self {
1270 front: ForwardIteratorMut::new(crate::make_sentinel_null()),
1271 back: ReverseIteratorMut::new(crate::make_sentinel_null()),
1272 }
1273 } else {
1274 let tail = list.get_tail();
1275 Self { front: ForwardIteratorMut::new(list.head), back: ReverseIteratorMut::new(tail) }
1276 }
1277 }
1278}
1279
1280impl<'a, P, Tag> core::iter::Iterator for IteratorMut<'a, P, Tag>
1281where
1282 P: PtrTraits,
1283 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1284{
1285 type Item = &'a mut P::Target;
1286
1287 fn next(&mut self) -> Option<Self::Item> {
1288 let met = self.front.current == self.back.current;
1289 let item = self.front.next();
1290 if item.is_some() && met {
1291 self.front.current = crate::make_sentinel_null();
1292 self.back.current = crate::make_sentinel_null();
1293 }
1294 item
1295 }
1296}
1297
1298impl<'a, P, Tag> core::iter::DoubleEndedIterator for IteratorMut<'a, P, Tag>
1299where
1300 P: PtrTraits,
1301 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1302{
1303 fn next_back(&mut self) -> Option<Self::Item> {
1304 let met = self.front.current == self.back.current;
1305 let item = self.back.next();
1306 if item.is_some() && met {
1307 self.front.current = crate::make_sentinel_null();
1308 self.back.current = crate::make_sentinel_null();
1309 }
1310 item
1311 }
1312}
1313
1314pub struct ForwardIteratorMut<'a, P, Tag = DefaultObjectTag>
1316where
1317 P: PtrTraits,
1318 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1319{
1320 current: *mut P::Target,
1321 _phantom: core::marker::PhantomData<&'a mut (P, Tag)>,
1322}
1323
1324impl<'a, P, Tag> ForwardIteratorMut<'a, P, Tag>
1325where
1326 P: PtrTraits,
1327 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1328{
1329 fn new(current: *mut P::Target) -> Self {
1330 Self { current, _phantom: core::marker::PhantomData }
1331 }
1332
1333 pub fn from_element(obj: &'a mut P::Target) -> Self {
1339 assert!(obj.get_node().in_container(), "Object must be in a container");
1340 Self { current: obj as *mut _, _phantom: core::marker::PhantomData }
1341 }
1342}
1343
1344impl<'a, P, Tag> core::iter::Iterator for ForwardIteratorMut<'a, P, Tag>
1345where
1346 P: PtrTraits,
1347 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1348{
1349 type Item = &'a mut P::Target;
1350
1351 fn next(&mut self) -> Option<Self::Item> {
1352 if is_sentinel_ptr(self.current) {
1353 None
1354 } else {
1355 let current = unsafe { &mut *self.current };
1359 self.current = current.get_node().get_next();
1360 Some(current)
1361 }
1362 }
1363}
1364
1365pub struct ReverseIteratorMut<'a, P, Tag = DefaultObjectTag>
1367where
1368 P: PtrTraits,
1369 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1370{
1371 current: *mut P::Target,
1372 _phantom: core::marker::PhantomData<&'a mut (P, Tag)>,
1373}
1374
1375impl<'a, P, Tag> ReverseIteratorMut<'a, P, Tag>
1376where
1377 P: PtrTraits,
1378 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1379{
1380 fn new(current: *mut P::Target) -> Self {
1381 Self { current, _phantom: core::marker::PhantomData }
1382 }
1383
1384 pub fn from_element(obj: &'a mut P::Target) -> Self {
1390 assert!(obj.get_node().in_container(), "Object must be in a container");
1391 Self { current: obj as *mut _, _phantom: core::marker::PhantomData }
1392 }
1393}
1394
1395impl<'a, P, Tag> core::iter::Iterator for ReverseIteratorMut<'a, P, Tag>
1396where
1397 P: PtrTraits,
1398 P::Target: DoublyLinkedListContainable<P::Target, Tag>,
1399{
1400 type Item = &'a mut P::Target;
1401
1402 fn next(&mut self) -> Option<Self::Item> {
1403 if is_sentinel_ptr(self.current) {
1404 None
1405 } else {
1406 let current = unsafe { &mut *self.current };
1410 let prev = current.get_node().get_prev();
1411
1412 let prev_node = unsafe { &*prev }.get_node();
1415 if is_sentinel_ptr(prev_node.get_next()) {
1416 self.current = prev_node.get_next();
1417 } else {
1418 self.current = prev;
1419 }
1420 Some(current)
1421 }
1422 }
1423}
1424
1425pub unsafe fn remove_from_container<T, Tag, P>(obj: &T) -> Option<P>
1433where
1434 P: PtrTraits<Target = T>,
1435 T: DoublyLinkedListContainable<T, Tag>,
1436{
1437 let node = obj.get_node();
1438 if !node.in_container() {
1439 return None;
1440 }
1441
1442 let mut current = obj as *const T as *mut T;
1443 unsafe {
1444 while !is_sentinel_ptr(current) {
1445 current = (*current).get_node().get_next();
1446 }
1447
1448 let list_ptr = crate::sentinel::unmake_sentinel::<
1449 DoublyLinkedList<P, Tag, NonTrackingSize>,
1450 T,
1451 >(current);
1452 let list_ref = &mut *list_ptr;
1453
1454 list_ref.erase(obj)
1455 }
1456}
1457
1458impl<P, Tag, S> core::fmt::Debug for DoublyLinkedList<P, Tag, S>
1459where
1460 P: PtrTraits,
1461 P::Target: DoublyLinkedListContainable<P::Target, Tag> + core::fmt::Debug,
1462 S: SizeTracker,
1463{
1464 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1465 f.debug_list().entries(self.iter()).finish()
1466 }
1467}
1468
1469#[cfg(test)]
1470mod tests {
1471 extern crate alloc;
1472 use super::*;
1473 use crate::intrusive_container_test_support::*;
1474 use crate::ref_ptr::RefPtr;
1475 use crate::unique_ptr::UniquePtr;
1476 use core::ffi::c_void;
1477 use pin_init::stack_pin_init;
1478
1479 #[derive(crate::DoublyLinkedListContainable, crate::Recyclable)]
1480 struct TestObject {
1481 value: i32,
1482 #[dll_node]
1483 node: DoublyLinkedListNode<TestObject>,
1484 }
1485
1486 impl TestObject {
1487 fn new(value: i32) -> Self {
1488 Self { value, node: DoublyLinkedListNode::new() }
1489 }
1490 }
1491
1492 impl TestValue for TestObject {
1493 fn new(value: i32) -> Self {
1494 Self::new(value)
1495 }
1496 }
1497
1498 ::zr::static_assert!(
1499 core::mem::size_of::<DoublyLinkedList<*mut TestObject>>()
1500 == core::mem::size_of::<*mut TestObject>()
1501 );
1502 ::zr::static_assert!(
1503 core::mem::align_of::<DoublyLinkedList<*mut TestObject>>()
1504 == core::mem::align_of::<*mut TestObject>()
1505 );
1506
1507 ::zr::static_assert!(
1508 core::mem::size_of::<DoublyLinkedList<*mut TestObject, DefaultObjectTag, TrackingSize>>()
1509 == 2 * core::mem::size_of::<*mut TestObject>()
1510 );
1511 ::zr::static_assert!(
1512 core::mem::align_of::<DoublyLinkedList<*mut TestObject, DefaultObjectTag, TrackingSize>>()
1513 == core::mem::align_of::<*mut TestObject>()
1514 );
1515
1516 ::zr::static_assert!(
1517 core::mem::size_of::<ForwardIterator<'_, *mut TestObject>>()
1518 == core::mem::size_of::<*mut TestObject>()
1519 );
1520 ::zr::static_assert!(
1521 core::mem::align_of::<ForwardIterator<'_, *mut TestObject>>()
1522 == core::mem::align_of::<*mut TestObject>()
1523 );
1524
1525 ::zr::static_assert!(
1526 core::mem::size_of::<ReverseIterator<'_, *mut TestObject>>()
1527 == core::mem::size_of::<*mut TestObject>()
1528 );
1529 ::zr::static_assert!(
1530 core::mem::align_of::<ReverseIterator<'_, *mut TestObject>>()
1531 == core::mem::align_of::<*mut TestObject>()
1532 );
1533
1534 #[derive(crate::DoublyLinkedListContainable, crate::Recyclable)]
1535 struct UniqueTestObject {
1536 value: i32,
1537 #[dll_node]
1538 node: DoublyLinkedListNode<UniqueTestObject>,
1539 }
1540
1541 impl UniqueTestObject {
1542 fn new(value: i32) -> Self {
1543 Self { value, node: DoublyLinkedListNode::new() }
1544 }
1545 }
1546
1547 impl TestValue for UniqueTestObject {
1548 fn new(value: i32) -> Self {
1549 Self::new(value)
1550 }
1551 }
1552
1553 #[fbl::ref_counted]
1554 #[derive(crate::DoublyLinkedListContainable, crate::Recyclable)]
1555 #[repr(C)]
1556 pub struct RefTestObject {
1557 value: i32,
1558 #[dll_node]
1559 node: DoublyLinkedListNode<RefTestObject>,
1560 }
1561
1562 impl TestValue for RefTestObject {
1563 fn new_ref_counted(value: i32) -> RefPtr<Self> {
1564 crate::make_ref_counted!(RefTestObject {
1565 value: value,
1566 node: DoublyLinkedListNode::new()
1567 })
1568 .unwrap()
1569 }
1570 }
1571
1572 macro_rules! generate_list_tests {
1573 ($mod_name:ident, $ptr_type:ty, $factory_type:ty, $get_val:expr, $push:expr) => {
1574 mod $mod_name {
1575 use super::*;
1576
1577 #[test]
1578 fn test_basic() {
1579 let mut factory = <$factory_type>::new();
1580 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1581 let list = unsafe { list.get_unchecked_mut() };
1582 assert!(list.is_empty());
1583
1584 let obj1 = factory.create(1);
1585 let obj2 = factory.create(2);
1586
1587 $push(list, obj1);
1588 $push(list, obj2);
1589
1590 assert!(!list.is_empty());
1591
1592 let mut iter = list.iter();
1593 assert_eq!(iter.next().unwrap().value, 2);
1594 assert_eq!(iter.next().unwrap().value, 1);
1595 assert!(iter.next().is_none());
1596
1597 list.clear();
1598 assert!(list.is_empty());
1599 }
1600
1601 #[test]
1602 fn test_double_ended_iterator() {
1603 let mut factory = <$factory_type>::new();
1604 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1605 let list = unsafe { list.get_unchecked_mut() };
1606 let obj1 = factory.create(1);
1607 let obj2 = factory.create(2);
1608 let obj3 = factory.create(3);
1609
1610 $push(list, obj1);
1611 $push(list, obj2);
1612 $push(list, obj3);
1613
1614 let mut iter = list.iter();
1615 assert_eq!(iter.next().unwrap().value, 3);
1616 assert_eq!(iter.next_back().unwrap().value, 1);
1617 assert_eq!(iter.next().unwrap().value, 2);
1618 assert!(iter.next().is_none());
1619 assert!(iter.next_back().is_none());
1620
1621 list.clear();
1622 }
1623
1624 #[test]
1625 fn test_explicit_pops() {
1626 let mut factory = <$factory_type>::new();
1627 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1628 let list = unsafe { list.get_unchecked_mut() };
1629 let obj1 = factory.create(1);
1630 let obj2 = factory.create(2);
1631
1632 $push(list, obj1);
1633 $push(list, obj2);
1634
1635 let p1 = list.pop_front();
1636 assert!(p1.is_some());
1637 let p2 = list.pop_front();
1638 assert!(p2.is_some());
1639 assert!(list.pop_front().is_none());
1640 }
1641
1642 #[test]
1643 fn test_cursor_move_prev() {
1644 let mut factory = <$factory_type>::new();
1645 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1646 let list = unsafe { list.get_unchecked_mut() };
1647 let obj1 = factory.create(1);
1648 let obj2 = factory.create(2);
1649 let obj3 = factory.create(3);
1650
1651 $push(list, obj1);
1652 $push(list, obj2);
1653 $push(list, obj3);
1654
1655 let (a, b, c) = {
1656 let mut iter = list.iter();
1657 (
1658 $get_val(iter.next().unwrap()),
1659 $get_val(iter.next().unwrap()),
1660 $get_val(iter.next().unwrap()),
1661 )
1662 };
1663
1664 let mut cursor = list.cursor_front_mut();
1665 assert_eq!($get_val(cursor.get().unwrap()), a);
1666
1667 cursor.move_prev();
1668 assert!(cursor.get().is_none()); cursor.move_prev();
1671 assert_eq!($get_val(cursor.get().unwrap()), c);
1672
1673 cursor.move_prev();
1674 assert_eq!($get_val(cursor.get().unwrap()), b);
1675
1676 cursor.move_prev();
1677 assert_eq!($get_val(cursor.get().unwrap()), a);
1678
1679 list.clear();
1680 }
1681
1682 #[test]
1683 fn test_cursor_insert_after() {
1684 let mut factory = <$factory_type>::new();
1685 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1686 let list = unsafe { list.get_unchecked_mut() };
1687 let obj1 = factory.create(1);
1688 let obj2 = factory.create(2);
1689 let obj3 = factory.create(3);
1690
1691 $push(list, obj1);
1692
1693 let mut cursor = list.cursor_front_mut();
1694 unsafe {
1695 cursor.insert_after_raw(obj3);
1696 cursor.insert_after_raw(obj2);
1697 }
1698
1699 let mut iter = list.iter();
1700 assert_eq!($get_val(iter.next().unwrap()), 1);
1701 assert_eq!($get_val(iter.next().unwrap()), 2);
1702 assert_eq!($get_val(iter.next().unwrap()), 3);
1703 assert!(iter.next().is_none());
1704
1705 list.clear();
1706 }
1707
1708 #[test]
1709 fn test_pop_back() {
1710 let mut factory = <$factory_type>::new();
1711 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1712 let list = unsafe { list.get_unchecked_mut() };
1713 let obj1 = factory.create(1);
1714 let obj2 = factory.create(2);
1715
1716 $push(list, obj1);
1717 $push(list, obj2);
1718
1719 let p1 = list.pop_back();
1720 assert!(p1.is_some());
1721 let p2 = list.pop_back();
1722 assert!(p2.is_some());
1723 assert!(list.pop_back().is_none());
1724 }
1725
1726 #[test]
1727 fn test_erase() {
1728 let mut factory = <$factory_type>::new();
1729 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1730 let list = unsafe { list.get_unchecked_mut() };
1731 let obj1 = factory.create(1);
1732 let obj2 = factory.create(2);
1733 let obj3 = factory.create(3);
1734
1735 $push(list, obj1);
1736 $push(list, obj2);
1737 $push(list, obj3);
1738
1739 let mut cursor = list.cursor_front_mut();
1740 cursor.move_next();
1741 let erased = cursor.erase();
1742 assert!(erased.is_some());
1743 factory.cleanup(erased.unwrap());
1744
1745 let mut iter = list.iter();
1746 assert!(iter.next().is_some());
1747 assert!(iter.next().is_some());
1748 assert!(iter.next().is_none());
1749
1750 list.clear();
1751 }
1752
1753 #[test]
1754 fn test_erase_if() {
1755 let mut factory = <$factory_type>::new();
1756 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1757 let list = unsafe { list.get_unchecked_mut() };
1758 let obj1 = factory.create(1);
1759 let obj2 = factory.create(2);
1760 let obj3 = factory.create(3);
1761
1762 $push(list, obj1);
1763 $push(list, obj2);
1764 $push(list, obj3);
1765
1766 let erased = list.erase_if(|o| o.value == 2);
1767 assert!(erased.is_some());
1768 assert_eq!($get_val(erased.unwrap().get_ref()), 2);
1769
1770 let mut iter = list.iter();
1771 assert_eq!($get_val(iter.next().unwrap()), 3);
1772 assert_eq!($get_val(iter.next().unwrap()), 1);
1773 assert!(iter.next().is_none());
1774
1775 list.clear();
1776 }
1777
1778 #[test]
1779 fn test_find_if() {
1780 let mut factory = <$factory_type>::new();
1781 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1782 let list = unsafe { list.get_unchecked_mut() };
1783 let obj1 = factory.create(1);
1784 let obj2 = factory.create(2);
1785
1786 $push(list, obj1);
1787 $push(list, obj2);
1788
1789 let found = list.find_if(|o| o.value == 1);
1790 assert!(found.is_some());
1791 assert_eq!(found.unwrap().value, 1);
1792
1793 let found = list.find_if(|o| o.value == 3);
1794 assert!(found.is_none());
1795
1796 list.clear();
1797 }
1798
1799 #[test]
1800 fn test_complete_reverse_iteration() {
1801 let mut factory = <$factory_type>::new();
1802 stack_pin_init!(let list = DoublyLinkedList::<$ptr_type>::new());
1803 let list = unsafe { list.get_unchecked_mut() };
1804 let obj1 = factory.create(1);
1805 let obj2 = factory.create(2);
1806 let obj3 = factory.create(3);
1807
1808 $push(list, obj1);
1809 $push(list, obj2);
1810 $push(list, obj3);
1811
1812 let (a, b, c) = {
1813 let mut iter = list.iter();
1814 (
1815 $get_val(iter.next().unwrap()),
1816 $get_val(iter.next().unwrap()),
1817 $get_val(iter.next().unwrap()),
1818 )
1819 };
1820
1821 let mut iter = list.iter();
1822 assert_eq!($get_val(iter.next_back().unwrap()), c);
1823 assert_eq!($get_val(iter.next_back().unwrap()), b);
1824 assert_eq!($get_val(iter.next_back().unwrap()), a);
1825 assert!(iter.next_back().is_none());
1826
1827 list.clear();
1828 }
1829
1830 #[test]
1831 fn test_split_after() {
1832 let mut factory = <$factory_type>::new();
1833 stack_pin_init!(let list1 = DoublyLinkedList::<$ptr_type>::new());
1834 let list1 = unsafe { list1.get_unchecked_mut() };
1835 stack_pin_init!(let list2 = DoublyLinkedList::<$ptr_type>::new());
1836 let list2 = unsafe { list2.get_unchecked_mut() };
1837
1838 let obj1 = factory.create(1);
1839 let obj2 = factory.create(2);
1840 let obj3 = factory.create(3);
1841 let obj4 = factory.create(4);
1842
1843 $push(list1, obj4);
1844 $push(list1, obj3);
1845 $push(list1, obj2);
1846 $push(list1, obj1);
1847
1848 let mut cursor = list1.cursor_front_mut();
1849 cursor.move_next(); let mut dest_cursor = list2.cursor_back_mut();
1852 cursor.split_after(&mut dest_cursor);
1853
1854 let mut iter1 = list1.iter();
1855 assert_eq!($get_val(iter1.next().unwrap()), 1);
1856 assert_eq!($get_val(iter1.next().unwrap()), 2);
1857 assert!(iter1.next().is_none());
1858
1859 let mut iter2 = list2.iter();
1860 assert_eq!($get_val(iter2.next().unwrap()), 3);
1861 assert_eq!($get_val(iter2.next().unwrap()), 4);
1862 assert!(iter2.next().is_none());
1863
1864 list1.clear();
1865 list2.clear();
1866 }
1867
1868 #[test]
1869 fn test_split_before() {
1870 let mut factory = <$factory_type>::new();
1871 stack_pin_init!(let list1 = DoublyLinkedList::<$ptr_type>::new());
1872 let list1 = unsafe { list1.get_unchecked_mut() };
1873 stack_pin_init!(let list2 = DoublyLinkedList::<$ptr_type>::new());
1874 let list2 = unsafe { list2.get_unchecked_mut() };
1875
1876 let obj1 = factory.create(1);
1877 let obj2 = factory.create(2);
1878 let obj3 = factory.create(3);
1879 let obj4 = factory.create(4);
1880
1881 $push(list1, obj4);
1882 $push(list1, obj3);
1883 $push(list1, obj2);
1884 $push(list1, obj1);
1885
1886 let mut cursor = list1.cursor_front_mut();
1887 cursor.move_next();
1888 cursor.move_next(); let mut dest_cursor = list2.cursor_back_mut();
1891 cursor.split_before(&mut dest_cursor);
1892
1893 let mut iter2 = list2.iter();
1895 assert_eq!($get_val(iter2.next().unwrap()), 1);
1896 assert_eq!($get_val(iter2.next().unwrap()), 2);
1897 assert!(iter2.next().is_none());
1898
1899 let mut iter1 = list1.iter();
1901 assert_eq!($get_val(iter1.next().unwrap()), 3);
1902 assert_eq!($get_val(iter1.next().unwrap()), 4);
1903 assert!(iter1.next().is_none());
1904
1905 list1.clear();
1906 list2.clear();
1907 }
1908 }
1909 };
1910 }
1911
1912 generate_list_tests!(
1913 raw_ptr_tests,
1914 *mut TestObject,
1915 RawFactory<TestObject>,
1916 |p: &TestObject| p.value,
1917 |list: &mut DoublyLinkedList<*mut TestObject>, obj| unsafe {
1918 list.push_front_raw(obj);
1919 }
1920 );
1921
1922 generate_list_tests!(
1923 unique_ptr_tests,
1924 UniquePtr<UniqueTestObject>,
1925 UniqueFactory<UniqueTestObject>,
1926 |p: &UniqueTestObject| p.value,
1927 |list: &mut DoublyLinkedList<UniquePtr<UniqueTestObject>>, obj| list.push_front(obj)
1928 );
1929
1930 generate_list_tests!(
1931 ref_ptr_tests,
1932 RefPtr<RefTestObject>,
1933 RefFactory<RefTestObject>,
1934 |p: &RefTestObject| p.value,
1935 |list: &mut DoublyLinkedList<RefPtr<RefTestObject>>, obj| list.push_front(obj)
1936 );
1937
1938 #[test]
1939 fn test_tracking_size() {
1940 stack_pin_init!(let list =
1941 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
1942 let list = unsafe { list.get_unchecked_mut() };
1943
1944 assert_eq!(list.len(), 0);
1945 list.push_front(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
1946 assert_eq!(list.len(), 1);
1947 list.push_front(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
1948 assert_eq!(list.len(), 2);
1949 list.pop_front();
1950 assert_eq!(list.len(), 1);
1951 list.clear();
1952 assert_eq!(list.len(), 0);
1953 }
1954
1955 #[test]
1956 fn test_insert_before() {
1957 stack_pin_init!(let list =
1958 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
1959 let list = unsafe { list.get_unchecked_mut() };
1960
1961 let mut cursor = list.cursor_front_mut();
1962 cursor.insert_before(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
1963 assert_eq!(list.len(), 1);
1964 assert_eq!(list.front().unwrap().value, 1);
1965
1966 let mut cursor = list.cursor_front_mut();
1967 cursor.insert_before(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
1968 assert_eq!(list.len(), 2);
1969 assert_eq!(list.front().unwrap().value, 2);
1970
1971 let mut cursor = list.cursor_front_mut();
1972 cursor.move_next(); cursor.insert_before(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
1974 assert_eq!(list.len(), 3);
1975
1976 let mut cursor = list.cursor_front_mut();
1977 while cursor.get().unwrap().value != 1 {
1978 cursor.move_next();
1979 }
1980 cursor.move_next(); cursor.insert_before(UniquePtr::try_new(UniqueTestObject::new(4)).unwrap());
1982 assert_eq!(list.len(), 4);
1983
1984 let mut iter = list.iter();
1985 assert_eq!(iter.next().unwrap().value, 2);
1986 assert_eq!(iter.next().unwrap().value, 3);
1987 assert_eq!(iter.next().unwrap().value, 1);
1988 assert_eq!(iter.next().unwrap().value, 4);
1989 assert!(iter.next().is_none());
1990
1991 list.clear();
1992 }
1993
1994 #[test]
1995 fn test_front_mut_and_back_mut() {
1996 stack_pin_init!(let list =
1997 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
1998 let list = unsafe { list.get_unchecked_mut() };
1999
2000 assert!(list.front_mut().is_none());
2001 assert!(list.back_mut().is_none());
2002
2003 list.push_back(UniquePtr::try_new(UniqueTestObject::new(10)).unwrap());
2004 list.push_back(UniquePtr::try_new(UniqueTestObject::new(20)).unwrap());
2005
2006 assert_eq!(list.front_mut().unwrap().value, 10);
2007 assert_eq!(list.back_mut().unwrap().value, 20);
2008
2009 list.front_mut().unwrap().value = 100;
2010 list.back_mut().unwrap().value = 200;
2011
2012 assert_eq!(list.front().unwrap().value, 100);
2013 assert_eq!(list.back().unwrap().value, 200);
2014
2015 list.clear();
2016 }
2017
2018 #[test]
2019 fn test_cursor_front_and_back_mut() {
2020 stack_pin_init!(let list =
2021 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2022 let list = unsafe { list.get_unchecked_mut() };
2023
2024 assert!(list.cursor_front_mut().get().is_none());
2025 assert!(list.cursor_back_mut().get().is_none());
2026
2027 list.push_back(UniquePtr::try_new(UniqueTestObject::new(10)).unwrap());
2028 list.push_back(UniquePtr::try_new(UniqueTestObject::new(20)).unwrap());
2029
2030 let mut front_cursor = list.cursor_front_mut();
2031 assert_eq!(front_cursor.get().unwrap().value, 10);
2032 front_cursor.move_next();
2033 assert_eq!(front_cursor.get().unwrap().value, 20);
2034
2035 let mut back_cursor = list.cursor_back_mut();
2036 assert!(back_cursor.get().is_none());
2037 back_cursor.move_prev();
2038 assert_eq!(back_cursor.get().unwrap().value, 20);
2039
2040 let mut back_cursor = list.cursor_back_mut();
2041 back_cursor.insert_before(UniquePtr::try_new(UniqueTestObject::new(30)).unwrap());
2042 assert_eq!(list.len(), 3);
2043 assert_eq!(list.back().unwrap().value, 30);
2044
2045 list.clear();
2046 }
2047
2048 #[test]
2049 fn test_splice_middle() {
2050 stack_pin_init!(let list1 =
2051 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2052 let list1 = unsafe { list1.get_unchecked_mut() };
2053 stack_pin_init!(let list2 =
2054 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2055 let list2 = unsafe { list2.get_unchecked_mut() };
2056
2057 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2058 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2059 list2.push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2060 list2.push_back(UniquePtr::try_new(UniqueTestObject::new(4)).unwrap());
2061
2062 let mut cursor = list1.cursor_front_mut();
2063 cursor.move_next(); cursor.splice(list2);
2066
2067 assert!(list2.is_empty());
2068 assert_eq!(list1.len(), 4);
2069
2070 let mut iter = list1.iter();
2071 assert_eq!(iter.next().unwrap().value, 1);
2072 assert_eq!(iter.next().unwrap().value, 3);
2073 assert_eq!(iter.next().unwrap().value, 4);
2074 assert_eq!(iter.next().unwrap().value, 2);
2075 assert!(iter.next().is_none());
2076
2077 list1.clear();
2078 }
2079
2080 #[test]
2081 fn test_splice_head() {
2082 stack_pin_init!(let list1 =
2083 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2084 let list1 = unsafe { list1.get_unchecked_mut() };
2085 stack_pin_init!(let list2 =
2086 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2087 let list2 = unsafe { list2.get_unchecked_mut() };
2088
2089 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2090 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2091 list2.push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2092 list2.push_back(UniquePtr::try_new(UniqueTestObject::new(4)).unwrap());
2093
2094 let mut cursor = list1.cursor_front_mut();
2095
2096 cursor.splice(list2);
2097
2098 assert!(list2.is_empty());
2099 assert_eq!(list1.len(), 4);
2100
2101 let mut iter = list1.iter();
2102 assert_eq!(iter.next().unwrap().value, 3);
2103 assert_eq!(iter.next().unwrap().value, 4);
2104 assert_eq!(iter.next().unwrap().value, 1);
2105 assert_eq!(iter.next().unwrap().value, 2);
2106 assert!(iter.next().is_none());
2107
2108 list1.clear();
2109 }
2110
2111 #[test]
2112 fn test_splice_tail() {
2113 stack_pin_init!(let list1 =
2114 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2115 let list1 = unsafe { list1.get_unchecked_mut() };
2116 stack_pin_init!(let list2 =
2117 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2118 let list2 = unsafe { list2.get_unchecked_mut() };
2119
2120 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2121 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2122 list2.push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2123 list2.push_back(UniquePtr::try_new(UniqueTestObject::new(4)).unwrap());
2124
2125 let mut cursor = list1.cursor_front_mut();
2126 cursor.move_next();
2127 cursor.move_next(); cursor.splice(list2);
2130
2131 assert!(list2.is_empty());
2132 assert_eq!(list1.len(), 4);
2133
2134 let mut iter = list1.iter();
2135 assert_eq!(iter.next().unwrap().value, 1);
2136 assert_eq!(iter.next().unwrap().value, 2);
2137 assert_eq!(iter.next().unwrap().value, 3);
2138 assert_eq!(iter.next().unwrap().value, 4);
2139 assert!(iter.next().is_none());
2140
2141 list1.clear();
2142 }
2143
2144 #[test]
2145 fn test_splice_empty() {
2146 stack_pin_init!(let list1 =
2147 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2148 let list1 = unsafe { list1.get_unchecked_mut() };
2149 stack_pin_init!(let list2 =
2150 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2151 let list2 = unsafe { list2.get_unchecked_mut() };
2152
2153 list2.push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2154 list2.push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2155
2156 let mut cursor = list1.cursor_front_mut();
2157 cursor.splice(list2);
2158
2159 assert!(list2.is_empty());
2160 assert_eq!(list1.len(), 2);
2161
2162 let mut iter = list1.iter();
2163 assert_eq!(iter.next().unwrap().value, 1);
2164 assert_eq!(iter.next().unwrap().value, 2);
2165 assert!(iter.next().is_none());
2166
2167 list1.clear();
2168 }
2169
2170 #[test]
2171 fn test_splice_non_tracking() {
2172 stack_pin_init!(let list1 =
2173 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, NonTrackingSize>::new());
2174 let list1 = unsafe { list1.get_unchecked_mut() };
2175 stack_pin_init!(let list2 =
2176 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, NonTrackingSize>::new());
2177 let list2 = unsafe { list2.get_unchecked_mut() };
2178
2179 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2180 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2181 list2.push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2182 list2.push_back(UniquePtr::try_new(UniqueTestObject::new(4)).unwrap());
2183
2184 let mut cursor = list1.cursor_front_mut();
2185 cursor.move_next(); cursor.splice(list2);
2188
2189 assert!(list2.is_empty());
2190
2191 let mut iter = list1.iter();
2192 assert_eq!(iter.next().unwrap().value, 1);
2193 assert_eq!(iter.next().unwrap().value, 3);
2194 assert_eq!(iter.next().unwrap().value, 4);
2195 assert_eq!(iter.next().unwrap().value, 2);
2196 assert!(iter.next().is_none());
2197
2198 list1.clear();
2199 }
2200
2201 #[test]
2202 fn test_list_splice() {
2203 stack_pin_init!(let list1 =
2205 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2206 let list1 = unsafe { list1.get_unchecked_mut() };
2207 stack_pin_init!(let list2 =
2208 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2209 let list2 = unsafe { list2.get_unchecked_mut() };
2210
2211 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2212 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2213 list2.push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2214 list2.push_back(UniquePtr::try_new(UniqueTestObject::new(4)).unwrap());
2215
2216 list1.splice(list2);
2217
2218 assert!(list2.is_empty());
2219 assert_eq!(list2.len(), 0);
2220 assert_eq!(list1.len(), 4);
2221
2222 let mut iter = list1.iter();
2223 assert_eq!(iter.next().unwrap().value, 1);
2224 assert_eq!(iter.next().unwrap().value, 2);
2225 assert_eq!(iter.next().unwrap().value, 3);
2226 assert_eq!(iter.next().unwrap().value, 4);
2227 assert!(iter.next().is_none());
2228
2229 stack_pin_init!(let list3 =
2231 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2232 let list3 = unsafe { list3.get_unchecked_mut() };
2233
2234 list3.splice(list1);
2235
2236 assert!(list1.is_empty());
2237 assert_eq!(list1.len(), 0);
2238 assert_eq!(list3.len(), 4);
2239
2240 let mut iter = list3.iter();
2241 assert_eq!(iter.next().unwrap().value, 1);
2242 assert_eq!(iter.next().unwrap().value, 2);
2243 assert_eq!(iter.next().unwrap().value, 3);
2244 assert_eq!(iter.next().unwrap().value, 4);
2245 assert!(iter.next().is_none());
2246
2247 list3.splice(list1);
2249 assert_eq!(list3.len(), 4);
2250 assert!(list1.is_empty());
2251
2252 list3.clear();
2253 }
2254
2255 #[test]
2256 fn test_split_after_at_tail() {
2257 stack_pin_init!(let list1 =
2258 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2259 let list1 = unsafe { list1.get_unchecked_mut() };
2260 stack_pin_init!(let list2 =
2261 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2262 let list2 = unsafe { list2.get_unchecked_mut() };
2263
2264 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2265 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2266
2267 let mut cursor = list1.cursor_front_mut();
2268 cursor.move_next(); let mut dest_cursor = list2.cursor_back_mut();
2271 cursor.split_after(&mut dest_cursor);
2272
2273 assert!(list2.is_empty());
2274 assert_eq!(list2.len(), 0);
2275 assert_eq!(list1.len(), 2);
2276
2277 list1.clear();
2278 }
2279
2280 #[test]
2281 fn test_split_after_at_head() {
2282 stack_pin_init!(let list1 =
2283 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2284 let list1 = unsafe { list1.get_unchecked_mut() };
2285 stack_pin_init!(let list2 =
2286 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2287 let list2 = unsafe { list2.get_unchecked_mut() };
2288
2289 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2290 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2291 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2292
2293 let mut cursor = list1.cursor_front_mut(); let mut dest_cursor = list2.cursor_back_mut();
2296 cursor.split_after(&mut dest_cursor);
2297
2298 assert_eq!(list1.len(), 1);
2299 assert_eq!(list2.len(), 2);
2300
2301 let mut iter1 = list1.iter();
2302 assert_eq!(iter1.next().unwrap().value, 1);
2303 assert!(iter1.next().is_none());
2304
2305 let mut iter2 = list2.iter();
2306 assert_eq!(iter2.next().unwrap().value, 2);
2307 assert_eq!(iter2.next().unwrap().value, 3);
2308 assert!(iter2.next().is_none());
2309
2310 list1.clear();
2311 list2.clear();
2312 }
2313
2314 #[test]
2315 fn test_split_before_at_head() {
2316 stack_pin_init!(let list1 =
2317 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2318 let list1 = unsafe { list1.get_unchecked_mut() };
2319 stack_pin_init!(let list2 =
2320 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2321 let list2 = unsafe { list2.get_unchecked_mut() };
2322
2323 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2324 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2325
2326 let mut cursor = list1.cursor_front_mut(); let mut dest_cursor = list2.cursor_back_mut();
2329 cursor.split_before(&mut dest_cursor);
2330
2331 assert!(list2.is_empty());
2332 assert_eq!(list2.len(), 0);
2333 assert_eq!(list1.len(), 2);
2334
2335 list1.clear();
2336 }
2337
2338 #[test]
2339 fn test_split_before_at_tail() {
2340 stack_pin_init!(let list1 =
2341 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2342 let list1 = unsafe { list1.get_unchecked_mut() };
2343 stack_pin_init!(let list2 =
2344 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2345 let list2 = unsafe { list2.get_unchecked_mut() };
2346
2347 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2348 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2349 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2350
2351 let mut cursor = list1.cursor_front_mut();
2352 cursor.move_next();
2353 cursor.move_next(); let mut dest_cursor = list2.cursor_back_mut();
2356 cursor.split_before(&mut dest_cursor);
2357
2358 assert_eq!(list2.len(), 2);
2359 assert_eq!(list1.len(), 1);
2360
2361 let mut iter2 = list2.iter();
2362 assert_eq!(iter2.next().unwrap().value, 1);
2363 assert_eq!(iter2.next().unwrap().value, 2);
2364 assert!(iter2.next().is_none());
2365
2366 let mut iter1 = list1.iter();
2367 assert_eq!(iter1.next().unwrap().value, 3);
2368 assert!(iter1.next().is_none());
2369
2370 list1.clear();
2371 list2.clear();
2372 }
2373
2374 #[test]
2375 fn test_split_before_at_sentinel() {
2376 stack_pin_init!(let list1 =
2377 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2378 let list1 = unsafe { list1.get_unchecked_mut() };
2379 stack_pin_init!(let list2 =
2380 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2381 let list2 = unsafe { list2.get_unchecked_mut() };
2382
2383 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2384 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2385
2386 let mut cursor = list1.cursor_back_mut(); let mut dest_cursor = list2.cursor_back_mut();
2389 cursor.split_before(&mut dest_cursor);
2390
2391 assert!(list1.is_empty());
2392 assert_eq!(list1.len(), 0);
2393 assert_eq!(list2.len(), 2);
2394
2395 let mut iter2 = list2.iter();
2396 assert_eq!(iter2.next().unwrap().value, 1);
2397 assert_eq!(iter2.next().unwrap().value, 2);
2398 assert!(iter2.next().is_none());
2399
2400 list2.clear();
2401 }
2402
2403 #[test]
2404 fn test_split_into_middle_of_dest_list() {
2405 stack_pin_init!(let list1 =
2406 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2407 let list1 = unsafe { list1.get_unchecked_mut() };
2408 stack_pin_init!(let list2 =
2409 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2410 let list2 = unsafe { list2.get_unchecked_mut() };
2411
2412 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2413 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2414 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2415 list1.push_back(UniquePtr::try_new(UniqueTestObject::new(4)).unwrap());
2416
2417 list2.push_back(UniquePtr::try_new(UniqueTestObject::new(10)).unwrap());
2418 list2.push_back(UniquePtr::try_new(UniqueTestObject::new(20)).unwrap());
2419
2420 let mut cursor1 = list1.cursor_front_mut();
2422 cursor1.move_next(); let mut cursor2 = list2.cursor_front_mut();
2425 cursor2.move_next(); cursor1.split_after(&mut cursor2);
2428
2429 assert_eq!(list1.len(), 2);
2431 let mut iter1 = list1.iter();
2432 assert_eq!(iter1.next().unwrap().value, 1);
2433 assert_eq!(iter1.next().unwrap().value, 2);
2434 assert!(iter1.next().is_none());
2435
2436 assert_eq!(list2.len(), 4);
2438 let mut iter2 = list2.iter();
2439 assert_eq!(iter2.next().unwrap().value, 10);
2440 assert_eq!(iter2.next().unwrap().value, 3);
2441 assert_eq!(iter2.next().unwrap().value, 4);
2442 assert_eq!(iter2.next().unwrap().value, 20);
2443 assert!(iter2.next().is_none());
2444
2445 list1.clear();
2446 list2.clear();
2447 }
2448
2449 #[test]
2450 fn test_list_split_methods() {
2451 let mut obj1 = TestObject::new(1);
2452 let mut obj2 = TestObject::new(2);
2453 let mut obj3 = TestObject::new(3);
2454
2455 stack_pin_init!(let list1 = DoublyLinkedList::<*mut TestObject>::new());
2456 let list1 = unsafe { list1.get_unchecked_mut() };
2457 stack_pin_init!(let list2 = DoublyLinkedList::<*mut TestObject>::new());
2458 let list2 = unsafe { list2.get_unchecked_mut() };
2459
2460 unsafe {
2461 list1.push_back_raw(&mut obj1);
2462 list1.push_back_raw(&mut obj2);
2463 list1.push_back_raw(&mut obj3);
2464
2465 let mut cursor1 = list1.cursor_at(&obj1);
2467 let mut cursor2 = list2.cursor_back_mut();
2468 cursor1.split_after(&mut cursor2);
2469
2470 assert_eq!(list1.iter().count(), 1);
2471 assert_eq!(list2.iter().count(), 2);
2472
2473 let mut iter1 = list1.iter();
2474 assert_eq!(iter1.next().unwrap().value, 1);
2475 assert!(iter1.next().is_none());
2476
2477 let mut iter2 = list2.iter();
2478 assert_eq!(iter2.next().unwrap().value, 2);
2479 assert_eq!(iter2.next().unwrap().value, 3);
2480 assert!(iter2.next().is_none());
2481
2482 list1.splice(list2);
2484 assert_eq!(list1.iter().count(), 3);
2485
2486 let mut cursor1 = list1.cursor_at(&obj3);
2488 let mut cursor2 = list2.cursor_back_mut();
2489 cursor1.split_before(&mut cursor2);
2490
2491 assert_eq!(list2.iter().count(), 2);
2492 assert_eq!(list1.iter().count(), 1);
2493
2494 let mut iter2 = list2.iter();
2495 assert_eq!(iter2.next().unwrap().value, 1);
2496 assert_eq!(iter2.next().unwrap().value, 2);
2497 assert!(iter2.next().is_none());
2498
2499 let mut iter1 = list1.iter();
2500 assert_eq!(iter1.next().unwrap().value, 3);
2501 assert!(iter1.next().is_none());
2502
2503 list1.clear();
2504 list2.clear();
2505 }
2506 }
2507
2508 #[test]
2509 fn test_cursor_get() {
2510 stack_pin_init!(let list = DoublyLinkedList::<UniquePtr<UniqueTestObject>>::new());
2511 let list = unsafe { list.get_unchecked_mut() };
2512
2513 let cursor = list.cursor_front_mut();
2514 assert!(cursor.get().is_none());
2515
2516 list.push_back(UniquePtr::try_new(UniqueTestObject::new(42)).unwrap());
2517
2518 let mut cursor = list.cursor_front_mut();
2519 assert!(cursor.get().is_some());
2520 assert_eq!(cursor.get().unwrap().value, 42);
2521
2522 cursor.move_next();
2523 assert!(cursor.get().is_none());
2524
2525 list.clear();
2526 }
2527
2528 #[test]
2529 fn test_pop_back() {
2530 stack_pin_init!(let list =
2531 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2532 let list = unsafe { list.get_unchecked_mut() };
2533
2534 list.push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2535 list.push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2536
2537 assert_eq!(list.len(), 2);
2538 let popped = list.pop_back();
2539 assert!(popped.is_some());
2540 assert_eq!(popped.unwrap().value, 2);
2541 assert_eq!(list.len(), 1);
2542
2543 let popped = list.pop_back();
2544 assert!(popped.is_some());
2545 assert_eq!(popped.unwrap().value, 1);
2546 assert_eq!(list.len(), 0);
2547
2548 assert!(list.pop_back().is_none());
2549 }
2550
2551 #[test]
2552 fn test_erase() {
2553 stack_pin_init!(let list =
2554 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2555 let list = unsafe { list.get_unchecked_mut() };
2556
2557 list.push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2558 list.push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2559 list.push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2560
2561 assert_eq!(list.len(), 3);
2562
2563 let mut cursor = list.cursor_front_mut();
2565 cursor.move_next(); let erased = cursor.erase();
2567 assert!(erased.is_some());
2568 assert_eq!(erased.unwrap().value, 2);
2569 assert_eq!(list.len(), 2);
2570
2571 let mut iter = list.iter();
2572 assert_eq!(iter.next().unwrap().value, 1);
2573 assert_eq!(iter.next().unwrap().value, 3);
2574 assert!(iter.next().is_none());
2575
2576 let mut cursor = list.cursor_front_mut();
2578 let erased = cursor.erase(); assert!(erased.is_some());
2580 assert_eq!(erased.unwrap().value, 1);
2581 assert_eq!(list.len(), 1);
2582 assert_eq!(list.front().unwrap().value, 3); let mut cursor = list.cursor_front_mut();
2586 let erased = cursor.erase(); assert!(erased.is_some());
2588 assert_eq!(erased.unwrap().value, 3);
2589 assert_eq!(list.len(), 0);
2590 assert!(list.is_empty());
2591
2592 list.clear();
2593 }
2594
2595 #[test]
2596 fn test_erase_if() {
2597 stack_pin_init!(let list =
2598 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2599 let list = unsafe { list.get_unchecked_mut() };
2600
2601 list.push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2602 list.push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2603 list.push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2604
2605 let erased = list.erase_if(|obj| obj.value % 2 == 0);
2606 assert!(erased.is_some());
2607 assert_eq!(erased.unwrap().value, 2);
2608
2609 assert_eq!(list.len(), 2);
2610 let mut iter = list.iter();
2611 assert_eq!(iter.next().unwrap().value, 1);
2612 assert_eq!(iter.next().unwrap().value, 3);
2613 assert!(iter.next().is_none());
2614
2615 list.clear();
2616 }
2617
2618 #[test]
2619 fn test_erase_by_reference() {
2620 stack_pin_init!(let list =
2621 DoublyLinkedList::<*mut TestObject, DefaultObjectTag, TrackingSize>::new());
2622 let list = unsafe { list.get_unchecked_mut() };
2623 let mut obj1 = TestObject::new(1);
2624 let mut obj2 = TestObject::new(2);
2625 let mut obj3 = TestObject::new(3);
2626
2627 unsafe {
2628 list.push_back_raw(&mut obj1);
2629 list.push_back_raw(&mut obj2);
2630 list.push_back_raw(&mut obj3);
2631 }
2632
2633 assert_eq!(list.len(), 3);
2634
2635 let erased = unsafe { list.erase(&obj2) };
2637 assert!(erased.is_some());
2638 assert_eq!(unsafe { &*erased.unwrap() }.value, 2);
2639 assert_eq!(list.len(), 2);
2640
2641 let mut iter = list.iter();
2642 assert_eq!(iter.next().unwrap().value, 1);
2643 assert_eq!(iter.next().unwrap().value, 3);
2644 assert!(iter.next().is_none());
2645
2646 list.clear();
2647 }
2648
2649 #[test]
2650 fn test_remove_from_container() {
2651 stack_pin_init!(let list = DoublyLinkedList::<*mut TestObject>::new());
2652 let list = unsafe { list.get_unchecked_mut() };
2653 let mut obj1 = TestObject::new(1);
2654 let mut obj2 = TestObject::new(2);
2655 let mut obj3 = TestObject::new(3);
2656
2657 let removed = unsafe {
2659 remove_from_container::<TestObject, DefaultObjectTag, *mut TestObject>(&obj1)
2660 };
2661 assert!(removed.is_none());
2662
2663 unsafe {
2664 list.push_back_raw(&mut obj1);
2665 list.push_back_raw(&mut obj2);
2666 list.push_back_raw(&mut obj3);
2667 }
2668
2669 let removed = unsafe {
2671 remove_from_container::<TestObject, DefaultObjectTag, *mut TestObject>(&obj2)
2672 };
2673 assert!(removed.is_some());
2674 assert_eq!(unsafe { &*removed.unwrap() }.value, 2);
2675
2676 let mut iter = list.iter();
2677 assert_eq!(iter.next().unwrap().value, 1);
2678 assert_eq!(iter.next().unwrap().value, 3);
2679 assert!(iter.next().is_none());
2680
2681 let removed = unsafe {
2683 remove_from_container::<TestObject, DefaultObjectTag, *mut TestObject>(&obj1)
2684 };
2685 assert!(removed.is_some());
2686 assert_eq!(unsafe { &*removed.unwrap() }.value, 1);
2687
2688 let mut iter = list.iter();
2689 assert_eq!(iter.next().unwrap().value, 3);
2690 assert!(iter.next().is_none());
2691
2692 let removed = unsafe {
2694 remove_from_container::<TestObject, DefaultObjectTag, *mut TestObject>(&obj3)
2695 };
2696 assert!(removed.is_some());
2697 assert_eq!(unsafe { &*removed.unwrap() }.value, 3);
2698 assert!(list.is_empty());
2699
2700 list.clear();
2701 }
2702
2703 #[test]
2704 fn test_replace() {
2705 stack_pin_init!(let list =
2706 DoublyLinkedList::<*mut TestObject, DefaultObjectTag, TrackingSize>::new());
2707 let list = unsafe { list.get_unchecked_mut() };
2708 let mut obj1 = TestObject::new(1);
2709 let mut obj2 = TestObject::new(2);
2710 let mut obj3 = TestObject::new(3);
2711
2712 unsafe {
2713 list.push_back_raw(&mut obj1);
2714 list.push_back_raw(&mut obj2);
2715 }
2716
2717 assert_eq!(list.len(), 2);
2718
2719 let old = unsafe { list.replace_raw(&obj2, &mut obj3) };
2720 assert!(old.is_some());
2721 assert_eq!(unsafe { &*old.unwrap() }.value, 2);
2722 assert_eq!(list.len(), 2);
2723
2724 let mut iter = list.iter();
2725 assert_eq!(iter.next().unwrap().value, 1);
2726 assert_eq!(iter.next().unwrap().value, 3);
2727 assert!(iter.next().is_none());
2728
2729 list.clear();
2730 }
2731
2732 #[test]
2733 fn test_cursor_replace() {
2734 stack_pin_init!(let list = DoublyLinkedList::<UniquePtr<UniqueTestObject>>::new());
2735 let list = unsafe { list.get_unchecked_mut() };
2736
2737 let obj1 = UniquePtr::try_new(UniqueTestObject::new(1)).unwrap();
2738 let obj2 = UniquePtr::try_new(UniqueTestObject::new(2)).unwrap();
2739 let obj3 = UniquePtr::try_new(UniqueTestObject::new(3)).unwrap();
2740
2741 list.push_back(obj1);
2742 list.push_back(obj2);
2743
2744 let mut cursor = list.cursor_front_mut();
2745 cursor.move_next(); let old = cursor.replace(obj3);
2748 assert!(old.is_some());
2749 assert_eq!(old.unwrap().value, 2);
2750
2751 let mut iter = list.iter();
2752 assert_eq!(iter.next().unwrap().value, 1);
2753 assert_eq!(iter.next().unwrap().value, 3);
2754 assert!(iter.next().is_none());
2755
2756 list.clear();
2757 }
2758
2759 struct Tag2;
2760
2761 #[fbl::ref_counted]
2762 #[derive(crate::DoublyLinkedListContainable, crate::Recyclable)]
2763 #[repr(C)]
2764 struct MultiListObject {
2765 value: i32,
2766 #[dll_node]
2767 node1: DoublyLinkedListNode<MultiListObject>,
2768 #[dll_node(tag = Tag2)]
2769 node2: DoublyLinkedListNode<MultiListObject>,
2770 }
2771
2772 #[test]
2773 fn test_multiple_containers() {
2774 stack_pin_init!(let list1 =
2775 DoublyLinkedList::<RefPtr<MultiListObject>, DefaultObjectTag>::new());
2776 let list1 = unsafe { list1.get_unchecked_mut() };
2777 stack_pin_init!(let list2 = DoublyLinkedList::<RefPtr<MultiListObject>, Tag2>::new());
2778 let list2 = unsafe { list2.get_unchecked_mut() };
2779
2780 let obj1 = fbl::make_ref_counted!(MultiListObject {
2781 value: 1,
2782 node1: DoublyLinkedListNode::new(),
2783 node2: DoublyLinkedListNode::new(),
2784 })
2785 .unwrap();
2786
2787 let obj2 = fbl::make_ref_counted!(MultiListObject {
2788 value: 2,
2789 node1: DoublyLinkedListNode::new(),
2790 node2: DoublyLinkedListNode::new(),
2791 })
2792 .unwrap();
2793
2794 list1.push_back(obj1.clone());
2795 list1.push_back(obj2.clone());
2796
2797 list2.push_back(obj2); let mut iter1 = list1.iter();
2800 assert_eq!(iter1.next().unwrap().value, 1);
2801 assert_eq!(iter1.next().unwrap().value, 2);
2802 assert!(iter1.next().is_none());
2803
2804 let mut iter2 = list2.iter();
2805 assert_eq!(iter2.next().unwrap().value, 2);
2806 assert!(iter2.next().is_none());
2807
2808 list1.clear();
2809 list2.clear();
2810 }
2811
2812 use alloc::sync::Arc;
2813 use core::sync::atomic::{AtomicBool, Ordering};
2814
2815 #[derive(crate::DoublyLinkedListContainable, crate::Recyclable)]
2816 struct LifecycleObject {
2817 destroyed: Arc<AtomicBool>,
2818 #[dll_node]
2819 node: DoublyLinkedListNode<LifecycleObject>,
2820 }
2821
2822 impl LifecycleObject {
2823 fn new(destroyed: Arc<AtomicBool>) -> Self {
2824 Self { destroyed, node: DoublyLinkedListNode::new() }
2825 }
2826 }
2827
2828 impl Drop for LifecycleObject {
2829 fn drop(&mut self) {
2830 self.destroyed.store(true, Ordering::Relaxed);
2831 }
2832 }
2833
2834 #[test]
2835 fn test_lifecycle_on_drop() {
2836 let destroyed1 = Arc::new(AtomicBool::new(false));
2837 let destroyed2 = Arc::new(AtomicBool::new(false));
2838
2839 {
2840 stack_pin_init!(let list = DoublyLinkedList::<UniquePtr<LifecycleObject>>::new());
2841 let list = unsafe { list.get_unchecked_mut() };
2842
2843 let obj1 = UniquePtr::try_new(LifecycleObject::new(destroyed1.clone())).unwrap();
2844 let obj2 = UniquePtr::try_new(LifecycleObject::new(destroyed2.clone())).unwrap();
2845
2846 list.push_back(obj1);
2847 list.push_back(obj2);
2848
2849 assert!(!destroyed1.load(Ordering::Relaxed));
2850 assert!(!destroyed2.load(Ordering::Relaxed));
2851 } assert!(destroyed1.load(Ordering::Relaxed));
2854 assert!(destroyed2.load(Ordering::Relaxed));
2855 }
2856
2857 #[test]
2858 fn test_sized_managed_list() {
2859 stack_pin_init!(let list =
2860 DoublyLinkedList::<UniquePtr<UniqueTestObject>, DefaultObjectTag, TrackingSize>::new());
2861 let list = unsafe { list.get_unchecked_mut() };
2862
2863 assert_eq!(list.len(), 0);
2864
2865 let obj1 = UniquePtr::try_new(UniqueTestObject::new(1)).unwrap();
2866 let obj2 = UniquePtr::try_new(UniqueTestObject::new(2)).unwrap();
2867
2868 list.push_back(obj1);
2869 assert_eq!(list.len(), 1);
2870
2871 list.push_back(obj2);
2872 assert_eq!(list.len(), 2);
2873
2874 let popped = list.pop_front();
2875 assert!(popped.is_some());
2876 assert_eq!(list.len(), 1);
2877
2878 list.clear();
2879 assert_eq!(list.len(), 0);
2880 }
2881
2882 #[test]
2883 fn test_unidirectional_iterators() {
2884 stack_pin_init!(let list = DoublyLinkedList::<UniquePtr<UniqueTestObject>>::new());
2885 let list = unsafe { list.get_unchecked_mut() };
2886
2887 list.push_back(UniquePtr::try_new(UniqueTestObject::new(1)).unwrap());
2888 list.push_back(UniquePtr::try_new(UniqueTestObject::new(2)).unwrap());
2889 list.push_back(UniquePtr::try_new(UniqueTestObject::new(3)).unwrap());
2890
2891 let mut f_iter = list.forward_iter();
2893 assert_eq!(f_iter.next().unwrap().value, 1);
2894 let obj2_ref = f_iter.next().unwrap();
2895 assert_eq!(obj2_ref.value, 2);
2896 assert_eq!(f_iter.next().unwrap().value, 3);
2897 assert!(f_iter.next().is_none());
2898
2899 let mut f_element_iter =
2901 ForwardIterator::<UniquePtr<UniqueTestObject>>::from_element(obj2_ref);
2902 assert_eq!(f_element_iter.next().unwrap().value, 2);
2903 assert_eq!(f_element_iter.next().unwrap().value, 3);
2904 assert!(f_element_iter.next().is_none());
2905
2906 let mut r_iter = list.reverse_iter();
2908 assert_eq!(r_iter.next().unwrap().value, 3);
2909 let obj2_ref_r = r_iter.next().unwrap();
2910 assert_eq!(obj2_ref_r.value, 2);
2911 assert_eq!(r_iter.next().unwrap().value, 1);
2912 assert!(r_iter.next().is_none());
2913
2914 let mut r_element_iter =
2916 ReverseIterator::<UniquePtr<UniqueTestObject>>::from_element(obj2_ref_r);
2917 assert_eq!(r_element_iter.next().unwrap().value, 2);
2918 assert_eq!(r_element_iter.next().unwrap().value, 1);
2919 assert!(r_element_iter.next().is_none());
2920
2921 list.clear();
2922 }
2923
2924 #[test]
2925 fn test_cursor_at() {
2926 stack_pin_init!(let list =
2927 DoublyLinkedList::<*mut TestObject, DefaultObjectTag, TrackingSize>::new());
2928 let list = unsafe { list.get_unchecked_mut() };
2929 let mut obj1 = TestObject::new(1);
2930 let mut obj2 = TestObject::new(2);
2931 let mut obj3 = TestObject::new(3);
2932
2933 unsafe {
2934 list.push_back_raw(&mut obj1);
2935 list.push_back_raw(&mut obj2);
2936 list.push_back_raw(&mut obj3);
2937 }
2938
2939 let mut cursor = unsafe { list.cursor_at(&obj2) };
2942 assert_eq!(cursor.get().unwrap().value, 2);
2943
2944 cursor.move_next();
2946 assert_eq!(cursor.get().unwrap().value, 3);
2947
2948 let mut cursor = unsafe { list.cursor_at(&obj2) };
2951 cursor.move_prev();
2952 assert_eq!(cursor.get().unwrap().value, 1);
2953
2954 let mut cursor = unsafe { list.cursor_at(&obj2) };
2957 let erased = cursor.erase().unwrap();
2958 assert_eq!(unsafe { &*erased }.value, 2);
2959
2960 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 list.clear();
2967 }
2968
2969 unsafe extern "C" {
2971 fn cpp_create_unique_list() -> *mut c_void;
2973 fn cpp_destroy_unique_list(list: *mut c_void);
2974 fn cpp_unique_list_push_back(list: *mut c_void, item: *mut c_void);
2975 fn cpp_unique_list_pop_front(list: *mut c_void) -> *mut c_void;
2976 fn cpp_unique_list_is_empty(list: *mut c_void) -> bool;
2977
2978 fn cpp_create_ref_list() -> *mut c_void;
2980 fn cpp_destroy_ref_list(list: *mut c_void);
2981 fn cpp_ref_list_push_back(list: *mut c_void, item: *mut c_void);
2982 fn cpp_ref_list_pop_front(list: *mut c_void) -> *mut c_void;
2983 fn cpp_ref_list_is_empty(list: *mut c_void) -> bool;
2984
2985 fn cpp_create_unique_object(value: i32, destruction_flag: *mut bool) -> *mut c_void;
2987 fn cpp_get_unique_object_value(obj: *mut c_void) -> i32;
2988
2989 fn cpp_create_ref_object(value: i32, destruction_flag: *mut bool) -> *mut c_void;
2991 fn cpp_get_ref_object_value(obj: *mut c_void) -> i32;
2992 }
2993
2994 #[test]
2995 fn test_interop_rust_list_cpp_unique_objects() {
2996 let destroyed1 = AtomicBool::new(false);
2997 let destroyed2 = AtomicBool::new(false);
2998
2999 unsafe {
3000 stack_pin_init!(let list = DoublyLinkedList::<UniquePtr<SharedUniqueObject>>::new());
3001 let list = list.get_unchecked_mut();
3002
3003 let cpp_raw1 = cpp_create_unique_object(1, destroyed1.as_ptr() as *mut bool);
3004 let cpp_raw2 = cpp_create_unique_object(2, destroyed2.as_ptr() as *mut bool);
3005
3006 let obj1 = UniquePtr::from_raw(cpp_raw1 as *mut SharedUniqueObject);
3007 let obj2 = UniquePtr::from_raw(cpp_raw2 as *mut SharedUniqueObject);
3008
3009 list.push_back(obj1);
3010 list.push_back(obj2);
3011
3012 assert!(!destroyed1.load(Ordering::Relaxed));
3013 assert!(!destroyed2.load(Ordering::Relaxed));
3014
3015 let popped = list.pop_front();
3017 assert!(popped.is_some());
3018 assert_eq!(popped.as_ref().unwrap().value, 1);
3019
3020 drop(popped);
3022 assert!(destroyed1.load(Ordering::Relaxed));
3023 assert!(!destroyed2.load(Ordering::Relaxed));
3024
3025 }
3027 assert!(destroyed2.load(Ordering::Relaxed));
3028 }
3029
3030 #[test]
3031 fn test_interop_cpp_list_rust_unique_objects() {
3032 let destroyed1 = Arc::new(AtomicBool::new(false));
3033 let destroyed2 = Arc::new(AtomicBool::new(false));
3034
3035 unsafe {
3036 let cpp_list = cpp_create_unique_list();
3037 assert!(cpp_unique_list_is_empty(cpp_list));
3038
3039 let obj1 = UniquePtr::try_new(SharedUniqueObject::new(1)).unwrap();
3040 let obj2 = UniquePtr::try_new(SharedUniqueObject::new(2)).unwrap();
3041
3042 let raw1 = UniquePtr::as_ptr(&obj1) as *mut SharedUniqueObject;
3044 (*raw1).destruction_flag = destroyed1.as_ptr() as *mut bool;
3045 let raw2 = UniquePtr::as_ptr(&obj2) as *mut SharedUniqueObject;
3046 (*raw2).destruction_flag = destroyed2.as_ptr() as *mut bool;
3047
3048 cpp_unique_list_push_back(cpp_list, UniquePtr::into_raw(obj1) as *mut c_void);
3050 cpp_unique_list_push_back(cpp_list, UniquePtr::into_raw(obj2) as *mut c_void);
3051
3052 assert!(!destroyed1.load(Ordering::Relaxed));
3053 assert!(!destroyed2.load(Ordering::Relaxed));
3054
3055 let popped = cpp_unique_list_pop_front(cpp_list);
3057 assert!(!popped.is_null());
3058 assert_eq!(cpp_get_unique_object_value(popped), 1);
3059
3060 let popped_rust = UniquePtr::from_raw(popped as *mut SharedUniqueObject);
3062 drop(popped_rust);
3063 assert!(destroyed1.load(Ordering::Relaxed));
3064 assert!(!destroyed2.load(Ordering::Relaxed));
3065
3066 cpp_destroy_unique_list(cpp_list);
3068 }
3069 assert!(destroyed2.load(Ordering::Relaxed));
3070 }
3071
3072 #[test]
3073 fn test_interop_rust_list_cpp_ref_objects() {
3074 let destroyed1 = AtomicBool::new(false);
3075 let destroyed2 = AtomicBool::new(false);
3076
3077 unsafe {
3078 stack_pin_init!(let list = DoublyLinkedList::<RefPtr<SharedRefObject>>::new());
3079 let list = list.get_unchecked_mut();
3080
3081 let cpp_raw1 = cpp_create_ref_object(1, destroyed1.as_ptr() as *mut bool);
3082 let cpp_raw2 = cpp_create_ref_object(2, destroyed2.as_ptr() as *mut bool);
3083
3084 let obj1 = RefPtr::from_raw(cpp_raw1 as *mut SharedRefObject);
3085 let obj2 = RefPtr::from_raw(cpp_raw2 as *mut SharedRefObject);
3086
3087 list.push_back(obj1);
3088 list.push_back(obj2);
3089
3090 assert!(!destroyed1.load(Ordering::Relaxed));
3091 assert!(!destroyed2.load(Ordering::Relaxed));
3092
3093 let popped = list.pop_front();
3095 assert!(popped.is_some());
3096 assert_eq!(popped.as_ref().unwrap().value, 1);
3097
3098 drop(popped);
3100 assert!(destroyed1.load(Ordering::Relaxed));
3101 assert!(!destroyed2.load(Ordering::Relaxed));
3102
3103 }
3105 assert!(destroyed2.load(Ordering::Relaxed));
3106 }
3107
3108 #[test]
3109 fn test_interop_cpp_list_rust_ref_objects() {
3110 let destroyed1 = Arc::new(AtomicBool::new(false));
3111 let destroyed2 = Arc::new(AtomicBool::new(false));
3112
3113 unsafe {
3114 let cpp_list = cpp_create_ref_list();
3115 assert!(cpp_ref_list_is_empty(cpp_list));
3116
3117 let obj1 = SharedRefObject::new_ref_counted(1);
3118 let obj2 = SharedRefObject::new_ref_counted(2);
3119
3120 let raw1 = RefPtr::as_ptr(&obj1) as *mut SharedRefObject;
3122 (*raw1).destruction_flag = destroyed1.as_ptr() as *mut bool;
3123 let raw2 = RefPtr::as_ptr(&obj2) as *mut SharedRefObject;
3124 (*raw2).destruction_flag = destroyed2.as_ptr() as *mut bool;
3125
3126 cpp_ref_list_push_back(
3128 cpp_list,
3129 RefPtr::into_raw(obj1) as *mut SharedRefObject as *mut c_void,
3130 );
3131 cpp_ref_list_push_back(
3132 cpp_list,
3133 RefPtr::into_raw(obj2) as *mut SharedRefObject as *mut c_void,
3134 );
3135
3136 assert!(!destroyed1.load(Ordering::Relaxed));
3137 assert!(!destroyed2.load(Ordering::Relaxed));
3138
3139 let popped = cpp_ref_list_pop_front(cpp_list);
3141 assert!(!popped.is_null());
3142 assert_eq!(cpp_get_ref_object_value(popped), 1);
3143
3144 let popped_rust = RefPtr::from_raw(popped as *mut SharedRefObject);
3146 drop(popped_rust);
3147 assert!(destroyed1.load(Ordering::Relaxed));
3148 assert!(!destroyed2.load(Ordering::Relaxed));
3149
3150 cpp_destroy_ref_list(cpp_list);
3152 }
3153 assert!(destroyed2.load(Ordering::Relaxed));
3154 }
3155}