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