indicator/gat/tumbling_operator/queue/
mod.rs1use core::ops::{Deref, DerefMut, Index, IndexMut};
2
3pub mod circular;
5
6pub trait Collection {
8 fn with_capacity(cap: usize) -> Self;
10}
11
12pub trait Queue {
14 type Item;
16
17 fn enque(&mut self, item: Self::Item);
19
20 fn deque(&mut self) -> Option<Self::Item>;
22
23 fn len(&self) -> usize;
25
26 fn cap(&self) -> usize;
28
29 fn get(&self, idx: usize) -> Option<&Self::Item>;
31
32 fn get_mut(&mut self, idx: usize) -> Option<&mut Self::Item>;
34
35 #[inline]
37 fn is_empty(&self) -> bool {
38 self.len() == 0
39 }
40
41 #[inline]
43 fn is_full(&self) -> bool {
44 self.len() == self.cap()
45 }
46
47 fn is_inline(&self) -> bool;
49
50 #[inline]
52 fn enque_and_deque_overflow(&mut self, item: Self::Item) -> Option<Self::Item> {
53 if self.is_full() {
54 let oldest = self.deque();
55 self.enque(item);
56 oldest
57 } else {
58 self.enque(item);
59 None
60 }
61 }
62}
63
64#[derive(Debug, Clone, Copy)]
66pub enum Change<T> {
67 Push(Option<T>),
69 Swap(Option<T>),
71}
72
73impl<T> Change<T> {
74 pub fn as_ref(&self) -> Change<&T> {
76 match self {
77 Self::Push(v) => Change::Push(v.as_ref()),
78 Self::Swap(v) => Change::Swap(v.as_ref()),
79 }
80 }
81
82 pub fn outdated(self) -> Option<T> {
84 match self {
85 Self::Push(v) => v,
86 Self::Swap(v) => v,
87 }
88 }
89
90 pub fn is_new_period(&self) -> bool {
92 matches!(self, Self::Push(_))
93 }
94
95 fn as_push(&self) -> Option<&T> {
96 if let Self::Push(v) = self {
97 v.as_ref()
98 } else {
99 None
100 }
101 }
102
103 fn as_swap(&self) -> Option<&T> {
104 if let Self::Swap(v) = self {
105 v.as_ref()
106 } else {
107 None
108 }
109 }
110}
111
112#[derive(Debug, Clone)]
114pub struct Tumbling<Q: Queue>(Q, Change<Q::Item>);
115
116impl<Q> Tumbling<Q>
117where
118 Q: Queue,
119{
120 pub(crate) fn new(queue: Q) -> Self {
121 Self(queue, Change::Push(None))
122 }
123
124 pub fn as_view<'a>(&'a self) -> View<'a, dyn Queue<Item = Q::Item> + 'a> {
126 View {
127 queue: &self.0,
128 change: &self.1,
129 }
130 }
131
132 pub fn as_queue_ref(&self) -> QueueRef<'_, Q::Item> {
134 QueueRef(self.as_view())
135 }
136
137 pub fn as_view_mut<'a>(&'a mut self) -> ViewMut<'a, dyn Queue<Item = Q::Item> + 'a> {
139 ViewMut {
140 queue: &mut self.0,
141 change: &mut self.1,
142 }
143 }
144
145 pub fn as_queue_mut(&mut self) -> QueueMut<'_, Q::Item> {
147 QueueMut(self.as_view_mut())
148 }
149}
150
151impl<Q> Deref for Tumbling<Q>
152where
153 Q: Queue,
154{
155 type Target = Q;
156
157 fn deref(&self) -> &Self::Target {
158 &self.0
159 }
160}
161
162pub struct View<'a, Q: Queue + ?Sized> {
164 queue: &'a Q,
165 change: &'a Change<Q::Item>,
166}
167
168impl<'a, Q: Queue + ?Sized> Clone for View<'a, Q> {
169 fn clone(&self) -> Self {
170 *self
171 }
172}
173
174impl<'a, Q: Queue + ?Sized> Copy for View<'a, Q> {}
175
176impl<'a, Q: Queue + ?Sized> View<'a, Q> {
177 #[inline]
179 pub fn change(&self) -> Change<&Q::Item> {
180 self.change.as_ref()
181 }
182}
183
184impl<'a, Q> Deref for View<'a, Q>
185where
186 Q: Queue + ?Sized,
187{
188 type Target = Q;
189
190 fn deref(&self) -> &Self::Target {
191 self.queue
192 }
193}
194
195impl<'a, Q> Index<usize> for View<'a, Q>
196where
197 Q: Queue + ?Sized,
198{
199 type Output = Q::Item;
200
201 #[inline]
202 fn index(&self, index: usize) -> &Self::Output {
203 self.queue.get(index).expect("index out of range")
204 }
205}
206
207pub struct QueueRef<'a, T>(View<'a, dyn Queue<Item = T> + 'a>);
209
210impl<'a, T> Clone for QueueRef<'a, T> {
211 fn clone(&self) -> Self {
212 *self
213 }
214}
215
216impl<'a, T> Copy for QueueRef<'a, T> {}
217
218impl<'a, T> Deref for QueueRef<'a, T> {
219 type Target = View<'a, dyn Queue<Item = T> + 'a>;
220
221 fn deref(&self) -> &Self::Target {
222 &self.0
223 }
224}
225
226pub struct ViewMut<'a, Q: Queue + ?Sized> {
228 queue: &'a mut Q,
229 change: &'a mut Change<Q::Item>,
230}
231
232impl<'a, Q: Queue + ?Sized> ViewMut<'a, Q> {
233 #[inline]
235 pub fn push(&mut self, item: Q::Item) -> Option<&Q::Item> {
236 *self.change = Change::Push(self.queue.enque_and_deque_overflow(item));
237 self.change.as_push()
238 }
239
240 #[inline]
242 pub fn swap(&mut self, mut item: Q::Item) -> Option<&Q::Item> {
243 if let Some(head) = self.queue.get_mut(0) {
244 core::mem::swap(head, &mut item);
245 }
246 *self.change = Change::Swap(Some(item));
247 self.change.as_swap()
248 }
249
250 #[inline]
252 pub fn change(&self) -> Change<&Q::Item> {
253 self.change.as_ref()
254 }
255}
256
257impl<'a, Q> Deref for ViewMut<'a, Q>
258where
259 Q: Queue + ?Sized,
260{
261 type Target = Q;
262
263 fn deref(&self) -> &Self::Target {
264 self.queue
265 }
266}
267
268impl<'a, Q> DerefMut for ViewMut<'a, Q>
269where
270 Q: Queue + ?Sized,
271{
272 fn deref_mut(&mut self) -> &mut Self::Target {
273 self.queue
274 }
275}
276
277impl<'a, Q> Index<usize> for ViewMut<'a, Q>
278where
279 Q: Queue + ?Sized,
280{
281 type Output = Q::Item;
282
283 #[inline]
284 fn index(&self, index: usize) -> &Self::Output {
285 self.queue.get(index).expect("index out of range")
286 }
287}
288
289impl<'a, Q> IndexMut<usize> for ViewMut<'a, Q>
290where
291 Q: Queue,
292{
293 #[inline]
294 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
295 self.queue.get_mut(index).expect("index out of range")
296 }
297}
298
299pub struct QueueMut<'a, T>(ViewMut<'a, dyn Queue<Item = T> + 'a>);
301
302impl<'a, T> QueueMut<'a, T> {
303 pub fn as_queue_ref(&self) -> QueueRef<T> {
305 QueueRef(View {
306 queue: self.queue,
307 change: self.change,
308 })
309 }
310
311 pub fn into_queue_ref(self) -> QueueRef<'a, T> {
313 QueueRef(View {
314 queue: self.0.queue,
315 change: self.0.change,
316 })
317 }
318}
319
320impl<'a, T> Deref for QueueMut<'a, T> {
321 type Target = ViewMut<'a, dyn Queue<Item = T> + 'a>;
322
323 fn deref(&self) -> &Self::Target {
324 &self.0
325 }
326}
327
328impl<'a, T> DerefMut for QueueMut<'a, T> {
329 fn deref_mut(&mut self) -> &mut Self::Target {
330 &mut self.0
331 }
332}