trait_stack/
iter.rs

1/*
2 * Created on Sat Jun 18 2022
3 *
4 * Copyright (c) storycraft. Licensed under the MIT Licence.
5 */
6
7use core::{slice, ptr::{self, DynMetadata, Pointee}};
8
9pub struct Iter<'a, T: ?Sized + Pointee<Metadata = DynMetadata<T>>> {
10    pub(crate) ptr: *const u8,
11    pub(crate) table_iter: slice::Iter<'a, (usize, DynMetadata<T>)>,
12}
13
14impl<'a, T: ?Sized + Pointee<Metadata = DynMetadata<T>>> Iter<'a, T> {
15    unsafe fn item_at(&self, offset: usize, metadata: DynMetadata<T>) -> &'a T {
16        &*(ptr::from_raw_parts(self.ptr.add(offset) as _, metadata) as *const T)
17    }
18}
19
20impl<'a, T: ?Sized + Pointee<Metadata = DynMetadata<T>>> Iterator for Iter<'a, T> {
21    type Item = &'a T;
22
23    fn next(&mut self) -> Option<Self::Item> {
24        let (offset, metadata) = self.table_iter.next()?;
25
26        // SAFETY: Pointer is offseted using valid offset
27        Some(unsafe { self.item_at(*offset, *metadata) })
28    }
29
30    fn size_hint(&self) -> (usize, Option<usize>) {
31        self.table_iter.size_hint()
32    }
33
34    fn count(self) -> usize
35    where
36        Self: Sized,
37    {
38        self.table_iter.count()
39    }
40
41    fn nth(&mut self, n: usize) -> Option<Self::Item> {
42        let (offset, metadata) = self.table_iter.nth(n)?;
43
44        return Some(unsafe { self.item_at(*offset, *metadata) });
45    }
46}
47
48impl<'a, T: ?Sized + Pointee<Metadata = DynMetadata<T>>> DoubleEndedIterator for Iter<'a, T> {
49    fn next_back(&mut self) -> Option<Self::Item> {
50        let (offset, metadata) = self.table_iter.next_back()?;
51
52        // SAFETY: Pointer is offseted using valid offset
53        Some(unsafe { self.item_at(*offset, *metadata) })
54    }
55
56    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
57        let (offset, metadata) = self.table_iter.nth_back(n)?;
58
59        // SAFETY: Pointer is offseted using valid offset
60        return Some(unsafe { self.item_at(*offset, *metadata) });
61    }
62}
63
64impl<'a, T: ?Sized + Pointee<Metadata = DynMetadata<T>>> ExactSizeIterator for Iter<'a, T> {}
65
66pub struct IterMut<'a, T: ?Sized + Pointee<Metadata = DynMetadata<T>>> {
67    pub(crate) ptr: *const u8,
68    pub(crate) table_iter: slice::Iter<'a, (usize, DynMetadata<T>)>,
69}
70
71impl<'a, T: ?Sized + Pointee<Metadata = DynMetadata<T>>> IterMut<'a, T> {
72    unsafe fn item_at(&mut self, offset: usize, metadata: DynMetadata<T>) -> &'a mut T {
73        &mut *(ptr::from_raw_parts::<T>(self.ptr.add(offset) as _, metadata) as *mut T)
74    }
75}
76
77impl<'a, T: ?Sized + Pointee<Metadata = DynMetadata<T>>> Iterator for IterMut<'a, T> {
78    type Item = &'a mut T;
79
80    fn next(&mut self) -> Option<Self::Item> {
81        let (offset, metadata) = self.table_iter.next()?;
82
83        // SAFETY: Pointer is offseted using valid offset
84        Some(unsafe { self.item_at(*offset, *metadata) })
85    }
86
87    fn size_hint(&self) -> (usize, Option<usize>) {
88        self.table_iter.size_hint()
89    }
90
91    fn count(self) -> usize
92    where
93        Self: Sized,
94    {
95        self.table_iter.count()
96    }
97
98    fn nth(&mut self, n: usize) -> Option<Self::Item> {
99        let (offset, metadata) = self.table_iter.nth(n)?;
100
101        return Some(unsafe { self.item_at(*offset, *metadata) });
102    }
103}
104
105impl<'a, T: ?Sized + Pointee<Metadata = DynMetadata<T>>> DoubleEndedIterator for IterMut<'a, T> {
106    fn next_back(&mut self) -> Option<Self::Item> {
107        let (offset, metadata) = self.table_iter.next_back()?;
108
109        // SAFETY: Pointer is offseted using valid offset
110        Some(unsafe { self.item_at(*offset, *metadata) })
111    }
112
113    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
114        let (offset, metadata) = self.table_iter.nth_back(n)?;
115
116        // SAFETY: Pointer is offseted using valid offset
117        return Some(unsafe { self.item_at(*offset, *metadata) });
118    }
119}
120
121impl<'a, T: ?Sized + Pointee<Metadata = DynMetadata<T>>> ExactSizeIterator for IterMut<'a, T> {}