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