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