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