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