circular_queue/lib.rs
1//! A circular buffer-like queue.
2//!
3//! The `CircularQueue<T>` is created with a set capacity, then items are pushed in. When the queue
4//! runs out of capacity, newer items start overwriting the old ones, starting from the oldest.
5//!
6//! There are built-in iterators that go from the newest items to the oldest ones and from the
7//! oldest items to the newest ones.
8//!
9//! Two queues are considered equal if iterating over them with `iter()` would yield the same
10//! sequence of elements.
11//!
12//! Enable the `serde_support` feature for [Serde](https://serde.rs/) support.
13//!
14//! # Examples
15//!
16//! ```
17//! use circular_queue::CircularQueue;
18//!
19//! let mut queue = CircularQueue::with_capacity(3);
20//! queue.push(1);
21//! queue.push(2);
22//! queue.push(3);
23//! queue.push(4);
24//!
25//! assert_eq!(queue.len(), 3);
26//!
27//! let mut iter = queue.iter();
28//!
29//! assert_eq!(iter.next(), Some(&4));
30//! assert_eq!(iter.next(), Some(&3));
31//! assert_eq!(iter.next(), Some(&2));
32//! ```
33
34#![cfg_attr(has_extern_crate_alloc, no_std)]
35#![doc(html_root_url = "https://docs.rs/circular-queue/0.2.6")]
36
37#[cfg(has_extern_crate_alloc)]
38extern crate alloc;
39
40#[cfg(has_extern_crate_alloc)]
41use alloc::vec::Vec;
42#[cfg(has_extern_crate_alloc)]
43use core::iter::{Chain, Rev};
44#[cfg(has_extern_crate_alloc)]
45use core::mem::replace;
46#[cfg(has_extern_crate_alloc)]
47use core::slice::{Iter as SliceIter, IterMut as SliceIterMut};
48
49#[cfg(not(has_extern_crate_alloc))]
50use std::iter::{Chain, Rev};
51#[cfg(not(has_extern_crate_alloc))]
52use std::mem::replace;
53#[cfg(not(has_extern_crate_alloc))]
54use std::slice::{Iter as SliceIter, IterMut as SliceIterMut};
55
56#[cfg(feature = "serde_support")]
57mod serde_support;
58
59/// A circular buffer-like queue.
60#[derive(Clone, Debug)]
61pub struct CircularQueue<T> {
62 data: Vec<T>,
63 // Using our own capacity instead of the one stored in Vec to ensure consistent behavior with
64 // zero-sized types.
65 capacity: usize,
66 insertion_index: usize,
67}
68
69/// An iterator over `CircularQueue<T>`.
70pub type Iter<'a, T> = Chain<Rev<SliceIter<'a, T>>, Rev<SliceIter<'a, T>>>;
71
72/// A mutable iterator over `CircularQueue<T>`.
73pub type IterMut<'a, T> = Chain<Rev<SliceIterMut<'a, T>>, Rev<SliceIterMut<'a, T>>>;
74
75/// An ascending iterator over `CircularQueue<T>`.
76pub type AscIter<'a, T> = Chain<SliceIter<'a, T>, SliceIter<'a, T>>;
77
78/// An mutable ascending iterator over `CircularQueue<T>`.
79pub type AscIterMut<'a, T> = Chain<SliceIterMut<'a, T>, SliceIterMut<'a, T>>;
80
81/// A value popped from `CircularQueue<T>` as the result of a push operation.
82pub type Popped<T> = Option<T>;
83
84impl<T> CircularQueue<T> {
85 /// Constructs a new, empty `CircularQueue<T>` with the requested capacity.
86 ///
87 /// # Examples
88 ///
89 /// ```
90 /// use circular_queue::CircularQueue;
91 ///
92 /// let mut queue: CircularQueue<i32> = CircularQueue::with_capacity(5);
93 /// ```
94 #[inline]
95 pub fn with_capacity(capacity: usize) -> Self {
96 Self {
97 data: Vec::with_capacity(capacity),
98 capacity,
99 insertion_index: 0,
100 }
101 }
102
103 /// Returns the current number of elements in the queue.
104 ///
105 /// # Examples
106 ///
107 /// ```
108 /// use circular_queue::CircularQueue;
109 ///
110 /// let mut queue = CircularQueue::with_capacity(5);
111 /// queue.push(1);
112 /// queue.push(2);
113 /// queue.push(3);
114 ///
115 /// assert_eq!(queue.len(), 3);
116 /// ```
117 #[inline]
118 pub fn len(&self) -> usize {
119 self.data.len()
120 }
121
122 /// Returns `true` if the queue contains no elements.
123 ///
124 /// # Examples
125 ///
126 /// ```
127 /// use circular_queue::CircularQueue;
128 ///
129 /// let mut queue = CircularQueue::with_capacity(5);
130 /// assert!(queue.is_empty());
131 ///
132 /// queue.push(1);
133 /// assert!(!queue.is_empty());
134 /// ```
135 #[inline]
136 pub fn is_empty(&self) -> bool {
137 self.data.is_empty()
138 }
139
140 /// Returns `true` if the queue is full.
141 ///
142 /// # Examples
143 ///
144 /// ```
145 /// use circular_queue::CircularQueue;
146 ///
147 /// let mut queue = CircularQueue::with_capacity(5);
148 ///
149 /// assert!(!queue.is_full());
150 ///
151 /// queue.push(1);
152 /// queue.push(2);
153 /// queue.push(3);
154 /// queue.push(4);
155 /// queue.push(5);
156 ///
157 /// assert!(queue.is_full());
158 /// ```
159 #[inline]
160 pub fn is_full(&self) -> bool {
161 self.capacity() == self.len()
162 }
163
164 /// Returns the capacity of the queue.
165 ///
166 /// # Examples
167 ///
168 /// ```
169 /// use circular_queue::CircularQueue;
170 ///
171 /// let queue: CircularQueue<i32> = CircularQueue::with_capacity(5);
172 /// assert_eq!(queue.capacity(), 5);
173 /// ```
174 #[inline]
175 pub fn capacity(&self) -> usize {
176 self.capacity
177 }
178
179 /// Clears the queue.
180 ///
181 /// # Examples
182 ///
183 /// ```
184 /// use circular_queue::CircularQueue;
185 ///
186 /// let mut queue = CircularQueue::with_capacity(5);
187 /// queue.push(1);
188 /// queue.push(2);
189 /// queue.push(3);
190 ///
191 /// queue.clear();
192 /// assert_eq!(queue.len(), 0);
193 /// ```
194 #[inline]
195 pub fn clear(&mut self) {
196 self.data.clear();
197 self.insertion_index = 0;
198 }
199
200 /// Pushes a new element into the queue.
201 ///
202 /// Once the capacity is reached, pushing new items will overwrite old ones.
203 ///
204 /// In case an old value is overwritten, it will be returned.
205 ///
206 /// # Examples
207 ///
208 /// ```
209 /// use circular_queue::CircularQueue;
210 ///
211 /// let mut queue = CircularQueue::with_capacity(3);
212 ///
213 /// queue.push(1);
214 /// queue.push(2);
215 ///
216 /// assert_eq!(queue.push(3), None);
217 /// assert_eq!(queue.push(4), Some(1));
218 ///
219 /// assert_eq!(queue.len(), 3);
220 ///
221 /// let mut iter = queue.iter();
222 ///
223 /// assert_eq!(iter.next(), Some(&4));
224 /// assert_eq!(iter.next(), Some(&3));
225 /// assert_eq!(iter.next(), Some(&2));
226 /// ```
227 #[inline]
228 pub fn push(&mut self, x: T) -> Popped<T> {
229 let mut old = None;
230
231 if self.capacity() == 0 {
232 return old;
233 }
234
235 if !self.is_full() {
236 self.data.push(x);
237 } else {
238 old = Some(replace(&mut self.data[self.insertion_index], x));
239 }
240
241 self.insertion_index = (self.insertion_index + 1) % self.capacity();
242
243 old
244 }
245
246 /// Returns an iterator over the queue's contents.
247 ///
248 /// The iterator goes from the most recently pushed items to the oldest ones.
249 ///
250 /// # Examples
251 ///
252 /// ```
253 /// use circular_queue::CircularQueue;
254 ///
255 /// let mut queue = CircularQueue::with_capacity(3);
256 /// queue.push(1);
257 /// queue.push(2);
258 /// queue.push(3);
259 /// queue.push(4);
260 ///
261 /// let mut iter = queue.iter();
262 ///
263 /// assert_eq!(iter.next(), Some(&4));
264 /// assert_eq!(iter.next(), Some(&3));
265 /// assert_eq!(iter.next(), Some(&2));
266 /// ```
267 #[inline]
268 pub fn iter(&self) -> Iter<T> {
269 let (a, b) = self.data.split_at(self.insertion_index);
270 a.iter().rev().chain(b.iter().rev())
271 }
272
273 /// Returns a mutable iterator over the queue's contents.
274 ///
275 /// The iterator goes from the most recently pushed items to the oldest ones.
276 ///
277 /// # Examples
278 ///
279 /// ```
280 /// use circular_queue::CircularQueue;
281 ///
282 /// let mut queue = CircularQueue::with_capacity(3);
283 /// queue.push(1);
284 /// queue.push(2);
285 /// queue.push(3);
286 /// queue.push(4);
287 ///
288 /// let mut iter = queue.iter_mut();
289 ///
290 /// assert_eq!(iter.next(), Some(&mut 4));
291 /// assert_eq!(iter.next(), Some(&mut 3));
292 /// assert_eq!(iter.next(), Some(&mut 2));
293 /// ```
294 #[inline]
295 pub fn iter_mut(&mut self) -> IterMut<T> {
296 let (a, b) = self.data.split_at_mut(self.insertion_index);
297 a.iter_mut().rev().chain(b.iter_mut().rev())
298 }
299
300 /// Returns an ascending iterator over the queue's contents.
301 ///
302 /// The iterator goes from the least recently pushed items to the newest ones.
303 ///
304 /// # Examples
305 ///
306 /// ```
307 /// use circular_queue::CircularQueue;
308 ///
309 /// let mut queue = CircularQueue::with_capacity(3);
310 /// queue.push(1);
311 /// queue.push(2);
312 /// queue.push(3);
313 /// queue.push(4);
314 ///
315 /// let mut iter = queue.asc_iter();
316 ///
317 /// assert_eq!(iter.next(), Some(&2));
318 /// assert_eq!(iter.next(), Some(&3));
319 /// assert_eq!(iter.next(), Some(&4));
320 /// ```
321 #[inline]
322 pub fn asc_iter(&self) -> AscIter<T> {
323 let (a, b) = self.data.split_at(self.insertion_index);
324 b.iter().chain(a.iter())
325 }
326
327 /// Returns a mutable ascending iterator over the queue's contents.
328 ///
329 /// The iterator goes from the least recently pushed items to the newest ones.
330 ///
331 /// # Examples
332 ///
333 /// ```
334 /// use circular_queue::CircularQueue;
335 ///
336 /// let mut queue = CircularQueue::with_capacity(3);
337 /// queue.push(1);
338 /// queue.push(2);
339 /// queue.push(3);
340 /// queue.push(4);
341 ///
342 /// let mut iter = queue.asc_iter_mut();
343 ///
344 /// assert_eq!(iter.next(), Some(&mut 2));
345 /// assert_eq!(iter.next(), Some(&mut 3));
346 /// assert_eq!(iter.next(), Some(&mut 4));
347 /// ```
348 #[inline]
349 pub fn asc_iter_mut(&mut self) -> AscIterMut<T> {
350 let (a, b) = self.data.split_at_mut(self.insertion_index);
351 b.iter_mut().chain(a.iter_mut())
352 }
353}
354
355impl<T: PartialEq> PartialEq for CircularQueue<T> {
356 #[inline]
357 fn eq(&self, other: &CircularQueue<T>) -> bool {
358 self.len() == other.len() && self.iter().zip(other.iter()).all(|(a, b)| a == b)
359 }
360}
361
362impl<T: Eq> Eq for CircularQueue<T> {}
363
364#[cfg(test)]
365mod tests {
366 use super::*;
367
368 #[test]
369 fn zero_capacity() {
370 let mut q = CircularQueue::<i32>::with_capacity(0);
371 assert_eq!(q.len(), 0);
372 assert_eq!(q.capacity(), 0);
373 assert!(q.is_empty());
374
375 q.push(3);
376 q.push(4);
377 q.push(5);
378
379 assert_eq!(q.len(), 0);
380 assert_eq!(q.capacity(), 0);
381 assert!(q.is_empty());
382
383 assert_eq!(q.iter().count(), 0);
384 assert_eq!(q.asc_iter().count(), 0);
385
386 q.clear();
387 }
388
389 #[test]
390 fn empty_queue() {
391 let q = CircularQueue::<i32>::with_capacity(5);
392
393 assert!(q.is_empty());
394 assert_eq!(q.iter().next(), None);
395 }
396
397 #[test]
398 fn partially_full_queue() {
399 let mut q = CircularQueue::with_capacity(5);
400 q.push(1);
401 q.push(2);
402 q.push(3);
403
404 assert!(!q.is_empty());
405 assert_eq!(q.len(), 3);
406
407 let res: Vec<_> = q.iter().map(|&x| x).collect();
408 assert_eq!(res, [3, 2, 1]);
409 }
410
411 #[test]
412 fn full_queue() {
413 let mut q = CircularQueue::with_capacity(5);
414 q.push(1);
415 q.push(2);
416 q.push(3);
417 q.push(4);
418 q.push(5);
419
420 assert_eq!(q.len(), 5);
421
422 let res: Vec<_> = q.iter().map(|&x| x).collect();
423 assert_eq!(res, [5, 4, 3, 2, 1]);
424 }
425
426 #[test]
427 fn over_full_queue() {
428 let mut q = CircularQueue::with_capacity(5);
429 q.push(1);
430 q.push(2);
431 q.push(3);
432 q.push(4);
433 q.push(5);
434 q.push(6);
435 q.push(7);
436
437 assert_eq!(q.len(), 5);
438
439 let res: Vec<_> = q.iter().map(|&x| x).collect();
440 assert_eq!(res, [7, 6, 5, 4, 3]);
441 }
442
443 #[test]
444 fn clear() {
445 let mut q = CircularQueue::with_capacity(5);
446 q.push(1);
447 q.push(2);
448 q.push(3);
449 q.push(4);
450 q.push(5);
451 q.push(6);
452 q.push(7);
453
454 q.clear();
455
456 assert_eq!(q.len(), 0);
457 assert_eq!(q.iter().next(), None);
458
459 q.push(1);
460 q.push(2);
461 q.push(3);
462
463 assert_eq!(q.len(), 3);
464
465 let res: Vec<_> = q.iter().map(|&x| x).collect();
466 assert_eq!(res, [3, 2, 1]);
467 }
468
469 #[test]
470 fn mutable_iterator() {
471 let mut q = CircularQueue::with_capacity(5);
472 q.push(1);
473 q.push(2);
474 q.push(3);
475 q.push(4);
476 q.push(5);
477 q.push(6);
478 q.push(7);
479
480 for x in q.iter_mut() {
481 *x *= 2;
482 }
483
484 let res: Vec<_> = q.iter().map(|&x| x).collect();
485 assert_eq!(res, [14, 12, 10, 8, 6]);
486 }
487
488 #[test]
489 fn zero_sized() {
490 let mut q = CircularQueue::with_capacity(3);
491 assert_eq!(q.capacity(), 3);
492
493 q.push(());
494 q.push(());
495 q.push(());
496 q.push(());
497
498 assert_eq!(q.len(), 3);
499
500 let mut iter = q.iter();
501 assert_eq!(iter.next(), Some(&()));
502 assert_eq!(iter.next(), Some(&()));
503 assert_eq!(iter.next(), Some(&()));
504 assert_eq!(iter.next(), None);
505 }
506
507 #[test]
508 fn empty_queue_eq() {
509 let q1 = CircularQueue::<i32>::with_capacity(5);
510 let q2 = CircularQueue::<i32>::with_capacity(5);
511 assert_eq!(q1, q2);
512
513 let q3 = CircularQueue::<i32>::with_capacity(6);
514 assert_eq!(q1, q3); // Capacity doesn't matter as long as the same elements are yielded.
515 }
516
517 #[test]
518 fn partially_full_queue_eq() {
519 let mut q1 = CircularQueue::with_capacity(5);
520 q1.push(1);
521 q1.push(2);
522 q1.push(3);
523
524 let mut q2 = CircularQueue::with_capacity(5);
525 q2.push(1);
526 q2.push(2);
527 assert_ne!(q1, q2);
528
529 q2.push(3);
530 assert_eq!(q1, q2);
531
532 q2.push(4);
533 assert_ne!(q1, q2);
534 }
535
536 #[test]
537 fn full_queue_eq() {
538 let mut q1 = CircularQueue::with_capacity(5);
539 q1.push(1);
540 q1.push(2);
541 q1.push(3);
542 q1.push(4);
543 q1.push(5);
544
545 let mut q2 = CircularQueue::with_capacity(5);
546 q2.push(1);
547 q2.push(2);
548 q2.push(3);
549 q2.push(4);
550 q2.push(5);
551
552 assert_eq!(q1, q2);
553 }
554
555 #[test]
556 fn over_full_queue_eq() {
557 let mut q1 = CircularQueue::with_capacity(5);
558 q1.push(1);
559 q1.push(2);
560 q1.push(3);
561 q1.push(4);
562 q1.push(5);
563 q1.push(6);
564 q1.push(7);
565
566 let mut q2 = CircularQueue::with_capacity(5);
567 q2.push(1);
568 q2.push(2);
569 q2.push(3);
570 q2.push(4);
571 q2.push(5);
572 q2.push(6);
573 assert_ne!(q1, q2);
574
575 q2.push(7);
576 assert_eq!(q1, q2);
577
578 q2.push(8);
579 assert_ne!(q1, q2);
580
581 q2.push(3);
582 q2.push(4);
583 q2.push(5);
584 q2.push(6);
585 q2.push(7);
586 assert_eq!(q1, q2);
587 }
588
589 #[test]
590 fn clear_eq() {
591 let mut q1 = CircularQueue::with_capacity(5);
592 q1.push(1);
593 q1.push(2);
594 q1.push(3);
595 q1.push(4);
596 q1.push(5);
597 q1.push(6);
598 q1.push(7);
599 q1.clear();
600
601 let mut q2 = CircularQueue::with_capacity(5);
602 assert_eq!(q1, q2);
603
604 q2.push(1);
605 q2.clear();
606 assert_eq!(q1, q2);
607 }
608
609 #[test]
610 fn zero_sized_eq() {
611 let mut q1 = CircularQueue::with_capacity(3);
612 q1.push(());
613 q1.push(());
614 q1.push(());
615 q1.push(());
616
617 let mut q2 = CircularQueue::with_capacity(3);
618 q2.push(());
619 q2.push(());
620 assert_ne!(q1, q2);
621
622 q2.push(());
623 assert_eq!(q1, q2);
624
625 q2.push(());
626 assert_eq!(q1, q2);
627
628 q2.push(());
629 assert_eq!(q1, q2);
630 }
631}