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