cordyceps/list.rs
1//! An intrusive doubly-linked list.
2//!
3//! See the [`List`] type for details.
4
5use super::Linked;
6use crate::util::FmtOption;
7use core::{
8 cell::UnsafeCell,
9 fmt, iter,
10 marker::PhantomPinned,
11 mem,
12 pin::Pin,
13 ptr::{self, NonNull},
14};
15
16#[cfg(test)]
17#[cfg(not(loom))]
18mod tests;
19
20mod cursor;
21pub use self::cursor::{Cursor, CursorMut};
22
23/// An [intrusive] doubly-linked list.
24///
25/// This data structure may be used as a first-in, first-out queue by using the
26/// [`List::push_front`] and [`List::pop_back`] methods. It also supports
27/// random-access removals using the [`List::remove`] method. This makes the
28/// [`List`] type suitable for use in cases where elements must be able to drop
29/// themselves while linked into a list.
30///
31/// This data structure can also be used as a stack or doubly-linked list by using
32/// the [`List::pop_front`] and [`List::push_back`] methods.
33///
34/// The [`List`] type is **not** a lock-free data structure, and can only be
35/// modified through `&mut` references.
36///
37/// In order to be part of a `List`, a type `T` must implement [`Linked`] for
38/// [`list::Links<T>`].
39///
40/// # Examples
41///
42/// Implementing the [`Linked`] trait for an entry type:
43///
44/// ```
45/// use cordyceps::{
46/// Linked,
47/// list::{self, List},
48/// };
49///
50/// // This example uses the Rust standard library for convenience, but
51/// // the doubly-linked list itself does not require std.
52/// use std::{pin::Pin, ptr::{self, NonNull}, thread, sync::Arc};
53///
54/// /// A simple queue entry that stores an `i32`.
55/// #[derive(Debug, Default)]
56/// struct Entry {
57/// links: list::Links<Entry>,
58/// val: i32,
59/// }
60///
61/// // Implement the `Linked` trait for our entry type so that it can be used
62/// // as a queue entry.
63/// unsafe impl Linked<list::Links<Entry>> for Entry {
64/// // In this example, our entries will be "owned" by a `Box`, but any
65/// // heap-allocated type that owns an element may be used.
66/// //
67/// // An element *must not* move while part of an intrusive data
68/// // structure. In many cases, `Pin` may be used to enforce this.
69/// type Handle = Pin<Box<Self>>;
70///
71/// /// Convert an owned `Handle` into a raw pointer
72/// fn into_ptr(handle: Pin<Box<Entry>>) -> NonNull<Entry> {
73/// unsafe { NonNull::from(Box::leak(Pin::into_inner_unchecked(handle))) }
74/// }
75///
76/// /// Convert a raw pointer back into an owned `Handle`.
77/// unsafe fn from_ptr(ptr: NonNull<Entry>) -> Pin<Box<Entry>> {
78/// // Safety: if this function is only called by the linked list
79/// // implementation (and it is not intended for external use), we can
80/// // expect that the `NonNull` was constructed from a reference which
81/// // was pinned.
82/// //
83/// // If other callers besides `List`'s internals were to call this on
84/// // some random `NonNull<Entry>`, this would not be the case, and
85/// // this could be constructing an erroneous `Pin` from a referent
86/// // that may not be pinned!
87/// Pin::new_unchecked(Box::from_raw(ptr.as_ptr()))
88/// }
89///
90/// /// Access an element's `Links`.
91/// unsafe fn links(target: NonNull<Entry>) -> NonNull<list::Links<Entry>> {
92/// // Using `ptr::addr_of_mut!` permits us to avoid creating a temporary
93/// // reference without using layout-dependent casts.
94/// let links = ptr::addr_of_mut!((*target.as_ptr()).links);
95///
96/// // `NonNull::new_unchecked` is safe to use here, because the pointer that
97/// // we offset was not null, implying that the pointer produced by offsetting
98/// // it will also not be null.
99/// NonNull::new_unchecked(links)
100/// }
101/// }
102///
103/// impl Entry {
104/// fn new(val: i32) -> Self {
105/// Self {
106/// val,
107/// ..Self::default()
108/// }
109/// }
110/// }
111/// ```
112///
113/// Using a `List` as a first-in, first-out (FIFO) queue with
114/// [`List::push_back`] and [`List::pop_front`]:
115/// ```
116/// # use cordyceps::{
117/// # Linked,
118/// # list::{self, List},
119/// # };
120/// # use std::{pin::Pin, ptr::{self, NonNull}, thread, sync::Arc};
121/// # #[derive(Debug, Default)]
122/// # struct Entry {
123/// # links: list::Links<Entry>,
124/// # val: i32,
125/// # }
126/// # unsafe impl Linked<list::Links<Entry>> for Entry {
127/// # type Handle = Pin<Box<Self>>;
128/// # fn into_ptr(handle: Pin<Box<Entry>>) -> NonNull<Entry> {
129/// # unsafe { NonNull::from(Box::leak(Pin::into_inner_unchecked(handle))) }
130/// # }
131/// # unsafe fn from_ptr(ptr: NonNull<Entry>) -> Pin<Box<Entry>> {
132/// # Pin::new_unchecked(Box::from_raw(ptr.as_ptr()))
133/// # }
134/// # unsafe fn links(target: NonNull<Entry>) -> NonNull<list::Links<Entry>> {
135/// # let links = ptr::addr_of_mut!((*target.as_ptr()).links);
136/// # NonNull::new_unchecked(links)
137/// # }
138/// # }
139/// # impl Entry {
140/// # fn new(val: i32) -> Self {
141/// # Self {
142/// # val,
143/// # ..Self::default()
144/// # }
145/// # }
146/// # }
147/// // Now that we've implemented the `Linked` trait for our `Entry` type, we can
148/// // create a `List` of entries:
149/// let mut list = List::<Entry>::new();
150///
151/// // Push some entries to the list:
152/// for i in 0..5 {
153/// list.push_back(Box::pin(Entry::new(i)));
154/// }
155///
156/// // The list is a doubly-ended queue. We can use the `pop_front` method with
157/// // `push_back` to dequeue elements in FIFO order:
158/// for i in 0..5 {
159/// let entry = list.pop_front()
160/// .expect("the list should have 5 entries in it");
161/// assert_eq!(entry.val, i, "entries are dequeued in FIFO order");
162/// }
163///
164/// assert!(list.is_empty());
165/// ```
166///
167/// Using a `List` as a last-in, first-out (LIFO) stack with
168/// [`List::push_back`] and [`List::pop_back`]:
169/// ```
170/// # use cordyceps::{
171/// # Linked,
172/// # list::{self, List},
173/// # };
174/// # use std::{pin::Pin, ptr::{self, NonNull}, thread, sync::Arc};
175/// # #[derive(Debug, Default)]
176/// # struct Entry {
177/// # links: list::Links<Entry>,
178/// # val: i32,
179/// # }
180/// # unsafe impl Linked<list::Links<Entry>> for Entry {
181/// # type Handle = Pin<Box<Self>>;
182/// # fn into_ptr(handle: Pin<Box<Entry>>) -> NonNull<Entry> {
183/// # unsafe { NonNull::from(Box::leak(Pin::into_inner_unchecked(handle))) }
184/// # }
185/// # unsafe fn from_ptr(ptr: NonNull<Entry>) -> Pin<Box<Entry>> {
186/// # Pin::new_unchecked(Box::from_raw(ptr.as_ptr()))
187/// # }
188/// # unsafe fn links(target: NonNull<Entry>) -> NonNull<list::Links<Entry>> {
189/// # let links = ptr::addr_of_mut!((*target.as_ptr()).links);
190/// # NonNull::new_unchecked(links)
191/// # }
192/// # }
193/// # impl Entry {
194/// # fn new(val: i32) -> Self {
195/// # Self {
196/// # val,
197/// # ..Self::default()
198/// # }
199/// # }
200/// # }
201/// let mut list = List::<Entry>::new();
202///
203/// // Push some entries to the list:
204/// for i in 0..5 {
205/// list.push_back(Box::pin(Entry::new(i)));
206/// }
207///
208/// // Note that we have reversed the direction of the iterator, since
209/// // we are popping from the *back* of the list:
210/// for i in (0..5).into_iter().rev() {
211/// let entry = list.pop_back()
212/// .expect("the list should have 5 entries in it");
213/// assert_eq!(entry.val, i, "entries are dequeued in LIFO order");
214/// }
215///
216/// assert!(list.is_empty());
217/// ```
218///
219/// [intrusive]: crate#intrusive-data-structures
220/// [`list::Links<T>`]: crate::list::Links
221pub struct List<T: Linked<Links<T>> + ?Sized> {
222 head: Link<T>,
223 tail: Link<T>,
224 len: usize,
225}
226
227/// Links to other nodes in a [`List`].
228///
229/// In order to be part of a [`List`], a type must contain an instance of this
230/// type, and must implement the [`Linked`] trait for `Links<Self>`.
231pub struct Links<T: ?Sized> {
232 inner: UnsafeCell<LinksInner<T>>,
233}
234
235/// Iterates over the items in a [`List`] by reference.
236pub struct Iter<'list, T: Linked<Links<T>> + ?Sized> {
237 _list: &'list List<T>,
238
239 /// The current node when iterating head -> tail.
240 curr: Link<T>,
241
242 /// The current node when iterating tail -> head.
243 ///
244 /// This is used by the [`DoubleEndedIterator`] impl.
245 curr_back: Link<T>,
246
247 /// The number of remaining entries in the iterator.
248 len: usize,
249}
250
251/// Iterates over the items in a [`List`] as [`NonNull`]`<T>` node pointers.
252///
253/// Whenever possible, prefer [`Iter`] or [`IterMut`], as they provide
254/// easier-to-hold-right interfaces when iterating over nodes.
255///
256/// ## Safety
257///
258/// Although iteration of items is safe, care must be taken with
259/// the returned `NonNull<T>` nodes. See [`List::iter_raw()`] for
260/// more details on safety invariants.
261pub struct IterRaw<'list, T: Linked<Links<T>> + ?Sized> {
262 _list: &'list List<T>,
263
264 /// The current node when iterating head -> tail.
265 curr: Link<T>,
266
267 /// The current node when iterating tail -> head.
268 ///
269 /// This is used by the [`DoubleEndedIterator`] impl.
270 curr_back: Link<T>,
271
272 /// The number of remaining entries in the iterator.
273 len: usize,
274}
275
276/// Iterates over the items in a [`List`] by mutable reference.
277pub struct IterMut<'list, T: Linked<Links<T>> + ?Sized> {
278 _list: &'list mut List<T>,
279
280 /// The current node when iterating head -> tail.
281 curr: Link<T>,
282
283 /// The current node when iterating tail -> head.
284 ///
285 /// This is used by the [`DoubleEndedIterator`] impl.
286 curr_back: Link<T>,
287
288 /// The number of remaining entries in the iterator.
289 len: usize,
290}
291
292/// An owning iterator over the elements of a [`List`].
293///
294/// This `struct` is created by the [`into_iter`] method on [`List`]
295/// (provided by the [`IntoIterator`] trait). See its documentation for more.
296///
297/// [`into_iter`]: List::into_iter
298/// [`IntoIterator`]: core::iter::IntoIterator
299pub struct IntoIter<T: Linked<Links<T>> + ?Sized> {
300 list: List<T>,
301}
302
303/// An iterator returned by [`List::drain_filter`].
304pub struct DrainFilter<'list, T, F>
305where
306 F: FnMut(&T) -> bool,
307 T: Linked<Links<T>> + ?Sized,
308{
309 cursor: CursorMut<'list, T>,
310 pred: F,
311}
312
313type Link<T> = Option<NonNull<T>>;
314
315#[repr(C)]
316struct LinksInner<T: ?Sized> {
317 next: Link<T>,
318 prev: Link<T>,
319 /// Linked list links must always be `!Unpin`, in order to ensure that they
320 /// never recieve LLVM `noalias` annotations; see also
321 /// <https://github.com/rust-lang/rust/issues/63818>.
322 _unpin: PhantomPinned,
323}
324
325// ==== impl List ====
326
327impl<T: Linked<Links<T>> + ?Sized> List<T> {
328 /// Returns a new empty list.
329 #[must_use]
330 pub const fn new() -> List<T> {
331 List {
332 head: None,
333 tail: None,
334 len: 0,
335 }
336 }
337
338 /// Moves all elements from `other` to the end of the list.
339 ///
340 /// This reuses all the nodes from `other` and moves them into `self`. After
341 /// this operation, `other` becomes empty.
342 ///
343 /// This operation should complete in *O*(1) time and *O*(1) memory.
344 pub fn append(&mut self, other: &mut Self) {
345 // TODO(eliza): this could be rewritten to use `let ... else` when
346 // that's supported on `cordyceps`' MSRV.
347 let tail = match self.tail {
348 Some(tail) => tail,
349 None => {
350 // if this list is empty, simply replace it with `other`
351 debug_assert!(self.is_empty());
352 mem::swap(self, other);
353 return;
354 }
355 };
356
357 // if `other` is empty, do nothing.
358 if let Some((other_head, other_tail, other_len)) = other.take_all() {
359 // attach the other list's head node to this list's tail node.
360 unsafe {
361 T::links(tail).as_mut().set_next(Some(other_head));
362 T::links(other_head).as_mut().set_prev(Some(tail));
363 }
364
365 // this list's tail node is now the other list's tail node.
366 self.tail = Some(other_tail);
367 // this list's length increases by the other list's length, which
368 // becomes 0.
369 self.len += other_len;
370 }
371 }
372
373 /// Attempts to split the list into two at the given index (inclusive).
374 ///
375 /// Returns everything after the given index (including the node at that
376 /// index), or `None` if the index is greater than the list's [length].
377 ///
378 /// This operation should complete in *O*(*n*) time.
379 ///
380 /// # Returns
381 ///
382 /// - [`Some`]`(`[`List`]`<T>)` with a new list containing every element after
383 /// `at`, if `at` <= `self.len()`
384 /// - [`None`] if `at > self.len()`
385 ///
386 /// [length]: Self::len
387 pub fn try_split_off(&mut self, at: usize) -> Option<Self> {
388 let len = self.len();
389 // what is the index of the last node that should be left in this list?
390 let split_idx = match at {
391 // trying to split at the 0th index. we can just return the whole
392 // list, leaving `self` empty.
393 0 => return Some(core::mem::take(self)),
394 // trying to split at the last index. the new list will be empty.
395 at if at == len => return Some(Self::new()),
396 // we cannot split at an index that is greater than the length of
397 // this list.
398 at if at > len => return None,
399 // otherwise, the last node in this list will be `at - 1`.
400 at => at - 1,
401 };
402
403 let mut iter = self.iter();
404
405 // advance to the node at `split_idx`, starting either from the head or
406 // tail of the list.
407 let dist_from_tail = len - 1 - split_idx;
408 let split_node = if split_idx <= dist_from_tail {
409 // advance from the head of the list.
410 for _ in 0..split_idx {
411 iter.next();
412 }
413 iter.curr
414 } else {
415 // advance from the tail of the list.
416 for _ in 0..dist_from_tail {
417 iter.next_back();
418 }
419 iter.curr_back
420 };
421
422 Some(unsafe { self.split_after_node(split_node, at) })
423 }
424
425 /// Split the list into two at the given index (inclusive).
426 ///
427 /// Every element after the given index, including the node at that
428 /// index, is removed from this list, and returned as a new list.
429 ///
430 /// This operation should complete in *O*(*n*) time.
431 ///
432 /// # Returns
433 ///
434 /// A new [`List`]`<T>` containing every element after the index `at` in
435 /// this list.
436 ///
437 /// # Panics
438 ///
439 /// If `at > self.len()`.
440 #[track_caller]
441 #[must_use]
442 pub fn split_off(&mut self, at: usize) -> Self {
443 match self.try_split_off(at) {
444 Some(new_list) => new_list,
445 None => panic!(
446 "Cannot split off at a nonexistent index (the index was {} but the len was {})",
447 at,
448 self.len()
449 ),
450 }
451 }
452
453 /// Returns `true` if this list is empty.
454 #[inline]
455 pub fn is_empty(&self) -> bool {
456 if self.head.is_none() {
457 debug_assert!(
458 self.tail.is_none(),
459 "inconsistent state: a list had a tail but no head!"
460 );
461 debug_assert_eq!(
462 self.len, 0,
463 "inconsistent state: a list was empty, but its length was not zero"
464 );
465 return true;
466 }
467
468 debug_assert_ne!(
469 self.len, 0,
470 "inconsistent state: a list was not empty, but its length was zero"
471 );
472 false
473 }
474
475 /// Returns the number of elements in the list.
476 #[inline]
477 pub fn len(&self) -> usize {
478 self.len
479 }
480
481 /// Asserts as many of the linked list's invariants as possible.
482 #[track_caller]
483 pub fn assert_valid(&self) {
484 self.assert_valid_named("")
485 }
486
487 /// Asserts as many of the linked list's invariants as possible.
488 #[track_caller]
489 pub(crate) fn assert_valid_named(&self, name: &str) {
490 // TODO(eliza): this could be rewritten to use `let ... else` when
491 // that's supported on `cordyceps`' MSRV.
492 let head = match self.head {
493 Some(head) => head,
494 None => {
495 assert!(
496 self.tail.is_none(),
497 "{name}if the linked list's head is null, the tail must also be null"
498 );
499 assert_eq!(
500 self.len, 0,
501 "{name}if a linked list's head is null, its length must be 0"
502 );
503 return;
504 }
505 };
506
507 assert_ne!(
508 self.len, 0,
509 "{name}if a linked list's head is not null, its length must be greater than 0"
510 );
511
512 assert_ne!(
513 self.tail, None,
514 "{name}if the linked list has a head, it must also have a tail"
515 );
516 let tail = self.tail.unwrap();
517
518 let head_links = unsafe { T::links(head) };
519 let tail_links = unsafe { T::links(tail) };
520 let head_links = unsafe { head_links.as_ref() };
521 let tail_links = unsafe { tail_links.as_ref() };
522 // Cast to untyped pointers to ignore wide pointer metadata.
523 // This is equivalent to `core::ptr::addr_eq` but without having to bump
524 // MSRV.
525 if head.cast::<()>() == tail.cast::<()>() {
526 assert_eq!(
527 head_links, tail_links,
528 "{name}if the head and tail nodes are the same, their links must be the same"
529 );
530 assert_eq!(
531 head_links.next(),
532 None,
533 "{name}if the linked list has only one node, it must not be linked"
534 );
535 assert_eq!(
536 head_links.prev(),
537 None,
538 "{name}if the linked list has only one node, it must not be linked"
539 );
540 return;
541 }
542
543 let mut curr = Some(head);
544 let mut actual_len = 0;
545 while let Some(node) = curr {
546 let links = unsafe { T::links(node) };
547 let links = unsafe { links.as_ref() };
548 links.assert_valid(head_links, tail_links);
549 curr = links.next();
550 actual_len += 1;
551 }
552
553 assert_eq!(
554 self.len, actual_len,
555 "{name}linked list's actual length did not match its `len` variable"
556 );
557 }
558
559 /// Removes an item from the tail of the list.
560 ///
561 /// This operation should complete in *O*(1) time.
562 ///
563 /// This returns a [`Handle`] that owns the popped element. Dropping the
564 /// [`Handle`] will drop the element.
565 ///
566 /// # Returns
567 ///
568 /// - [`Some`]`(T::Handle)` containing the last element of this list, if the
569 /// list was not empty.
570 /// - [`None`] if this list is empty.
571 ///
572 /// [`Handle`]: crate::Linked::Handle
573 pub fn pop_back(&mut self) -> Option<T::Handle> {
574 let tail = self.tail?;
575 self.len -= 1;
576
577 unsafe {
578 let mut tail_links = T::links(tail);
579 // tracing::trace!(?self, tail.addr = ?tail, tail.links = ?tail_links, "pop_back");
580 self.tail = tail_links.as_ref().prev();
581 debug_assert_eq!(
582 tail_links.as_ref().next(),
583 None,
584 "the tail node must not have a next link"
585 );
586
587 if let Some(prev) = tail_links.as_mut().prev() {
588 T::links(prev).as_mut().set_next(None);
589 } else {
590 self.head = None;
591 }
592
593 tail_links.as_mut().unlink();
594 // tracing::trace!(?self, tail.links = ?tail_links, "pop_back: popped");
595 Some(T::from_ptr(tail))
596 }
597 }
598
599 /// Removes an item from the head of the list.
600 ///
601 /// This operation should complete in *O*(1) time.
602 ///
603 /// This returns a [`Handle`] that owns the popped element. Dropping the
604 /// [`Handle`] will drop the element.
605 ///
606 /// # Returns
607 ///
608 /// - [`Some`]`(T::Handle)` containing the last element of this list, if the
609 /// list was not empty.
610 /// - [`None`] if this list is empty.
611 ///
612 /// [`Handle`]: crate::Linked::Handle
613 pub fn pop_front(&mut self) -> Option<T::Handle> {
614 let head = self.head?;
615 self.len -= 1;
616
617 unsafe {
618 let mut head_links = T::links(head);
619 self.head = head_links.as_ref().next();
620 if let Some(next) = head_links.as_mut().next() {
621 T::links(next).as_mut().set_prev(None);
622 } else {
623 self.tail = None;
624 }
625
626 head_links.as_mut().unlink();
627 Some(T::from_ptr(head))
628 }
629 }
630
631 /// Appends an item to the tail of the list.
632 ///
633 /// This operation should complete in *O*(1) time.
634 ///
635 /// This takes a [`Handle`] that owns the appended `item`. While the element
636 /// is in the list, it is owned by the list, and will be dropped when the
637 /// list is dropped. If the element is removed or otherwise unlinked from
638 /// the list, ownership is assigned back to the [`Handle`].
639 ///
640 /// [`Handle`]: crate::Linked::Handle
641 pub fn push_back(&mut self, item: T::Handle) {
642 let ptr = T::into_ptr(item);
643 assert_ne!(self.tail, Some(ptr));
644 unsafe {
645 T::links(ptr).as_mut().set_next(None);
646 T::links(ptr).as_mut().set_prev(self.tail);
647 if let Some(tail) = self.tail {
648 T::links(tail).as_mut().set_next(Some(ptr));
649 }
650 }
651
652 self.tail = Some(ptr);
653 if self.head.is_none() {
654 self.head = Some(ptr);
655 }
656
657 self.len += 1;
658 }
659
660 /// Appends an item to the head of the list.
661 ///
662 /// This operation should complete in *O*(1) time.
663 ///
664 /// This takes a [`Handle`] that owns the appended `item`. While the element
665 /// is in the list, it is owned by the list, and will be dropped when the
666 /// list is dropped. If the element is removed or otherwise unlinked from
667 /// the list, ownership is assigned back to the [`Handle`].
668 ///
669 /// [`Handle`]: crate::Linked::Handle
670 pub fn push_front(&mut self, item: T::Handle) {
671 let ptr = T::into_ptr(item);
672 // tracing::trace!(?self, ?ptr, "push_front");
673 assert_ne!(self.head, Some(ptr));
674 unsafe {
675 T::links(ptr).as_mut().set_next(self.head);
676 T::links(ptr).as_mut().set_prev(None);
677 // tracing::trace!(?links);
678 if let Some(head) = self.head {
679 T::links(head).as_mut().set_prev(Some(ptr));
680 // tracing::trace!(head.links = ?T::links(head).as_ref(), "set head prev ptr",);
681 }
682 }
683
684 self.head = Some(ptr);
685
686 if self.tail.is_none() {
687 self.tail = Some(ptr);
688 }
689
690 self.len += 1;
691 // tracing::trace!(?self, "push_front: pushed");
692 }
693
694 /// Returns an immutable reference to the first element in the list.
695 ///
696 /// This operation should complete in *O*(1) time.
697 ///
698 /// The node is [`Pin`]ned in memory, as moving it to a different memory
699 /// location while it is in the list would corrupt the links pointing to
700 /// that node.
701 ///
702 /// # Returns
703 ///
704 /// - [`Some`]`(`[`Pin`]`<&mut T>)` containing a pinned immutable reference to
705 /// the first element of the list, if the list is non-empty.
706 /// - [`None`] if the list is empty.
707 #[must_use]
708 pub fn front(&self) -> Option<Pin<&T>> {
709 let head = self.head?;
710 let pin = unsafe {
711 // NOTE(eliza): in this case, we don't *need* to pin the reference,
712 // because it's immutable and you can't move out of a shared
713 // reference in safe code. but...it makes the API more consistent
714 // with `front_mut` etc.
715 Pin::new_unchecked(head.as_ref())
716 };
717 Some(pin)
718 }
719
720 /// Returns a mutable reference to the first element in the list.
721 ///
722 /// The node is [`Pin`]ned in memory, as moving it to a different memory
723 /// location while it is in the list would corrupt the links pointing to
724 /// that node.
725 ///
726 /// This operation should complete in *O*(1) time.
727 ///
728 /// # Returns
729 ///
730 /// - [`Some`]`(`[`Pin`]`<&mut T>)` containing a pinned mutable reference to
731 /// the first element of the list, if the list is non-empty.
732 /// - [`None`] if the list is empty.
733 #[must_use]
734 pub fn front_mut(&mut self) -> Option<Pin<&mut T>> {
735 let mut node = self.head?;
736 let pin = unsafe {
737 // safety: pinning the returned element is actually *necessary* to
738 // uphold safety invariants here. if we returned `&mut T`, the
739 // element could be `mem::replace`d out of the list, invalidating
740 // any pointers to it. thus, we *must* pin it before returning it.
741 Pin::new_unchecked(node.as_mut())
742 };
743 Some(pin)
744 }
745
746 /// Returns a reference to the last element in the list/
747 ///
748 /// The node is [`Pin`]ned in memory, as moving it to a different memory
749 /// location while it is in the list would corrupt the links pointing to
750 /// that node.
751 ///
752 /// This operation should complete in *O*(1) time.
753 ///
754 /// # Returns
755 ///
756 /// - [`Some`]`(`[`Pin`]`<&T>)` containing a pinned immutable reference to
757 /// the last element of the list, if the list is non-empty.
758 /// - [`None`] if the list is empty.
759 #[must_use]
760 pub fn back(&self) -> Option<Pin<&T>> {
761 let node = self.tail?;
762 let pin = unsafe {
763 // NOTE(eliza): in this case, we don't *need* to pin the reference,
764 // because it's immutable and you can't move out of a shared
765 // reference in safe code. but...it makes the API more consistent
766 // with `front_mut` etc.
767 Pin::new_unchecked(node.as_ref())
768 };
769 Some(pin)
770 }
771
772 /// Returns a mutable reference to the last element in the list, or `None`
773 /// if the list is empty.
774 ///
775 /// The node is [`Pin`]ned in memory, as moving it to a different memory
776 /// location while it is in the list would corrupt the links pointing to
777 /// that node.
778 ///
779 /// This operation should complete in *O*(1) time.
780 ///
781 /// # Returns
782 ///
783 /// - [`Some`]`(`[`Pin`]`<&T>)` containing a pinned mutable reference to
784 /// the last element of the list, if the list is non-empty.
785 /// - [`None`] if the list is empty.
786 #[must_use]
787 pub fn back_mut(&mut self) -> Option<Pin<&mut T>> {
788 let mut node = self.tail?;
789 let pin = unsafe {
790 // safety: pinning the returned element is actually *necessary* to
791 // uphold safety invariants here. if we returned `&mut T`, the
792 // element could be `mem::replace`d out of the list, invalidating
793 // any pointers to it. thus, we *must* pin it before returning it.
794 Pin::new_unchecked(node.as_mut())
795 };
796 Some(pin)
797 }
798
799 /// Remove an arbitrary node from the list.
800 ///
801 /// This operation should complete in *O*(1) time.
802 ///
803 /// This returns a [`Handle`] that owns the popped element. Dropping the
804 /// [`Handle`] will drop the element.
805 ///
806 /// # Returns
807 ///
808 /// - [`Some`]`(T::Handle)` containing a [`Handle`] that owns `item`, if
809 /// `item` is currently linked into this list.
810 /// - [`None`] if `item` is not an element of this list.
811 ///
812 /// [`Handle`]: crate::Linked::Handle
813 ///
814 /// # Safety
815 ///
816 /// The caller *must* ensure that the removed node is an element of this
817 /// linked list, and not any other linked list.
818 pub unsafe fn remove(&mut self, item: NonNull<T>) -> Option<T::Handle> {
819 let mut links = T::links(item);
820 let links = links.as_mut();
821
822 debug_assert!(
823 !self.is_empty() || !links.is_linked(),
824 "tried to remove an item from an empty list, but the item is linked!\n\
825 is the item linked to a different list?\n \
826 item: {item:p}\n links: {links:?}\n list: {self:?}\n"
827 );
828
829 // tracing::trace!(?self, item.addr = ?item, item.links = ?links, "remove");
830 let prev = links.set_prev(None);
831 let next = links.set_next(None);
832
833 if let Some(prev) = prev {
834 T::links(prev).as_mut().set_next(next);
835 } else if self.head != Some(item) {
836 // tracing::trace!(?self.head, "item is not head, but has no prev; return None");
837 return None;
838 } else {
839 debug_assert_ne!(Some(item), next, "node must not be linked to itself");
840 self.head = next;
841 }
842
843 if let Some(next) = next {
844 T::links(next).as_mut().set_prev(prev);
845 } else if self.tail != Some(item) {
846 // tracing::trace!(?self.tail, "item is not tail, but has no prev; return None");
847 return None;
848 } else {
849 debug_assert_ne!(Some(item), prev, "node must not be linked to itself");
850 self.tail = prev;
851 }
852
853 self.len -= 1;
854 // tracing::trace!(?self, item.addr = ?item, "remove: done");
855 Some(T::from_ptr(item))
856 }
857
858 /// Returns a [`CursorMut`] starting at the first element.
859 ///
860 /// The [`CursorMut`] type can be used as a mutable [`Iterator`]. In addition,
861 /// however, it also permits modifying the *structure* of the list by
862 /// inserting or removing elements at the cursor's current position.
863 #[must_use]
864 pub fn cursor_front_mut(&mut self) -> CursorMut<'_, T> {
865 CursorMut::new(self, self.head, 0)
866 }
867
868 /// Returns a [`CursorMut`] starting at the last element.
869 ///
870 /// The [`CursorMut`] type can be used as a mutable [`Iterator`]. In addition,
871 /// however, it also permits modifying the *structure* of the list by
872 /// inserting or removing elements at the cursor's current position.
873 #[must_use]
874 pub fn cursor_back_mut(&mut self) -> CursorMut<'_, T> {
875 let index = self.len().saturating_sub(1);
876 CursorMut::new(self, self.tail, index)
877 }
878
879 /// Returns a [`Cursor`] starting at the first element.
880 ///
881 /// The [`Cursor`] type can be used as [`Iterator`] over this list. In
882 /// addition, it may be seeked back and forth to an arbitrary position in
883 /// the list.
884 #[must_use]
885 pub fn cursor_front(&self) -> Cursor<'_, T> {
886 Cursor::new(self, self.head, 0)
887 }
888
889 /// Returns a [`Cursor`] starting at the last element.
890 ///
891 /// The [`Cursor`] type can be used as [`Iterator`] over this list. In
892 /// addition, it may be seeked back and forth to an arbitrary position in
893 /// the list.
894 #[must_use]
895 pub fn cursor_back(&self) -> Cursor<'_, T> {
896 let index = self.len().saturating_sub(1);
897 Cursor::new(self, self.tail, index)
898 }
899
900 /// Returns an iterator over the items in this list, by reference.
901 #[must_use]
902 pub fn iter(&self) -> Iter<'_, T> {
903 Iter {
904 _list: self,
905 curr: self.head,
906 curr_back: self.tail,
907 len: self.len(),
908 }
909 }
910
911 /// Returns an iterator over the items in this list, by mutable reference.
912 #[must_use]
913 pub fn iter_mut(&mut self) -> IterMut<'_, T> {
914 let curr = self.head;
915 let curr_back = self.tail;
916 let len = self.len();
917 IterMut {
918 _list: self,
919 curr,
920 curr_back,
921 len,
922 }
923 }
924
925 /// Returns an iterator over the items in this list, by pointer.
926 ///
927 /// ## Safety
928 ///
929 /// Although this method is safe, care must be taken with the items
930 /// yielded by the returned iterator.
931 ///
932 /// This iterator returns [`NonNull`]`<T>` of the individual node elements,
933 /// rather than references. This is done to allow "type punning" of nodes,
934 /// where the creation of a reference could restrict the provenance of the
935 /// pointed-to item. This is relevant if your nodes are of a common header
936 /// type, but may have different "body" types you'd like to cast to. This is similar
937 /// to how executors like `maitake` or `tokio` store `Task`s: with a common
938 /// `TaskHeader` but containing varying futured in their bodies. If this is
939 /// NOT a feature you need, consider using [`List::iter()`] or
940 /// [`List::iter_mut()`] instead.
941 ///
942 /// Morally, the elements yielded by this iterator should be treated *as if*
943 /// they were `Pin<NonNull<T>>`, or `Pin<&mut T>`, in that you MUST NOT move
944 /// out of the pointed-to nodes. The nodes are still logically OWNED by the
945 /// list, and must not be removed using this interface. You may still use
946 /// these pointers with whatever provenance they were originally created with,
947 /// allowing for type-punning to a larger type with a common header base.
948 ///
949 /// Unfortunatly we [cannot create] a `Pin<NonNull<T>>`, so you must use the
950 /// pointers yielded by this iterator carefully.
951 ///
952 /// [cannot create]: https://github.com/rust-lang/rust/issues/54815
953 ///
954 /// ## Example
955 ///
956 /// For an end-to-end example of the kind of "spooky type punning" this interface
957 /// aims to allow, check out the [test for `iter_raw`], which demonstrates the
958 /// ability to call a dynamic "print" function on any item in the list, where
959 /// all items are of differing types (but all implement the [`Debug`][core::fmt::Debug]
960 /// trait).
961 ///
962 /// [test for `iter_raw`]: https://github.com/hawkw/mycelium/blob/main/cordyceps/src/list/tests/iter_raw.rs
963 #[must_use]
964 pub fn iter_raw(&mut self) -> IterRaw<'_, T> {
965 IterRaw {
966 _list: self,
967 curr: self.head,
968 curr_back: self.tail,
969 len: self.len(),
970 }
971 }
972
973 /// Returns an iterator which uses a closure to determine if an element
974 /// should be removed from the list.
975 ///
976 /// If the closure returns `true`, then the element is removed and yielded.
977 /// If the closure returns `false`, the element will remain in the list and
978 /// will not be yielded by the iterator.
979 ///
980 /// Note that the closure is *not* permitted to mutate the elements of the
981 /// list, as a mutable reference could be used to improperly unlink list
982 /// nodes.
983 #[must_use]
984 pub fn drain_filter<F>(&mut self, pred: F) -> DrainFilter<'_, T, F>
985 where
986 F: FnMut(&T) -> bool,
987 {
988 let cursor = self.cursor_front_mut();
989 DrainFilter { cursor, pred }
990 }
991
992 /// Inserts the list segment represented by `splice_start` and `splice_end`
993 /// between `next` and `prev`.
994 ///
995 /// # Safety
996 ///
997 /// This method requires the following invariants be upheld:
998 ///
999 /// - `prev` and `next` are part of the same list.
1000 /// - `prev` and `next` are not the same node.
1001 /// - `splice_start` and `splice_end` are part of the same list, which is
1002 /// *not* the same list that `prev` and `next` are part of.
1003 /// - `prev` is `next`'s `prev` node, and `next` is `prev`'s `prev` node.
1004 /// - `splice_start` is ahead of `splice_end` in the list that they came from.
1005 #[inline]
1006 unsafe fn insert_nodes_between(
1007 &mut self,
1008 prev: Link<T>,
1009 next: Link<T>,
1010 splice_start: NonNull<T>,
1011 splice_end: NonNull<T>,
1012 spliced_length: usize,
1013 ) {
1014 debug_assert!(
1015 (prev.is_none() && next.is_none()) || prev != next,
1016 "cannot insert between a node and itself!\n \
1017 prev: {prev:?}\n next: {next:?}",
1018 );
1019 // This method takes care not to create multiple mutable references to
1020 // whole nodes at the same time, to maintain validity of aliasing
1021 // pointers into `element`.
1022
1023 if let Some(prev) = prev {
1024 let links = T::links(prev).as_mut();
1025 debug_assert_eq!(links.next(), next);
1026 links.set_next(Some(splice_start));
1027 } else {
1028 self.head = Some(splice_start);
1029 }
1030
1031 if let Some(next) = next {
1032 let links = T::links(next).as_mut();
1033 debug_assert_eq!(links.prev(), prev);
1034 links.set_prev(Some(splice_end));
1035 } else {
1036 self.tail = Some(splice_end);
1037 }
1038
1039 let start_links = T::links(splice_start).as_mut();
1040 let end_links = T::links(splice_end).as_mut();
1041 debug_assert!(
1042 // cast to untyped ptrs to ignore wide ptr metadata
1043 splice_start.cast::<()>() == splice_end.cast::<()>()
1044 || (start_links.next().is_some() && end_links.prev().is_some()),
1045 "splice_start must be ahead of splice_end!\n \
1046 splice_start: {splice_start:?}\n \
1047 splice_end: {splice_end:?}\n \
1048 start_links: {start_links:?}\n \
1049 end_links: {end_links:?}",
1050 );
1051
1052 start_links.set_prev(prev);
1053 end_links.set_next(next);
1054
1055 self.len += spliced_length;
1056 }
1057
1058 #[inline]
1059 unsafe fn split_after_node(&mut self, split_node: Link<T>, idx: usize) -> Self {
1060 // TODO(eliza): this could be rewritten to use `let ... else` when
1061 // that's supported on `cordyceps`' MSRV.
1062 let split_node = match split_node {
1063 Some(node) => node,
1064 None => return core::mem::take(self),
1065 };
1066
1067 // the head of the new list is the split node's `next` node (which is
1068 // replaced with `None`)
1069 let head = unsafe { T::links(split_node).as_mut().set_next(None) };
1070 let tail = if let Some(head) = head {
1071 // since `head` is now the head of its own list, it has no `prev`
1072 // link any more.
1073 let _prev = unsafe { T::links(head).as_mut().set_prev(None) };
1074 debug_assert_eq!(_prev, Some(split_node));
1075
1076 // the tail of the new list is this list's old tail, if the split list
1077 // is not empty.
1078 self.tail.replace(split_node)
1079 } else {
1080 None
1081 };
1082
1083 let split = Self {
1084 head,
1085 tail,
1086 len: self.len - idx,
1087 };
1088
1089 // update this list's length (note that this occurs after constructing
1090 // the new list, because we use this list's length to determine the new
1091 // list's length).
1092 self.len = idx;
1093
1094 split
1095 }
1096
1097 /// Empties this list, returning its head, tail, and length if it is
1098 /// non-empty. If the list is empty, this returns `None`.
1099 #[inline]
1100 fn take_all(&mut self) -> Option<(NonNull<T>, NonNull<T>, usize)> {
1101 let head = self.head.take()?;
1102 let tail = self.tail.take();
1103 debug_assert!(
1104 tail.is_some(),
1105 "if a list's `head` is `Some`, its tail must also be `Some`"
1106 );
1107 let tail = tail?;
1108 let len = mem::replace(&mut self.len, 0);
1109 debug_assert_ne!(
1110 len, 0,
1111 "if a list is non-empty, its `len` must be greater than 0"
1112 );
1113 Some((head, tail, len))
1114 }
1115}
1116
1117impl<T> iter::Extend<T::Handle> for List<T>
1118where
1119 T: Linked<Links<T>> + ?Sized,
1120{
1121 fn extend<I: IntoIterator<Item = T::Handle>>(&mut self, iter: I) {
1122 for item in iter {
1123 self.push_back(item);
1124 }
1125 }
1126
1127 // TODO(eliza): when `Extend::extend_one` becomes stable, implement that
1128 // as well, so that we can just call `push_back` without looping.
1129}
1130
1131impl<T> iter::FromIterator<T::Handle> for List<T>
1132where
1133 T: Linked<Links<T>> + ?Sized,
1134{
1135 fn from_iter<I: IntoIterator<Item = T::Handle>>(iter: I) -> Self {
1136 let mut list = Self::new();
1137 list.extend(iter);
1138 list
1139 }
1140}
1141
1142unsafe impl<T: Linked<Links<T>> + ?Sized> Send for List<T> where T: Send {}
1143unsafe impl<T: Linked<Links<T>> + ?Sized> Sync for List<T> where T: Sync {}
1144
1145impl<T: Linked<Links<T>> + ?Sized> fmt::Debug for List<T> {
1146 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1147 let Self { head, tail, len } = self;
1148 f.debug_struct("List")
1149 .field("head", &FmtOption::new(head))
1150 .field("tail", &FmtOption::new(tail))
1151 .field("len", len)
1152 .finish()
1153 }
1154}
1155
1156impl<'list, T: Linked<Links<T>> + ?Sized> IntoIterator for &'list List<T> {
1157 type Item = &'list T;
1158 type IntoIter = Iter<'list, T>;
1159
1160 #[inline]
1161 fn into_iter(self) -> Self::IntoIter {
1162 self.iter()
1163 }
1164}
1165
1166impl<'list, T: Linked<Links<T>> + ?Sized> IntoIterator for &'list mut List<T> {
1167 type Item = Pin<&'list mut T>;
1168 type IntoIter = IterMut<'list, T>;
1169
1170 #[inline]
1171 fn into_iter(self) -> Self::IntoIter {
1172 self.iter_mut()
1173 }
1174}
1175
1176impl<T: Linked<Links<T>> + ?Sized> IntoIterator for List<T> {
1177 type Item = T::Handle;
1178 type IntoIter = IntoIter<T>;
1179
1180 #[inline]
1181 fn into_iter(self) -> Self::IntoIter {
1182 IntoIter { list: self }
1183 }
1184}
1185
1186impl<T: Linked<Links<T>> + ?Sized> Drop for List<T> {
1187 fn drop(&mut self) {
1188 while let Some(node) = self.pop_front() {
1189 drop(node);
1190 }
1191
1192 debug_assert!(self.is_empty());
1193 }
1194}
1195
1196impl<T: Linked<Links<T>> + ?Sized> Default for List<T> {
1197 fn default() -> Self {
1198 Self::new()
1199 }
1200}
1201
1202// ==== impl Links ====
1203
1204impl<T: ?Sized> Links<T> {
1205 /// Returns new links for a [doubly-linked intrusive list](List).
1206 #[must_use]
1207 pub const fn new() -> Self {
1208 Self {
1209 inner: UnsafeCell::new(LinksInner {
1210 next: None,
1211 prev: None,
1212 _unpin: PhantomPinned,
1213 }),
1214 }
1215 }
1216
1217 /// Returns `true` if this node is currently linked to a [`List`].
1218 pub fn is_linked(&self) -> bool {
1219 self.next().is_some() || self.prev().is_some()
1220 }
1221
1222 fn unlink(&mut self) {
1223 self.inner.get_mut().next = None;
1224 self.inner.get_mut().prev = None;
1225 }
1226
1227 #[inline]
1228 fn next(&self) -> Link<T> {
1229 unsafe { (*self.inner.get()).next }
1230 }
1231
1232 #[inline]
1233 fn prev(&self) -> Link<T> {
1234 unsafe { (*self.inner.get()).prev }
1235 }
1236
1237 #[inline]
1238 fn set_next(&mut self, next: Link<T>) -> Link<T> {
1239 mem::replace(&mut self.inner.get_mut().next, next)
1240 }
1241
1242 #[inline]
1243 fn set_prev(&mut self, prev: Link<T>) -> Link<T> {
1244 mem::replace(&mut self.inner.get_mut().prev, prev)
1245 }
1246
1247 fn assert_valid(&self, head: &Self, tail: &Self)
1248 where
1249 T: Linked<Self>,
1250 {
1251 if ptr::eq(self, head) {
1252 assert_eq!(
1253 self.prev(),
1254 None,
1255 "head node must not have a prev link; node={self:#?}",
1256 );
1257 }
1258
1259 if ptr::eq(self, tail) {
1260 assert_eq!(
1261 self.next(),
1262 None,
1263 "tail node must not have a next link; node={self:#?}",
1264 );
1265 }
1266
1267 assert_ne!(
1268 self.next(),
1269 self.prev(),
1270 "node cannot be linked in a loop; node={self:#?}",
1271 );
1272
1273 if let Some(next) = self.next() {
1274 assert_ne!(
1275 unsafe { T::links(next) },
1276 NonNull::from(self),
1277 "node's next link cannot be to itself; node={self:#?}",
1278 );
1279 }
1280 if let Some(prev) = self.prev() {
1281 assert_ne!(
1282 unsafe { T::links(prev) },
1283 NonNull::from(self),
1284 "node's prev link cannot be to itself; node={self:#?}",
1285 );
1286 }
1287 }
1288}
1289
1290impl<T: ?Sized> Default for Links<T> {
1291 fn default() -> Self {
1292 Self::new()
1293 }
1294}
1295
1296impl<T: ?Sized> fmt::Debug for Links<T> {
1297 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1298 f.debug_struct("Links")
1299 .field("self", &format_args!("{self:p}"))
1300 .field("next", &FmtOption::new(&self.next()))
1301 .field("prev", &FmtOption::new(&self.prev()))
1302 .finish()
1303 }
1304}
1305
1306impl<T: ?Sized> PartialEq for Links<T> {
1307 fn eq(&self, other: &Self) -> bool {
1308 self.next() == other.next() && self.prev() == other.prev()
1309 }
1310}
1311
1312/// # Safety
1313///
1314/// Types containing [`Links`] may be `Send`: the pointers within the `Links` may
1315/// mutably alias another value, but the links can only be _accessed_ by the
1316/// owner of the [`List`] itself, because the pointers are private. As long as
1317/// [`List`] upholds its own invariants, `Links` should not make a type `!Send`.
1318unsafe impl<T: Send> Send for Links<T> {}
1319
1320/// # Safety
1321///
1322/// Types containing [`Links`] may be `Sync`: the pointers within the `Links` may
1323/// mutably alias another value, but the links can only be _accessed_ by the
1324/// owner of the [`List`] itself, because the pointers are private. As long as
1325/// [`List`] upholds its own invariants, `Links` should not make a type `!Sync`.
1326unsafe impl<T: Sync> Sync for Links<T> {}
1327
1328// === impl Iter ====
1329
1330impl<'list, T: Linked<Links<T>> + ?Sized> Iterator for Iter<'list, T> {
1331 type Item = &'list T;
1332
1333 fn next(&mut self) -> Option<Self::Item> {
1334 if self.len == 0 {
1335 return None;
1336 }
1337
1338 let curr = self.curr.take()?;
1339 self.len -= 1;
1340 unsafe {
1341 // safety: it is safe for us to borrow `curr`, because the iterator
1342 // borrows the `List`, ensuring that the list will not be dropped
1343 // while the iterator exists. the returned item will not outlive the
1344 // iterator.
1345 self.curr = T::links(curr).as_ref().next();
1346 Some(curr.as_ref())
1347 }
1348 }
1349
1350 #[inline]
1351 fn size_hint(&self) -> (usize, Option<usize>) {
1352 let len = self.len();
1353 (len, Some(len))
1354 }
1355}
1356
1357impl<T: Linked<Links<T>> + ?Sized> ExactSizeIterator for Iter<'_, T> {
1358 #[inline]
1359 fn len(&self) -> usize {
1360 self.len
1361 }
1362}
1363
1364impl<T: Linked<Links<T>> + ?Sized> DoubleEndedIterator for Iter<'_, T> {
1365 fn next_back(&mut self) -> Option<Self::Item> {
1366 if self.len == 0 {
1367 return None;
1368 }
1369
1370 let curr = self.curr_back.take()?;
1371 self.len -= 1;
1372 unsafe {
1373 // safety: it is safe for us to borrow `curr`, because the iterator
1374 // borrows the `List`, ensuring that the list will not be dropped
1375 // while the iterator exists. the returned item will not outlive the
1376 // iterator.
1377 self.curr_back = T::links(curr).as_ref().prev();
1378 Some(curr.as_ref())
1379 }
1380 }
1381}
1382
1383impl<T: Linked<Links<T>> + ?Sized> iter::FusedIterator for Iter<'_, T> {}
1384
1385// === impl IterMut ====
1386
1387impl<'list, T: Linked<Links<T>> + ?Sized> Iterator for IterMut<'list, T> {
1388 type Item = Pin<&'list mut T>;
1389
1390 fn next(&mut self) -> Option<Self::Item> {
1391 if self.len == 0 {
1392 return None;
1393 }
1394
1395 let mut curr = self.curr.take()?;
1396 self.len -= 1;
1397 unsafe {
1398 // safety: it is safe for us to borrow `curr`, because the iterator
1399 // borrows the `List`, ensuring that the list will not be dropped
1400 // while the iterator exists. the returned item will not outlive the
1401 // iterator.
1402 self.curr = T::links(curr).as_ref().next();
1403
1404 // safety: pinning the returned element is actually *necessary* to
1405 // uphold safety invariants here. if we returned `&mut T`, the
1406 // element could be `mem::replace`d out of the list, invalidating
1407 // any pointers to it. thus, we *must* pin it before returning it.
1408 let pin = Pin::new_unchecked(curr.as_mut());
1409 Some(pin)
1410 }
1411 }
1412
1413 #[inline]
1414 fn size_hint(&self) -> (usize, Option<usize>) {
1415 let len = self.len();
1416 (len, Some(len))
1417 }
1418}
1419
1420impl<T: Linked<Links<T>> + ?Sized> ExactSizeIterator for IterMut<'_, T> {
1421 #[inline]
1422 fn len(&self) -> usize {
1423 self.len
1424 }
1425}
1426
1427impl<T: Linked<Links<T>> + ?Sized> DoubleEndedIterator for IterMut<'_, T> {
1428 fn next_back(&mut self) -> Option<Self::Item> {
1429 if self.len == 0 {
1430 return None;
1431 }
1432
1433 let mut curr = self.curr_back.take()?;
1434 self.len -= 1;
1435 unsafe {
1436 // safety: it is safe for us to borrow `curr`, because the iterator
1437 // borrows the `List`, ensuring that the list will not be dropped
1438 // while the iterator exists. the returned item will not outlive the
1439 // iterator.
1440 self.curr_back = T::links(curr).as_ref().prev();
1441
1442 // safety: pinning the returned element is actually *necessary* to
1443 // uphold safety invariants here. if we returned `&mut T`, the
1444 // element could be `mem::replace`d out of the list, invalidating
1445 // any pointers to it. thus, we *must* pin it before returning it.
1446 let pin = Pin::new_unchecked(curr.as_mut());
1447 Some(pin)
1448 }
1449 }
1450}
1451
1452impl<T: Linked<Links<T>> + ?Sized> iter::FusedIterator for IterMut<'_, T> {}
1453
1454// === impl RawIter ====
1455
1456impl<T: Linked<Links<T>> + ?Sized> Iterator for IterRaw<'_, T> {
1457 type Item = NonNull<T>;
1458
1459 fn next(&mut self) -> Option<Self::Item> {
1460 if self.len == 0 {
1461 return None;
1462 }
1463
1464 let curr = self.curr.take()?;
1465 self.len -= 1;
1466 unsafe {
1467 // safety: it is safe for us to borrow `curr`, because the iterator
1468 // borrows the `List`, ensuring that the list will not be dropped
1469 // while the iterator exists. the returned item will not outlive the
1470 // iterator.
1471 self.curr = T::links(curr).as_ref().next();
1472 Some(curr)
1473 }
1474 }
1475
1476 #[inline]
1477 fn size_hint(&self) -> (usize, Option<usize>) {
1478 let len = self.len();
1479 (len, Some(len))
1480 }
1481}
1482
1483impl<T: Linked<Links<T>> + ?Sized> ExactSizeIterator for IterRaw<'_, T> {
1484 #[inline]
1485 fn len(&self) -> usize {
1486 self.len
1487 }
1488}
1489
1490impl<T: Linked<Links<T>> + ?Sized> DoubleEndedIterator for IterRaw<'_, T> {
1491 fn next_back(&mut self) -> Option<Self::Item> {
1492 if self.len == 0 {
1493 return None;
1494 }
1495
1496 let curr = self.curr_back.take()?;
1497 self.len -= 1;
1498 unsafe {
1499 // safety: it is safe for us to borrow `curr`, because the iterator
1500 // borrows the `List`, ensuring that the list will not be dropped
1501 // while the iterator exists. the returned item will not outlive the
1502 // iterator.
1503 self.curr_back = T::links(curr).as_ref().prev();
1504 Some(curr)
1505 }
1506 }
1507}
1508
1509impl<T: Linked<Links<T>> + ?Sized> iter::FusedIterator for IterRaw<'_, T> {}
1510
1511// === impl IntoIter ===
1512
1513impl<T: Linked<Links<T>> + ?Sized> fmt::Debug for IntoIter<T> {
1514 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1515 let Self { list } = self;
1516 f.debug_tuple("IntoIter").field(list).finish()
1517 }
1518}
1519
1520impl<T: Linked<Links<T>> + ?Sized> Iterator for IntoIter<T> {
1521 type Item = T::Handle;
1522
1523 #[inline]
1524 fn next(&mut self) -> Option<T::Handle> {
1525 self.list.pop_front()
1526 }
1527
1528 #[inline]
1529 fn size_hint(&self) -> (usize, Option<usize>) {
1530 (self.list.len, Some(self.list.len))
1531 }
1532}
1533
1534impl<T: Linked<Links<T>> + ?Sized> DoubleEndedIterator for IntoIter<T> {
1535 #[inline]
1536 fn next_back(&mut self) -> Option<T::Handle> {
1537 self.list.pop_back()
1538 }
1539}
1540
1541impl<T: Linked<Links<T>> + ?Sized> ExactSizeIterator for IntoIter<T> {
1542 #[inline]
1543 fn len(&self) -> usize {
1544 self.list.len
1545 }
1546}
1547
1548impl<T: Linked<Links<T>> + ?Sized> iter::FusedIterator for IntoIter<T> {}
1549
1550// === impl DrainFilter ===
1551
1552impl<T, F> Iterator for DrainFilter<'_, T, F>
1553where
1554 F: FnMut(&T) -> bool,
1555 T: Linked<Links<T>> + ?Sized,
1556{
1557 type Item = T::Handle;
1558
1559 #[inline]
1560 fn next(&mut self) -> Option<Self::Item> {
1561 self.cursor.remove_first(&mut self.pred)
1562 }
1563
1564 fn size_hint(&self) -> (usize, Option<usize>) {
1565 (0, Some(self.cursor.len()))
1566 }
1567}
1568
1569impl<T, F> fmt::Debug for DrainFilter<'_, T, F>
1570where
1571 F: FnMut(&T) -> bool,
1572 T: Linked<Links<T>> + ?Sized,
1573{
1574 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1575 let Self { cursor, pred: _ } = self;
1576 f.debug_struct("DrainFilter")
1577 .field("cursor", cursor)
1578 .field("pred", &format_args!("..."))
1579 .finish()
1580 }
1581}