Skip to main content

standard_lib/collections/circular/stack/
iter.rs

1use std::{mem::{self, MaybeUninit}, ptr::NonNull};
2
3use crate::collections::circular::CircStack;
4
5impl<T, const N: usize> IntoIterator for CircStack<T, N> {
6    type Item = T;
7
8    type IntoIter = IntoIter<T, N>;
9
10    fn into_iter(self) -> Self::IntoIter {
11        IntoIter {
12            inner: self.forget_init(),
13            index: 0,
14        }
15    }
16}
17
18#[derive(#[automatically_derived]
impl<T: ::core::fmt::Debug, const N : usize> ::core::fmt::Debug for
    IntoIter<T, N> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "IntoIter",
            "inner", &self.inner, "index", &&self.index)
    }
}Debug)]
19pub struct IntoIter<T, const N: usize> {
20    pub(crate) inner: CircStack<MaybeUninit<T>, N>,
21    // Index here refers to the next index to retrieve a value from, or N if exhausted.
22    pub(crate) index: usize,
23}
24
25impl<T, const N: usize> Drop for IntoIter<T, N> {
26    fn drop(&mut self) {
27        for i in self {
28            drop(i);
29        }
30    }
31}
32
33impl<T, const N: usize> Iterator for IntoIter<T, N> {
34    type Item = T;
35
36    fn next(&mut self) -> Option<Self::Item> {
37        // We use N as a guard value, because it will always be available but unreachable.
38        if self.index >= N {
39            return None
40        }
41
42        let value = unsafe {
43            mem::replace(&mut self.inner[self.index], MaybeUninit::uninit()).assume_init()
44        };
45
46        self.index += 1;
47
48        Some(value)
49    }
50}
51
52impl<'a, T, const N: usize> IntoIterator for &'a mut CircStack<T, N> {
53    type Item = &'a mut T;
54
55    type IntoIter = IterMut<'a, T, N>;
56
57    fn into_iter(self) -> Self::IntoIter {
58        let CircStack { buffer, tail } = self;
59
60        IterMut {
61            buffer,
62            tail: *tail,
63            index: *tail,
64        }
65    }
66}
67
68#[derive(#[automatically_derived]
impl<'a, T: ::core::fmt::Debug, const N : usize> ::core::fmt::Debug for
    IterMut<'a, T, N> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f, "IterMut",
            "buffer", &self.buffer, "tail", &self.tail, "index", &&self.index)
    }
}Debug)]
69pub struct IterMut<'a, T, const N: usize> {
70    // pub(crate) inner: &'a mut CircStack<T, N>,
71    pub(crate) buffer: &'a mut [T; N],
72    pub(crate) tail: usize,
73    // Index here refers to the next index to retrieve a value from, or N if exhausted.
74    pub(crate) index: usize,
75}
76
77impl<'a, T, const N: usize> Iterator for IterMut<'a, T, N> {
78    type Item = &'a mut T;
79
80    fn next(&mut self) -> Option<Self::Item> {
81        // // We use N as a guard value, because it will always be available but unreachable.
82        // if self.index >= N {
83        //     return None
84        // }
85
86        // let value = self.buffer.index_mut(self.index);
87
88        // self.index = super::increment::<N>(self.index);
89
90        // if self.index == self.last {
91        //     self.index = N;
92        // }
93
94        // Some(value)
95
96        if self.index >= N {
97            return None
98        }
99
100        let head: NonNull<T> = NonNull::from_mut(&mut self.buffer).cast();
101        let mut ptr = unsafe { head.offset(self.index as isize) };
102
103        // Iterate backwards, stopping if we hit the point where we started.
104        self.index = super::sub_wrapping::<N>(self.index, 1);
105
106        if self.index == self.tail {
107            self.index = N;
108        }
109
110        Some(unsafe { ptr.as_mut() })
111    }
112}
113
114impl<'a, T, const N: usize> IntoIterator for &'a CircStack<T, N> {
115    type Item = &'a T;
116
117    type IntoIter = Iter<'a, T, N>;
118
119    fn into_iter(self) -> Self::IntoIter {
120        Iter {
121            inner: self,
122            index: 0,
123        }
124    }
125}
126
127#[derive(#[automatically_derived]
impl<'a, T: ::core::fmt::Debug, const N : usize> ::core::fmt::Debug for
    Iter<'a, T, N> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "Iter", "inner",
            &self.inner, "index", &&self.index)
    }
}Debug)]
128pub struct Iter<'a, T, const N: usize> {
129    pub(crate) inner: &'a CircStack<T, N>,
130    // Index here refers to the next index to retrieve a value from, or N if exhausted.
131    pub(crate) index: usize,
132}
133
134impl<'a, T, const N: usize> Iterator for Iter<'a, T, N> {
135    type Item = &'a T;
136
137    fn next(&mut self) -> Option<Self::Item> {
138        // We use N as a guard value, because it will always be available but unreachable.
139        if self.index >= N {
140            return None
141        }
142
143        let value = &self.inner[self.index];
144
145        self.index += 1;
146
147        Some(value)
148    }
149}