xitca_unsafe_collection/bound_queue/
mod.rs1pub mod heap;
4pub mod stack;
5
6use core::fmt;
7
8pub trait Queueable {
9 type Item;
10
11 fn capacity(&self) -> usize;
13
14 unsafe fn _get_unchecked(&self, idx: usize) -> &Self::Item;
17
18 unsafe fn _get_mut_unchecked(&mut self, idx: usize) -> &mut Self::Item;
21
22 unsafe fn _read_unchecked(&mut self, idx: usize) -> Self::Item;
25
26 unsafe fn _write_unchecked(&mut self, idx: usize, item: Self::Item);
29}
30
31struct Bounded<Q>
32where
33 Q: Queueable,
34{
35 queue: Q,
36 next: usize,
37 len: usize,
38}
39
40impl<Q> Bounded<Q>
41where
42 Q: Queueable,
43{
44 const fn is_empty(&self) -> bool {
45 self.len == 0
46 }
47
48 fn is_full(&self) -> bool {
49 self.len == self.queue.capacity()
50 }
51
52 const fn len(&self) -> usize {
53 self.len
54 }
55
56 fn incr_tail_len(&mut self) {
57 self.next += 1;
58 self.len += 1;
59
60 if self.next == self.queue.capacity() {
61 self.next = 0;
62 }
63 }
64
65 fn front(&self) -> Option<&Q::Item> {
66 if self.is_empty() {
67 None
68 } else {
69 Some(unsafe { self.front_unchecked() })
70 }
71 }
72
73 unsafe fn front_unchecked(&self) -> &Q::Item {
76 let idx = self.front_idx();
77 self.queue._get_unchecked(idx)
78 }
79
80 fn truncate(&mut self, n: usize) {
81 if self.len > n {
82 let delta = self.len - n;
83 self.len = n;
84 if delta > self.next {
85 self.next = self.queue.capacity() + self.next - delta;
86 } else {
87 self.next -= delta;
88 }
89 }
90 }
91
92 fn front_mut(&mut self) -> Option<&mut Q::Item> {
93 if self.is_empty() {
94 None
95 } else {
96 Some(unsafe { self.front_mut_unchecked() })
97 }
98 }
99
100 unsafe fn front_mut_unchecked(&mut self) -> &mut Q::Item {
103 let idx = self.front_idx();
104 self.queue._get_mut_unchecked(idx)
105 }
106
107 fn clear(&mut self) {
108 while self.pop_front().is_some() {}
109 self.next = 0;
110 self.len = 0;
111 }
112
113 fn pop_front(&mut self) -> Option<Q::Item> {
114 if self.is_empty() {
115 None
116 } else {
117 unsafe { Some(self.pop_front_unchecked()) }
118 }
119 }
120
121 unsafe fn pop_front_unchecked(&mut self) -> Q::Item {
124 let idx = self.front_idx();
125 self.len -= 1;
126 self.queue._read_unchecked(idx)
127 }
128
129 fn push_back(&mut self, item: Q::Item) -> Result<(), PushError<Q::Item>> {
130 if self.is_full() {
131 Err(PushError(item))
132 } else {
133 unsafe {
134 self.push_back_unchecked(item);
135 }
136 Ok(())
137 }
138 }
139
140 unsafe fn push_back_unchecked(&mut self, item: Q::Item) {
143 self.queue._write_unchecked(self.next, item);
144 self.incr_tail_len();
145 }
146
147 const fn iter(&self) -> Iter<'_, Q> {
148 Iter {
149 queue: &self.queue,
150 tail: self.next,
151 len: self.len(),
152 }
153 }
154
155 fn front_idx(&self) -> usize {
156 if self.next >= self.len {
157 self.next - self.len
158 } else {
159 self.queue.capacity() + self.next - self.len
160 }
161 }
162}
163
164impl<Q> fmt::Debug for Bounded<Q>
165where
166 Q: Queueable,
167{
168 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
169 write!(f, "ArrayQueue")
170 }
171}
172
173impl<Q> Drop for Bounded<Q>
174where
175 Q: Queueable,
176{
177 fn drop(&mut self) {
178 self.clear();
179 }
180}
181
182pub struct PushError<T>(T);
183
184impl<T> PushError<T> {
185 pub fn into_inner(self) -> T {
186 self.0
187 }
188}
189
190impl<T> fmt::Debug for PushError<T> {
191 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
192 write!(f, "PushError(..)")
193 }
194}
195
196#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
197#[derive(Clone)]
198pub struct Iter<'a, Q>
199where
200 Q: Queueable,
201{
202 queue: &'a Q,
203 tail: usize,
204 len: usize,
205}
206
207impl<'a, Q> Iterator for Iter<'a, Q>
208where
209 Q: Queueable,
210{
211 type Item = &'a Q::Item;
212
213 #[inline]
214 fn next(&mut self) -> Option<&'a Q::Item> {
215 if self.len == 0 {
216 return None;
217 }
218
219 let idx = if self.tail >= self.len {
220 self.tail - self.len
221 } else {
222 self.queue.capacity() + self.tail - self.len
223 };
224
225 self.len -= 1;
226
227 unsafe { Some(self.queue._get_unchecked(idx)) }
228 }
229
230 #[inline]
231 fn size_hint(&self) -> (usize, Option<usize>) {
232 (self.len, Some(self.len))
233 }
234}