Skip to main content

circular_buffer/
lib.rs

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