circular_buffer/lib.rs
1// Copyright © 2023-2025 Andrea Corbellini and contributors
2// SPDX-License-Identifier: BSD-3-Clause
3
4//! This crate implements a [circular buffer], also known as cyclic buffer, circular queue or ring.
5//!
6//! The main struct is [`CircularBuffer`]. It can live on the stack and does not require any heap
7//! memory allocation. A `CircularBuffer` is sequence of elements with a maximum capacity: elements
8//! can be added to the buffer, and once the maximum capacity is reached, the elements at the start
9//! of the buffer are discarded and overwritten.
10//!
11//! [circular buffer]: https://en.wikipedia.org/wiki/Circular_buffer
12//!
13//! # Examples
14//!
15//! ```
16//! use circular_buffer::CircularBuffer;
17//!
18//! // Initialize a new, empty circular buffer with a capacity of 5 elements
19//! let mut buf = CircularBuffer::<5, u32>::new();
20//!
21//! // Add a few elements
22//! buf.push_back(1);
23//! buf.push_back(2);
24//! buf.push_back(3);
25//! assert_eq!(buf, [1, 2, 3]);
26//!
27//! // Add more elements to fill the buffer capacity completely
28//! buf.push_back(4);
29//! buf.push_back(5);
30//! assert_eq!(buf, [1, 2, 3, 4, 5]);
31//!
32//! // Adding more elements than the buffer can contain causes the front elements to be
33//! // automatically dropped
34//! buf.push_back(6);
35//! assert_eq!(buf, [2, 3, 4, 5, 6]); // `1` got dropped to make room for `6`
36//! ```
37//!
38//! # Interface
39//!
40//! [`CircularBuffer`] provides methods akin the ones for the standard
41//! [`VecDeque`](std::collections::VecDeque) and [`LinkedList`](std::collections::LinkedList). The
42//! list below includes the most common methods, but see the [`CircularBuffer` struct
43//! documentation](CircularBuffer) to see more.
44//!
45//! ## Adding/removing elements
46//!
47//! * [`push_back()`](CircularBuffer::push_back), [`push_front()`](CircularBuffer::push_front)
48//! * [`pop_back()`](CircularBuffer::pop_back), [`pop_front()`](CircularBuffer::pop_front)
49//! * [`swap_remove_back()`](CircularBuffer::swap_remove_back),
50//! [`swap_remove_front()`](CircularBuffer::swap_remove_front)
51//!
52//! ## Getting/mutating elements
53//!
54//! * [`get()`](CircularBuffer::get), [`get_mut()`](CircularBuffer::get_mut)
55//! * [`front()`](CircularBuffer::front), [`front_mut()`](CircularBuffer::front_mut)
56//! * [`back()`](CircularBuffer::back), [`back_mut()`](CircularBuffer::back_mut)
57//! * [`nth_front()`](CircularBuffer::nth_front), [`nth_front_mut()`](CircularBuffer::nth_front_mut)
58//! * [`nth_back()`](CircularBuffer::nth_back), [`nth_back_mut()`](CircularBuffer::nth_back_mut)
59//!
60//! ## Adding multiple elements at once
61//!
62//! * [`extend()`](CircularBuffer::extend),
63//! [`extend_from_slice()`](CircularBuffer::extend_from_slice)
64//! * [`fill()`](CircularBuffer::fill), [`fill_with()`](CircularBuffer::fill_with)
65//! * [`fill_spare()`](CircularBuffer::fill), [`fill_spare_with()`](CircularBuffer::fill_with)
66//!
67//! ## Iterators
68//!
69//! * [`into_iter()`](CircularBuffer::into_iter)
70//! * [`iter()`](CircularBuffer::iter), [`iter_mut()`](CircularBuffer::iter_mut)
71//! * [`range()`](CircularBuffer::range), [`range_mut()`](CircularBuffer::range_mut)
72//! * [`drain()`](CircularBuffer::drain)
73//!
74//! ## Writing/reading bytes
75//!
76//! For the special case of a `CircularBuffer` containing `u8` elements, bytes can be written and
77//! read using the standard [`Write`](std::io::Write) and [`Read`](std::io::Read) traits. Writing
78//! past the buffer capacity will overwrite the bytes at the start of the buffer, and reading
79//! elements will consume elements from the buffer.
80//!
81//! ```
82//! # #[allow(unused_must_use)]
83//! # #[cfg(feature = "std")]
84//! # {
85//! use circular_buffer::CircularBuffer;
86//! use std::io::Read;
87//! use std::io::Write;
88//!
89//! let mut buf = CircularBuffer::<5, u8>::new();
90//! assert_eq!(buf, b"");
91//!
92//! write!(buf, "hello");
93//! assert_eq!(buf, b"hello");
94//!
95//! write!(buf, "this string will overflow the buffer and wrap around");
96//! assert_eq!(buf, b"round");
97//!
98//! let mut s = String::new();
99//! buf.read_to_string(&mut s)
100//! .expect("failed to read from buffer");
101//! assert_eq!(s, "round");
102//! assert_eq!(buf, b"");
103//! # }
104//! ```
105//!
106//! # Time complexity
107//!
108//! Most of the methods implemented by [`CircularBuffer`] run in constant time. Some of the methods
109//! may run in linear time if the type of the elements implements [`Drop`], as each element needs
110//! to be deallocated one-by-one.
111//!
112//! | Method | Complexity |
113//! |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------|
114//! | [`push_back()`](CircularBuffer::push_back), [`push_front()`](CircularBuffer::push_front) | *O*(1) |
115//! | [`pop_back()`](CircularBuffer::pop_back), [`pop_front()`](CircularBuffer::pop_front) | *O*(1) |
116//! | [`remove(i)`](CircularBuffer::remove) | *O*(*n* − *i*) |
117//! | [`truncate_back(i)`](CircularBuffer::truncate_back), [`truncate_front(i)`](CircularBuffer::truncate_front) | *O*(*n* − *i*) for types that implement [`Drop`], *O*(1) otherwise |
118//! | [`clear()`](CircularBuffer::clear) | *O*(*n*) for types that implement [`Drop`], *O*(1) otherwise |
119//! | [`drain(i..j)`](CircularBuffer::drain) | *O*(*n* − *j*) |
120//! | [`fill()`](CircularBuffer::fill), [`fill_with()`](CircularBuffer::fill_with) | *O*(*c* + *n*) for types that implement [`Drop`], *O*(*c*) otherwise |
121//! | [`fill_spare()`](CircularBuffer::fill_spare), [`fill_spare_with()`](CircularBuffer::fill_spare_with) | *O*(*c* − *n*) |
122//! | [`get()`](CircularBuffer::get), [`front()`](CircularBuffer::front), [`back()`](CircularBuffer::back), [`nth_front()`](CircularBuffer::nth_front), [`nth_back()`](CircularBuffer::nth_back) | *O*(1) |
123//! | [`swap()`](CircularBuffer::swap), [`swap_remove_front()`](CircularBuffer::swap_remove_front), [`swap_remove_back()`](CircularBuffer::swap_remove_back) | *O*(1) |
124//! | [`as_slices()`](CircularBuffer::as_slices), [`as_mut_slices()`](CircularBuffer::as_mut_slices) | *O*(1) |
125//! | [`len()`](CircularBuffer::len), [`capacity()`](CircularBuffer::capacity) | *O*(1) |
126//!
127//! Notation: *n* is the [length](CircularBuffer::len) of the buffer, *c* is the
128//! [capacity](CircularBuffer::capacity) of the buffer, *i* and *j* are variables.
129//!
130//! # Stack vs heap
131//!
132//! The [`CircularBuffer`] struct is compact and has a fixed size, so it may live on the stack.
133//! This can provide optimal performance for small buffers as memory allocation can be avoided.
134//!
135//! For large buffers, or for buffers that need to be passed around often, it can be useful to
136//! allocate the buffer on the heap. Use a [`Box`](std::boxed) for that:
137//!
138//! ```
139//! # #[cfg(feature = "std")]
140//! # {
141//! use circular_buffer::CircularBuffer;
142//!
143//! let mut buf = CircularBuffer::<4096, u32>::boxed();
144//! assert_eq!(buf.len(), 0);
145//!
146//! for i in 0..1024 {
147//! buf.push_back(i);
148//! }
149//! assert_eq!(buf.len(), 1024);
150//!
151//! buf.truncate_back(128);
152//! assert_eq!(buf.len(), 128);
153//! # }
154//! ```
155//!
156//! # `no_std`
157//!
158//! This crate can be used in a [`no_std` environment], although the I/O features and
159//! heap-allocation features won't be available by default in `no_std` mode. By default, this crate
160//! uses `std`; to use this crate in `no_std` mode, disable the default features for this crate in
161//! your `Cargo.toml`:
162//!
163//! ```text
164//! [dependencies]
165//! circular-buffer = { version = "0.1", default-features = false }
166//! ```
167//!
168//! When using `no_std` mode, this crate supports heap-allocation features through the [`alloc`
169//! crate](alloc). To enable the use of the `alloc` crate, enable the `alloc` feature:
170//!
171//! ```text
172//! [dependencies]
173//! circular-buffer = { version = "0.1", default-features = false, features = ["alloc"] }
174//! ```
175//!
176//! [`no_std` environment]: https://docs.rust-embedded.org/book/intro/no-std.html
177//!
178//! # Cargo feature flags
179//!
180//! * `std`: enables support for the [`std` library](https://doc.rust-lang.org/std/) (enabled by
181//! default).
182//! * `alloc`: enables support for the [`alloc` crate](https://doc.rust-lang.org/alloc/) (enabled
183//! by default).
184//! * `embedded-io`: enables implementation for the
185//! [`embedded_io`](https://docs.rs/embedded-io/) traits.
186//! * `embedded-io-async`: enables implementation for the
187//! [`embedded_io_async`](https://docs.rs/embedded-io-async) traits.
188
189#![cfg_attr(not(feature = "std"), no_std)]
190#![cfg_attr(feature = "unstable", feature(maybe_uninit_slice))]
191#![cfg_attr(feature = "unstable", feature(maybe_uninit_write_slice))]
192#![warn(missing_debug_implementations)]
193#![warn(missing_docs)]
194#![warn(unreachable_pub)]
195#![warn(unused_qualifications)]
196#![doc(test(attr(deny(warnings))))]
197
198mod drain;
199mod iter;
200
201#[cfg(feature = "std")]
202mod io;
203
204#[cfg(any(feature = "embedded-io", feature = "embedded-io-async"))]
205mod embedded_io;
206
207#[cfg(test)]
208mod tests;
209
210use core::cmp::Ordering;
211use core::fmt;
212use core::hash::Hash;
213use core::hash::Hasher;
214use core::mem;
215use core::mem::MaybeUninit;
216use core::ops::Index;
217use core::ops::IndexMut;
218use core::ops::Range;
219use core::ops::RangeBounds;
220use core::ptr;
221
222pub use crate::drain::Drain;
223pub use crate::iter::IntoIter;
224pub use crate::iter::Iter;
225pub use crate::iter::IterMut;
226
227#[cfg(feature = "alloc")]
228extern crate alloc;
229
230#[cfg(all(not(feature = "std"), feature = "alloc"))]
231use alloc::boxed::Box;
232#[cfg(all(not(feature = "std"), feature = "alloc"))]
233use alloc::vec::Vec;
234
235/// Returns `(x + y) % m` without risk of overflows if `x + y` cannot fit in `usize`.
236///
237/// `x` and `y` are expected to be less than, or equal to `m`.
238#[inline]
239const fn add_mod(x: usize, y: usize, m: usize) -> usize {
240 debug_assert!(m > 0);
241 debug_assert!(x <= m);
242 debug_assert!(y <= m);
243 let (z, overflow) = x.overflowing_add(y);
244 (z + (overflow as usize) * (usize::MAX % m + 1)) % m
245}
246
247/// Returns `(x - y) % m` without risk of underflows if `x - y` is negative.
248///
249/// `x` and `y` are expected to be less than, or equal to `m`.
250#[inline]
251const fn sub_mod(x: usize, y: usize, m: usize) -> usize {
252 debug_assert!(m > 0);
253 debug_assert!(x <= m);
254 debug_assert!(y <= m);
255 add_mod(x, m - y, m)
256}
257
258#[inline]
259const unsafe fn slice_assume_init_ref<T>(slice: &[MaybeUninit<T>]) -> &[T] {
260 #[cfg(feature = "unstable")]
261 unsafe {
262 slice.assume_init_ref()
263 }
264 #[cfg(not(feature = "unstable"))]
265 unsafe {
266 &*(slice as *const [MaybeUninit<T>] as *const [T])
267 }
268}
269
270#[inline]
271unsafe fn slice_assume_init_mut<T>(slice: &mut [MaybeUninit<T>]) -> &mut [T] {
272 #[cfg(feature = "unstable")]
273 unsafe {
274 slice.assume_init_mut()
275 }
276 #[cfg(not(feature = "unstable"))]
277 unsafe {
278 &mut *(slice as *mut [MaybeUninit<T>] as *mut [T])
279 }
280}
281
282/// A fixed-size circular buffer.
283///
284/// A `CircularBuffer` may live on the stack. Wrap the `CircularBuffer` in a [`Box`](std::boxed)
285/// using [`CircularBuffer::boxed()`] if you need the struct to be heap-allocated.
286///
287/// See the [module-level documentation](self) for more details and examples.
288pub struct CircularBuffer<const N: usize, T> {
289 size: usize,
290 start: usize,
291 items: [MaybeUninit<T>; N],
292}
293
294impl<const N: usize, T> CircularBuffer<N, T> {
295 /// Returns an empty `CircularBuffer`.
296 ///
297 /// # Examples
298 ///
299 /// ```
300 /// use circular_buffer::CircularBuffer;
301 /// let buf = CircularBuffer::<16, u32>::new();
302 /// assert_eq!(buf, []);
303 /// ```
304 #[inline]
305 #[must_use]
306 pub const fn new() -> Self {
307 #[cfg(feature = "unstable")]
308 {
309 Self {
310 size: 0,
311 start: 0,
312 items: [const { MaybeUninit::uninit() }; N],
313 }
314 }
315 #[cfg(not(feature = "unstable"))]
316 {
317 Self {
318 size: 0,
319 start: 0,
320 items: unsafe { MaybeUninit::<[MaybeUninit<T>; N]>::uninit().assume_init() },
321 }
322 }
323 }
324
325 /// Returns an empty heap-allocated `CircularBuffer`.
326 ///
327 /// # Examples
328 ///
329 /// ```
330 /// use circular_buffer::CircularBuffer;
331 /// let buf = CircularBuffer::<1024, f64>::boxed();
332 /// assert_eq!(buf.len(), 0);
333 /// ```
334 #[must_use]
335 #[cfg(feature = "alloc")]
336 pub fn boxed() -> Box<Self> {
337 let mut uninit: Box<MaybeUninit<Self>> = Box::new_uninit();
338 let ptr = uninit.as_mut_ptr();
339
340 unsafe {
341 // SAFETY: the pointer contains enough memory to contain `Self` and `addr_of_mut`
342 // ensures that the address written to is properly aligned.
343 core::ptr::addr_of_mut!((*ptr).size).write(0);
344 core::ptr::addr_of_mut!((*ptr).start).write(0);
345
346 // SAFETY: `size` and `start` have been properly initialized to 0; `items` does not
347 // need to be initialized if `size` is 0
348 uninit.assume_init()
349 }
350 }
351
352 /// Returns the number of elements in the buffer.
353 ///
354 /// # Examples
355 ///
356 /// ```
357 /// use circular_buffer::CircularBuffer;
358 ///
359 /// let mut buf = CircularBuffer::<16, u32>::new();
360 /// assert_eq!(buf.len(), 0);
361 ///
362 /// buf.push_back(1);
363 /// buf.push_back(2);
364 /// buf.push_back(3);
365 /// assert_eq!(buf.len(), 3);
366 /// ```
367 #[inline]
368 pub const fn len(&self) -> usize {
369 self.size
370 }
371
372 /// Returns the capacity of the buffer.
373 ///
374 /// This is the maximum number of elements that the buffer can hold.
375 ///
376 /// This method always returns the generic const parameter `N`.
377 ///
378 /// # Examples
379 ///
380 /// ```
381 /// use circular_buffer::CircularBuffer;
382 /// let buf = CircularBuffer::<16, u32>::new();
383 /// assert_eq!(buf.capacity(), 16);
384 /// ```
385 #[inline]
386 pub const fn capacity(&self) -> usize {
387 N
388 }
389
390 /// Returns `true` if the buffer contains 0 elements.
391 ///
392 /// # Examples
393 ///
394 /// ```
395 /// use circular_buffer::CircularBuffer;
396 ///
397 /// let mut buf = CircularBuffer::<16, u32>::new();
398 /// assert!(buf.is_empty());
399 ///
400 /// buf.push_back(1);
401 /// assert!(!buf.is_empty());
402 /// ```
403 #[inline]
404 pub const fn is_empty(&self) -> bool {
405 self.size == 0
406 }
407
408 /// Returns `true` if the number of elements in the buffer matches the buffer capacity.
409 ///
410 /// # Examples
411 ///
412 /// ```
413 /// use circular_buffer::CircularBuffer;
414 ///
415 /// let mut buf = CircularBuffer::<5, u32>::new();
416 /// assert!(!buf.is_full());
417 ///
418 /// buf.push_back(1);
419 /// assert!(!buf.is_full());
420 ///
421 /// buf.push_back(2);
422 /// buf.push_back(3);
423 /// buf.push_back(4);
424 /// buf.push_back(5);
425 /// assert!(buf.is_full());
426 /// ```
427 #[inline]
428 pub const fn is_full(&self) -> bool {
429 self.size == N
430 }
431
432 /// Returns an iterator over the elements of the buffer.
433 ///
434 /// The iterator advances from front to back. Use [`.rev()`](Iter::rev) to advance from
435 /// back to front.
436 ///
437 /// # Examples
438 ///
439 /// Iterate from front to back:
440 ///
441 /// ```
442 /// use circular_buffer::CircularBuffer;
443 ///
444 /// let buf = CircularBuffer::<5, char>::from_iter("abc".chars());
445 /// let mut it = buf.iter();
446 ///
447 /// assert_eq!(it.next(), Some(&'a'));
448 /// assert_eq!(it.next(), Some(&'b'));
449 /// assert_eq!(it.next(), Some(&'c'));
450 /// assert_eq!(it.next(), None);
451 /// ```
452 ///
453 /// Iterate from back to front:
454 ///
455 /// ```
456 /// use circular_buffer::CircularBuffer;
457 ///
458 /// let buf = CircularBuffer::<5, char>::from_iter("abc".chars());
459 /// let mut it = buf.iter().rev();
460 ///
461 /// assert_eq!(it.next(), Some(&'c'));
462 /// assert_eq!(it.next(), Some(&'b'));
463 /// assert_eq!(it.next(), Some(&'a'));
464 /// assert_eq!(it.next(), None);
465 /// ```
466 #[inline]
467 #[must_use]
468 pub fn iter(&self) -> Iter<'_, T> {
469 Iter::new(self)
470 }
471
472 /// Returns an iterator over the elements of the buffer that allows modifying each value.
473 ///
474 /// The iterator advances from front to back. Use [`.rev()`](Iter::rev) to advance from back to
475 /// front.
476 ///
477 /// # Examples
478 ///
479 /// ```
480 /// use circular_buffer::CircularBuffer;
481 ///
482 /// let mut buf = CircularBuffer::<5, u32>::from([1, 2, 3]);
483 /// for elem in buf.iter_mut() {
484 /// *elem += 5;
485 /// }
486 /// assert_eq!(buf, [6, 7, 8]);
487 /// ```
488 #[inline]
489 #[must_use]
490 pub fn iter_mut(&mut self) -> IterMut<'_, T> {
491 IterMut::new(self)
492 }
493
494 /// Returns an iterator over the specified range of elements of the buffer.
495 ///
496 /// The iterator advances from front to back. Use [`.rev()`](Iter::rev) to advance from back to
497 /// front.
498 ///
499 /// # Panics
500 ///
501 /// If the start of the range is greater than the end, or if the end is greater than the length
502 /// of the buffer.
503 ///
504 /// # Examples
505 ///
506 /// Iterate from front to back:
507 ///
508 /// ```
509 /// use circular_buffer::CircularBuffer;
510 ///
511 /// let buf = CircularBuffer::<16, char>::from_iter("abcdefghi".chars());
512 /// let mut it = buf.range(3..6);
513 ///
514 /// assert_eq!(it.next(), Some(&'d'));
515 /// assert_eq!(it.next(), Some(&'e'));
516 /// assert_eq!(it.next(), Some(&'f'));
517 /// assert_eq!(it.next(), None);
518 /// ```
519 ///
520 /// Iterate from back to front:
521 ///
522 /// ```
523 /// use circular_buffer::CircularBuffer;
524 ///
525 /// let buf = CircularBuffer::<16, char>::from_iter("abcdefghi".chars());
526 /// let mut it = buf.range(3..6).rev();
527 ///
528 /// assert_eq!(it.next(), Some(&'f'));
529 /// assert_eq!(it.next(), Some(&'e'));
530 /// assert_eq!(it.next(), Some(&'d'));
531 /// assert_eq!(it.next(), None);
532 /// ```
533 #[inline]
534 #[must_use]
535 pub fn range<R>(&self, range: R) -> Iter<'_, T>
536 where
537 R: RangeBounds<usize>,
538 {
539 Iter::over_range(self, range)
540 }
541
542 /// Returns an iterator over the specified range of elements of the buffer that allows
543 /// modifying each value.
544 ///
545 /// The iterator advances from front to back. Use [`.rev()`](Iter::rev) to advance from back to
546 /// front.
547 ///
548 /// # Panics
549 ///
550 /// If the start of the range is greater than the end, or if the end is greater than the length
551 /// of the buffer.
552 ///
553 /// # Examples
554 ///
555 /// Iterate from front to back:
556 ///
557 /// ```
558 /// use circular_buffer::CircularBuffer;
559 ///
560 /// let mut buf = CircularBuffer::<16, i32>::from_iter([1, 2, 3, 4, 5, 6]);
561 /// for elem in buf.range_mut(..3) {
562 /// *elem *= -1;
563 /// }
564 /// assert_eq!(buf, [-1, -2, -3, 4, 5, 6]);
565 /// ```
566 #[inline]
567 #[must_use]
568 pub fn range_mut<R>(&mut self, range: R) -> IterMut<'_, T>
569 where
570 R: RangeBounds<usize>,
571 {
572 IterMut::over_range(self, range)
573 }
574
575 /// Removes the specified range from the buffer in bulk, returning the removed elements as an
576 /// iterator. If the iterator is dropped before being fully consumed, it drops the remaining
577 /// removed elements.
578 ///
579 /// # Panics
580 ///
581 /// If the start of the range is greater than the end, or if the end is greater than the length
582 /// of the buffer.
583 ///
584 /// # Leaking
585 ///
586 /// If the returned iterator goes out of scope without being dropped (for example, due to
587 /// calling [`mem::forget()`] on it), the buffer may have lost and leaked arbitrary elements,
588 /// including elements outside of the range.
589 ///
590 /// The current implementation leaks all the elements of the buffer if the iterator is leaked,
591 /// but this behavior may change in the future.
592 ///
593 /// # Examples
594 ///
595 /// ```
596 /// use circular_buffer::CircularBuffer;
597 ///
598 /// let mut buf = CircularBuffer::<6, char>::from_iter("abcdef".chars());
599 /// let drained = buf.drain(3..).collect::<Vec<char>>();
600 ///
601 /// assert_eq!(drained, ['d', 'e', 'f']);
602 /// assert_eq!(buf, ['a', 'b', 'c']);
603 /// ```
604 ///
605 /// Not consuming the draining iterator still removes the range of elements:
606 ///
607 /// ```
608 /// use circular_buffer::CircularBuffer;
609 ///
610 /// let mut buf = CircularBuffer::<6, char>::from_iter("abcdef".chars());
611 /// buf.drain(3..);
612 ///
613 /// assert_eq!(buf, ['a', 'b', 'c']);
614 /// ```
615 #[inline]
616 pub fn drain<R>(&mut self, range: R) -> Drain<'_, N, T>
617 where
618 R: RangeBounds<usize>,
619 {
620 Drain::over_range(self, range)
621 }
622
623 /// Rearranges the internal memory of the buffer so that all elements are in a contiguous
624 /// slice, which is then returned.
625 ///
626 /// This method does not allocate and does not change the order of the inserted elements.
627 /// Because it returns a mutable slice, any [slice methods](slice) may be called on the
628 /// elements of the buffer, such as sorting methods.
629 ///
630 /// Once the internal storage is contiguous, the [`as_slices()`](CircularBuffer::as_slices) and
631 /// [`as_mut_slices()`](CircularBuffer::as_mut_slices) methods will return the entire contents
632 /// of the deque in a single slice. Adding new elements to the buffer may make the buffer
633 /// disjoint (not contiguous).
634 ///
635 /// # Complexity
636 ///
637 /// If the buffer is disjoint (not contiguous), this method takes *O*(*N*) time, where *N* is
638 /// the capacity of the buffer.
639 ///
640 /// If the buffer is already contiguous, this method takes *O*(1) time.
641 ///
642 /// This means that this method may be called multiple times on the same buffer without a
643 /// performance penalty (provided that no new elements are added to the buffer in between
644 /// calls).
645 ///
646 /// # Examples
647 ///
648 /// ```
649 /// use circular_buffer::CircularBuffer;
650 ///
651 /// // Create a new buffer, adding more elements than its capacity
652 /// let mut buf = CircularBuffer::<4, u32>::from_iter([1, 4, 3, 0, 2, 5]);
653 /// assert_eq!(buf, [3, 0, 2, 5]);
654 ///
655 /// // The buffer is disjoint: as_slices() returns two non-empty slices
656 /// assert_eq!(buf.as_slices(), (&[3, 0][..], &[2, 5][..]));
657 ///
658 /// // Make the buffer contiguous
659 /// assert_eq!(buf.make_contiguous(), &mut [3, 0, 2, 5]);
660 /// // as_slices() now returns a single non-empty slice
661 /// assert_eq!(buf.as_slices(), (&[3, 0, 2, 5][..], &[][..]));
662 /// // The order of the elements in the buffer did not get modified
663 /// assert_eq!(buf, [3, 0, 2, 5]);
664 ///
665 /// // Make the buffer contiguous and sort its elements
666 /// buf.make_contiguous().sort();
667 /// assert_eq!(buf, [0, 2, 3, 5]);
668 /// ```
669 pub fn make_contiguous(&mut self) -> &mut [T] {
670 if N == 0 || self.size == 0 {
671 return &mut [];
672 }
673
674 debug_assert!(self.start < N, "start out-of-bounds");
675 debug_assert!(self.size <= N, "size out-of-bounds");
676
677 let start = self.start;
678 let end = add_mod(self.start, self.size, N);
679
680 let slice = if start < end {
681 // Already contiguous; nothing to do
682 &mut self.items[start..end]
683 } else {
684 // Not contiguous; need to rotate
685 self.start = 0;
686 self.items.rotate_left(start);
687 &mut self.items[..self.size]
688 };
689
690 // SAFETY: The elements in the slice are guaranteed to be initialized
691 unsafe { slice_assume_init_mut(slice) }
692 }
693
694 /// Returns a pair of slices which contain the elements of this buffer.
695 ///
696 /// The second slice may be empty if the internal buffer is contiguous.
697 ///
698 /// # Examples
699 ///
700 /// ```
701 /// use circular_buffer::CircularBuffer;
702 ///
703 /// let mut buf = CircularBuffer::<4, char>::new();
704 /// buf.push_back('a');
705 /// buf.push_back('b');
706 /// buf.push_back('c');
707 /// buf.push_back('d');
708 ///
709 /// // Buffer is contiguous; second slice is empty
710 /// assert_eq!(buf.as_slices(), (&['a', 'b', 'c', 'd'][..], &[][..]));
711 ///
712 /// buf.push_back('e');
713 /// buf.push_back('f');
714 ///
715 /// // Buffer is disjoint; both slices are non-empty
716 /// assert_eq!(buf.as_slices(), (&['c', 'd'][..], &['e', 'f'][..]));
717 /// ```
718 #[inline]
719 pub fn as_slices(&self) -> (&[T], &[T]) {
720 if N == 0 || self.size == 0 {
721 return (&[], &[]);
722 }
723
724 debug_assert!(self.start < N, "start out-of-bounds");
725 debug_assert!(self.size <= N, "size out-of-bounds");
726
727 let start = self.start;
728 let end = add_mod(self.start, self.size, N);
729
730 let (front, back) = if start < end {
731 (&self.items[start..end], &[][..])
732 } else {
733 let (back, front) = self.items.split_at(start);
734 (front, &back[..end])
735 };
736
737 // SAFETY: The elements in these slices are guaranteed to be initialized
738 unsafe { (slice_assume_init_ref(front), slice_assume_init_ref(back)) }
739 }
740
741 /// Returns a pair of mutable slices which contain the elements of this buffer.
742 ///
743 /// These slices can be used to modify or replace the elements in the buffer.
744 ///
745 /// The second slice may be empty if the internal buffer is contiguous.
746 ///
747 /// # Examples
748 ///
749 /// ```
750 /// use circular_buffer::CircularBuffer;
751 ///
752 /// let mut buf = CircularBuffer::<4, char>::new();
753 /// buf.push_back('a');
754 /// buf.push_back('b');
755 /// buf.push_back('c');
756 /// buf.push_back('d');
757 /// buf.push_back('e');
758 /// buf.push_back('f');
759 ///
760 /// assert_eq!(buf, ['c', 'd', 'e', 'f']);
761 ///
762 /// let (left, right) = buf.as_mut_slices();
763 /// assert_eq!(left, &mut ['c', 'd'][..]);
764 /// assert_eq!(right, &mut ['e', 'f'][..]);
765 ///
766 /// left[0] = 'z';
767 ///
768 /// assert_eq!(buf, ['z', 'd', 'e', 'f']);
769 /// ```
770 #[inline]
771 pub fn as_mut_slices(&mut self) -> (&mut [T], &mut [T]) {
772 if N == 0 || self.size == 0 {
773 return (&mut [][..], &mut [][..]);
774 }
775
776 debug_assert!(self.start < N, "start out-of-bounds");
777 debug_assert!(self.size <= N, "size out-of-bounds");
778
779 let start = self.start;
780 let end = add_mod(self.start, self.size, N);
781
782 let (front, back) = if start < end {
783 (&mut self.items[start..end], &mut [][..])
784 } else {
785 let (back, front) = self.items.split_at_mut(start);
786 (front, &mut back[..end])
787 };
788
789 // SAFETY: The elements in these slices are guaranteed to be initialized
790 unsafe { (slice_assume_init_mut(front), slice_assume_init_mut(back)) }
791 }
792
793 #[inline]
794 fn front_maybe_uninit_mut(&mut self) -> &mut MaybeUninit<T> {
795 debug_assert!(self.size > 0, "empty buffer");
796 debug_assert!(self.start < N, "start out-of-bounds");
797 &mut self.items[self.start]
798 }
799
800 #[inline]
801 const fn front_maybe_uninit(&self) -> &MaybeUninit<T> {
802 debug_assert!(self.size > 0, "empty buffer");
803 debug_assert!(self.size <= N, "size out-of-bounds");
804 debug_assert!(self.start < N, "start out-of-bounds");
805 &self.items[self.start]
806 }
807
808 #[inline]
809 const fn back_maybe_uninit(&self) -> &MaybeUninit<T> {
810 debug_assert!(self.size > 0, "empty buffer");
811 debug_assert!(self.size <= N, "size out-of-bounds");
812 debug_assert!(self.start < N, "start out-of-bounds");
813 let back = add_mod(self.start, self.size - 1, N);
814 &self.items[back]
815 }
816
817 #[inline]
818 fn back_maybe_uninit_mut(&mut self) -> &mut MaybeUninit<T> {
819 debug_assert!(self.size > 0, "empty buffer");
820 debug_assert!(self.size <= N, "size out-of-bounds");
821 debug_assert!(self.start < N, "start out-of-bounds");
822 let back = add_mod(self.start, self.size - 1, N);
823 &mut self.items[back]
824 }
825
826 #[inline]
827 const fn get_maybe_uninit(&self, index: usize) -> &MaybeUninit<T> {
828 debug_assert!(self.size > 0, "empty buffer");
829 debug_assert!(index < N, "index out-of-bounds");
830 debug_assert!(self.start < N, "start out-of-bounds");
831 let index = add_mod(self.start, index, N);
832 &self.items[index]
833 }
834
835 #[inline]
836 fn get_maybe_uninit_mut(&mut self, index: usize) -> &mut MaybeUninit<T> {
837 debug_assert!(self.size > 0, "empty buffer");
838 debug_assert!(index < N, "index out-of-bounds");
839 debug_assert!(self.start < N, "start out-of-bounds");
840 let index = add_mod(self.start, index, N);
841 &mut self.items[index]
842 }
843
844 #[inline]
845 fn slices_uninit_mut(&mut self) -> (&mut [MaybeUninit<T>], &mut [MaybeUninit<T>]) {
846 if N == 0 {
847 return (&mut [][..], &mut [][..]);
848 }
849
850 debug_assert!(self.start < N, "start out-of-bounds");
851 debug_assert!(self.size <= N, "size out-of-bounds");
852
853 let start = self.start;
854 let end = add_mod(start, self.size, N);
855 if end < start {
856 (&mut self.items[end..start], &mut [][..])
857 } else {
858 let (left, right) = self.items.split_at_mut(end);
859 let left = &mut left[..start];
860 (right, left)
861 }
862 }
863
864 #[inline]
865 fn inc_start(&mut self) {
866 debug_assert!(self.start < N, "start out-of-bounds");
867 self.start = add_mod(self.start, 1, N);
868 }
869
870 #[inline]
871 fn dec_start(&mut self) {
872 debug_assert!(self.start < N, "start out-of-bounds");
873 self.start = sub_mod(self.start, 1, N);
874 }
875
876 #[inline]
877 fn inc_size(&mut self) {
878 debug_assert!(self.size <= N, "size out-of-bounds");
879 debug_assert!(self.size < N, "size at capacity limit");
880 self.size += 1;
881 }
882
883 #[inline]
884 fn dec_size(&mut self) {
885 debug_assert!(self.size > 0, "size is 0");
886 self.size -= 1;
887 }
888
889 /// Drops the elements at the specified range.
890 ///
891 /// The `start` and `size` attributes are automatically updated before the elements are dropped.
892 ///
893 /// # Safety
894 ///
895 /// `range` must be at a boundary of the buffer (either starting at index 0, or ending at the
896 /// end of the buffer), and must reference initialized elements.
897 #[inline]
898 unsafe fn drop_range(&mut self, range: Range<usize>) {
899 if range.is_empty() {
900 return;
901 }
902
903 debug_assert!(self.start < N, "start out-of-bounds");
904 debug_assert!(self.size <= N, "size out-of-bounds");
905 debug_assert!(range.start < self.size, "start of range out-of-bounds");
906 debug_assert!(range.end <= self.size, "end of range out-of-bounds");
907 debug_assert!(range.start < range.end, "start of range is past its end");
908 debug_assert!(
909 range.start == 0 || range.end == self.size,
910 "range does not include boundary of the buffer"
911 );
912
913 // Drops all the items in the slice when dropped. This is needed to ensure that all
914 // elements are dropped in case a panic occurs during the drop of a single element.
915 struct Dropper<'a, T>(&'a mut [MaybeUninit<T>]);
916
917 impl<T> Drop for Dropper<'_, T> {
918 #[inline]
919 fn drop(&mut self) {
920 // SAFETY: the caller of `drop_range` is responsible to check that this slice was
921 // initialized.
922 unsafe {
923 ptr::drop_in_place(slice_assume_init_mut(self.0));
924 }
925 }
926 }
927
928 // Constructs the slices of elements to drop (without dropping any element yet).
929 let drop_from = add_mod(self.start, range.start, N);
930 let drop_to = add_mod(self.start, range.end, N);
931
932 let (right, left) = if drop_from < drop_to {
933 (&mut self.items[drop_from..drop_to], &mut [][..])
934 } else {
935 let (left, right) = self.items.split_at_mut(drop_from);
936 let left = &mut left[..drop_to];
937 (right, left)
938 };
939
940 // Adjust `start` and `size` so that the dropped elements are excluded. This must be done
941 // *before* dropping the elements, so that, if a panic occurs in a `Drop` implementation,
942 // the buffer won't be left in an invalid state.
943 if range.start == 0 {
944 self.start = drop_to;
945 }
946 self.size -= range.len();
947
948 // Wrap the slices into the `Dropper` struct. When these go out of scope, they will be
949 // automatically dropped.
950 let _left = Dropper(left);
951 let _right = Dropper(right);
952 }
953
954 /// Returns a reference to the back element, or `None` if the buffer is empty.
955 ///
956 /// # Examples
957 ///
958 /// ```
959 /// use circular_buffer::CircularBuffer;
960 ///
961 /// let mut buf = CircularBuffer::<4, char>::new();
962 /// assert_eq!(buf.back(), None);
963 ///
964 /// buf.push_back('a');
965 /// buf.push_back('b');
966 /// buf.push_back('c');
967 /// assert_eq!(buf.back(), Some(&'c'));
968 /// ```
969 #[inline]
970 pub fn back(&self) -> Option<&T> {
971 if N == 0 || self.size == 0 {
972 // Nothing to do
973 return None;
974 }
975 // SAFETY: `size` is non-zero; back element is guaranteed to be initialized
976 Some(unsafe { self.back_maybe_uninit().assume_init_ref() })
977 }
978
979 /// Returns a mutable reference to the back element, or `None` if the buffer is empty.
980 ///
981 /// # Examples
982 ///
983 /// ```
984 /// use circular_buffer::CircularBuffer;
985 ///
986 /// let mut buf = CircularBuffer::<4, char>::new();
987 /// assert_eq!(buf.back_mut(), None);
988 ///
989 /// buf.push_back('a');
990 /// buf.push_back('b');
991 /// buf.push_back('c');
992 /// match buf.back_mut() {
993 /// None => (),
994 /// Some(x) => *x = 'z',
995 /// }
996 /// assert_eq!(buf, ['a', 'b', 'z']);
997 /// ```
998 #[inline]
999 pub fn back_mut(&mut self) -> Option<&mut T> {
1000 if N == 0 || self.size == 0 {
1001 // Nothing to do
1002 return None;
1003 }
1004 // SAFETY: `size` is non-zero; back element is guaranteed to be initialized
1005 Some(unsafe { self.back_maybe_uninit_mut().assume_init_mut() })
1006 }
1007
1008 /// Returns a reference to the front element, or `None` if the buffer is empty.
1009 ///
1010 /// # Examples
1011 ///
1012 /// ```
1013 /// use circular_buffer::CircularBuffer;
1014 ///
1015 /// let mut buf = CircularBuffer::<4, char>::new();
1016 /// assert_eq!(buf.front(), None);
1017 ///
1018 /// buf.push_back('a');
1019 /// buf.push_back('b');
1020 /// buf.push_back('c');
1021 /// assert_eq!(buf.front(), Some(&'a'));
1022 /// ```
1023 #[inline]
1024 pub fn front(&self) -> Option<&T> {
1025 if N == 0 || self.size == 0 {
1026 // Nothing to do
1027 return None;
1028 }
1029 // SAFETY: `size` is non-zero; front element is guaranteed to be initialized
1030 Some(unsafe { self.front_maybe_uninit().assume_init_ref() })
1031 }
1032
1033 /// Returns a mutable reference to the front element, or `None` if the buffer is empty.
1034 ///
1035 /// # Examples
1036 ///
1037 /// ```
1038 /// use circular_buffer::CircularBuffer;
1039 ///
1040 /// let mut buf = CircularBuffer::<4, char>::new();
1041 /// assert_eq!(buf.front_mut(), None);
1042 ///
1043 /// buf.push_back('a');
1044 /// buf.push_back('b');
1045 /// buf.push_back('c');
1046 /// match buf.front_mut() {
1047 /// None => (),
1048 /// Some(x) => *x = 'z',
1049 /// }
1050 /// assert_eq!(buf, ['z', 'b', 'c']);
1051 /// ```
1052 #[inline]
1053 pub fn front_mut(&mut self) -> Option<&mut T> {
1054 if N == 0 || self.size == 0 {
1055 // Nothing to do
1056 return None;
1057 }
1058 // SAFETY: `size` is non-zero; front element is guaranteed to be initialized
1059 Some(unsafe { self.front_maybe_uninit_mut().assume_init_mut() })
1060 }
1061
1062 /// Returns a reference to the element at the given index from the front of the buffer, or
1063 /// `None` if the element does not exist.
1064 ///
1065 /// Element at index 0 is the front of the queue.
1066 ///
1067 /// This is the same as [`nth_front()`](CircularBuffer::nth_front).
1068 ///
1069 /// # Examples
1070 ///
1071 /// ```
1072 /// use circular_buffer::CircularBuffer;
1073 ///
1074 /// let mut buf = CircularBuffer::<5, char>::new();
1075 /// assert_eq!(buf.get(1), None);
1076 ///
1077 /// buf.push_back('a');
1078 /// buf.push_back('b');
1079 /// buf.push_back('c');
1080 /// buf.push_back('d');
1081 /// assert_eq!(buf.get(1), Some(&'b'));
1082 /// ```
1083 #[inline]
1084 pub fn get(&self, index: usize) -> Option<&T> {
1085 if N == 0 || index >= self.size {
1086 // Nothing to do
1087 return None;
1088 }
1089 // SAFETY: `index` is in a valid range; it is guaranteed to point to an initialized element
1090 Some(unsafe { self.get_maybe_uninit(index).assume_init_ref() })
1091 }
1092
1093 /// Returns a mutable reference to the element at the given index, or `None` if the element
1094 /// does not exist.
1095 ///
1096 /// Element at index 0 is the front of the queue.
1097 ///
1098 /// This is the same as [`nth_front_mut()`](CircularBuffer::nth_front_mut).
1099 ///
1100 /// # Examples
1101 ///
1102 /// ```
1103 /// use circular_buffer::CircularBuffer;
1104 ///
1105 /// let mut buf = CircularBuffer::<5, char>::new();
1106 /// assert_eq!(buf.get_mut(1), None);
1107 ///
1108 /// buf.push_back('a');
1109 /// buf.push_back('b');
1110 /// buf.push_back('c');
1111 /// buf.push_back('d');
1112 /// match buf.get_mut(1) {
1113 /// None => (),
1114 /// Some(x) => *x = 'z',
1115 /// }
1116 /// assert_eq!(buf, ['a', 'z', 'c', 'd']);
1117 /// ```
1118 #[inline]
1119 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
1120 if N == 0 || index >= self.size {
1121 // Nothing to do
1122 return None;
1123 }
1124 // SAFETY: `index` is in a valid range; it is guaranteed to point to an initialized element
1125 Some(unsafe { self.get_maybe_uninit_mut(index).assume_init_mut() })
1126 }
1127
1128 /// Returns a reference to the element at the given index from the front of the buffer, or
1129 /// `None` if the element does not exist.
1130 ///
1131 /// Like most indexing operations, the count starts from zero, so `nth_front(0)` returns the
1132 /// first value, `nth_front(1)` the second, and so on. Element at index 0 is the front of the
1133 /// queue.
1134 ///
1135 /// This is the same as [`get()`](CircularBuffer::get).
1136 ///
1137 /// # Examples
1138 ///
1139 /// ```
1140 /// use circular_buffer::CircularBuffer;
1141 ///
1142 /// let mut buf = CircularBuffer::<5, char>::new();
1143 /// assert_eq!(buf.nth_front(1), None);
1144 ///
1145 /// buf.push_back('a');
1146 /// buf.push_back('b');
1147 /// buf.push_back('c');
1148 /// buf.push_back('d');
1149 /// assert_eq!(buf.nth_front(1), Some(&'b'));
1150 /// ```
1151 #[inline]
1152 pub fn nth_front(&self, index: usize) -> Option<&T> {
1153 self.get(index)
1154 }
1155
1156 /// Returns a mutable reference to the element at the given index from the front of the buffer,
1157 /// or `None` if the element does not exist.
1158 ///
1159 /// Like most indexing operations, the count starts from zero, so `nth_front_mut(0)` returns
1160 /// the first value, `nth_front_mut(1)` the second, and so on. Element at index 0 is the front
1161 /// of the queue.
1162 ///
1163 /// This is the same as [`get_mut()`](CircularBuffer::get_mut).
1164 ///
1165 /// # Examples
1166 ///
1167 /// ```
1168 /// use circular_buffer::CircularBuffer;
1169 ///
1170 /// let mut buf = CircularBuffer::<5, char>::new();
1171 /// assert_eq!(buf.nth_front_mut(1), None);
1172 ///
1173 /// buf.push_back('a');
1174 /// buf.push_back('b');
1175 /// buf.push_back('c');
1176 /// buf.push_back('d');
1177 /// match buf.nth_front_mut(1) {
1178 /// None => (),
1179 /// Some(x) => *x = 'z',
1180 /// }
1181 /// assert_eq!(buf, ['a', 'z', 'c', 'd']);
1182 /// ```
1183 #[inline]
1184 pub fn nth_front_mut(&mut self, index: usize) -> Option<&mut T> {
1185 self.get_mut(index)
1186 }
1187
1188 /// Returns a reference to the element at the given index from the back of the buffer, or
1189 /// `None` if the element does not exist.
1190 ///
1191 /// Like most indexing operations, the count starts from zero, so `nth_back(0)` returns the
1192 /// first value, `nth_back(1)` the second, and so on. Element at index 0 is the back of the
1193 /// queue.
1194 ///
1195 /// # Examples
1196 ///
1197 /// ```
1198 /// use circular_buffer::CircularBuffer;
1199 ///
1200 /// let mut buf = CircularBuffer::<5, char>::new();
1201 /// assert_eq!(buf.nth_back(1), None);
1202 ///
1203 /// buf.push_back('a');
1204 /// buf.push_back('b');
1205 /// buf.push_back('c');
1206 /// buf.push_back('d');
1207 /// assert_eq!(buf.nth_back(1), Some(&'c'));
1208 /// ```
1209 #[inline]
1210 pub fn nth_back(&self, index: usize) -> Option<&T> {
1211 let index = self.size.checked_sub(index)?.checked_sub(1)?;
1212 self.get(index)
1213 }
1214
1215 /// Returns a mutable reference to the element at the given index from the back of the buffer,
1216 /// or `None` if the element does not exist.
1217 ///
1218 /// Like most indexing operations, the count starts from zero, so `nth_back_mut(0)` returns the
1219 /// first value, `nth_back_mut(1)` the second, and so on. Element at index 0 is the back of the
1220 /// queue.
1221 ///
1222 /// # Examples
1223 ///
1224 /// ```
1225 /// use circular_buffer::CircularBuffer;
1226 ///
1227 /// let mut buf = CircularBuffer::<5, char>::new();
1228 /// assert_eq!(buf.nth_back_mut(1), None);
1229 ///
1230 /// buf.push_back('a');
1231 /// buf.push_back('b');
1232 /// buf.push_back('c');
1233 /// buf.push_back('d');
1234 /// match buf.nth_back_mut(1) {
1235 /// None => (),
1236 /// Some(x) => *x = 'z',
1237 /// }
1238 /// assert_eq!(buf, ['a', 'b', 'z', 'd']);
1239 /// ```
1240 #[inline]
1241 pub fn nth_back_mut(&mut self, index: usize) -> Option<&mut T> {
1242 let index = self.size.checked_sub(index)?.checked_sub(1)?;
1243 self.get_mut(index)
1244 }
1245
1246 /// Appends an element to the back of the buffer.
1247 ///
1248 /// If the buffer is full, the element at the front of the buffer is overwritten and returned.
1249 ///
1250 /// See also [`try_push_back()`](CircularBuffer::try_push_back) for a non-overwriting version
1251 /// of this method.
1252 ///
1253 /// # Examples
1254 ///
1255 /// ```
1256 /// use circular_buffer::CircularBuffer;
1257 ///
1258 /// let mut buf = CircularBuffer::<3, char>::new();
1259 ///
1260 /// assert_eq!(buf.push_back('a'), None);
1261 /// assert_eq!(buf, ['a']);
1262 ///
1263 /// assert_eq!(buf.push_back('b'), None);
1264 /// assert_eq!(buf, ['a', 'b']);
1265 ///
1266 /// assert_eq!(buf.push_back('c'), None);
1267 /// assert_eq!(buf, ['a', 'b', 'c']);
1268 ///
1269 /// // The buffer is now full; adding more values causes the front elements to be removed and
1270 /// // returned
1271 /// assert_eq!(buf.push_back('d'), Some('a'));
1272 /// assert_eq!(buf, ['b', 'c', 'd']);
1273 ///
1274 /// assert_eq!(buf.push_back('e'), Some('b'));
1275 /// assert_eq!(buf, ['c', 'd', 'e']);
1276 ///
1277 /// assert_eq!(buf.push_back('f'), Some('c'));
1278 /// assert_eq!(buf, ['d', 'e', 'f']);
1279 /// ```
1280 pub fn push_back(&mut self, item: T) -> Option<T> {
1281 if N == 0 {
1282 // Nothing to do
1283 return Some(item);
1284 }
1285
1286 if self.size >= N {
1287 // At capacity; need to replace the front item
1288 //
1289 // SAFETY: if size is greater than 0, the front item is guaranteed to be initialized.
1290 let replaced_item = mem::replace(
1291 unsafe { self.front_maybe_uninit_mut().assume_init_mut() },
1292 item,
1293 );
1294 self.inc_start();
1295 Some(replaced_item)
1296 } else {
1297 // Some uninitialized slots left; append at the end
1298 self.inc_size();
1299 self.back_maybe_uninit_mut().write(item);
1300 None
1301 }
1302 }
1303
1304 /// Appends an element to the back of the buffer.
1305 ///
1306 /// If the buffer is full, the buffer is not modified and the given element is returned as an
1307 /// error.
1308 ///
1309 /// See also [`push_back()`](CircularBuffer::push_back) for a version of this method that
1310 /// overwrites the front of the buffer when full.
1311 ///
1312 /// # Examples
1313 ///
1314 /// ```
1315 /// use circular_buffer::CircularBuffer;
1316 ///
1317 /// let mut buf = CircularBuffer::<3, char>::new();
1318 ///
1319 /// assert_eq!(buf.try_push_back('a'), Ok(()));
1320 /// assert_eq!(buf, ['a']);
1321 ///
1322 /// assert_eq!(buf.try_push_back('b'), Ok(()));
1323 /// assert_eq!(buf, ['a', 'b']);
1324 ///
1325 /// assert_eq!(buf.try_push_back('c'), Ok(()));
1326 /// assert_eq!(buf, ['a', 'b', 'c']);
1327 ///
1328 /// // The buffer is now full; adding more values results in an error
1329 /// assert_eq!(buf.try_push_back('d'), Err('d'))
1330 /// ```
1331 pub fn try_push_back(&mut self, item: T) -> Result<(), T> {
1332 if self.size >= N {
1333 // At capacity; return the pushed item as error
1334 Err(item)
1335 } else {
1336 // Some uninitialized slots left; append at the end
1337 self.inc_size();
1338 self.back_maybe_uninit_mut().write(item);
1339 Ok(())
1340 }
1341 }
1342
1343 /// Appends an element to the front of the buffer.
1344 ///
1345 /// If the buffer is full, the element at the back of the buffer is overwritten and returned.
1346 ///
1347 /// See also [`try_push_front()`](CircularBuffer::try_push_front) for a non-overwriting version
1348 /// of this method.
1349 ///
1350 /// # Examples
1351 ///
1352 /// ```
1353 /// use circular_buffer::CircularBuffer;
1354 ///
1355 /// let mut buf = CircularBuffer::<3, char>::new();
1356 ///
1357 /// assert_eq!(buf.push_front('a'), None);
1358 /// assert_eq!(buf, ['a']);
1359 ///
1360 /// assert_eq!(buf.push_front('b'), None);
1361 /// assert_eq!(buf, ['b', 'a']);
1362 ///
1363 /// assert_eq!(buf.push_front('c'), None);
1364 /// assert_eq!(buf, ['c', 'b', 'a']);
1365 ///
1366 /// // The buffer is now full; adding more values causes the back elements to be dropped
1367 /// assert_eq!(buf.push_front('d'), Some('a'));
1368 /// assert_eq!(buf, ['d', 'c', 'b']);
1369 ///
1370 /// assert_eq!(buf.push_front('e'), Some('b'));
1371 /// assert_eq!(buf, ['e', 'd', 'c']);
1372 ///
1373 /// assert_eq!(buf.push_front('f'), Some('c'));
1374 /// assert_eq!(buf, ['f', 'e', 'd']);
1375 /// ```
1376 pub fn push_front(&mut self, item: T) -> Option<T> {
1377 if N == 0 {
1378 // Nothing to do
1379 return Some(item);
1380 }
1381
1382 if self.size >= N {
1383 // At capacity; need to replace the back item
1384 //
1385 // SAFETY: if size is greater than 0, the back item is guaranteed to be initialized.
1386 let replaced_item = mem::replace(
1387 unsafe { self.back_maybe_uninit_mut().assume_init_mut() },
1388 item,
1389 );
1390 self.dec_start();
1391 Some(replaced_item)
1392 } else {
1393 // Some uninitialized slots left; insert at the start
1394 self.inc_size();
1395 self.dec_start();
1396 self.front_maybe_uninit_mut().write(item);
1397 None
1398 }
1399 }
1400
1401 /// Appends an element to the front of the buffer.
1402 ///
1403 /// If the buffer is full, the buffer is not modified and the given element is returned as an
1404 /// error.
1405 ///
1406 /// See also [`push_front()`](CircularBuffer::push_front) for a version of this method that
1407 /// overwrites the back of the buffer when full.
1408 ///
1409 /// # Examples
1410 ///
1411 /// ```
1412 /// use circular_buffer::CircularBuffer;
1413 ///
1414 /// let mut buf = CircularBuffer::<3, char>::new();
1415 ///
1416 /// assert_eq!(buf.try_push_front('a'), Ok(()));
1417 /// assert_eq!(buf, ['a']);
1418 ///
1419 /// assert_eq!(buf.try_push_front('b'), Ok(()));
1420 /// assert_eq!(buf, ['b', 'a']);
1421 ///
1422 /// assert_eq!(buf.try_push_front('c'), Ok(()));
1423 /// assert_eq!(buf, ['c', 'b', 'a']);
1424 ///
1425 /// // The buffer is now full; adding more values results in an error
1426 /// assert_eq!(buf.try_push_front('d'), Err('d'));
1427 /// ```
1428 pub fn try_push_front(&mut self, item: T) -> Result<(), T> {
1429 if self.size >= N {
1430 // At capacity; return the pushed item as error
1431 Err(item)
1432 } else {
1433 // Some uninitialized slots left; insert at the start
1434 self.inc_size();
1435 self.dec_start();
1436 self.front_maybe_uninit_mut().write(item);
1437 Ok(())
1438 }
1439 }
1440
1441 /// Removes and returns an element from the back of the buffer.
1442 ///
1443 /// If the buffer is empty, `None` is returned.
1444 ///
1445 /// # Examples
1446 ///
1447 /// ```
1448 /// use circular_buffer::CircularBuffer;
1449 ///
1450 /// let mut buf = CircularBuffer::<3, char>::from(['a', 'b', 'c']);
1451 ///
1452 /// assert_eq!(buf.pop_back(), Some('c'));
1453 /// assert_eq!(buf.pop_back(), Some('b'));
1454 /// assert_eq!(buf.pop_back(), Some('a'));
1455 /// assert_eq!(buf.pop_back(), None);
1456 /// ```
1457 pub fn pop_back(&mut self) -> Option<T> {
1458 if N == 0 || self.size == 0 {
1459 // Nothing to do
1460 return None;
1461 }
1462
1463 // SAFETY: if size is greater than 0, the back item is guaranteed to be initialized.
1464 let back = unsafe { self.back_maybe_uninit().assume_init_read() };
1465 self.dec_size();
1466 Some(back)
1467 }
1468
1469 /// Removes and returns an element from the front of the buffer.
1470 ///
1471 /// If the buffer is empty, `None` is returned.
1472 ///
1473 /// # Examples
1474 ///
1475 /// ```
1476 /// use circular_buffer::CircularBuffer;
1477 ///
1478 /// let mut buf = CircularBuffer::<3, char>::from(['a', 'b', 'c']);
1479 ///
1480 /// assert_eq!(buf.pop_front(), Some('a'));
1481 /// assert_eq!(buf.pop_front(), Some('b'));
1482 /// assert_eq!(buf.pop_front(), Some('c'));
1483 /// assert_eq!(buf.pop_front(), None);
1484 /// ```
1485 pub fn pop_front(&mut self) -> Option<T> {
1486 if N == 0 || self.size == 0 {
1487 // Nothing to do
1488 return None;
1489 }
1490
1491 // SAFETY: if size is greater than 0, the front item is guaranteed to be initialized.
1492 let front = unsafe { self.front_maybe_uninit().assume_init_read() };
1493 self.dec_size();
1494 self.inc_start();
1495 Some(front)
1496 }
1497
1498 /// Removes and returns an element at the specified index.
1499 ///
1500 /// If the index is out of bounds, `None` is returned.
1501 ///
1502 /// # Examples
1503 ///
1504 /// ```
1505 /// use circular_buffer::CircularBuffer;
1506 ///
1507 /// let mut buf = CircularBuffer::<3, char>::from(['a', 'b', 'c']);
1508 ///
1509 /// assert_eq!(buf.remove(1), Some('b'));
1510 /// assert_eq!(buf, ['a', 'c']);
1511 ///
1512 /// assert_eq!(buf.remove(5), None);
1513 /// ```
1514 pub fn remove(&mut self, index: usize) -> Option<T> {
1515 if N == 0 || index >= self.size {
1516 return None;
1517 }
1518
1519 let index = add_mod(self.start, index, N);
1520 let back_index = add_mod(self.start, self.size - 1, N);
1521
1522 // SAFETY: `index` is in a valid range; the element is guaranteed to be initialized
1523 let item = unsafe { self.items[index].assume_init_read() };
1524
1525 // SAFETY: the pointers being moved are in a valid range; the elements behind those
1526 // pointers are guaranteed to be initialized
1527 unsafe {
1528 // TODO: optimize for the case where `index < len - index` (i.e. when copying items to
1529 // the right is cheaper than moving items to the left)
1530 let ptr = self.items.as_mut_ptr();
1531 if back_index >= index {
1532 // Move the values at the right of `index` by 1 position to the left
1533 ptr::copy(ptr.add(index).add(1), ptr.add(index), back_index - index);
1534 } else {
1535 // Move the values at the right of `index` by 1 position to the left
1536 ptr::copy(ptr.add(index).add(1), ptr.add(index), N - index - 1);
1537 // Move the leftmost value to the end of the array
1538 ptr::copy(ptr, ptr.add(N - 1), 1);
1539 // Move the values at the left of `back_index` by 1 position to the left
1540 ptr::copy(ptr.add(1), ptr, back_index);
1541 }
1542 }
1543
1544 self.dec_size();
1545 Some(item)
1546 }
1547
1548 /// Swap the element at index `i` with the element at index `j`.
1549 ///
1550 /// # Panics
1551 ///
1552 /// If either `i` or `j` is out of bounds.
1553 ///
1554 /// # Examples
1555 ///
1556 /// ```
1557 /// use circular_buffer::CircularBuffer;
1558 ///
1559 /// let mut buf = CircularBuffer::<5, char>::from(['a', 'b', 'c', 'd']);
1560 /// assert_eq!(buf, ['a', 'b', 'c', 'd']);
1561 ///
1562 /// buf.swap(0, 3);
1563 /// assert_eq!(buf, ['d', 'b', 'c', 'a']);
1564 /// ```
1565 ///
1566 /// Trying to swap an invalid index panics:
1567 ///
1568 /// ```should_panic
1569 /// use circular_buffer::CircularBuffer;
1570 /// let mut buf = CircularBuffer::<5, char>::from(['a', 'b', 'c', 'd']);
1571 /// buf.swap(0, 7);
1572 /// ```
1573 pub fn swap(&mut self, i: usize, j: usize) {
1574 assert!(i < self.size, "i index out-of-bounds");
1575 assert!(j < self.size, "j index out-of-bounds");
1576 if i != j {
1577 let i = add_mod(self.start, i, N);
1578 let j = add_mod(self.start, j, N);
1579 // SAFETY: these are valid pointers
1580 unsafe { ptr::swap_nonoverlapping(&mut self.items[i], &mut self.items[j], 1) };
1581 }
1582 }
1583
1584 /// Removes the element at `index` and returns it, replacing it with the back of the buffer.
1585 ///
1586 /// Returns `None` if `index` is out-of-bounds.
1587 ///
1588 /// # Examples
1589 ///
1590 /// ```
1591 /// use circular_buffer::CircularBuffer;
1592 ///
1593 /// let mut buf = CircularBuffer::<5, char>::from(['a', 'b', 'c', 'd']);
1594 /// assert_eq!(buf, ['a', 'b', 'c', 'd']);
1595 ///
1596 /// assert_eq!(buf.swap_remove_back(2), Some('c'));
1597 /// assert_eq!(buf, ['a', 'b', 'd']);
1598 ///
1599 /// assert_eq!(buf.swap_remove_back(7), None);
1600 /// ```
1601 pub fn swap_remove_back(&mut self, index: usize) -> Option<T> {
1602 if index >= self.size {
1603 return None;
1604 }
1605 self.swap(index, self.size - 1);
1606 self.pop_back()
1607 }
1608
1609 /// Removes the element at `index` and returns it, replacing it with the front of the buffer.
1610 ///
1611 /// Returns `None` if `index` is out-of-bounds.
1612 ///
1613 /// # Examples
1614 ///
1615 /// ```
1616 /// use circular_buffer::CircularBuffer;
1617 ///
1618 /// let mut buf = CircularBuffer::<5, char>::from(['a', 'b', 'c', 'd']);
1619 /// assert_eq!(buf, ['a', 'b', 'c', 'd']);
1620 ///
1621 /// assert_eq!(buf.swap_remove_front(2), Some('c'));
1622 /// assert_eq!(buf, ['b', 'a', 'd']);
1623 ///
1624 /// assert_eq!(buf.swap_remove_front(7), None);
1625 /// ```
1626 pub fn swap_remove_front(&mut self, index: usize) -> Option<T> {
1627 if index >= self.size {
1628 return None;
1629 }
1630 self.swap(index, 0);
1631 self.pop_front()
1632 }
1633
1634 /// Fills the entire capacity of `self` with elements by cloning `value`.
1635 ///
1636 /// The elements already present in the buffer (if any) are all replaced by clones of `value`,
1637 /// and the spare capacity of the buffer is also filled with clones of `value`.
1638 ///
1639 /// This is equivalent to clearing the buffer and adding clones of `value` until reaching the
1640 /// maximum capacity.
1641 ///
1642 /// If you want to replace only the existing elements of the buffer, without affecting the
1643 /// spare capacity, use [`as_mut_slices()`](CircularBuffer::as_mut_slices) and call
1644 /// [`slice::fill()`]([]::fill) on the resulting slices.
1645 ///
1646 /// See also: [`fill_with()`](CircularBuffer::fill_with),
1647 /// [`fill_spare()`](CircularBuffer::fill_spare),
1648 /// [`fill_spare_with()`](CircularBuffer::fill_spare_with).
1649 ///
1650 /// # Examples
1651 ///
1652 /// ```
1653 /// use circular_buffer::CircularBuffer;
1654 ///
1655 /// let mut buf = CircularBuffer::<10, u32>::from([1, 2, 3]);
1656 /// assert_eq!(buf, [1, 2, 3]);
1657 ///
1658 /// buf.fill(9);
1659 /// assert_eq!(buf, [9, 9, 9, 9, 9, 9, 9, 9, 9, 9]);
1660 /// ```
1661 ///
1662 /// If you want to replace existing elements only:
1663 ///
1664 /// ```
1665 /// use circular_buffer::CircularBuffer;
1666 ///
1667 /// let mut buf = CircularBuffer::<10, u32>::from([1, 2, 3]);
1668 /// assert_eq!(buf, [1, 2, 3]);
1669 ///
1670 /// let (front, back) = buf.as_mut_slices();
1671 /// front.fill(9);
1672 /// back.fill(9);
1673 /// assert_eq!(buf, [9, 9, 9]);
1674 /// ```
1675 pub fn fill(&mut self, value: T)
1676 where
1677 T: Clone,
1678 {
1679 self.clear();
1680 self.fill_spare(value);
1681 }
1682
1683 /// Fills the entire capacity of `self` with elements by calling a closure.
1684 ///
1685 /// The elements already present in the buffer (if any) are all replaced by the result of the
1686 /// closure, and the spare capacity of the buffer is also filled with the result of the
1687 /// closure.
1688 ///
1689 /// This is equivalent to clearing the buffer and adding the result of the closure until
1690 /// reaching the maximum capacity.
1691 ///
1692 /// If you want to replace only the existing elements of the buffer, without affecting the
1693 /// spare capacity, use [`as_mut_slices()`](CircularBuffer::as_mut_slices) and call
1694 /// [`slice::fill_with()`]([]::fill_with) on the resulting slices.
1695 ///
1696 /// See also: [`fill()`](CircularBuffer::fill), [`fill_spare()`](CircularBuffer::fill_spare),
1697 /// [`fill_spare_with()`](CircularBuffer::fill_spare_with).
1698 ///
1699 /// # Examples
1700 ///
1701 /// ```
1702 /// use circular_buffer::CircularBuffer;
1703 ///
1704 /// let mut buf = CircularBuffer::<10, u32>::from([1, 2, 3]);
1705 /// assert_eq!(buf, [1, 2, 3]);
1706 ///
1707 /// let mut x = 2;
1708 /// buf.fill_with(|| {
1709 /// x *= 2;
1710 /// x
1711 /// });
1712 /// assert_eq!(buf, [4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048]);
1713 /// ```
1714 ///
1715 /// If you want to replace existing elements only:
1716 ///
1717 /// ```
1718 /// use circular_buffer::CircularBuffer;
1719 ///
1720 /// let mut buf = CircularBuffer::<10, u32>::from([1, 2, 3]);
1721 /// assert_eq!(buf, [1, 2, 3]);
1722 ///
1723 /// let mut x = 2;
1724 /// let (front, back) = buf.as_mut_slices();
1725 /// front.fill_with(|| {
1726 /// x *= 2;
1727 /// x
1728 /// });
1729 /// back.fill_with(|| {
1730 /// x *= 2;
1731 /// x
1732 /// });
1733 /// assert_eq!(buf, [4, 8, 16]);
1734 /// ```
1735 pub fn fill_with<F>(&mut self, f: F)
1736 where
1737 F: FnMut() -> T,
1738 {
1739 self.clear();
1740 self.fill_spare_with(f);
1741 }
1742
1743 /// Fills the spare capacity of `self` with elements by cloning `value`.
1744 ///
1745 /// The elements already present in the buffer (if any) are unaffected.
1746 ///
1747 /// This is equivalent to adding clones of `value` to the buffer until reaching the maximum
1748 /// capacity.
1749 ///
1750 /// See also: [`fill()`](CircularBuffer::fill), [`fill_with()`](CircularBuffer::fill_with),
1751 /// [`fill_spare_with()`](CircularBuffer::fill_spare_with).
1752 ///
1753 /// # Examples
1754 ///
1755 /// ```
1756 /// use circular_buffer::CircularBuffer;
1757 ///
1758 /// let mut buf = CircularBuffer::<10, u32>::from([1, 2, 3]);
1759 /// assert_eq!(buf, [1, 2, 3]);
1760 ///
1761 /// buf.fill_spare(9);
1762 /// assert_eq!(buf, [1, 2, 3, 9, 9, 9, 9, 9, 9, 9]);
1763 /// ```
1764 pub fn fill_spare(&mut self, value: T)
1765 where
1766 T: Clone,
1767 {
1768 if N == 0 || self.size == N {
1769 return;
1770 }
1771 // TODO Optimize
1772 while self.size < N - 1 {
1773 self.push_back(value.clone());
1774 }
1775 self.push_back(value);
1776 }
1777
1778 /// Fills the spare capacity of `self` with elements by calling a closure.
1779 ///
1780 /// The elements already present in the buffer (if any) are unaffected.
1781 ///
1782 /// This is equivalent adding the result of the closure to the buffer until reaching the
1783 /// maximum capacity.
1784 ///
1785 /// See also: [`fill()`](CircularBuffer::fill), [`fill_with()`](CircularBuffer::fill_with),
1786 /// [`fill_spare()`](CircularBuffer::fill_spare).
1787 ///
1788 /// # Examples
1789 ///
1790 /// ```
1791 /// use circular_buffer::CircularBuffer;
1792 ///
1793 /// let mut buf = CircularBuffer::<10, u32>::from([1, 2, 3]);
1794 /// assert_eq!(buf, [1, 2, 3]);
1795 ///
1796 /// let mut x = 2;
1797 /// buf.fill_spare_with(|| {
1798 /// x *= 2;
1799 /// x
1800 /// });
1801 /// assert_eq!(buf, [1, 2, 3, 4, 8, 16, 32, 64, 128, 256]);
1802 /// ```
1803 pub fn fill_spare_with<F>(&mut self, mut f: F)
1804 where
1805 F: FnMut() -> T,
1806 {
1807 if N == 0 {
1808 return;
1809 }
1810 // TODO Optimize
1811 while self.size < N {
1812 self.push_back(f());
1813 }
1814 }
1815
1816 /// Shortens the buffer, keeping only the front `len` elements and dropping the rest.
1817 ///
1818 /// If `len` is equal or greater to the buffer's current length, this has no effect.
1819 ///
1820 /// Calling `truncate_back(0)` is equivalent to [`clear()`](Self::clear).
1821 ///
1822 /// # Examples
1823 ///
1824 /// ```
1825 /// use circular_buffer::CircularBuffer;
1826 ///
1827 /// let mut buf = CircularBuffer::<4, u32>::from([10, 20, 30]);
1828 ///
1829 /// buf.truncate_back(1);
1830 /// assert_eq!(buf, [10]);
1831 ///
1832 /// // Truncating to a length that is greater than the buffer's length has no effect
1833 /// buf.truncate_back(8);
1834 /// assert_eq!(buf, [10]);
1835 /// ```
1836 pub fn truncate_back(&mut self, len: usize) {
1837 if N == 0 || len >= self.size {
1838 // Nothing to do
1839 return;
1840 }
1841
1842 let drop_range = len..self.size;
1843 // SAFETY: `drop_range` is a valid range, so elements within are guaranteed to be
1844 // initialized. The `size` of the buffer is shrunk before dropping, so no value will be
1845 // dropped twice in case of panics.
1846 unsafe { self.drop_range(drop_range) };
1847 }
1848
1849 /// Shortens the buffer, keeping only the back `len` elements and dropping the rest.
1850 ///
1851 /// If `len` is equal or greater to the buffer's current length, this has no effect.
1852 ///
1853 /// Calling `truncate_front(0)` is equivalent to [`clear()`](Self::clear).
1854 ///
1855 /// # Examples
1856 ///
1857 /// ```
1858 /// use circular_buffer::CircularBuffer;
1859 ///
1860 /// let mut buf = CircularBuffer::<4, u32>::from([10, 20, 30]);
1861 ///
1862 /// buf.truncate_front(1);
1863 /// assert_eq!(buf, [30]);
1864 ///
1865 /// // Truncating to a length that is greater than the buffer's length has no effect
1866 /// buf.truncate_front(8);
1867 /// assert_eq!(buf, [30]);
1868 /// ```
1869 pub fn truncate_front(&mut self, len: usize) {
1870 if N == 0 || len >= self.size {
1871 // Nothing to do
1872 return;
1873 }
1874
1875 let drop_len = self.size - len;
1876 let drop_range = 0..drop_len;
1877 // SAFETY: `drop_range` is a valid range, so elements within are guaranteed to be
1878 // initialized. The `start` of the buffer is shrunk before dropping, so no value will be
1879 // dropped twice in case of panics.
1880 unsafe { self.drop_range(drop_range) };
1881 }
1882
1883 /// Drops all the elements in the buffer.
1884 ///
1885 /// # Examples
1886 ///
1887 /// ```
1888 /// use circular_buffer::CircularBuffer;
1889 ///
1890 /// let mut buf = CircularBuffer::<4, u32>::from([10, 20, 30]);
1891 /// assert_eq!(buf, [10, 20, 30]);
1892 /// buf.clear();
1893 /// assert_eq!(buf, []);
1894 /// ```
1895 #[inline]
1896 pub fn clear(&mut self) {
1897 self.truncate_back(0)
1898 }
1899}
1900
1901impl<const N: usize, T> CircularBuffer<N, T>
1902where
1903 T: Clone,
1904{
1905 /// Clones and appends all the elements from the slice to the back of the buffer.
1906 ///
1907 /// This is an optimized version of [`extend()`](CircularBuffer::extend) for slices.
1908 ///
1909 /// If slice contains more values than the available capacity, the elements at the front of the
1910 /// buffer are dropped.
1911 ///
1912 /// # Examples
1913 ///
1914 /// ```
1915 /// use circular_buffer::CircularBuffer;
1916 ///
1917 /// let mut buf: CircularBuffer<5, u32> = CircularBuffer::from([1, 2, 3]);
1918 /// buf.extend_from_slice(&[4, 5, 6, 7]);
1919 /// assert_eq!(buf, [3, 4, 5, 6, 7]);
1920 /// ```
1921 pub fn extend_from_slice(&mut self, other: &[T]) {
1922 if N == 0 {
1923 return;
1924 }
1925
1926 debug_assert!(self.start < N, "start out-of-bounds");
1927 debug_assert!(self.size <= N, "size out-of-bounds");
1928
1929 #[cfg(not(feature = "unstable"))]
1930 fn write_uninit_slice_cloned<T: Clone>(dst: &mut [MaybeUninit<T>], src: &[T]) {
1931 // Each call to `clone()` may panic, therefore we need to track how many elements we
1932 // successfully cloned so that we can drop them in case of panic. This `Guard` struct
1933 // does exactly that: it keeps track of how many items have been successfully cloned
1934 // and drops them if the guard is dropped.
1935 //
1936 // This implementation was highly inspired by the implementation of
1937 // `MaybeUninit::clone_from_slice`
1938 struct Guard<'a, T> {
1939 dst: &'a mut [MaybeUninit<T>],
1940 initialized: usize,
1941 }
1942
1943 impl<T> Drop for Guard<'_, T> {
1944 fn drop(&mut self) {
1945 let initialized = &mut self.dst[..self.initialized];
1946 // SAFETY: this slice contain only initialized objects; `MaybeUninit<T>` has
1947 // the same alignment and size as `T`
1948 unsafe {
1949 let initialized =
1950 &mut *(initialized as *mut [MaybeUninit<T>] as *mut [T]);
1951 ptr::drop_in_place(initialized);
1952 }
1953 }
1954 }
1955
1956 debug_assert_eq!(dst.len(), src.len());
1957 let len = dst.len();
1958 let mut guard = Guard {
1959 dst,
1960 initialized: 0,
1961 };
1962 #[allow(clippy::needless_range_loop)]
1963 for i in 0..len {
1964 guard.dst[i].write(src[i].clone());
1965 guard.initialized += 1;
1966 }
1967
1968 // All the `clone()` calls succeded; get rid of the guard without running its `drop()`
1969 // implementation
1970 mem::forget(guard);
1971 }
1972
1973 if other.len() < N {
1974 // All the elements of `other` fit into the buffer
1975 let free_size = N - self.size;
1976 let final_size = if other.len() < free_size {
1977 // All the elements of `other` fit at the back of the buffer
1978 self.size + other.len()
1979 } else {
1980 // Some of the elements of `other` need to overwrite the front of the buffer
1981 self.truncate_front(N - other.len());
1982 N
1983 };
1984
1985 let (right, left) = self.slices_uninit_mut();
1986
1987 let write_len = core::cmp::min(right.len(), other.len());
1988 #[cfg(feature = "unstable")]
1989 right[..write_len].write_clone_of_slice(&other[..write_len]);
1990 #[cfg(not(feature = "unstable"))]
1991 write_uninit_slice_cloned(&mut right[..write_len], &other[..write_len]);
1992
1993 let other = &other[write_len..];
1994 debug_assert!(left.len() >= other.len());
1995 let write_len = other.len();
1996 #[cfg(feature = "unstable")]
1997 left[..write_len].write_clone_of_slice(other);
1998 #[cfg(not(feature = "unstable"))]
1999 write_uninit_slice_cloned(&mut left[..write_len], other);
2000
2001 self.size = final_size;
2002 } else {
2003 // `other` overwrites the whole buffer; get only the last `N` elements from `other` and
2004 // overwrite
2005 self.clear();
2006 self.start = 0;
2007
2008 let other = &other[other.len() - N..];
2009 debug_assert_eq!(self.items.len(), other.len());
2010 #[cfg(feature = "unstable")]
2011 self.items.write_clone_of_slice(other);
2012 #[cfg(not(feature = "unstable"))]
2013 write_uninit_slice_cloned(&mut self.items, other);
2014
2015 self.size = N;
2016 }
2017 }
2018
2019 /// Clones the elements of the buffer into a new [`Vec`], leaving the buffer unchanged.
2020 ///
2021 /// # Examples
2022 ///
2023 /// ```
2024 /// use circular_buffer::CircularBuffer;
2025 ///
2026 /// let buf: CircularBuffer<5, u32> = CircularBuffer::from([1, 2, 3]);
2027 /// let vec: Vec<u32> = buf.to_vec();
2028 ///
2029 /// assert_eq!(buf, [1, 2, 3]);
2030 /// assert_eq!(vec, [1, 2, 3]);
2031 /// ```
2032 #[must_use]
2033 #[cfg(feature = "alloc")]
2034 pub fn to_vec(&self) -> Vec<T> {
2035 let mut vec = Vec::with_capacity(self.size);
2036 vec.extend(self.iter().cloned());
2037 debug_assert_eq!(vec.len(), self.size);
2038 vec
2039 }
2040}
2041
2042impl<const N: usize, T> Default for CircularBuffer<N, T> {
2043 #[inline]
2044 fn default() -> Self {
2045 Self::new()
2046 }
2047}
2048
2049impl<const N: usize, const M: usize, T> From<[T; M]> for CircularBuffer<N, T> {
2050 fn from(mut arr: [T; M]) -> Self {
2051 let size = if N >= M { M } else { N };
2052 #[cfg(feature = "unstable")]
2053 let mut elems = [const { MaybeUninit::uninit() }; N];
2054 #[cfg(not(feature = "unstable"))]
2055 let mut elems = unsafe { MaybeUninit::<[MaybeUninit<T>; N]>::uninit().assume_init() };
2056 let (discard, copy) = arr.split_at_mut(M - size);
2057
2058 debug_assert_eq!(copy.len(), size);
2059
2060 let elems_ptr = &mut elems as *mut MaybeUninit<T>;
2061 let discard_ptr = discard as *mut [T];
2062 let copy_ptr = copy as *const [T] as *const [MaybeUninit<T>] as *const MaybeUninit<T>;
2063
2064 // SAFETY:
2065 // - `copy_ptr` points to a memory location that contains exactly `size` elements.
2066 // - `elems_ptr` points to a memory location that contains exactly `N` elements, and `N` is
2067 // greater than or equal to `size`.
2068 unsafe {
2069 ptr::copy_nonoverlapping(copy_ptr, elems_ptr, size);
2070 }
2071
2072 // Now that some elements have been moved, ensure that no destructors are implicitly run.
2073 mem::forget(arr);
2074
2075 // Prevent destructors from running on those elements that we've taken ownership of; only
2076 // destroy the elements that were discareded
2077 //
2078 // SAFETY: All elements in `arr` are initialized; the call to `forget()` earlier ensures
2079 // that destructors are not run twice, even if a panic occurs in a `Drop` implementation.
2080 unsafe {
2081 ptr::drop_in_place(discard_ptr);
2082 }
2083
2084 Self {
2085 size,
2086 start: 0,
2087 items: elems,
2088 }
2089 }
2090}
2091
2092impl<const N: usize, T> FromIterator<T> for CircularBuffer<N, T> {
2093 fn from_iter<I>(iter: I) -> Self
2094 where
2095 I: IntoIterator<Item = T>,
2096 {
2097 // TODO Optimize
2098 let mut buf = Self::new();
2099 iter.into_iter().for_each(|item| {
2100 buf.push_back(item);
2101 });
2102 buf
2103 }
2104}
2105
2106impl<const N: usize, T> Extend<T> for CircularBuffer<N, T> {
2107 fn extend<I>(&mut self, iter: I)
2108 where
2109 I: IntoIterator<Item = T>,
2110 {
2111 // TODO Optimize
2112 iter.into_iter().for_each(|item| {
2113 self.push_back(item);
2114 });
2115 }
2116}
2117
2118impl<'a, const N: usize, T> Extend<&'a T> for CircularBuffer<N, T>
2119where
2120 T: Copy,
2121{
2122 fn extend<I>(&mut self, iter: I)
2123 where
2124 I: IntoIterator<Item = &'a T>,
2125 {
2126 // TODO Optimize
2127 iter.into_iter().for_each(|item| {
2128 self.push_back(*item);
2129 });
2130 }
2131}
2132
2133impl<const N: usize, T> Index<usize> for CircularBuffer<N, T> {
2134 type Output = T;
2135
2136 #[inline]
2137 fn index(&self, index: usize) -> &Self::Output {
2138 self.get(index).expect("index out-of-bounds")
2139 }
2140}
2141
2142impl<const N: usize, T> IndexMut<usize> for CircularBuffer<N, T> {
2143 #[inline]
2144 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
2145 self.get_mut(index).expect("index out-of-bounds")
2146 }
2147}
2148
2149impl<const N: usize, T> IntoIterator for CircularBuffer<N, T> {
2150 type Item = T;
2151 type IntoIter = IntoIter<N, T>;
2152
2153 #[inline]
2154 fn into_iter(self) -> Self::IntoIter {
2155 IntoIter::new(self)
2156 }
2157}
2158
2159impl<'a, const N: usize, T> IntoIterator for &'a CircularBuffer<N, T> {
2160 type Item = &'a T;
2161 type IntoIter = Iter<'a, T>;
2162
2163 #[inline]
2164 fn into_iter(self) -> Self::IntoIter {
2165 Iter::new(self)
2166 }
2167}
2168
2169impl<const N: usize, const M: usize, T, U> PartialEq<CircularBuffer<M, U>> for CircularBuffer<N, T>
2170where
2171 T: PartialEq<U>,
2172{
2173 fn eq(&self, other: &CircularBuffer<M, U>) -> bool {
2174 if self.len() != other.len() {
2175 return false;
2176 }
2177
2178 let (a_left, a_right) = self.as_slices();
2179 let (b_left, b_right) = other.as_slices();
2180
2181 match a_left.len().cmp(&b_left.len()) {
2182 Ordering::Less => {
2183 let x = a_left.len();
2184 let y = b_left.len() - x;
2185 a_left[..] == b_left[..x]
2186 && a_right[..y] == b_left[x..]
2187 && a_right[y..] == b_right[..]
2188 }
2189 Ordering::Greater => {
2190 let x = b_left.len();
2191 let y = a_left.len() - x;
2192 a_left[..x] == b_left[..]
2193 && a_left[x..] == b_right[..y]
2194 && a_right[..] == b_right[y..]
2195 }
2196 Ordering::Equal => {
2197 debug_assert_eq!(a_left.len(), b_left.len());
2198 debug_assert_eq!(a_right.len(), b_right.len());
2199 a_left == b_left && a_right == b_right
2200 }
2201 }
2202 }
2203}
2204
2205impl<const N: usize, T> Eq for CircularBuffer<N, T> where T: Eq {}
2206
2207impl<const N: usize, T, U> PartialEq<[U]> for CircularBuffer<N, T>
2208where
2209 T: PartialEq<U>,
2210{
2211 fn eq(&self, other: &[U]) -> bool {
2212 if self.len() != other.len() {
2213 return false;
2214 }
2215
2216 let (a_left, a_right) = self.as_slices();
2217 let (b_left, b_right) = other.split_at(a_left.len());
2218
2219 debug_assert_eq!(a_left.len(), b_left.len());
2220 debug_assert_eq!(a_right.len(), b_right.len());
2221 a_left == b_left && a_right == b_right
2222 }
2223}
2224
2225impl<const N: usize, const M: usize, T, U> PartialEq<[U; M]> for CircularBuffer<N, T>
2226where
2227 T: PartialEq<U>,
2228{
2229 #[inline]
2230 fn eq(&self, other: &[U; M]) -> bool {
2231 self == &other[..]
2232 }
2233}
2234
2235impl<'a, const N: usize, T, U> PartialEq<&'a [U]> for CircularBuffer<N, T>
2236where
2237 T: PartialEq<U>,
2238{
2239 #[inline]
2240 fn eq(&self, other: &&'a [U]) -> bool {
2241 self == *other
2242 }
2243}
2244
2245impl<'a, const N: usize, T, U> PartialEq<&'a mut [U]> for CircularBuffer<N, T>
2246where
2247 T: PartialEq<U>,
2248{
2249 #[inline]
2250 fn eq(&self, other: &&'a mut [U]) -> bool {
2251 self == *other
2252 }
2253}
2254
2255impl<'a, const N: usize, const M: usize, T, U> PartialEq<&'a [U; M]> for CircularBuffer<N, T>
2256where
2257 T: PartialEq<U>,
2258{
2259 #[inline]
2260 fn eq(&self, other: &&'a [U; M]) -> bool {
2261 self == *other
2262 }
2263}
2264
2265impl<'a, const N: usize, const M: usize, T, U> PartialEq<&'a mut [U; M]> for CircularBuffer<N, T>
2266where
2267 T: PartialEq<U>,
2268{
2269 #[inline]
2270 fn eq(&self, other: &&'a mut [U; M]) -> bool {
2271 self == *other
2272 }
2273}
2274
2275impl<const N: usize, const M: usize, T, U> PartialOrd<CircularBuffer<M, U>> for CircularBuffer<N, T>
2276where
2277 T: PartialOrd<U>,
2278{
2279 fn partial_cmp(&self, other: &CircularBuffer<M, U>) -> Option<Ordering> {
2280 self.iter().partial_cmp(other.iter())
2281 }
2282}
2283
2284impl<const N: usize, T> Ord for CircularBuffer<N, T>
2285where
2286 T: Ord,
2287{
2288 fn cmp(&self, other: &Self) -> Ordering {
2289 self.iter().cmp(other.iter())
2290 }
2291}
2292
2293impl<const N: usize, T> Hash for CircularBuffer<N, T>
2294where
2295 T: Hash,
2296{
2297 fn hash<H: Hasher>(&self, state: &mut H) {
2298 self.size.hash(state);
2299 self.iter().for_each(|item| item.hash(state));
2300 }
2301}
2302
2303impl<const N: usize, T> Clone for CircularBuffer<N, T>
2304where
2305 T: Clone,
2306{
2307 fn clone(&self) -> Self {
2308 // TODO Optimize
2309 Self::from_iter(self.iter().cloned())
2310 }
2311
2312 fn clone_from(&mut self, other: &Self) {
2313 // TODO Optimize
2314 self.clear();
2315 self.extend(other.iter().cloned());
2316 }
2317}
2318
2319impl<const N: usize, T> Drop for CircularBuffer<N, T> {
2320 #[inline]
2321 fn drop(&mut self) {
2322 // `clear()` will make sure that every element is dropped in a safe way
2323 self.clear();
2324 }
2325}
2326
2327impl<const N: usize, T> fmt::Debug for CircularBuffer<N, T>
2328where
2329 T: fmt::Debug,
2330{
2331 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2332 f.debug_list().entries(self).finish()
2333 }
2334}