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