weak_lists/unsync/
list.rs

1use {
2    crate::unsync::{Iter, WeakList, WeakListData},
3    alloc::rc::Rc,
4    core::{
5        cell::UnsafeCell,
6        fmt::{Debug, Formatter},
7    },
8};
9
10impl<T> WeakList<T>
11where
12    T: ?Sized,
13{
14    /// Removes all elements from the list.
15    ///
16    /// # Examples
17    ///
18    /// ```
19    /// use std::rc::{Rc, Weak};
20    /// use weak_lists::{WeakList, WeakListElement};
21    ///
22    /// let list = WeakList::default();
23    /// let entry = Rc::new(1);
24    /// let entry = WeakListElement::new(Rc::downgrade(&entry));
25    /// entry.attach(&list);
26    /// assert!(list.iter().next().is_some());
27    /// list.clear();
28    /// assert!(list.iter().next().is_none());
29    /// ```
30    pub fn clear(&self) {
31        let data = unsafe {
32            // SAFETY:
33            // - While we hold this reference, we do not call any functions that might
34            //   create additional references to self.data. This applies to all code that
35            //   creates references to self.data.
36            // - Therefore, this is an exclusive reference to self.data.
37            // - In particular, dropping the Weak objects below will never run the drop
38            //   impl of T itself.
39            &mut *self.data.get()
40        };
41        data.members.clear();
42    }
43
44    /// Creates an iterator over the entries of the list.
45    ///
46    /// The list can be mutated during the iteration. It is guaranteed that, if an element
47    /// was part of the list when this iterator was created, and if the element was not
48    /// removed during the iteration, then the element will be returned exactly once by
49    /// this iterator.
50    pub fn iter(&self) -> Iter<'_, T> {
51        let data = unsafe {
52            // SAFETY:
53            // - While we hold this reference, we do not call any functions that might
54            //   create additional references to self.data. This applies to all code that
55            //   creates references to self.data.
56            // - Therefore, this is an exclusive reference to self.data.
57            // - In particular, the calls to compact and index_len are safe.
58            &mut *self.data.get()
59        };
60        if data.active_iterators == 0 {
61            data.members.compact();
62        }
63        data.active_iterators += 1;
64        Iter {
65            iter: 0..data.members.index_len(),
66            data: &self.data,
67        }
68    }
69}
70
71impl<T> Default for WeakList<T>
72where
73    T: ?Sized,
74{
75    fn default() -> Self {
76        Self {
77            data: Rc::new(UnsafeCell::new(WeakListData {
78                next_id: 0,
79                active_iterators: 0,
80                members: Default::default(),
81            })),
82        }
83    }
84}
85
86impl<'a, T> IntoIterator for &'a WeakList<T>
87where
88    T: ?Sized,
89{
90    type Item = Rc<T>;
91    type IntoIter = Iter<'a, T>;
92
93    fn into_iter(self) -> Self::IntoIter {
94        self.iter()
95    }
96}
97
98impl<T> Debug for WeakList<T>
99where
100    T: ?Sized,
101{
102    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
103        f.debug_struct("WeakList")
104            .field("id", &Rc::as_ptr(&self.data))
105            .finish_non_exhaustive()
106    }
107}