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