kernel/list.rs
1// SPDX-License-Identifier: GPL-2.0
2
3// Copyright (C) 2024 Google LLC.
4
5//! A linked list implementation.
6
7// May not be needed in Rust 1.87.0 (pending beta backport).
8#![allow(clippy::ptr_eq)]
9
10use crate::init::PinInit;
11use crate::sync::ArcBorrow;
12use crate::types::Opaque;
13use core::iter::{DoubleEndedIterator, FusedIterator};
14use core::marker::PhantomData;
15use core::ptr;
16
17mod impl_list_item_mod;
18pub use self::impl_list_item_mod::{
19 impl_has_list_links, impl_has_list_links_self_ptr, impl_list_item, HasListLinks, HasSelfPtr,
20};
21
22mod arc;
23pub use self::arc::{impl_list_arc_safe, AtomicTracker, ListArc, ListArcSafe, TryNewListArc};
24
25mod arc_field;
26pub use self::arc_field::{define_list_arc_field_getter, ListArcField};
27
28/// A linked list.
29///
30/// All elements in this linked list will be [`ListArc`] references to the value. Since a value can
31/// only have one `ListArc` (for each pair of prev/next pointers), this ensures that the same
32/// prev/next pointers are not used for several linked lists.
33///
34/// # Invariants
35///
36/// * If the list is empty, then `first` is null. Otherwise, `first` points at the `ListLinks`
37/// field of the first element in the list.
38/// * All prev/next pointers in `ListLinks` fields of items in the list are valid and form a cycle.
39/// * For every item in the list, the list owns the associated [`ListArc`] reference and has
40/// exclusive access to the `ListLinks` field.
41pub struct List<T: ?Sized + ListItem<ID>, const ID: u64 = 0> {
42 first: *mut ListLinksFields,
43 _ty: PhantomData<ListArc<T, ID>>,
44}
45
46// SAFETY: This is a container of `ListArc<T, ID>`, and access to the container allows the same
47// type of access to the `ListArc<T, ID>` elements.
48unsafe impl<T, const ID: u64> Send for List<T, ID>
49where
50 ListArc<T, ID>: Send,
51 T: ?Sized + ListItem<ID>,
52{
53}
54// SAFETY: This is a container of `ListArc<T, ID>`, and access to the container allows the same
55// type of access to the `ListArc<T, ID>` elements.
56unsafe impl<T, const ID: u64> Sync for List<T, ID>
57where
58 ListArc<T, ID>: Sync,
59 T: ?Sized + ListItem<ID>,
60{
61}
62
63/// Implemented by types where a [`ListArc<Self>`] can be inserted into a [`List`].
64///
65/// # Safety
66///
67/// Implementers must ensure that they provide the guarantees documented on methods provided by
68/// this trait.
69///
70/// [`ListArc<Self>`]: ListArc
71pub unsafe trait ListItem<const ID: u64 = 0>: ListArcSafe<ID> {
72 /// Views the [`ListLinks`] for this value.
73 ///
74 /// # Guarantees
75 ///
76 /// If there is a previous call to `prepare_to_insert` and there is no call to `post_remove`
77 /// since the most recent such call, then this returns the same pointer as the one returned by
78 /// the most recent call to `prepare_to_insert`.
79 ///
80 /// Otherwise, the returned pointer points at a read-only [`ListLinks`] with two null pointers.
81 ///
82 /// # Safety
83 ///
84 /// The provided pointer must point at a valid value. (It need not be in an `Arc`.)
85 unsafe fn view_links(me: *const Self) -> *mut ListLinks<ID>;
86
87 /// View the full value given its [`ListLinks`] field.
88 ///
89 /// Can only be used when the value is in a list.
90 ///
91 /// # Guarantees
92 ///
93 /// * Returns the same pointer as the one passed to the most recent call to `prepare_to_insert`.
94 /// * The returned pointer is valid until the next call to `post_remove`.
95 ///
96 /// # Safety
97 ///
98 /// * The provided pointer must originate from the most recent call to `prepare_to_insert`, or
99 /// from a call to `view_links` that happened after the most recent call to
100 /// `prepare_to_insert`.
101 /// * Since the most recent call to `prepare_to_insert`, the `post_remove` method must not have
102 /// been called.
103 unsafe fn view_value(me: *mut ListLinks<ID>) -> *const Self;
104
105 /// This is called when an item is inserted into a [`List`].
106 ///
107 /// # Guarantees
108 ///
109 /// The caller is granted exclusive access to the returned [`ListLinks`] until `post_remove` is
110 /// called.
111 ///
112 /// # Safety
113 ///
114 /// * The provided pointer must point at a valid value in an [`Arc`].
115 /// * Calls to `prepare_to_insert` and `post_remove` on the same value must alternate.
116 /// * The caller must own the [`ListArc`] for this value.
117 /// * The caller must not give up ownership of the [`ListArc`] unless `post_remove` has been
118 /// called after this call to `prepare_to_insert`.
119 ///
120 /// [`Arc`]: crate::sync::Arc
121 unsafe fn prepare_to_insert(me: *const Self) -> *mut ListLinks<ID>;
122
123 /// This undoes a previous call to `prepare_to_insert`.
124 ///
125 /// # Guarantees
126 ///
127 /// The returned pointer is the pointer that was originally passed to `prepare_to_insert`.
128 ///
129 /// # Safety
130 ///
131 /// The provided pointer must be the pointer returned by the most recent call to
132 /// `prepare_to_insert`.
133 unsafe fn post_remove(me: *mut ListLinks<ID>) -> *const Self;
134}
135
136#[repr(C)]
137#[derive(Copy, Clone)]
138struct ListLinksFields {
139 next: *mut ListLinksFields,
140 prev: *mut ListLinksFields,
141}
142
143/// The prev/next pointers for an item in a linked list.
144///
145/// # Invariants
146///
147/// The fields are null if and only if this item is not in a list.
148#[repr(transparent)]
149pub struct ListLinks<const ID: u64 = 0> {
150 // This type is `!Unpin` for aliasing reasons as the pointers are part of an intrusive linked
151 // list.
152 inner: Opaque<ListLinksFields>,
153}
154
155// SAFETY: The only way to access/modify the pointers inside of `ListLinks<ID>` is via holding the
156// associated `ListArc<T, ID>`. Since that type correctly implements `Send`, it is impossible to
157// move this an instance of this type to a different thread if the pointees are `!Send`.
158unsafe impl<const ID: u64> Send for ListLinks<ID> {}
159// SAFETY: The type is opaque so immutable references to a ListLinks are useless. Therefore, it's
160// okay to have immutable access to a ListLinks from several threads at once.
161unsafe impl<const ID: u64> Sync for ListLinks<ID> {}
162
163impl<const ID: u64> ListLinks<ID> {
164 /// Creates a new initializer for this type.
165 pub fn new() -> impl PinInit<Self> {
166 // INVARIANT: Pin-init initializers can't be used on an existing `Arc`, so this value will
167 // not be constructed in an `Arc` that already has a `ListArc`.
168 ListLinks {
169 inner: Opaque::new(ListLinksFields {
170 prev: ptr::null_mut(),
171 next: ptr::null_mut(),
172 }),
173 }
174 }
175
176 /// # Safety
177 ///
178 /// `me` must be dereferenceable.
179 #[inline]
180 unsafe fn fields(me: *mut Self) -> *mut ListLinksFields {
181 // SAFETY: The caller promises that the pointer is valid.
182 unsafe { Opaque::raw_get(ptr::addr_of!((*me).inner)) }
183 }
184
185 /// # Safety
186 ///
187 /// `me` must be dereferenceable.
188 #[inline]
189 unsafe fn from_fields(me: *mut ListLinksFields) -> *mut Self {
190 me.cast()
191 }
192}
193
194/// Similar to [`ListLinks`], but also contains a pointer to the full value.
195///
196/// This type can be used instead of [`ListLinks`] to support lists with trait objects.
197#[repr(C)]
198pub struct ListLinksSelfPtr<T: ?Sized, const ID: u64 = 0> {
199 /// The `ListLinks` field inside this value.
200 ///
201 /// This is public so that it can be used with `impl_has_list_links!`.
202 pub inner: ListLinks<ID>,
203 // UnsafeCell is not enough here because we use `Opaque::uninit` as a dummy value, and
204 // `ptr::null()` doesn't work for `T: ?Sized`.
205 self_ptr: Opaque<*const T>,
206}
207
208// SAFETY: The fields of a ListLinksSelfPtr can be moved across thread boundaries.
209unsafe impl<T: ?Sized + Send, const ID: u64> Send for ListLinksSelfPtr<T, ID> {}
210// SAFETY: The type is opaque so immutable references to a ListLinksSelfPtr are useless. Therefore,
211// it's okay to have immutable access to a ListLinks from several threads at once.
212//
213// Note that `inner` being a public field does not prevent this type from being opaque, since
214// `inner` is a opaque type.
215unsafe impl<T: ?Sized + Sync, const ID: u64> Sync for ListLinksSelfPtr<T, ID> {}
216
217impl<T: ?Sized, const ID: u64> ListLinksSelfPtr<T, ID> {
218 /// The offset from the [`ListLinks`] to the self pointer field.
219 pub const LIST_LINKS_SELF_PTR_OFFSET: usize = core::mem::offset_of!(Self, self_ptr);
220
221 /// Creates a new initializer for this type.
222 pub fn new() -> impl PinInit<Self> {
223 // INVARIANT: Pin-init initializers can't be used on an existing `Arc`, so this value will
224 // not be constructed in an `Arc` that already has a `ListArc`.
225 Self {
226 inner: ListLinks {
227 inner: Opaque::new(ListLinksFields {
228 prev: ptr::null_mut(),
229 next: ptr::null_mut(),
230 }),
231 },
232 self_ptr: Opaque::uninit(),
233 }
234 }
235}
236
237impl<T: ?Sized + ListItem<ID>, const ID: u64> List<T, ID> {
238 /// Creates a new empty list.
239 pub const fn new() -> Self {
240 Self {
241 first: ptr::null_mut(),
242 _ty: PhantomData,
243 }
244 }
245
246 /// Returns whether this list is empty.
247 pub fn is_empty(&self) -> bool {
248 self.first.is_null()
249 }
250
251 /// Add the provided item to the back of the list.
252 pub fn push_back(&mut self, item: ListArc<T, ID>) {
253 let raw_item = ListArc::into_raw(item);
254 // SAFETY:
255 // * We just got `raw_item` from a `ListArc`, so it's in an `Arc`.
256 // * Since we have ownership of the `ListArc`, `post_remove` must have been called after
257 // the most recent call to `prepare_to_insert`, if any.
258 // * We own the `ListArc`.
259 // * Removing items from this list is always done using `remove_internal_inner`, which
260 // calls `post_remove` before giving up ownership.
261 let list_links = unsafe { T::prepare_to_insert(raw_item) };
262 // SAFETY: We have not yet called `post_remove`, so `list_links` is still valid.
263 let item = unsafe { ListLinks::fields(list_links) };
264
265 if self.first.is_null() {
266 self.first = item;
267 // SAFETY: The caller just gave us ownership of these fields.
268 // INVARIANT: A linked list with one item should be cyclic.
269 unsafe {
270 (*item).next = item;
271 (*item).prev = item;
272 }
273 } else {
274 let next = self.first;
275 // SAFETY: By the type invariant, this pointer is valid or null. We just checked that
276 // it's not null, so it must be valid.
277 let prev = unsafe { (*next).prev };
278 // SAFETY: Pointers in a linked list are never dangling, and the caller just gave us
279 // ownership of the fields on `item`.
280 // INVARIANT: This correctly inserts `item` between `prev` and `next`.
281 unsafe {
282 (*item).next = next;
283 (*item).prev = prev;
284 (*prev).next = item;
285 (*next).prev = item;
286 }
287 }
288 }
289
290 /// Add the provided item to the front of the list.
291 pub fn push_front(&mut self, item: ListArc<T, ID>) {
292 let raw_item = ListArc::into_raw(item);
293 // SAFETY:
294 // * We just got `raw_item` from a `ListArc`, so it's in an `Arc`.
295 // * If this requirement is violated, then the previous caller of `prepare_to_insert`
296 // violated the safety requirement that they can't give up ownership of the `ListArc`
297 // until they call `post_remove`.
298 // * We own the `ListArc`.
299 // * Removing items] from this list is always done using `remove_internal_inner`, which
300 // calls `post_remove` before giving up ownership.
301 let list_links = unsafe { T::prepare_to_insert(raw_item) };
302 // SAFETY: We have not yet called `post_remove`, so `list_links` is still valid.
303 let item = unsafe { ListLinks::fields(list_links) };
304
305 if self.first.is_null() {
306 // SAFETY: The caller just gave us ownership of these fields.
307 // INVARIANT: A linked list with one item should be cyclic.
308 unsafe {
309 (*item).next = item;
310 (*item).prev = item;
311 }
312 } else {
313 let next = self.first;
314 // SAFETY: We just checked that `next` is non-null.
315 let prev = unsafe { (*next).prev };
316 // SAFETY: Pointers in a linked list are never dangling, and the caller just gave us
317 // ownership of the fields on `item`.
318 // INVARIANT: This correctly inserts `item` between `prev` and `next`.
319 unsafe {
320 (*item).next = next;
321 (*item).prev = prev;
322 (*prev).next = item;
323 (*next).prev = item;
324 }
325 }
326 self.first = item;
327 }
328
329 /// Removes the last item from this list.
330 pub fn pop_back(&mut self) -> Option<ListArc<T, ID>> {
331 if self.first.is_null() {
332 return None;
333 }
334
335 // SAFETY: We just checked that the list is not empty.
336 let last = unsafe { (*self.first).prev };
337 // SAFETY: The last item of this list is in this list.
338 Some(unsafe { self.remove_internal(last) })
339 }
340
341 /// Removes the first item from this list.
342 pub fn pop_front(&mut self) -> Option<ListArc<T, ID>> {
343 if self.first.is_null() {
344 return None;
345 }
346
347 // SAFETY: The first item of this list is in this list.
348 Some(unsafe { self.remove_internal(self.first) })
349 }
350
351 /// Removes the provided item from this list and returns it.
352 ///
353 /// This returns `None` if the item is not in the list. (Note that by the safety requirements,
354 /// this means that the item is not in any list.)
355 ///
356 /// # Safety
357 ///
358 /// `item` must not be in a different linked list (with the same id).
359 pub unsafe fn remove(&mut self, item: &T) -> Option<ListArc<T, ID>> {
360 // SAFETY: TODO.
361 let mut item = unsafe { ListLinks::fields(T::view_links(item)) };
362 // SAFETY: The user provided a reference, and reference are never dangling.
363 //
364 // As for why this is not a data race, there are two cases:
365 //
366 // * If `item` is not in any list, then these fields are read-only and null.
367 // * If `item` is in this list, then we have exclusive access to these fields since we
368 // have a mutable reference to the list.
369 //
370 // In either case, there's no race.
371 let ListLinksFields { next, prev } = unsafe { *item };
372
373 debug_assert_eq!(next.is_null(), prev.is_null());
374 if !next.is_null() {
375 // This is really a no-op, but this ensures that `item` is a raw pointer that was
376 // obtained without going through a pointer->reference->pointer conversion roundtrip.
377 // This ensures that the list is valid under the more restrictive strict provenance
378 // ruleset.
379 //
380 // SAFETY: We just checked that `next` is not null, and it's not dangling by the
381 // list invariants.
382 unsafe {
383 debug_assert_eq!(item, (*next).prev);
384 item = (*next).prev;
385 }
386
387 // SAFETY: We just checked that `item` is in a list, so the caller guarantees that it
388 // is in this list. The pointers are in the right order.
389 Some(unsafe { self.remove_internal_inner(item, next, prev) })
390 } else {
391 None
392 }
393 }
394
395 /// Removes the provided item from the list.
396 ///
397 /// # Safety
398 ///
399 /// `item` must point at an item in this list.
400 unsafe fn remove_internal(&mut self, item: *mut ListLinksFields) -> ListArc<T, ID> {
401 // SAFETY: The caller promises that this pointer is not dangling, and there's no data race
402 // since we have a mutable reference to the list containing `item`.
403 let ListLinksFields { next, prev } = unsafe { *item };
404 // SAFETY: The pointers are ok and in the right order.
405 unsafe { self.remove_internal_inner(item, next, prev) }
406 }
407
408 /// Removes the provided item from the list.
409 ///
410 /// # Safety
411 ///
412 /// The `item` pointer must point at an item in this list, and we must have `(*item).next ==
413 /// next` and `(*item).prev == prev`.
414 unsafe fn remove_internal_inner(
415 &mut self,
416 item: *mut ListLinksFields,
417 next: *mut ListLinksFields,
418 prev: *mut ListLinksFields,
419 ) -> ListArc<T, ID> {
420 // SAFETY: We have exclusive access to the pointers of items in the list, and the prev/next
421 // pointers are always valid for items in a list.
422 //
423 // INVARIANT: There are three cases:
424 // * If the list has at least three items, then after removing the item, `prev` and `next`
425 // will be next to each other.
426 // * If the list has two items, then the remaining item will point at itself.
427 // * If the list has one item, then `next == prev == item`, so these writes have no
428 // effect. The list remains unchanged and `item` is still in the list for now.
429 unsafe {
430 (*next).prev = prev;
431 (*prev).next = next;
432 }
433 // SAFETY: We have exclusive access to items in the list.
434 // INVARIANT: `item` is being removed, so the pointers should be null.
435 unsafe {
436 (*item).prev = ptr::null_mut();
437 (*item).next = ptr::null_mut();
438 }
439 // INVARIANT: There are three cases:
440 // * If `item` was not the first item, then `self.first` should remain unchanged.
441 // * If `item` was the first item and there is another item, then we just updated
442 // `prev->next` to `next`, which is the new first item, and setting `item->next` to null
443 // did not modify `prev->next`.
444 // * If `item` was the only item in the list, then `prev == item`, and we just set
445 // `item->next` to null, so this correctly sets `first` to null now that the list is
446 // empty.
447 if self.first == item {
448 // SAFETY: The `prev` pointer is the value that `item->prev` had when it was in this
449 // list, so it must be valid. There is no race since `prev` is still in the list and we
450 // still have exclusive access to the list.
451 self.first = unsafe { (*prev).next };
452 }
453
454 // SAFETY: `item` used to be in the list, so it is dereferenceable by the type invariants
455 // of `List`.
456 let list_links = unsafe { ListLinks::from_fields(item) };
457 // SAFETY: Any pointer in the list originates from a `prepare_to_insert` call.
458 let raw_item = unsafe { T::post_remove(list_links) };
459 // SAFETY: The above call to `post_remove` guarantees that we can recreate the `ListArc`.
460 unsafe { ListArc::from_raw(raw_item) }
461 }
462
463 /// Moves all items from `other` into `self`.
464 ///
465 /// The items of `other` are added to the back of `self`, so the last item of `other` becomes
466 /// the last item of `self`.
467 pub fn push_all_back(&mut self, other: &mut List<T, ID>) {
468 // First, we insert the elements into `self`. At the end, we make `other` empty.
469 if self.is_empty() {
470 // INVARIANT: All of the elements in `other` become elements of `self`.
471 self.first = other.first;
472 } else if !other.is_empty() {
473 let other_first = other.first;
474 // SAFETY: The other list is not empty, so this pointer is valid.
475 let other_last = unsafe { (*other_first).prev };
476 let self_first = self.first;
477 // SAFETY: The self list is not empty, so this pointer is valid.
478 let self_last = unsafe { (*self_first).prev };
479
480 // SAFETY: We have exclusive access to both lists, so we can update the pointers.
481 // INVARIANT: This correctly sets the pointers to merge both lists. We do not need to
482 // update `self.first` because the first element of `self` does not change.
483 unsafe {
484 (*self_first).prev = other_last;
485 (*other_last).next = self_first;
486 (*self_last).next = other_first;
487 (*other_first).prev = self_last;
488 }
489 }
490
491 // INVARIANT: The other list is now empty, so update its pointer.
492 other.first = ptr::null_mut();
493 }
494
495 /// Returns a cursor to the first element of the list.
496 ///
497 /// If the list is empty, this returns `None`.
498 pub fn cursor_front(&mut self) -> Option<Cursor<'_, T, ID>> {
499 if self.first.is_null() {
500 None
501 } else {
502 Some(Cursor {
503 current: self.first,
504 list: self,
505 })
506 }
507 }
508
509 /// Creates an iterator over the list.
510 pub fn iter(&self) -> Iter<'_, T, ID> {
511 // INVARIANT: If the list is empty, both pointers are null. Otherwise, both pointers point
512 // at the first element of the same list.
513 Iter {
514 current: self.first,
515 stop: self.first,
516 _ty: PhantomData,
517 }
518 }
519}
520
521impl<T: ?Sized + ListItem<ID>, const ID: u64> Default for List<T, ID> {
522 fn default() -> Self {
523 List::new()
524 }
525}
526
527impl<T: ?Sized + ListItem<ID>, const ID: u64> Drop for List<T, ID> {
528 fn drop(&mut self) {
529 while let Some(item) = self.pop_front() {
530 drop(item);
531 }
532 }
533}
534
535/// An iterator over a [`List`].
536///
537/// # Invariants
538///
539/// * There must be a [`List`] that is immutably borrowed for the duration of `'a`.
540/// * The `current` pointer is null or points at a value in that [`List`].
541/// * The `stop` pointer is equal to the `first` field of that [`List`].
542#[derive(Clone)]
543pub struct Iter<'a, T: ?Sized + ListItem<ID>, const ID: u64 = 0> {
544 current: *mut ListLinksFields,
545 stop: *mut ListLinksFields,
546 _ty: PhantomData<&'a ListArc<T, ID>>,
547}
548
549impl<'a, T: ?Sized + ListItem<ID>, const ID: u64> Iterator for Iter<'a, T, ID> {
550 type Item = ArcBorrow<'a, T>;
551
552 fn next(&mut self) -> Option<ArcBorrow<'a, T>> {
553 if self.current.is_null() {
554 return None;
555 }
556
557 let current = self.current;
558
559 // SAFETY: We just checked that `current` is not null, so it is in a list, and hence not
560 // dangling. There's no race because the iterator holds an immutable borrow to the list.
561 let next = unsafe { (*current).next };
562 // INVARIANT: If `current` was the last element of the list, then this updates it to null.
563 // Otherwise, we update it to the next element.
564 self.current = if next != self.stop {
565 next
566 } else {
567 ptr::null_mut()
568 };
569
570 // SAFETY: The `current` pointer points at a value in the list.
571 let item = unsafe { T::view_value(ListLinks::from_fields(current)) };
572 // SAFETY:
573 // * All values in a list are stored in an `Arc`.
574 // * The value cannot be removed from the list for the duration of the lifetime annotated
575 // on the returned `ArcBorrow`, because removing it from the list would require mutable
576 // access to the list. However, the `ArcBorrow` is annotated with the iterator's
577 // lifetime, and the list is immutably borrowed for that lifetime.
578 // * Values in a list never have a `UniqueArc` reference.
579 Some(unsafe { ArcBorrow::from_raw(item) })
580 }
581}
582
583/// A cursor into a [`List`].
584///
585/// # Invariants
586///
587/// The `current` pointer points a value in `list`.
588pub struct Cursor<'a, T: ?Sized + ListItem<ID>, const ID: u64 = 0> {
589 current: *mut ListLinksFields,
590 list: &'a mut List<T, ID>,
591}
592
593impl<'a, T: ?Sized + ListItem<ID>, const ID: u64> Cursor<'a, T, ID> {
594 /// Access the current element of this cursor.
595 pub fn current(&self) -> ArcBorrow<'_, T> {
596 // SAFETY: The `current` pointer points a value in the list.
597 let me = unsafe { T::view_value(ListLinks::from_fields(self.current)) };
598 // SAFETY:
599 // * All values in a list are stored in an `Arc`.
600 // * The value cannot be removed from the list for the duration of the lifetime annotated
601 // on the returned `ArcBorrow`, because removing it from the list would require mutable
602 // access to the cursor or the list. However, the `ArcBorrow` holds an immutable borrow
603 // on the cursor, which in turn holds a mutable borrow on the list, so any such
604 // mutable access requires first releasing the immutable borrow on the cursor.
605 // * Values in a list never have a `UniqueArc` reference, because the list has a `ListArc`
606 // reference, and `UniqueArc` references must be unique.
607 unsafe { ArcBorrow::from_raw(me) }
608 }
609
610 /// Move the cursor to the next element.
611 pub fn next(self) -> Option<Cursor<'a, T, ID>> {
612 // SAFETY: The `current` field is always in a list.
613 let next = unsafe { (*self.current).next };
614
615 if next == self.list.first {
616 None
617 } else {
618 // INVARIANT: Since `self.current` is in the `list`, its `next` pointer is also in the
619 // `list`.
620 Some(Cursor {
621 current: next,
622 list: self.list,
623 })
624 }
625 }
626
627 /// Move the cursor to the previous element.
628 pub fn prev(self) -> Option<Cursor<'a, T, ID>> {
629 // SAFETY: The `current` field is always in a list.
630 let prev = unsafe { (*self.current).prev };
631
632 if self.current == self.list.first {
633 None
634 } else {
635 // INVARIANT: Since `self.current` is in the `list`, its `prev` pointer is also in the
636 // `list`.
637 Some(Cursor {
638 current: prev,
639 list: self.list,
640 })
641 }
642 }
643
644 /// Remove the current element from the list.
645 pub fn remove(self) -> ListArc<T, ID> {
646 // SAFETY: The `current` pointer always points at a member of the list.
647 unsafe { self.list.remove_internal(self.current) }
648 }
649}
650
651impl<'a, T: ?Sized + ListItem<ID>, const ID: u64> FusedIterator for Iter<'a, T, ID> {}
652
653impl<'a, T: ?Sized + ListItem<ID>, const ID: u64> IntoIterator for &'a List<T, ID> {
654 type IntoIter = Iter<'a, T, ID>;
655 type Item = ArcBorrow<'a, T>;
656
657 fn into_iter(self) -> Iter<'a, T, ID> {
658 self.iter()
659 }
660}
661
662/// An owning iterator into a [`List`].
663pub struct IntoIter<T: ?Sized + ListItem<ID>, const ID: u64 = 0> {
664 list: List<T, ID>,
665}
666
667impl<T: ?Sized + ListItem<ID>, const ID: u64> Iterator for IntoIter<T, ID> {
668 type Item = ListArc<T, ID>;
669
670 fn next(&mut self) -> Option<ListArc<T, ID>> {
671 self.list.pop_front()
672 }
673}
674
675impl<T: ?Sized + ListItem<ID>, const ID: u64> FusedIterator for IntoIter<T, ID> {}
676
677impl<T: ?Sized + ListItem<ID>, const ID: u64> DoubleEndedIterator for IntoIter<T, ID> {
678 fn next_back(&mut self) -> Option<ListArc<T, ID>> {
679 self.list.pop_back()
680 }
681}
682
683impl<T: ?Sized + ListItem<ID>, const ID: u64> IntoIterator for List<T, ID> {
684 type IntoIter = IntoIter<T, ID>;
685 type Item = ListArc<T, ID>;
686
687 fn into_iter(self) -> IntoIter<T, ID> {
688 IntoIter { list: self }
689 }
690}