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}