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    #[inline]
892    unsafe fn drop_range(&mut self, range: Range<usize>) {
893        if range.is_empty() {
894            return;
895        }
896
897        debug_assert!(self.inner.start < self.capacity(), "start out-of-bounds");
898        debug_assert!(self.inner.size <= self.capacity(), "size out-of-bounds");
899        debug_assert!(
900            range.start < self.inner.size,
901            "start of range out-of-bounds"
902        );
903        debug_assert!(range.end <= self.inner.size, "end of range out-of-bounds");
904        debug_assert!(range.start < range.end, "start of range is past its end");
905        debug_assert!(
906            range.start == 0 || range.end == self.inner.size,
907            "range does not include boundary of the buffer"
908        );
909
910        // Drops all the items in the slice when dropped. This is needed to ensure that all
911        // elements are dropped in case a panic occurs during the drop of a single element.
912        struct Dropper<'a, T>(&'a mut [MaybeUninit<T>]);
913
914        impl<T> Drop for Dropper<'_, T> {
915            #[inline]
916            fn drop(&mut self) {
917                // SAFETY: the caller of `drop_range` is responsible to check that this slice was
918                // initialized.
919                unsafe {
920                    ptr::drop_in_place(self.0.assume_init_mut());
921                }
922            }
923        }
924
925        let drop_from = add_mod(self.inner.start, range.start, self.capacity());
926        let drop_to = add_mod(self.inner.start, range.end, self.capacity());
927
928        let (right, left) = if drop_from < drop_to {
929            (&mut self.inner.items[drop_from..drop_to], &mut [][..])
930        } else {
931            let (left, right) = self.inner.items.split_at_mut(drop_from);
932            let left = &mut left[..drop_to];
933            (right, left)
934        };
935
936        let _left = Dropper(left);
937        let _right = Dropper(right);
938    }
939
940    /// Returns a reference to the back element, or `None` if the buffer is empty.
941    ///
942    /// # Examples
943    ///
944    /// ```
945    /// use circular_buffer::FixedCircularBuffer;
946    ///
947    /// let mut buf = FixedCircularBuffer::<char, 4>::new();
948    /// assert_eq!(buf.back(), None);
949    ///
950    /// buf.push_back('a');
951    /// buf.push_back('b');
952    /// buf.push_back('c');
953    /// assert_eq!(buf.back(), Some(&'c'));
954    /// ```
955    #[inline]
956    pub const fn back(&self) -> Option<&T> {
957        if self.capacity() == 0 || self.inner.size == 0 {
958            // Nothing to do
959            return None;
960        }
961        // SAFETY: `size` is non-zero; back element is guaranteed to be initialized
962        Some(unsafe { self.back_maybe_uninit().assume_init_ref() })
963    }
964
965    /// Returns a mutable reference to the back element, or `None` if the buffer is empty.
966    ///
967    /// # Examples
968    ///
969    /// ```
970    /// use circular_buffer::FixedCircularBuffer;
971    ///
972    /// let mut buf = FixedCircularBuffer::<char, 4>::new();
973    /// assert_eq!(buf.back_mut(), None);
974    ///
975    /// buf.push_back('a');
976    /// buf.push_back('b');
977    /// buf.push_back('c');
978    /// match buf.back_mut() {
979    ///     None => (),
980    ///     Some(x) => *x = 'z',
981    /// }
982    /// assert_eq!(buf, ['a', 'b', 'z']);
983    /// ```
984    #[inline]
985    pub const fn back_mut(&mut self) -> Option<&mut T> {
986        if self.capacity() == 0 || self.inner.size == 0 {
987            // Nothing to do
988            return None;
989        }
990        // SAFETY: `size` is non-zero; back element is guaranteed to be initialized
991        Some(unsafe { self.back_maybe_uninit_mut().assume_init_mut() })
992    }
993
994    /// Returns a reference to the front element, or `None` if the buffer is empty.
995    ///
996    /// # Examples
997    ///
998    /// ```
999    /// use circular_buffer::FixedCircularBuffer;
1000    ///
1001    /// let mut buf = FixedCircularBuffer::<char, 4>::new();
1002    /// assert_eq!(buf.front(), None);
1003    ///
1004    /// buf.push_back('a');
1005    /// buf.push_back('b');
1006    /// buf.push_back('c');
1007    /// assert_eq!(buf.front(), Some(&'a'));
1008    /// ```
1009    #[inline]
1010    pub const fn front(&self) -> Option<&T> {
1011        if self.capacity() == 0 || self.inner.size == 0 {
1012            // Nothing to do
1013            return None;
1014        }
1015        // SAFETY: `size` is non-zero; front element is guaranteed to be initialized
1016        Some(unsafe { self.front_maybe_uninit().assume_init_ref() })
1017    }
1018
1019    /// Returns a mutable reference to the front element, or `None` if the buffer is empty.
1020    ///
1021    /// # Examples
1022    ///
1023    /// ```
1024    /// use circular_buffer::FixedCircularBuffer;
1025    ///
1026    /// let mut buf = FixedCircularBuffer::<char, 4>::new();
1027    /// assert_eq!(buf.front_mut(), None);
1028    ///
1029    /// buf.push_back('a');
1030    /// buf.push_back('b');
1031    /// buf.push_back('c');
1032    /// match buf.front_mut() {
1033    ///     None => (),
1034    ///     Some(x) => *x = 'z',
1035    /// }
1036    /// assert_eq!(buf, ['z', 'b', 'c']);
1037    /// ```
1038    #[inline]
1039    pub const fn front_mut(&mut self) -> Option<&mut T> {
1040        if self.capacity() == 0 || self.inner.size == 0 {
1041            // Nothing to do
1042            return None;
1043        }
1044        // SAFETY: `size` is non-zero; front element is guaranteed to be initialized
1045        Some(unsafe { self.front_maybe_uninit_mut().assume_init_mut() })
1046    }
1047
1048    /// Returns a reference to the element at the given index from the front of the buffer, or
1049    /// `None` if the element does not exist.
1050    ///
1051    /// Element at index 0 is the front of the queue.
1052    ///
1053    /// This is the same as [`nth_front()`](Self::nth_front).
1054    ///
1055    /// # Examples
1056    ///
1057    /// ```
1058    /// use circular_buffer::FixedCircularBuffer;
1059    ///
1060    /// let mut buf = FixedCircularBuffer::<char, 5>::new();
1061    /// assert_eq!(buf.get(1), None);
1062    ///
1063    /// buf.push_back('a');
1064    /// buf.push_back('b');
1065    /// buf.push_back('c');
1066    /// buf.push_back('d');
1067    /// assert_eq!(buf.get(1), Some(&'b'));
1068    /// ```
1069    #[inline]
1070    pub const fn get(&self, index: usize) -> Option<&T> {
1071        if self.capacity() == 0 || index >= self.inner.size {
1072            // Nothing to do
1073            return None;
1074        }
1075        // SAFETY: `index` is in a valid range; it is guaranteed to point to an initialized element
1076        Some(unsafe { self.get_maybe_uninit(index).assume_init_ref() })
1077    }
1078
1079    /// Returns a mutable reference to the element at the given index, or `None` if the element
1080    /// does not exist.
1081    ///
1082    /// Element at index 0 is the front of the queue.
1083    ///
1084    /// This is the same as [`nth_front_mut()`](Self::nth_front_mut).
1085    ///
1086    /// # Examples
1087    ///
1088    /// ```
1089    /// use circular_buffer::FixedCircularBuffer;
1090    ///
1091    /// let mut buf = FixedCircularBuffer::<char, 5>::new();
1092    /// assert_eq!(buf.get_mut(1), None);
1093    ///
1094    /// buf.push_back('a');
1095    /// buf.push_back('b');
1096    /// buf.push_back('c');
1097    /// buf.push_back('d');
1098    /// match buf.get_mut(1) {
1099    ///     None => (),
1100    ///     Some(x) => *x = 'z',
1101    /// }
1102    /// assert_eq!(buf, ['a', 'z', 'c', 'd']);
1103    /// ```
1104    #[inline]
1105    pub const fn get_mut(&mut self, index: usize) -> Option<&mut T> {
1106        if self.capacity() == 0 || index >= self.inner.size {
1107            // Nothing to do
1108            return None;
1109        }
1110        // SAFETY: `index` is in a valid range; it is guaranteed to point to an initialized element
1111        Some(unsafe { self.get_maybe_uninit_mut(index).assume_init_mut() })
1112    }
1113
1114    /// Returns a reference to the element at the given index from the front of the buffer, or
1115    /// `None` if the element does not exist.
1116    ///
1117    /// Like most indexing operations, the count starts from zero, so `nth_front(0)` returns the
1118    /// first value, `nth_front(1)` the second, and so on. Element at index 0 is the front of the
1119    /// queue.
1120    ///
1121    /// This is the same as [`get()`](Self::get).
1122    ///
1123    /// # Examples
1124    ///
1125    /// ```
1126    /// use circular_buffer::FixedCircularBuffer;
1127    ///
1128    /// let mut buf = FixedCircularBuffer::<char, 5>::new();
1129    /// assert_eq!(buf.nth_front(1), None);
1130    ///
1131    /// buf.push_back('a');
1132    /// buf.push_back('b');
1133    /// buf.push_back('c');
1134    /// buf.push_back('d');
1135    /// assert_eq!(buf.nth_front(1), Some(&'b'));
1136    /// ```
1137    #[inline]
1138    pub const fn nth_front(&self, index: usize) -> Option<&T> {
1139        self.get(index)
1140    }
1141
1142    /// Returns a mutable reference to the element at the given index from the front of the buffer,
1143    /// or `None` if the element does not exist.
1144    ///
1145    /// Like most indexing operations, the count starts from zero, so `nth_front_mut(0)` returns
1146    /// the first value, `nth_front_mut(1)` the second, and so on. Element at index 0 is the front
1147    /// of the queue.
1148    ///
1149    /// This is the same as [`get_mut()`](Self::get_mut).
1150    ///
1151    /// # Examples
1152    ///
1153    /// ```
1154    /// use circular_buffer::FixedCircularBuffer;
1155    ///
1156    /// let mut buf = FixedCircularBuffer::<char, 5>::new();
1157    /// assert_eq!(buf.nth_front_mut(1), None);
1158    ///
1159    /// buf.push_back('a');
1160    /// buf.push_back('b');
1161    /// buf.push_back('c');
1162    /// buf.push_back('d');
1163    /// match buf.nth_front_mut(1) {
1164    ///     None => (),
1165    ///     Some(x) => *x = 'z',
1166    /// }
1167    /// assert_eq!(buf, ['a', 'z', 'c', 'd']);
1168    /// ```
1169    #[inline]
1170    pub const fn nth_front_mut(&mut self, index: usize) -> Option<&mut T> {
1171        self.get_mut(index)
1172    }
1173
1174    /// Returns a reference to the element at the given index from the back of the buffer, or
1175    /// `None` if the element does not exist.
1176    ///
1177    /// Like most indexing operations, the count starts from zero, so `nth_back(0)` returns the
1178    /// first value, `nth_back(1)` the second, and so on. Element at index 0 is the back of the
1179    /// queue.
1180    ///
1181    /// # Examples
1182    ///
1183    /// ```
1184    /// use circular_buffer::FixedCircularBuffer;
1185    ///
1186    /// let mut buf = FixedCircularBuffer::<char, 5>::new();
1187    /// assert_eq!(buf.nth_back(1), None);
1188    ///
1189    /// buf.push_back('a');
1190    /// buf.push_back('b');
1191    /// buf.push_back('c');
1192    /// buf.push_back('d');
1193    /// assert_eq!(buf.nth_back(1), Some(&'c'));
1194    /// ```
1195    #[inline]
1196    pub const fn nth_back(&self, index: usize) -> Option<&T> {
1197        // TODO: Switch back to using `?` once it's stabilized in `const` contexts
1198        let index = match self.inner.size.checked_sub(index) {
1199            Some(index) => index,
1200            None => return None,
1201        };
1202        let index = match index.checked_sub(1) {
1203            Some(index) => index,
1204            None => return None,
1205        };
1206        self.get(index)
1207    }
1208
1209    /// Returns a mutable reference to the element at the given index from the back of the buffer,
1210    /// or `None` if the element does not exist.
1211    ///
1212    /// Like most indexing operations, the count starts from zero, so `nth_back_mut(0)` returns the
1213    /// first value, `nth_back_mut(1)` the second, and so on. Element at index 0 is the back of the
1214    /// queue.
1215    ///
1216    /// # Examples
1217    ///
1218    /// ```
1219    /// use circular_buffer::FixedCircularBuffer;
1220    ///
1221    /// let mut buf = FixedCircularBuffer::<char, 5>::new();
1222    /// assert_eq!(buf.nth_back_mut(1), None);
1223    ///
1224    /// buf.push_back('a');
1225    /// buf.push_back('b');
1226    /// buf.push_back('c');
1227    /// buf.push_back('d');
1228    /// match buf.nth_back_mut(1) {
1229    ///     None => (),
1230    ///     Some(x) => *x = 'z',
1231    /// }
1232    /// assert_eq!(buf, ['a', 'b', 'z', 'd']);
1233    /// ```
1234    #[inline]
1235    pub const fn nth_back_mut(&mut self, index: usize) -> Option<&mut T> {
1236        // TODO: Switch back to using `?` once it's stabilized in `const` contexts
1237        let index = match self.inner.size.checked_sub(index) {
1238            Some(index) => index,
1239            None => return None,
1240        };
1241        let index = match index.checked_sub(1) {
1242            Some(index) => index,
1243            None => return None,
1244        };
1245        self.get_mut(index)
1246    }
1247
1248    /// Appends an element to the back of the buffer.
1249    ///
1250    /// If the buffer is full, the element at the front of the buffer is overwritten and returned.
1251    ///
1252    /// See also [`try_push_back()`](Self::try_push_back) for a non-overwriting version of this
1253    /// method.
1254    ///
1255    /// # Examples
1256    ///
1257    /// ```
1258    /// use circular_buffer::FixedCircularBuffer;
1259    ///
1260    /// let mut buf = FixedCircularBuffer::<char, 3>::new();
1261    ///
1262    /// assert_eq!(buf.push_back('a'), None);
1263    /// assert_eq!(buf, ['a']);
1264    ///
1265    /// assert_eq!(buf.push_back('b'), None);
1266    /// assert_eq!(buf, ['a', 'b']);
1267    ///
1268    /// assert_eq!(buf.push_back('c'), None);
1269    /// assert_eq!(buf, ['a', 'b', 'c']);
1270    ///
1271    /// // The buffer is now full; adding more values causes the front elements to be removed and
1272    /// // returned
1273    /// assert_eq!(buf.push_back('d'), Some('a'));
1274    /// assert_eq!(buf, ['b', 'c', 'd']);
1275    ///
1276    /// assert_eq!(buf.push_back('e'), Some('b'));
1277    /// assert_eq!(buf, ['c', 'd', 'e']);
1278    ///
1279    /// assert_eq!(buf.push_back('f'), Some('c'));
1280    /// assert_eq!(buf, ['d', 'e', 'f']);
1281    /// ```
1282    pub const fn push_back(&mut self, item: T) -> Option<T> {
1283        if self.capacity() == 0 {
1284            // Nothing to do
1285            return Some(item);
1286        }
1287
1288        if self.inner.size >= self.capacity() {
1289            // At capacity; need to replace the front item
1290            //
1291            // SAFETY: if size is greater than 0, the front item is guaranteed to be initialized.
1292            let replaced_item = mem::replace(
1293                unsafe { self.front_maybe_uninit_mut().assume_init_mut() },
1294                item,
1295            );
1296            self.inc_start();
1297            Some(replaced_item)
1298        } else {
1299            // Some uninitialized slots left; append at the end
1300            self.inc_size();
1301            self.back_maybe_uninit_mut().write(item);
1302            None
1303        }
1304    }
1305
1306    /// Appends an element to the back of the buffer.
1307    ///
1308    /// If the buffer is full, the buffer is not modified and the given element is returned as an
1309    /// error.
1310    ///
1311    /// See also [`push_back()`](Self::push_back) for a version of this method that overwrites the
1312    /// front of the buffer when full.
1313    ///
1314    /// # Examples
1315    ///
1316    /// ```
1317    /// use circular_buffer::FixedCircularBuffer;
1318    ///
1319    /// let mut buf = FixedCircularBuffer::<char, 3>::new();
1320    ///
1321    /// assert_eq!(buf.try_push_back('a'), Ok(()));
1322    /// assert_eq!(buf, ['a']);
1323    ///
1324    /// assert_eq!(buf.try_push_back('b'), Ok(()));
1325    /// assert_eq!(buf, ['a', 'b']);
1326    ///
1327    /// assert_eq!(buf.try_push_back('c'), Ok(()));
1328    /// assert_eq!(buf, ['a', 'b', 'c']);
1329    ///
1330    /// // The buffer is now full; adding more values results in an error
1331    /// assert_eq!(buf.try_push_back('d'), Err('d'))
1332    /// ```
1333    pub const fn try_push_back(&mut self, item: T) -> Result<(), T> {
1334        if self.inner.size >= self.capacity() {
1335            // At capacity; return the pushed item as error
1336            Err(item)
1337        } else {
1338            // Some uninitialized slots left; append at the end
1339            self.inc_size();
1340            self.back_maybe_uninit_mut().write(item);
1341            Ok(())
1342        }
1343    }
1344
1345    /// Appends an element to the front of the buffer.
1346    ///
1347    /// If the buffer is full, the element at the back of the buffer is overwritten and returned.
1348    ///
1349    /// See also [`try_push_front()`](Self::try_push_front) for a non-overwriting version of this
1350    /// method.
1351    ///
1352    /// # Examples
1353    ///
1354    /// ```
1355    /// use circular_buffer::FixedCircularBuffer;
1356    ///
1357    /// let mut buf = FixedCircularBuffer::<char, 3>::new();
1358    ///
1359    /// assert_eq!(buf.push_front('a'), None);
1360    /// assert_eq!(buf, ['a']);
1361    ///
1362    /// assert_eq!(buf.push_front('b'), None);
1363    /// assert_eq!(buf, ['b', 'a']);
1364    ///
1365    /// assert_eq!(buf.push_front('c'), None);
1366    /// assert_eq!(buf, ['c', 'b', 'a']);
1367    ///
1368    /// // The buffer is now full; adding more values causes the back elements to be dropped
1369    /// assert_eq!(buf.push_front('d'), Some('a'));
1370    /// assert_eq!(buf, ['d', 'c', 'b']);
1371    ///
1372    /// assert_eq!(buf.push_front('e'), Some('b'));
1373    /// assert_eq!(buf, ['e', 'd', 'c']);
1374    ///
1375    /// assert_eq!(buf.push_front('f'), Some('c'));
1376    /// assert_eq!(buf, ['f', 'e', 'd']);
1377    /// ```
1378    pub const fn push_front(&mut self, item: T) -> Option<T> {
1379        if self.capacity() == 0 {
1380            // Nothing to do
1381            return Some(item);
1382        }
1383
1384        if self.inner.size >= self.capacity() {
1385            // At capacity; need to replace the back item
1386            //
1387            // SAFETY: if size is greater than 0, the back item is guaranteed to be initialized.
1388            let replaced_item = mem::replace(
1389                unsafe { self.back_maybe_uninit_mut().assume_init_mut() },
1390                item,
1391            );
1392            self.dec_start();
1393            Some(replaced_item)
1394        } else {
1395            // Some uninitialized slots left; insert at the start
1396            self.inc_size();
1397            self.dec_start();
1398            self.front_maybe_uninit_mut().write(item);
1399            None
1400        }
1401    }
1402
1403    /// Appends an element to the front of the buffer.
1404    ///
1405    /// If the buffer is full, the buffer is not modified and the given element is returned as an
1406    /// error.
1407    ///
1408    /// See also [`push_front()`](Self::push_front) for a version of this method that overwrites the
1409    /// back of the buffer when full.
1410    ///
1411    /// # Examples
1412    ///
1413    /// ```
1414    /// use circular_buffer::FixedCircularBuffer;
1415    ///
1416    /// let mut buf = FixedCircularBuffer::<char, 3>::new();
1417    ///
1418    /// assert_eq!(buf.try_push_front('a'), Ok(()));
1419    /// assert_eq!(buf, ['a']);
1420    ///
1421    /// assert_eq!(buf.try_push_front('b'), Ok(()));
1422    /// assert_eq!(buf, ['b', 'a']);
1423    ///
1424    /// assert_eq!(buf.try_push_front('c'), Ok(()));
1425    /// assert_eq!(buf, ['c', 'b', 'a']);
1426    ///
1427    /// // The buffer is now full; adding more values results in an error
1428    /// assert_eq!(buf.try_push_front('d'), Err('d'));
1429    /// ```
1430    pub const fn try_push_front(&mut self, item: T) -> Result<(), T> {
1431        if self.inner.size >= self.capacity() {
1432            // At capacity; return the pushed item as error
1433            Err(item)
1434        } else {
1435            // Some uninitialized slots left; insert at the start
1436            self.inc_size();
1437            self.dec_start();
1438            self.front_maybe_uninit_mut().write(item);
1439            Ok(())
1440        }
1441    }
1442
1443    /// Removes and returns an element from the back of the buffer.
1444    ///
1445    /// If the buffer is empty, `None` is returned.
1446    ///
1447    /// # Examples
1448    ///
1449    /// ```
1450    /// use circular_buffer::FixedCircularBuffer;
1451    ///
1452    /// let mut buf = FixedCircularBuffer::<char, 3>::from(['a', 'b', 'c']);
1453    ///
1454    /// assert_eq!(buf.pop_back(), Some('c'));
1455    /// assert_eq!(buf.pop_back(), Some('b'));
1456    /// assert_eq!(buf.pop_back(), Some('a'));
1457    /// assert_eq!(buf.pop_back(), None);
1458    /// ```
1459    pub const fn pop_back(&mut self) -> Option<T> {
1460        if self.capacity() == 0 || self.inner.size == 0 {
1461            // Nothing to do
1462            return None;
1463        }
1464
1465        // SAFETY: if size is greater than 0, the back item is guaranteed to be initialized.
1466        let back = unsafe { self.back_maybe_uninit().assume_init_read() };
1467        self.dec_size();
1468        Some(back)
1469    }
1470
1471    /// Removes and returns an element from the front of the buffer.
1472    ///
1473    /// If the buffer is empty, `None` is returned.
1474    ///
1475    /// # Examples
1476    ///
1477    /// ```
1478    /// use circular_buffer::FixedCircularBuffer;
1479    ///
1480    /// let mut buf = FixedCircularBuffer::<char, 3>::from(['a', 'b', 'c']);
1481    ///
1482    /// assert_eq!(buf.pop_front(), Some('a'));
1483    /// assert_eq!(buf.pop_front(), Some('b'));
1484    /// assert_eq!(buf.pop_front(), Some('c'));
1485    /// assert_eq!(buf.pop_front(), None);
1486    /// ```
1487    pub const fn pop_front(&mut self) -> Option<T> {
1488        if self.capacity() == 0 || self.inner.size == 0 {
1489            // Nothing to do
1490            return None;
1491        }
1492
1493        // SAFETY: if size is greater than 0, the front item is guaranteed to be initialized.
1494        let front = unsafe { self.front_maybe_uninit().assume_init_read() };
1495        self.dec_size();
1496        self.inc_start();
1497        Some(front)
1498    }
1499
1500    /// Removes and returns an element at the specified index.
1501    ///
1502    /// If the index is out of bounds, `None` is returned.
1503    ///
1504    /// # Examples
1505    ///
1506    /// ```
1507    /// use circular_buffer::FixedCircularBuffer;
1508    ///
1509    /// let mut buf = FixedCircularBuffer::<char, 3>::from(['a', 'b', 'c']);
1510    ///
1511    /// assert_eq!(buf.remove(1), Some('b'));
1512    /// assert_eq!(buf, ['a', 'c']);
1513    ///
1514    /// assert_eq!(buf.remove(5), None);
1515    /// ```
1516    pub const fn remove(&mut self, index: usize) -> Option<T> {
1517        if self.capacity() == 0 || index >= self.inner.size {
1518            return None;
1519        }
1520
1521        let index = add_mod(self.inner.start, index, self.capacity());
1522        let back_index = add_mod(self.inner.start, self.inner.size - 1, self.capacity());
1523
1524        // SAFETY: `index` is in a valid range; the element is guaranteed to be initialized
1525        let item = unsafe { self.inner.items[index].assume_init_read() };
1526
1527        // SAFETY: the pointers being moved are in a valid range; the elements behind those
1528        // pointers are guaranteed to be initialized
1529        unsafe {
1530            // TODO: optimize for the case where `index < len - index` (i.e. when copying items to
1531            // the right is cheaper than moving items to the left)
1532            let ptr = self.inner.items.as_mut_ptr();
1533            if back_index >= index {
1534                // Move the values at the right of `index` by 1 position to the left
1535                ptr::copy(ptr.add(index).add(1), ptr.add(index), back_index - index);
1536            } else {
1537                // Move the values at the right of `index` by 1 position to the left
1538                ptr::copy(
1539                    ptr.add(index).add(1),
1540                    ptr.add(index),
1541                    self.capacity() - index - 1,
1542                );
1543                // Move the leftmost value to the end of the array
1544                ptr::copy(ptr, ptr.add(self.capacity() - 1), 1);
1545                // Move the values at the left of `back_index` by 1 position to the left
1546                ptr::copy(ptr.add(1), ptr, back_index);
1547            }
1548        }
1549
1550        self.dec_size();
1551        Some(item)
1552    }
1553
1554    /// Swap the element at index `i` with the element at index `j`.
1555    ///
1556    /// # Panics
1557    ///
1558    /// If either `i` or `j` is out of bounds.
1559    ///
1560    /// # Examples
1561    ///
1562    /// ```
1563    /// use circular_buffer::FixedCircularBuffer;
1564    ///
1565    /// let mut buf = FixedCircularBuffer::<char, 5>::from(['a', 'b', 'c', 'd']);
1566    /// assert_eq!(buf, ['a', 'b', 'c', 'd']);
1567    ///
1568    /// buf.swap(0, 3);
1569    /// assert_eq!(buf, ['d', 'b', 'c', 'a']);
1570    /// ```
1571    ///
1572    /// Trying to swap an invalid index panics:
1573    ///
1574    /// ```should_panic
1575    /// use circular_buffer::FixedCircularBuffer;
1576    /// let mut buf = FixedCircularBuffer::<char, 5>::from(['a', 'b', 'c', 'd']);
1577    /// buf.swap(0, 7);
1578    /// ```
1579    pub const fn swap(&mut self, i: usize, j: usize) {
1580        assert!(i < self.inner.size, "i index out-of-bounds");
1581        assert!(j < self.inner.size, "j index out-of-bounds");
1582        if i != j {
1583            let i = add_mod(self.inner.start, i, self.capacity());
1584            let j = add_mod(self.inner.start, j, self.capacity());
1585            // SAFETY: these are valid pointers
1586            unsafe {
1587                ptr::swap_nonoverlapping(&mut self.inner.items[i], &mut self.inner.items[j], 1)
1588            };
1589        }
1590    }
1591
1592    /// Removes the element at `index` and returns it, replacing it with the back of the buffer.
1593    ///
1594    /// Returns `None` if `index` is out-of-bounds.
1595    ///
1596    /// # Examples
1597    ///
1598    /// ```
1599    /// use circular_buffer::FixedCircularBuffer;
1600    ///
1601    /// let mut buf = FixedCircularBuffer::<char, 5>::from(['a', 'b', 'c', 'd']);
1602    /// assert_eq!(buf, ['a', 'b', 'c', 'd']);
1603    ///
1604    /// assert_eq!(buf.swap_remove_back(2), Some('c'));
1605    /// assert_eq!(buf, ['a', 'b', 'd']);
1606    ///
1607    /// assert_eq!(buf.swap_remove_back(7), None);
1608    /// ```
1609    pub const fn swap_remove_back(&mut self, index: usize) -> Option<T> {
1610        if index >= self.inner.size {
1611            return None;
1612        }
1613        self.swap(index, self.inner.size - 1);
1614        self.pop_back()
1615    }
1616
1617    /// Removes the element at `index` and returns it, replacing it with the front of the buffer.
1618    ///
1619    /// Returns `None` if `index` is out-of-bounds.
1620    ///
1621    /// # Examples
1622    ///
1623    /// ```
1624    /// use circular_buffer::FixedCircularBuffer;
1625    ///
1626    /// let mut buf = FixedCircularBuffer::<char, 5>::from(['a', 'b', 'c', 'd']);
1627    /// assert_eq!(buf, ['a', 'b', 'c', 'd']);
1628    ///
1629    /// assert_eq!(buf.swap_remove_front(2), Some('c'));
1630    /// assert_eq!(buf, ['b', 'a', 'd']);
1631    ///
1632    /// assert_eq!(buf.swap_remove_front(7), None);
1633    /// ```
1634    pub const fn swap_remove_front(&mut self, index: usize) -> Option<T> {
1635        if index >= self.inner.size {
1636            return None;
1637        }
1638        self.swap(index, 0);
1639        self.pop_front()
1640    }
1641
1642    /// Fills the entire capacity of `self` with elements by cloning `value`.
1643    ///
1644    /// The elements already present in the buffer (if any) are all replaced by clones of `value`,
1645    /// and the spare capacity of the buffer is also filled with clones of `value`.
1646    ///
1647    /// This is equivalent to clearing the buffer and adding clones of `value` until reaching the
1648    /// maximum capacity.
1649    ///
1650    /// If you want to replace only the existing elements of the buffer, without affecting the spare
1651    /// capacity, use [`as_mut_slices()`](Self::as_mut_slices) and call [`slice::fill()`] on the
1652    /// resulting slices.
1653    ///
1654    /// See also: [`fill_with()`](Self::fill_with), [`fill_spare()`](Self::fill_spare),
1655    /// [`fill_spare_with()`](Self::fill_spare_with).
1656    ///
1657    /// # Examples
1658    ///
1659    /// ```
1660    /// use circular_buffer::FixedCircularBuffer;
1661    ///
1662    /// let mut buf = FixedCircularBuffer::<u32, 10>::from([1, 2, 3]);
1663    /// assert_eq!(buf, [1, 2, 3]);
1664    ///
1665    /// buf.fill(9);
1666    /// assert_eq!(buf, [9, 9, 9, 9, 9, 9, 9, 9, 9, 9]);
1667    /// ```
1668    ///
1669    /// If you want to replace existing elements only:
1670    ///
1671    /// ```
1672    /// use circular_buffer::FixedCircularBuffer;
1673    ///
1674    /// let mut buf = FixedCircularBuffer::<u32, 10>::from([1, 2, 3]);
1675    /// assert_eq!(buf, [1, 2, 3]);
1676    ///
1677    /// let (front, back) = buf.as_mut_slices();
1678    /// front.fill(9);
1679    /// back.fill(9);
1680    /// assert_eq!(buf, [9, 9, 9]);
1681    /// ```
1682    pub fn fill(&mut self, value: T)
1683    where
1684        T: Clone,
1685    {
1686        self.clear();
1687        self.fill_spare(value);
1688    }
1689
1690    /// Fills the entire capacity of `self` with elements by calling a closure.
1691    ///
1692    /// The elements already present in the buffer (if any) are all replaced by the result of the
1693    /// closure, and the spare capacity of the buffer is also filled with the result of the
1694    /// closure.
1695    ///
1696    /// This is equivalent to clearing the buffer and adding the result of the closure until
1697    /// reaching the maximum capacity.
1698    ///
1699    /// If you want to replace only the existing elements of the buffer, without affecting the spare
1700    /// capacity, use [`as_mut_slices()`](Self::as_mut_slices) and call [`slice::fill_with()`] on
1701    /// the resulting slices.
1702    ///
1703    /// See also: [`fill()`](Self::fill), [`fill_spare()`](Self::fill_spare),
1704    /// [`fill_spare_with()`](Self::fill_spare_with).
1705    ///
1706    /// # Examples
1707    ///
1708    /// ```
1709    /// use circular_buffer::FixedCircularBuffer;
1710    ///
1711    /// let mut buf = FixedCircularBuffer::<u32, 10>::from([1, 2, 3]);
1712    /// assert_eq!(buf, [1, 2, 3]);
1713    ///
1714    /// let mut x = 2;
1715    /// buf.fill_with(|| {
1716    ///     x *= 2;
1717    ///     x
1718    /// });
1719    /// assert_eq!(buf, [4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048]);
1720    /// ```
1721    ///
1722    /// If you want to replace existing elements only:
1723    ///
1724    /// ```
1725    /// use circular_buffer::FixedCircularBuffer;
1726    ///
1727    /// let mut buf = FixedCircularBuffer::<u32, 10>::from([1, 2, 3]);
1728    /// assert_eq!(buf, [1, 2, 3]);
1729    ///
1730    /// let mut x = 2;
1731    /// let (front, back) = buf.as_mut_slices();
1732    /// front.fill_with(|| {
1733    ///     x *= 2;
1734    ///     x
1735    /// });
1736    /// back.fill_with(|| {
1737    ///     x *= 2;
1738    ///     x
1739    /// });
1740    /// assert_eq!(buf, [4, 8, 16]);
1741    /// ```
1742    pub fn fill_with<F>(&mut self, f: F)
1743    where
1744        F: FnMut() -> T,
1745    {
1746        self.clear();
1747        self.fill_spare_with(f);
1748    }
1749
1750    /// Fills the spare capacity of `self` with elements by cloning `value`.
1751    ///
1752    /// The elements already present in the buffer (if any) are unaffected.
1753    ///
1754    /// This is equivalent to adding clones of `value` to the buffer until reaching the maximum
1755    /// capacity.
1756    ///
1757    /// See also: [`fill()`](Self::fill), [`fill_with()`](Self::fill_with),
1758    /// [`fill_spare_with()`](Self::fill_spare_with).
1759    ///
1760    /// # Examples
1761    ///
1762    /// ```
1763    /// use circular_buffer::FixedCircularBuffer;
1764    ///
1765    /// let mut buf = FixedCircularBuffer::<u32, 10>::from([1, 2, 3]);
1766    /// assert_eq!(buf, [1, 2, 3]);
1767    ///
1768    /// buf.fill_spare(9);
1769    /// assert_eq!(buf, [1, 2, 3, 9, 9, 9, 9, 9, 9, 9]);
1770    /// ```
1771    pub fn fill_spare(&mut self, value: T)
1772    where
1773        T: Clone,
1774    {
1775        if self.inner.size == self.capacity() {
1776            return;
1777        }
1778        // TODO Optimize
1779        while self.inner.size < self.capacity() - 1 {
1780            self.push_back(value.clone());
1781        }
1782        self.push_back(value);
1783    }
1784
1785    /// Fills the spare capacity of `self` with elements by calling a closure.
1786    ///
1787    /// The elements already present in the buffer (if any) are unaffected.
1788    ///
1789    /// This is equivalent to adding the result of the closure to the buffer until reaching the
1790    /// maximum capacity.
1791    ///
1792    /// See also: [`fill()`](Self::fill), [`fill_with()`](Self::fill_with),
1793    /// [`fill_spare()`](Self::fill_spare).
1794    ///
1795    /// # Examples
1796    ///
1797    /// ```
1798    /// use circular_buffer::FixedCircularBuffer;
1799    ///
1800    /// let mut buf = FixedCircularBuffer::<u32, 10>::from([1, 2, 3]);
1801    /// assert_eq!(buf, [1, 2, 3]);
1802    ///
1803    /// let mut x = 2;
1804    /// buf.fill_spare_with(|| {
1805    ///     x *= 2;
1806    ///     x
1807    /// });
1808    /// assert_eq!(buf, [1, 2, 3, 4, 8, 16, 32, 64, 128, 256]);
1809    /// ```
1810    pub fn fill_spare_with<F>(&mut self, mut f: F)
1811    where
1812        F: FnMut() -> T,
1813    {
1814        if self.capacity() == 0 {
1815            return;
1816        }
1817        // TODO Optimize
1818        while self.inner.size < self.capacity() {
1819            self.push_back(f());
1820        }
1821    }
1822
1823    /// Shortens the buffer, keeping only the front `len` elements and dropping the rest.
1824    ///
1825    /// If `len` is equal or greater to the buffer's current length, this has no effect.
1826    ///
1827    /// Calling `truncate_back(0)` is equivalent to [`clear()`](Self::clear).
1828    ///
1829    /// # Examples
1830    ///
1831    /// ```
1832    /// use circular_buffer::FixedCircularBuffer;
1833    ///
1834    /// let mut buf = FixedCircularBuffer::<u32, 4>::from([10, 20, 30]);
1835    ///
1836    /// buf.truncate_back(1);
1837    /// assert_eq!(buf, [10]);
1838    ///
1839    /// // Truncating to a length that is greater than the buffer's length has no effect
1840    /// buf.truncate_back(8);
1841    /// assert_eq!(buf, [10]);
1842    /// ```
1843    pub fn truncate_back(&mut self, len: usize) {
1844        if self.capacity() == 0 || len >= self.inner.size {
1845            // Nothing to do
1846            return;
1847        }
1848
1849        let drop_range = len..self.inner.size;
1850        // SAFETY: `drop_range` is a valid range, so elements within are guaranteed to be
1851        // initialized. The `size` of the buffer is shrunk before dropping, so no value will be
1852        // dropped twice in case of panics.
1853        unsafe { self.drop_range(drop_range) };
1854        self.inner.size = len;
1855    }
1856
1857    /// Shortens the buffer, keeping only the back `len` elements and dropping the rest.
1858    ///
1859    /// If `len` is equal or greater to the buffer's current length, this has no effect.
1860    ///
1861    /// Calling `truncate_front(0)` is equivalent to [`clear()`](Self::clear).
1862    ///
1863    /// # Examples
1864    ///
1865    /// ```
1866    /// use circular_buffer::FixedCircularBuffer;
1867    ///
1868    /// let mut buf = FixedCircularBuffer::<u32, 4>::from([10, 20, 30]);
1869    ///
1870    /// buf.truncate_front(1);
1871    /// assert_eq!(buf, [30]);
1872    ///
1873    /// // Truncating to a length that is greater than the buffer's length has no effect
1874    /// buf.truncate_front(8);
1875    /// assert_eq!(buf, [30]);
1876    /// ```
1877    pub fn truncate_front(&mut self, len: usize) {
1878        if self.capacity() == 0 || len >= self.inner.size {
1879            // Nothing to do
1880            return;
1881        }
1882
1883        let drop_len = self.inner.size - len;
1884        let drop_range = 0..drop_len;
1885        // SAFETY: `drop_range` is a valid range, so elements within are guaranteed to be
1886        // initialized. The `start` of the buffer is shrunk before dropping, so no value will be
1887        // dropped twice in case of panics.
1888        unsafe { self.drop_range(drop_range) };
1889        self.inner.start = add_mod(self.inner.start, drop_len, self.capacity());
1890        self.inner.size = len;
1891    }
1892
1893    /// Drops all the elements in the buffer.
1894    ///
1895    /// # Examples
1896    ///
1897    /// ```
1898    /// use circular_buffer::FixedCircularBuffer;
1899    ///
1900    /// let mut buf = FixedCircularBuffer::<u32, 4>::from([10, 20, 30]);
1901    /// assert_eq!(buf, [10, 20, 30]);
1902    /// buf.clear();
1903    /// assert_eq!(buf, []);
1904    /// ```
1905    #[inline]
1906    pub fn clear(&mut self) {
1907        self.truncate_back(0)
1908    }
1909}
1910
1911impl<T> CircularBuffer<T>
1912where
1913    T: Clone,
1914{
1915    /// Clones and appends all the elements from the slice to the back of the buffer.
1916    ///
1917    /// This is an optimized version of [`extend()`](Self::extend) for slices.
1918    ///
1919    /// If slice contains more values than the available capacity, the elements at the front of the
1920    /// buffer are dropped.
1921    ///
1922    /// # Examples
1923    ///
1924    /// ```
1925    /// use circular_buffer::FixedCircularBuffer;
1926    ///
1927    /// let mut buf: FixedCircularBuffer<u32, 5> = FixedCircularBuffer::from([1, 2, 3]);
1928    /// buf.extend_from_slice(&[4, 5, 6, 7]);
1929    /// assert_eq!(buf, [3, 4, 5, 6, 7]);
1930    /// ```
1931    pub fn extend_from_slice(&mut self, other: &[T]) {
1932        if self.capacity() == 0 {
1933            return;
1934        }
1935
1936        debug_assert!(self.inner.start < self.capacity(), "start out-of-bounds");
1937        debug_assert!(self.inner.size <= self.capacity(), "size out-of-bounds");
1938
1939        if other.len() < self.capacity() {
1940            // All the elements of `other` fit into the buffer
1941            let free_size = self.capacity() - self.inner.size;
1942            let final_size = if other.len() < free_size {
1943                // All the elements of `other` fit at the back of the buffer
1944                self.inner.size + other.len()
1945            } else {
1946                // Some of the elements of `other` need to overwrite the front of the buffer
1947                let truncate_to = self.capacity() - other.len();
1948                self.truncate_front(truncate_to);
1949                self.capacity()
1950            };
1951
1952            let (right, left) = self.slices_uninit_mut();
1953
1954            let write_len = core::cmp::min(right.len(), other.len());
1955            right[..write_len].write_clone_of_slice(&other[..write_len]);
1956
1957            let other = &other[write_len..];
1958            debug_assert!(left.len() >= other.len());
1959            let write_len = other.len();
1960            left[..write_len].write_clone_of_slice(other);
1961
1962            self.inner.size = final_size;
1963        } else {
1964            // `other` overwrites the whole buffer; get only the last `N` elements from `other` and
1965            // overwrite
1966            self.clear();
1967            self.inner.start = 0;
1968
1969            let other = &other[other.len() - self.capacity()..];
1970            debug_assert_eq!(self.inner.items.len(), other.len());
1971            self.inner.items.write_clone_of_slice(other);
1972
1973            self.inner.size = self.capacity();
1974        }
1975    }
1976
1977    /// Clones the elements of the buffer into a new [`Vec`], leaving the buffer unchanged.
1978    ///
1979    /// # Examples
1980    ///
1981    /// ```
1982    /// use circular_buffer::FixedCircularBuffer;
1983    ///
1984    /// let buf: FixedCircularBuffer<u32, 5> = FixedCircularBuffer::from([1, 2, 3]);
1985    /// let vec: Vec<u32> = buf.to_vec();
1986    ///
1987    /// assert_eq!(buf, [1, 2, 3]);
1988    /// assert_eq!(vec, [1, 2, 3]);
1989    /// ```
1990    #[must_use]
1991    #[cfg(feature = "alloc")]
1992    pub fn to_vec(&self) -> Vec<T> {
1993        let (front, back) = self.as_slices();
1994        let mut vec = Vec::with_capacity(self.len());
1995        vec.extend_from_slice(front);
1996        vec.extend_from_slice(back);
1997        debug_assert_eq!(vec.len(), self.len());
1998        vec
1999    }
2000}
2001
2002impl<T> Index<usize> for CircularBuffer<T> {
2003    type Output = T;
2004
2005    #[inline]
2006    fn index(&self, index: usize) -> &Self::Output {
2007        self.get(index).expect("index out-of-bounds")
2008    }
2009}
2010
2011impl<T> IndexMut<usize> for CircularBuffer<T> {
2012    #[inline]
2013    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
2014        self.get_mut(index).expect("index out-of-bounds")
2015    }
2016}
2017
2018impl<T> Extend<T> for CircularBuffer<T> {
2019    fn extend<I>(&mut self, iter: I)
2020    where
2021        I: IntoIterator<Item = T>,
2022    {
2023        // TODO Optimize
2024        iter.into_iter().for_each(|item| {
2025            self.push_back(item);
2026        });
2027    }
2028}
2029
2030impl<'a, T> Extend<&'a T> for CircularBuffer<T>
2031where
2032    T: Copy,
2033{
2034    fn extend<I>(&mut self, iter: I)
2035    where
2036        I: IntoIterator<Item = &'a T>,
2037    {
2038        // TODO Optimize
2039        iter.into_iter().for_each(|item| {
2040            self.push_back(*item);
2041        });
2042    }
2043}
2044
2045impl<'a, T> IntoIterator for &'a CircularBuffer<T> {
2046    type Item = &'a T;
2047    type IntoIter = Iter<'a, T>;
2048
2049    #[inline]
2050    fn into_iter(self) -> Self::IntoIter {
2051        Iter::new(self)
2052    }
2053}
2054
2055impl<'a, T> IntoIterator for &'a mut CircularBuffer<T> {
2056    type Item = &'a mut T;
2057    type IntoIter = IterMut<'a, T>;
2058
2059    #[inline]
2060    fn into_iter(self) -> Self::IntoIter {
2061        IterMut::new(self)
2062    }
2063}
2064
2065#[cfg(feature = "alloc")]
2066impl<T> ToOwned for CircularBuffer<T>
2067where
2068    T: Clone,
2069{
2070    type Owned = HeapCircularBuffer<T>;
2071
2072    fn to_owned(&self) -> Self::Owned {
2073        let (front, back) = self.as_slices();
2074        let mut buf = HeapCircularBuffer::<T>::with_capacity(self.capacity());
2075        buf.extend_from_slice(front);
2076        buf.extend_from_slice(back);
2077        buf
2078    }
2079}
2080
2081impl<T> Drop for CircularBuffer<T> {
2082    fn drop(&mut self) {
2083        // `clear()` will make sure that every element is dropped in a safe way
2084        self.clear();
2085    }
2086}
2087
2088#[cfg(feature = "alloc")]
2089impl<T> Clone for Box<CircularBuffer<T>>
2090where
2091    T: Clone,
2092{
2093    fn clone(&self) -> Box<CircularBuffer<T>> {
2094        let (front, back) = self.as_slices();
2095        let mut buf = HeapCircularBuffer::<T>::with_capacity(self.capacity());
2096        buf.extend_from_slice(front);
2097        buf.extend_from_slice(back);
2098        buf.into_boxed_circular_buffer()
2099    }
2100}