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}