Skip to main content

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}