Skip to main content

trait_obj_list/iters/
iter_mut.rs

1use crate::DynList;
2use crate::ptr;
3use crate::types::ListType;
4use crate::types::ListTypeRev;
5
6/// Mutable iterator for a [`DynList`].
7pub struct IterMut<'a, T, Typ>
8where
9	T: ptr::Pointee<Metadata = ptr::DynMetadata<T>> + ?Sized + 'a,
10	Typ: ListType<T>,
11{
12	pub(crate) list: &'a mut DynList<T, Typ>,
13	pub(crate) offset: usize,
14	pub(crate) index: usize,
15	pub(crate) rev_offset: usize,
16	pub(crate) rev_index: usize,
17}
18impl<'a, T, Typ> Iterator for IterMut<'a, T, Typ>
19where
20	T: ptr::Pointee<Metadata = ptr::DynMetadata<T>> + ?Sized,
21	Typ: ListType<T>,
22{
23	type Item = &'a mut T;
24
25	fn next(&mut self) -> Option<Self::Item> {
26		if self.offset >= self.rev_offset {
27			debug_assert_eq!(self.offset, self.rev_offset);
28			debug_assert_eq!(self.index, self.rev_index);
29			return None;
30		}
31		let (p, size) = unsafe {
32			self.list
33				.typ
34				.read_entry(self.list.data.as_ptr(), self.offset, self.index)
35		};
36		self.offset += size;
37		self.index += 1;
38		Some(unsafe { &mut *p })
39	}
40
41	fn size_hint(&self) -> (usize, Option<usize>) {
42		let n = self.rev_index - self.index;
43		(n, Some(n))
44	}
45}
46impl<'a, T, Typ> DoubleEndedIterator for IterMut<'a, T, Typ>
47where
48	T: ptr::Pointee<Metadata = ptr::DynMetadata<T>> + ?Sized,
49	Typ: ListTypeRev<T>,
50{
51	fn next_back(&mut self) -> Option<Self::Item> {
52		if self.offset >= self.rev_offset {
53			debug_assert_eq!(self.offset, self.rev_offset);
54			debug_assert_eq!(self.index, self.rev_index);
55			return None;
56		}
57		let size = unsafe {
58			self.list
59				.typ
60				.prev_entry_size(self.list.data.as_ptr(), self.rev_offset, self.rev_index)
61		};
62		debug_assert!(
63			self.rev_offset >= size,
64			"SOUNDNESS BUG: prev_entry_size returned too big of a size. rev_offset = {} but prev_entry_size returned {}",
65			self.rev_offset,
66			size
67		);
68		self.rev_offset -= size;
69		self.rev_index -= 1;
70
71		let (p, s) = unsafe {
72			self.list
73				.typ
74				.read_entry(self.list.data.as_ptr(), self.rev_offset, self.rev_index)
75		};
76		debug_assert_eq!(s, size);
77
78		Some(unsafe { &mut *p })
79	}
80}
81impl<'a, T, Typ> ExactSizeIterator for IterMut<'a, T, Typ>
82where
83	T: ptr::Pointee<Metadata = ptr::DynMetadata<T>> + ?Sized,
84	Typ: ListType<T>,
85{
86}
87impl<'a, T, Typ> IterMut<'a, T, Typ>
88where
89	T: ptr::Pointee<Metadata = ptr::DynMetadata<T>> + ?Sized,
90	Typ: ListType<T>,
91{
92	/// Creates an immutable iterator starting from this iterator's position.
93	///
94	/// This can be used to "look ahead" in the list.
95	pub fn as_immutable<'b>(&'b self) -> crate::iters::Iter<'b, T, Typ> {
96		crate::iters::Iter {
97			list: &*self.list,
98			offset: self.offset,
99			index: self.index,
100			rev_offset: self.rev_offset,
101			rev_index: self.rev_index,
102		}
103	}
104}