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}