Merge pull request #547 from pvdrz/fix-names

Renaming Bonanza
This commit is contained in:
Markus Reiter 2025-04-14 21:10:25 +00:00 committed by GitHub
commit a326f1135e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 292 additions and 262 deletions

View File

@ -49,6 +49,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Added `get_index` and `get_index_mut` to `IndexMap`. - Added `get_index` and `get_index_mut` to `IndexMap`.
- Added `String::uDisplay`. - Added `String::uDisplay`.
- Added `LenT` generic to `Vec<T, N>` and `VecView<T>` to save memory when using a sane capacity value. - Added `LenT` generic to `Vec<T, N>` and `VecView<T>` to save memory when using a sane capacity value.
- Added the `index_set` module.
- Added the `index_map` module.
### Changed ### Changed
@ -60,6 +62,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- `Vec::extend_from_slice` - `Vec::extend_from_slice`
- `Vec::from_slice` - `Vec::from_slice`
- `Vec::resize_default` - `Vec::resize_default`
> * [ ] Remove `Q*` type aliases for `MpMcQueue`, and rename it to just `Queue`
- `Vec::resize` - `Vec::resize`
- Renamed `FromUtf16Error::DecodeUtf16Error` to `FromUtf16Error::DecodeUtf16`. - Renamed `FromUtf16Error::DecodeUtf16Error` to `FromUtf16Error::DecodeUtf16`.
- Changed `stable_deref_trait` to a platform-dependent dependency. - Changed `stable_deref_trait` to a platform-dependent dependency.
@ -67,6 +70,28 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- `Vec::capacity` is no longer a `const` function. - `Vec::capacity` is no longer a `const` function.
- Relaxed bounds on `PartialEq` for `IndexMap` from `V: Eq` to `V1: PartialEq<V2>`. - Relaxed bounds on `PartialEq` for `IndexMap` from `V: Eq` to `V1: PartialEq<V2>`.
- Relaxed bounds on `PartialEq` for `LinearMap` from `V: PartialEq` to `V1: PartialEq<V2>`. - Relaxed bounds on `PartialEq` for `LinearMap` from `V: PartialEq` to `V1: PartialEq<V2>`.
- The `FnvIndexSet` type is now inside the `index_set` module.
- The `IndexSetIter` type is now inside the `index_set` module and has been renamed to `Iter`.
- The `Bucket` type is now inside the `index_map` module.
- The `Entry` type is now inside the `index_map` module.
- The `FnvIndexMap` type is now inside the `index_map` module.
- The `IndexMapIter` type is now inside the `index_map` module and has been renamed to `Iter`.
- The `IndexMapIterMut` type is now inside the `index_map` module and has been renamed to `IterMut`.
- The `IndexMapKeys` type is now inside the `index_map` module and has been renamed to `Keys`.
- The `OccupiedEntry` type is now inside the `index_map` module.
- The `Pos` type is now inside the `index_map` module.
- The `VacantEntry` type is now inside the `index_map` module.
- The `VacantEntry` type is now inside the `index_map` module.
- The `IndexMapValues` type is now inside the `index_map` module and has been renamed to `Values`.
- The `IndexMapValuesMut` type is now inside the `index_map` module and has been renamed to `ValuesMut`.
- The `histbuf` module has been renamed to `history_buf`.
- The `HistoryBuffer` type has been renamed to `HistoryBuf`.
- The `HistoryBufferView` type has been renamed to `HistoryBufView`.
- The `OwnedHistBufStorage` type has been renamed to `OwnedHistoryBufStorage`.
- The `ViewHistBufStorage` type has been renamed to `ViewHistoryBufStorage`.
- The `MpMcQueue` type has been renamed to `Queue`.
- The `MpMcQueueView` type has been renamed to `QueueView`.
- The `MpMcQueueInner` type has been renamed to `QueueInner`.
### Fixed ### Fixed
@ -82,6 +107,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- `Vec::storage_capacity` has been removed and `Vec::capacity` must be used instead. - `Vec::storage_capacity` has been removed and `Vec::capacity` must be used instead.
- Removed `sorted_linked_list::Iter` and `sorted_linked_list::IterInner`. - Removed `sorted_linked_list::Iter` and `sorted_linked_list::IterInner`.
- Removed `sorted_linked_list::FindMut` and `sorted_linked_list::FindMutInner`. - Removed `sorted_linked_list::FindMut` and `sorted_linked_list::FindMutInner`.
- The `Q2`, `Q4`, `Q8`, `Q16`, `Q32` and `Q64` aliases for `MpMcQueue` have been removed.
## [v0.8.0] - 2023-11-07 ## [v0.8.0] - 2023-11-07

View File

@ -1,5 +1,5 @@
use crate::{ use crate::{
binary_heap::Kind as BinaryHeapKind, len_type::LenType, BinaryHeap, Deque, HistoryBuffer, binary_heap::Kind as BinaryHeapKind, len_type::LenType, BinaryHeap, Deque, HistoryBuf,
IndexMap, IndexSet, LinearMap, String, Vec, IndexMap, IndexSet, LinearMap, String, Vec,
}; };
use core::{ use core::{
@ -174,7 +174,7 @@ where
} }
} }
impl<'de, T, const N: usize> Deserialize<'de> for HistoryBuffer<T, N> impl<'de, T, const N: usize> Deserialize<'de> for HistoryBuf<T, N>
where where
T: Deserialize<'de>, T: Deserialize<'de>,
{ {
@ -188,7 +188,7 @@ where
where where
T: Deserialize<'de>, T: Deserialize<'de>,
{ {
type Value = HistoryBuffer<T, N>; type Value = HistoryBuf<T, N>;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a sequence") formatter.write_str("a sequence")
@ -198,7 +198,7 @@ where
where where
A: SeqAccess<'de>, A: SeqAccess<'de>,
{ {
let mut values = HistoryBuffer::new(); let mut values = HistoryBuf::new();
while let Some(value) = seq.next_element()? { while let Some(value) = seq.next_element()? {
values.write(value); values.write(value);

View File

@ -6,10 +6,10 @@
//! //!
//! # Examples //! # Examples
//! ``` //! ```
//! use heapless::HistoryBuffer; //! use heapless::HistoryBuf;
//! //!
//! // Initialize a new buffer with 8 elements. //! // Initialize a new buffer with 8 elements.
//! let mut buf = HistoryBuffer::<_, 8>::new(); //! let mut buf = HistoryBuf::<_, 8>::new();
//! //!
//! // Starts with no data //! // Starts with no data
//! assert_eq!(buf.recent(), None); //! assert_eq!(buf.recent(), None);
@ -41,115 +41,114 @@ use core::slice;
mod storage { mod storage {
use core::mem::MaybeUninit; use core::mem::MaybeUninit;
use super::{HistoryBufferInner, HistoryBufferView}; use super::{HistoryBufInner, HistoryBufView};
/// Trait defining how data for a container is stored. /// Trait defining how data for a container is stored.
/// ///
/// There's two implementations available: /// There's two implementations available:
/// ///
/// - [`OwnedHistBufStorage`]: stores the data in an array `[T; N]` whose size is known at compile time. /// - [`OwnedHistoryBufStorage`]: stores the data in an array `[T; N]` whose size is known at compile time.
/// - [`ViewHistBufStorage`]: stores the data in an unsized `[T]`. /// - [`ViewHistoryBufStorage`]: stores the data in an unsized `[T]`.
/// ///
/// This allows [`HistoryBuffer`] to be generic over either sized or unsized storage. The [`histbuf`] /// This allows [`HistoryBuf`] to be generic over either sized or unsized storage. The [`histbuf`]
/// module contains a [`HistoryBufferInner`] struct that's generic on [`HistBufStorage`], /// module contains a [`HistoryBufInner`] struct that's generic on [`HistoryBufStorage`],
/// and two type aliases for convenience: /// and two type aliases for convenience:
/// ///
/// - [`HistBuf<T, N>`](super::HistoryBuffer) = `HistoryBufferInner<T, OwnedHistBufStorage<T, N>>` /// - [`HistoryBuf<T, N>`](super::HistoryBuf) = `HistoryBufInner<T, OwnedHistoryBufStorage<T, N>>`
/// - [`HistBufView<T>`](super::HistoryBufferView) = `HistoryBufferInner<T, ViewHistBufStorage<T>>` /// - [`HistoryBufView<T>`](super::HistoryBufView) = `HistoryBufInner<T, ViewHistoryBufStorage<T>>`
/// ///
/// `HistoryBuffer` can be unsized into `HistoryBufferView`, either by unsizing coercions such as `&mut HistoryBuffer -> &mut HistoryBufferView` or /// `HistoryBuf` can be unsized into `HistoryBufView`, either by unsizing coercions such as `&mut HistoryBuf -> &mut HistoryBufView` or
/// `Box<HistoryBuffer> -> Box<HistoryBufferView>`, or explicitly with [`.as_view()`](super::HistoryBuffer::as_view) or [`.as_mut_view()`](super::HistoryBuffer::as_mut_view). /// `Box<HistoryBuf> -> Box<HistoryBufView>`, or explicitly with [`.as_view()`](super::HistoryBuf::as_view) or [`.as_mut_view()`](super::HistoryBuf::as_mut_view).
/// ///
/// This trait is sealed, so you cannot implement it for your own types. You can only use /// This trait is sealed, so you cannot implement it for your own types. You can only use
/// the implementations provided by this crate. /// the implementations provided by this crate.
/// ///
/// [`HistoryBufferInner`]: super::HistoryBufferInner /// [`HistoryBufInner`]: super::HistoryBufInner
/// [`HistoryBuffer`]: super::HistoryBuffer /// [`HistoryBuf`]: super::HistoryBuf
/// [`HistoryBufferView`]: super::HistoryBufferView /// [`HistoryBufView`]: super::HistoryBufView
/// [`histbuf`]: super /// [`histbuf`]: super
#[allow(private_bounds)] #[allow(private_bounds)]
pub trait HistBufStorage<T>: HistBufSealedStorage<T> {} pub trait HistoryBufStorage<T>: HistoryBufSealedStorage<T> {}
pub trait HistBufSealedStorage<T> { pub trait HistoryBufSealedStorage<T> {
// part of the sealed trait so that no trait is publicly implemented by `OwnedHistBufStorage` besides `Storage` // part of the sealed trait so that no trait is publicly implemented by `OwnedHistoryBufStorage` besides `Storage`
fn borrow(&self) -> &[MaybeUninit<T>]; fn borrow(&self) -> &[MaybeUninit<T>];
fn borrow_mut(&mut self) -> &mut [MaybeUninit<T>]; fn borrow_mut(&mut self) -> &mut [MaybeUninit<T>];
fn as_hist_buf_view(this: &HistoryBufferInner<T, Self>) -> &HistoryBufferView<T> fn as_hist_buf_view(this: &HistoryBufInner<T, Self>) -> &HistoryBufView<T>
where where
Self: HistBufStorage<T>; Self: HistoryBufStorage<T>;
fn as_hist_buf_mut_view( fn as_hist_buf_mut_view(this: &mut HistoryBufInner<T, Self>) -> &mut HistoryBufView<T>
this: &mut HistoryBufferInner<T, Self>,
) -> &mut HistoryBufferView<T>
where where
Self: HistBufStorage<T>; Self: HistoryBufStorage<T>;
} }
// One sealed layer of indirection to hide the internal details (The MaybeUninit). // One sealed layer of indirection to hide the internal details (The MaybeUninit).
pub struct HistBufStorageInner<T: ?Sized> { pub struct HistoryBufStorageInner<T: ?Sized> {
pub(crate) buffer: T, pub(crate) buffer: T,
} }
/// Implementation of [`HistBufStorage`] that stores the data in an array `[T; N]` whose size is known at compile time. /// Implementation of [`HistoryBufStorage`] that stores the data in an array `[T; N]` whose size is known at compile time.
pub type OwnedHistBufStorage<T, const N: usize> = HistBufStorageInner<[MaybeUninit<T>; N]>; pub type OwnedHistoryBufStorage<T, const N: usize> =
/// Implementation of [`HistBufStorage`] that stores the data in an unsized `[T]`. HistoryBufStorageInner<[MaybeUninit<T>; N]>;
pub type ViewHistBufStorage<T> = HistBufStorageInner<[MaybeUninit<T>]>; /// Implementation of [`HistoryBufStorage`] that stores the data in an unsized `[T]`.
pub type ViewHistoryBufStorage<T> = HistoryBufStorageInner<[MaybeUninit<T>]>;
impl<T, const N: usize> HistBufSealedStorage<T> for OwnedHistBufStorage<T, N> { impl<T, const N: usize> HistoryBufSealedStorage<T> for OwnedHistoryBufStorage<T, N> {
fn borrow(&self) -> &[MaybeUninit<T>] { fn borrow(&self) -> &[MaybeUninit<T>] {
&self.buffer &self.buffer
} }
fn borrow_mut(&mut self) -> &mut [MaybeUninit<T>] { fn borrow_mut(&mut self) -> &mut [MaybeUninit<T>] {
&mut self.buffer &mut self.buffer
} }
fn as_hist_buf_view(this: &HistoryBufferInner<T, Self>) -> &HistoryBufferView<T> fn as_hist_buf_view(this: &HistoryBufInner<T, Self>) -> &HistoryBufView<T>
where where
Self: HistBufStorage<T>, Self: HistoryBufStorage<T>,
{ {
this this
} }
fn as_hist_buf_mut_view(this: &mut HistoryBufferInner<T, Self>) -> &mut HistoryBufferView<T> fn as_hist_buf_mut_view(this: &mut HistoryBufInner<T, Self>) -> &mut HistoryBufView<T>
where where
Self: HistBufStorage<T>, Self: HistoryBufStorage<T>,
{ {
this this
} }
} }
impl<T, const N: usize> HistBufStorage<T> for OwnedHistBufStorage<T, N> {} impl<T, const N: usize> HistoryBufStorage<T> for OwnedHistoryBufStorage<T, N> {}
impl<T> HistBufSealedStorage<T> for ViewHistBufStorage<T> { impl<T> HistoryBufSealedStorage<T> for ViewHistoryBufStorage<T> {
fn borrow(&self) -> &[MaybeUninit<T>] { fn borrow(&self) -> &[MaybeUninit<T>] {
&self.buffer &self.buffer
} }
fn borrow_mut(&mut self) -> &mut [MaybeUninit<T>] { fn borrow_mut(&mut self) -> &mut [MaybeUninit<T>] {
&mut self.buffer &mut self.buffer
} }
fn as_hist_buf_view(this: &HistoryBufferInner<T, Self>) -> &HistoryBufferView<T> fn as_hist_buf_view(this: &HistoryBufInner<T, Self>) -> &HistoryBufView<T>
where where
Self: HistBufStorage<T>, Self: HistoryBufStorage<T>,
{ {
this this
} }
fn as_hist_buf_mut_view(this: &mut HistoryBufferInner<T, Self>) -> &mut HistoryBufferView<T> fn as_hist_buf_mut_view(this: &mut HistoryBufInner<T, Self>) -> &mut HistoryBufView<T>
where where
Self: HistBufStorage<T>, Self: HistoryBufStorage<T>,
{ {
this this
} }
} }
impl<T> HistBufStorage<T> for ViewHistBufStorage<T> {} impl<T> HistoryBufStorage<T> for ViewHistoryBufStorage<T> {}
} }
pub use storage::{HistBufStorage, OwnedHistBufStorage, ViewHistBufStorage}; pub use storage::{HistoryBufStorage, OwnedHistoryBufStorage, ViewHistoryBufStorage};
use storage::HistBufStorageInner; use storage::HistoryBufStorageInner;
use self::storage::HistBufSealedStorage; use self::storage::HistoryBufSealedStorage;
/// Base struct for [`HistoryBuffer`] and [`HistoryBufferView`], generic over the [`HistBufStorage`]. /// Base struct for [`HistoryBuf`] and [`HistoryBufView`], generic over the [`HistoryBufStorage`].
/// ///
/// In most cases you should use [`HistoryBuffer`] or [`HistoryBufferView`] directly. Only use this /// In most cases you should use [`HistoryBuf`] or [`HistoryBufView`] directly. Only use this
/// struct if you want to write code that's generic over both. /// struct if you want to write code that's generic over both.
pub struct HistoryBufferInner<T, S: HistBufStorage<T> + ?Sized> { pub struct HistoryBufInner<T, S: HistoryBufStorage<T> + ?Sized> {
// This phantomdata is required because otherwise rustc thinks that `T` is not used // This phantomdata is required because otherwise rustc thinks that `T` is not used
phantom: PhantomData<T>, phantom: PhantomData<T>,
write_at: usize, write_at: usize,
@ -165,10 +164,10 @@ pub struct HistoryBufferInner<T, S: HistBufStorage<T> + ?Sized> {
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use heapless::HistoryBuffer; /// use heapless::HistoryBuf;
/// ///
/// // Initialize a new buffer with 8 elements. /// // Initialize a new buffer with 8 elements.
/// let mut buf = HistoryBuffer::<_, 8>::new(); /// let mut buf = HistoryBuf::<_, 8>::new();
/// ///
/// // Starts with no data /// // Starts with no data
/// assert_eq!(buf.recent(), None); /// assert_eq!(buf.recent(), None);
@ -189,19 +188,19 @@ pub struct HistoryBufferInner<T, S: HistBufStorage<T> + ?Sized> {
/// let avg = buf.as_slice().iter().sum::<usize>() / buf.len(); /// let avg = buf.as_slice().iter().sum::<usize>() / buf.len();
/// assert_eq!(avg, 4); /// assert_eq!(avg, 4);
/// ``` /// ```
pub type HistoryBuffer<T, const N: usize> = HistoryBufferInner<T, OwnedHistBufStorage<T, N>>; pub type HistoryBuf<T, const N: usize> = HistoryBufInner<T, OwnedHistoryBufStorage<T, N>>;
/// A "view" into a [`HistoryBuffer`] /// A "view" into a [`HistoryBuf`]
/// ///
/// Unlike [`HistoryBuffer`], it doesn't have the `const N: usize` in its type signature. /// Unlike [`HistoryBuf`], it doesn't have the `const N: usize` in its type signature.
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use heapless::histbuf::{HistoryBuffer, HistoryBufferView}; /// use heapless::history_buf::{HistoryBuf, HistoryBufView};
/// ///
/// // Initialize a new buffer with 8 elements. /// // Initialize a new buffer with 8 elements.
/// let mut owned_buf = HistoryBuffer::<_, 8>::new(); /// let mut owned_buf = HistoryBuf::<_, 8>::new();
/// let buf: &mut HistoryBufferView<_> = &mut owned_buf; /// let buf: &mut HistoryBufView<_> = &mut owned_buf;
/// ///
/// // Starts with no data /// // Starts with no data
/// assert_eq!(buf.recent(), None); /// assert_eq!(buf.recent(), None);
@ -222,22 +221,22 @@ pub type HistoryBuffer<T, const N: usize> = HistoryBufferInner<T, OwnedHistBufSt
/// let avg = buf.as_slice().iter().sum::<usize>() / buf.len(); /// let avg = buf.as_slice().iter().sum::<usize>() / buf.len();
/// assert_eq!(avg, 4); /// assert_eq!(avg, 4);
/// ``` /// ```
pub type HistoryBufferView<T> = HistoryBufferInner<T, ViewHistBufStorage<T>>; pub type HistoryBufView<T> = HistoryBufInner<T, ViewHistoryBufStorage<T>>;
impl<T, const N: usize> HistoryBuffer<T, N> { impl<T, const N: usize> HistoryBuf<T, N> {
const INIT: MaybeUninit<T> = MaybeUninit::uninit(); const INIT: MaybeUninit<T> = MaybeUninit::uninit();
/// Constructs a new history buffer. /// Constructs a new history buffer.
/// ///
/// The construction of a `HistoryBuffer` works in `const` contexts. /// The construction of a `HistoryBuf` works in `const` contexts.
/// ///
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::HistoryBuffer; /// use heapless::HistoryBuf;
/// ///
/// // Allocate a 16-element buffer on the stack /// // Allocate a 16-element buffer on the stack
/// let x: HistoryBuffer<u8, 16> = HistoryBuffer::new(); /// let x: HistoryBuf<u8, 16> = HistoryBuf::new();
/// assert_eq!(x.len(), 0); /// assert_eq!(x.len(), 0);
/// ``` /// ```
#[inline] #[inline]
@ -248,7 +247,7 @@ impl<T, const N: usize> HistoryBuffer<T, N> {
Self { Self {
phantom: PhantomData, phantom: PhantomData,
data: HistBufStorageInner { data: HistoryBufStorageInner {
buffer: [Self::INIT; N], buffer: [Self::INIT; N],
}, },
write_at: 0, write_at: 0,
@ -257,7 +256,7 @@ impl<T, const N: usize> HistoryBuffer<T, N> {
} }
} }
impl<T, const N: usize> HistoryBuffer<T, N> impl<T, const N: usize> HistoryBuf<T, N>
where where
T: Copy + Clone, T: Copy + Clone,
{ {
@ -266,10 +265,10 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::HistoryBuffer; /// use heapless::HistoryBuf;
/// ///
/// // Allocate a 16-element buffer on the stack /// // Allocate a 16-element buffer on the stack
/// let mut x: HistoryBuffer<u8, 16> = HistoryBuffer::new_with(4); /// let mut x: HistoryBuf<u8, 16> = HistoryBuf::new_with(4);
/// // All elements are four /// // All elements are four
/// assert_eq!(x.as_slice(), [4; 16]); /// assert_eq!(x.as_slice(), [4; 16]);
/// ``` /// ```
@ -277,7 +276,7 @@ where
pub fn new_with(t: T) -> Self { pub fn new_with(t: T) -> Self {
Self { Self {
phantom: PhantomData, phantom: PhantomData,
data: HistBufStorageInner { data: HistoryBufStorageInner {
buffer: [MaybeUninit::new(t); N], buffer: [MaybeUninit::new(t); N],
}, },
write_at: 0, write_at: 0,
@ -285,18 +284,20 @@ where
} }
} }
} }
impl<T: Copy, S: HistBufStorage<T> + ?Sized> HistoryBufferInner<T, S> {
/// Get a reference to the `HistoryBuffer`, erasing the `N` const-generic. impl<T: Copy, S: HistoryBufStorage<T> + ?Sized> HistoryBufInner<T, S> {
/// Get a reference to the `HistoryBuf`, erasing the `N` const-generic.
#[inline] #[inline]
pub fn as_view(&self) -> &HistoryBufferView<T> { pub fn as_view(&self) -> &HistoryBufView<T> {
S::as_hist_buf_view(self) S::as_hist_buf_view(self)
} }
/// Get a mutable reference to the `HistoryBuffer`, erasing the `N` const-generic. /// Get a mutable reference to the `HistoryBuf`, erasing the `N` const-generic.
#[inline] #[inline]
pub fn as_mut_view(&mut self) -> &mut HistoryBufferView<T> { pub fn as_mut_view(&mut self) -> &mut HistoryBufView<T> {
S::as_hist_buf_mut_view(self) S::as_hist_buf_mut_view(self)
} }
/// Clears the buffer, replacing every element with the given value. /// Clears the buffer, replacing every element with the given value.
pub fn clear_with(&mut self, t: T) { pub fn clear_with(&mut self, t: T) {
// SAFETY: we reset the values just after // SAFETY: we reset the values just after
@ -310,7 +311,7 @@ impl<T: Copy, S: HistBufStorage<T> + ?Sized> HistoryBufferInner<T, S> {
} }
} }
impl<T, S: HistBufStorage<T> + ?Sized> HistoryBufferInner<T, S> { impl<T, S: HistoryBufStorage<T> + ?Sized> HistoryBufInner<T, S> {
/// Clears the buffer /// Clears the buffer
pub fn clear(&mut self) { pub fn clear(&mut self) {
// SAFETY: we reset the values just after // SAFETY: we reset the values just after
@ -320,7 +321,7 @@ impl<T, S: HistBufStorage<T> + ?Sized> HistoryBufferInner<T, S> {
} }
} }
impl<T, S: HistBufStorage<T> + ?Sized> HistoryBufferInner<T, S> { impl<T, S: HistoryBufStorage<T> + ?Sized> HistoryBufInner<T, S> {
unsafe fn drop_contents(&mut self) { unsafe fn drop_contents(&mut self) {
unsafe { unsafe {
ptr::drop_in_place(ptr::slice_from_raw_parts_mut( ptr::drop_in_place(ptr::slice_from_raw_parts_mut(
@ -345,9 +346,9 @@ impl<T, S: HistBufStorage<T> + ?Sized> HistoryBufferInner<T, S> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::HistoryBuffer; /// use heapless::HistoryBuf;
/// ///
/// let x: HistoryBuffer<u8, 16> = HistoryBuffer::new(); /// let x: HistoryBuf<u8, 16> = HistoryBuf::new();
/// assert!(x.is_empty()); /// assert!(x.is_empty());
/// ``` /// ```
#[inline] #[inline]
@ -401,9 +402,9 @@ impl<T, S: HistBufStorage<T> + ?Sized> HistoryBufferInner<T, S> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::HistoryBuffer; /// use heapless::HistoryBuf;
/// ///
/// let mut x: HistoryBuffer<u8, 16> = HistoryBuffer::new(); /// let mut x: HistoryBuf<u8, 16> = HistoryBuf::new();
/// x.write(4); /// x.write(4);
/// x.write(10); /// x.write(10);
/// assert_eq!(x.recent(), Some(&10)); /// assert_eq!(x.recent(), Some(&10));
@ -418,9 +419,9 @@ impl<T, S: HistBufStorage<T> + ?Sized> HistoryBufferInner<T, S> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::HistoryBuffer; /// use heapless::HistoryBuf;
/// ///
/// let mut x: HistoryBuffer<u8, 16> = HistoryBuffer::new(); /// let mut x: HistoryBuf<u8, 16> = HistoryBuf::new();
/// x.write(4); /// x.write(4);
/// x.write(10); /// x.write(10);
/// assert_eq!(x.recent_index(), Some(1)); /// assert_eq!(x.recent_index(), Some(1));
@ -442,9 +443,9 @@ impl<T, S: HistBufStorage<T> + ?Sized> HistoryBufferInner<T, S> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::HistoryBuffer; /// use heapless::HistoryBuf;
/// ///
/// let mut x: HistoryBuffer<u8, 16> = HistoryBuffer::new(); /// let mut x: HistoryBuf<u8, 16> = HistoryBuf::new();
/// x.write(4); /// x.write(4);
/// x.write(10); /// x.write(10);
/// assert_eq!(x.oldest(), Some(&4)); /// assert_eq!(x.oldest(), Some(&4));
@ -459,9 +460,9 @@ impl<T, S: HistBufStorage<T> + ?Sized> HistoryBufferInner<T, S> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::HistoryBuffer; /// use heapless::HistoryBuf;
/// ///
/// let mut x: HistoryBuffer<u8, 16> = HistoryBuffer::new(); /// let mut x: HistoryBuf<u8, 16> = HistoryBuf::new();
/// x.write(4); /// x.write(4);
/// x.write(10); /// x.write(10);
/// assert_eq!(x.oldest_index(), Some(0)); /// assert_eq!(x.oldest_index(), Some(0));
@ -487,9 +488,9 @@ impl<T, S: HistBufStorage<T> + ?Sized> HistoryBufferInner<T, S> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::HistoryBuffer; /// use heapless::HistoryBuf;
/// ///
/// let mut buffer: HistoryBuffer<u8, 6> = HistoryBuffer::new(); /// let mut buffer: HistoryBuf<u8, 6> = HistoryBuf::new();
/// buffer.extend([0, 0, 0]); /// buffer.extend([0, 0, 0]);
/// buffer.extend([1, 2, 3, 4, 5, 6]); /// buffer.extend([1, 2, 3, 4, 5, 6]);
/// assert_eq!(buffer.as_slices(), (&[1, 2, 3][..], &[4, 5, 6][..])); /// assert_eq!(buffer.as_slices(), (&[1, 2, 3][..], &[4, 5, 6][..]));
@ -510,9 +511,9 @@ impl<T, S: HistBufStorage<T> + ?Sized> HistoryBufferInner<T, S> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::HistoryBuffer; /// use heapless::HistoryBuf;
/// ///
/// let mut buffer: HistoryBuffer<u8, 6> = HistoryBuffer::new(); /// let mut buffer: HistoryBuf<u8, 6> = HistoryBuf::new();
/// buffer.extend([0, 0, 0, 1, 2, 3, 4, 5, 6]); /// buffer.extend([0, 0, 0, 1, 2, 3, 4, 5, 6]);
/// let expected = [1, 2, 3, 4, 5, 6]; /// let expected = [1, 2, 3, 4, 5, 6];
/// for (x, y) in buffer.oldest_ordered().zip(expected.iter()) { /// for (x, y) in buffer.oldest_ordered().zip(expected.iter()) {
@ -528,7 +529,7 @@ impl<T, S: HistBufStorage<T> + ?Sized> HistoryBufferInner<T, S> {
} }
} }
impl<T, S: HistBufStorage<T> + ?Sized> Extend<T> for HistoryBufferInner<T, S> { impl<T, S: HistoryBufStorage<T> + ?Sized> Extend<T> for HistoryBufInner<T, S> {
fn extend<I>(&mut self, iter: I) fn extend<I>(&mut self, iter: I)
where where
I: IntoIterator<Item = T>, I: IntoIterator<Item = T>,
@ -539,7 +540,7 @@ impl<T, S: HistBufStorage<T> + ?Sized> Extend<T> for HistoryBufferInner<T, S> {
} }
} }
impl<'a, T, S: HistBufStorage<T> + ?Sized> Extend<&'a T> for HistoryBufferInner<T, S> impl<'a, T, S: HistoryBufStorage<T> + ?Sized> Extend<&'a T> for HistoryBufInner<T, S>
where where
T: 'a + Clone, T: 'a + Clone,
{ {
@ -551,7 +552,7 @@ where
} }
} }
impl<T, const N: usize> Clone for HistoryBuffer<T, N> impl<T, const N: usize> Clone for HistoryBuf<T, N>
where where
T: Clone, T: Clone,
{ {
@ -566,13 +567,13 @@ where
} }
} }
impl<T, S: HistBufStorage<T> + ?Sized> Drop for HistoryBufferInner<T, S> { impl<T, S: HistoryBufStorage<T> + ?Sized> Drop for HistoryBufInner<T, S> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { self.drop_contents() } unsafe { self.drop_contents() }
} }
} }
impl<T, S: HistBufStorage<T> + ?Sized> Deref for HistoryBufferInner<T, S> { impl<T, S: HistoryBufStorage<T> + ?Sized> Deref for HistoryBufInner<T, S> {
type Target = [T]; type Target = [T];
fn deref(&self) -> &[T] { fn deref(&self) -> &[T] {
@ -580,14 +581,14 @@ impl<T, S: HistBufStorage<T> + ?Sized> Deref for HistoryBufferInner<T, S> {
} }
} }
impl<T, S: HistBufStorage<T> + ?Sized> AsRef<[T]> for HistoryBufferInner<T, S> { impl<T, S: HistoryBufStorage<T> + ?Sized> AsRef<[T]> for HistoryBufInner<T, S> {
#[inline] #[inline]
fn as_ref(&self) -> &[T] { fn as_ref(&self) -> &[T] {
self self
} }
} }
impl<T, S: HistBufStorage<T> + ?Sized> fmt::Debug for HistoryBufferInner<T, S> impl<T, S: HistoryBufStorage<T> + ?Sized> fmt::Debug for HistoryBufInner<T, S>
where where
T: fmt::Debug, T: fmt::Debug,
{ {
@ -596,13 +597,13 @@ where
} }
} }
impl<T, const N: usize> Default for HistoryBuffer<T, N> { impl<T, const N: usize> Default for HistoryBuf<T, N> {
fn default() -> Self { fn default() -> Self {
Self::new() Self::new()
} }
} }
impl<T, S: HistBufStorage<T> + ?Sized> PartialEq for HistoryBufferInner<T, S> impl<T, S: HistoryBufStorage<T> + ?Sized> PartialEq for HistoryBufInner<T, S>
where where
T: PartialEq, T: PartialEq,
{ {
@ -611,11 +612,11 @@ where
} }
} }
/// Base struct for [`OldestOrdered`] and [`OldestOrderedView`], generic over the [`HistBufStorage`]. /// Base struct for [`OldestOrdered`] and [`OldestOrderedView`], generic over the [`HistoryBufStorage`].
/// ///
/// In most cases you should use [`OldestOrdered`] or [`OldestOrderedView`] directly. Only use this /// In most cases you should use [`OldestOrdered`] or [`OldestOrderedView`] directly. Only use this
/// struct if you want to write code that's generic over both. /// struct if you want to write code that's generic over both.
pub struct OldestOrderedInner<'a, T, S: HistBufStorage<T> + ?Sized> { pub struct OldestOrderedInner<'a, T, S: HistoryBufStorage<T> + ?Sized> {
phantom: PhantomData<S>, phantom: PhantomData<S>,
inner: core::iter::Chain<core::slice::Iter<'a, T>, core::slice::Iter<'a, T>>, inner: core::iter::Chain<core::slice::Iter<'a, T>, core::slice::Iter<'a, T>>,
} }
@ -625,11 +626,11 @@ pub struct OldestOrderedInner<'a, T, S: HistBufStorage<T> + ?Sized> {
/// ///
/// This type exists for backwards compatibility. It is always better to convert it to an [`OldestOrderedView`] with [`into_view`](OldestOrdered::into_view) /// This type exists for backwards compatibility. It is always better to convert it to an [`OldestOrderedView`] with [`into_view`](OldestOrdered::into_view)
pub type OldestOrdered<'a, T, const N: usize> = pub type OldestOrdered<'a, T, const N: usize> =
OldestOrderedInner<'a, T, OwnedHistBufStorage<T, N>>; OldestOrderedInner<'a, T, OwnedHistoryBufStorage<T, N>>;
/// Double ended iterator on the underlying buffer ordered from the oldest data /// Double ended iterator on the underlying buffer ordered from the oldest data
/// to the newest /// to the newest
pub type OldestOrderedView<'a, T> = OldestOrderedInner<'a, T, ViewHistBufStorage<T>>; pub type OldestOrderedView<'a, T> = OldestOrderedInner<'a, T, ViewHistoryBufStorage<T>>;
impl<'a, T, const N: usize> OldestOrdered<'a, T, N> { impl<'a, T, const N: usize> OldestOrdered<'a, T, N> {
/// Remove the `N` const-generic parameter from the iterator /// Remove the `N` const-generic parameter from the iterator
@ -657,7 +658,7 @@ impl<'a, T> OldestOrderedView<'a, T> {
} }
} }
impl<T, S: HistBufStorage<T> + ?Sized> Clone for OldestOrderedInner<'_, T, S> { impl<T, S: HistoryBufStorage<T> + ?Sized> Clone for OldestOrderedInner<'_, T, S> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
phantom: PhantomData, phantom: PhantomData,
@ -666,7 +667,7 @@ impl<T, S: HistBufStorage<T> + ?Sized> Clone for OldestOrderedInner<'_, T, S> {
} }
} }
impl<'a, T, S: HistBufStorage<T> + ?Sized> Iterator for OldestOrderedInner<'a, T, S> { impl<'a, T, S: HistoryBufStorage<T> + ?Sized> Iterator for OldestOrderedInner<'a, T, S> {
type Item = &'a T; type Item = &'a T;
fn next(&mut self) -> Option<&'a T> { fn next(&mut self) -> Option<&'a T> {
@ -691,27 +692,27 @@ mod tests {
use static_assertions::assert_not_impl_any; use static_assertions::assert_not_impl_any;
use super::{HistoryBuffer, HistoryBufferView}; use super::{HistoryBuf, HistoryBufView};
// Ensure a `HistoryBuffer` containing `!Send` values stays `!Send` itself. // Ensure a `HistoryBuf` containing `!Send` values stays `!Send` itself.
assert_not_impl_any!(HistoryBuffer<*const (), 4>: Send); assert_not_impl_any!(HistoryBuf<*const (), 4>: Send);
#[test] #[test]
fn new() { fn new() {
let x: HistoryBuffer<u8, 4> = HistoryBuffer::new_with(1); let x: HistoryBuf<u8, 4> = HistoryBuf::new_with(1);
assert_eq!(x.len(), 4); assert_eq!(x.len(), 4);
assert_eq!(x.as_slice(), [1; 4]); assert_eq!(x.as_slice(), [1; 4]);
assert_eq!(*x, [1; 4]); assert_eq!(*x, [1; 4]);
assert!(x.is_full()); assert!(x.is_full());
let x: HistoryBuffer<u8, 4> = HistoryBuffer::new(); let x: HistoryBuf<u8, 4> = HistoryBuf::new();
assert_eq!(x.as_slice(), []); assert_eq!(x.as_slice(), []);
assert!(!x.is_full()); assert!(!x.is_full());
} }
#[test] #[test]
fn write() { fn write() {
let mut x: HistoryBuffer<u8, 4> = HistoryBuffer::new(); let mut x: HistoryBuf<u8, 4> = HistoryBuf::new();
x.write(1); x.write(1);
x.write(4); x.write(4);
assert_eq!(x.as_slice(), [1, 4]); assert_eq!(x.as_slice(), [1, 4]);
@ -727,18 +728,18 @@ mod tests {
#[test] #[test]
fn clear() { fn clear() {
let mut x: HistoryBuffer<u8, 4> = HistoryBuffer::new_with(1); let mut x: HistoryBuf<u8, 4> = HistoryBuf::new_with(1);
x.clear(); x.clear();
assert_eq!(x.as_slice(), []); assert_eq!(x.as_slice(), []);
let mut x: HistoryBuffer<u8, 4> = HistoryBuffer::new(); let mut x: HistoryBuf<u8, 4> = HistoryBuf::new();
x.clear_with(1); x.clear_with(1);
assert_eq!(x.as_slice(), [1; 4]); assert_eq!(x.as_slice(), [1; 4]);
} }
#[test] #[test]
fn clone() { fn clone() {
let mut x: HistoryBuffer<u8, 3> = HistoryBuffer::new(); let mut x: HistoryBuf<u8, 3> = HistoryBuf::new();
for i in 0..10 { for i in 0..10 {
assert_eq!(x.as_slice(), x.clone().as_slice()); assert_eq!(x.as_slice(), x.clone().as_slice());
x.write(i); x.write(i);
@ -756,7 +757,7 @@ mod tests {
} }
} }
let mut y: HistoryBuffer<InstrumentedClone, 2> = HistoryBuffer::new(); let mut y: HistoryBuf<InstrumentedClone, 2> = HistoryBuf::new();
let _ = y.clone(); let _ = y.clone();
assert_eq!(GLOBAL.load(Ordering::Relaxed), 0); assert_eq!(GLOBAL.load(Ordering::Relaxed), 0);
y.write(InstrumentedClone(0)); y.write(InstrumentedClone(0));
@ -779,7 +780,7 @@ mod tests {
#[test] #[test]
fn recent() { fn recent() {
let mut x: HistoryBuffer<u8, 4> = HistoryBuffer::new(); let mut x: HistoryBuf<u8, 4> = HistoryBuf::new();
assert_eq!(x.recent_index(), None); assert_eq!(x.recent_index(), None);
assert_eq!(x.recent(), None); assert_eq!(x.recent(), None);
@ -797,7 +798,7 @@ mod tests {
#[test] #[test]
fn oldest() { fn oldest() {
let mut x: HistoryBuffer<u8, 4> = HistoryBuffer::new(); let mut x: HistoryBuf<u8, 4> = HistoryBuf::new();
assert_eq!(x.oldest_index(), None); assert_eq!(x.oldest_index(), None);
assert_eq!(x.oldest(), None); assert_eq!(x.oldest(), None);
@ -815,7 +816,7 @@ mod tests {
#[test] #[test]
fn as_slice() { fn as_slice() {
let mut x: HistoryBuffer<u8, 4> = HistoryBuffer::new(); let mut x: HistoryBuf<u8, 4> = HistoryBuf::new();
assert_eq!(x.as_slice(), []); assert_eq!(x.as_slice(), []);
@ -827,7 +828,7 @@ mod tests {
/// Test whether `.as_slices()` behaves as expected. /// Test whether `.as_slices()` behaves as expected.
#[test] #[test]
fn as_slices() { fn as_slices() {
let mut buffer: HistoryBuffer<u8, 4> = HistoryBuffer::new(); let mut buffer: HistoryBuf<u8, 4> = HistoryBuf::new();
let mut extend_then_assert = |extend: &[u8], assert: (&[u8], &[u8])| { let mut extend_then_assert = |extend: &[u8], assert: (&[u8], &[u8])| {
buffer.extend(extend); buffer.extend(extend);
assert_eq!(buffer.as_slices(), assert); assert_eq!(buffer.as_slices(), assert);
@ -843,7 +844,7 @@ mod tests {
/// Test whether `.as_slices()` and `.oldest_ordered()` produce elements in the same order. /// Test whether `.as_slices()` and `.oldest_ordered()` produce elements in the same order.
#[test] #[test]
fn as_slices_equals_ordered() { fn as_slices_equals_ordered() {
let mut buffer: HistoryBuffer<u8, 6> = HistoryBuffer::new(); let mut buffer: HistoryBuf<u8, 6> = HistoryBuf::new();
for n in 0..20 { for n in 0..20 {
buffer.write(n); buffer.write(n);
@ -858,7 +859,7 @@ mod tests {
#[test] #[test]
fn ordered() { fn ordered() {
// test on an empty buffer // test on an empty buffer
let buffer: HistoryBuffer<u8, 6> = HistoryBuffer::new(); let buffer: HistoryBuf<u8, 6> = HistoryBuf::new();
let mut iter = buffer.oldest_ordered(); let mut iter = buffer.oldest_ordered();
assert_eq!(iter.next(), None); assert_eq!(iter.next(), None);
assert_eq!(iter.next(), None); assert_eq!(iter.next(), None);
@ -866,7 +867,7 @@ mod tests {
assert_eq!(iter.next_back(), None); assert_eq!(iter.next_back(), None);
// test on a un-filled buffer // test on a un-filled buffer
let mut buffer: HistoryBuffer<u8, 6> = HistoryBuffer::new(); let mut buffer: HistoryBuf<u8, 6> = HistoryBuf::new();
buffer.extend([1, 2, 3]); buffer.extend([1, 2, 3]);
assert_eq!(buffer.len(), 3); assert_eq!(buffer.len(), 3);
assert_eq_iter(buffer.oldest_ordered(), &[1, 2, 3]); assert_eq_iter(buffer.oldest_ordered(), &[1, 2, 3]);
@ -879,14 +880,14 @@ mod tests {
assert_eq!(iter.next(), None); assert_eq!(iter.next(), None);
// test on an exactly filled buffer // test on an exactly filled buffer
let mut buffer: HistoryBuffer<u8, 6> = HistoryBuffer::new(); let mut buffer: HistoryBuf<u8, 6> = HistoryBuf::new();
buffer.extend([1, 2, 3, 4, 5, 6]); buffer.extend([1, 2, 3, 4, 5, 6]);
assert_eq!(buffer.len(), 6); assert_eq!(buffer.len(), 6);
assert_eq_iter(buffer.oldest_ordered(), &[1, 2, 3, 4, 5, 6]); assert_eq_iter(buffer.oldest_ordered(), &[1, 2, 3, 4, 5, 6]);
assert_eq_iter(buffer.oldest_ordered().rev(), &[6, 5, 4, 3, 2, 1]); assert_eq_iter(buffer.oldest_ordered().rev(), &[6, 5, 4, 3, 2, 1]);
// test on a filled buffer // test on a filled buffer
let mut buffer: HistoryBuffer<u8, 6> = HistoryBuffer::new(); let mut buffer: HistoryBuf<u8, 6> = HistoryBuf::new();
buffer.extend([0, 0, 0, 1, 2, 3, 4, 5, 6]); buffer.extend([0, 0, 0, 1, 2, 3, 4, 5, 6]);
assert_eq!(buffer.len(), 6); assert_eq!(buffer.len(), 6);
assert_eq_iter(buffer.oldest_ordered(), &[1, 2, 3, 4, 5, 6]); assert_eq_iter(buffer.oldest_ordered(), &[1, 2, 3, 4, 5, 6]);
@ -895,7 +896,7 @@ mod tests {
// comprehensive test all cases // comprehensive test all cases
for n in 0..50 { for n in 0..50 {
const N: usize = 7; const N: usize = 7;
let mut buffer: HistoryBuffer<u8, N> = HistoryBuffer::new(); let mut buffer: HistoryBuf<u8, N> = HistoryBuf::new();
buffer.extend(0..n); buffer.extend(0..n);
assert_eq_iter( assert_eq_iter(
buffer.oldest_ordered().copied(), buffer.oldest_ordered().copied(),
@ -933,8 +934,8 @@ mod tests {
#[test] #[test]
fn partial_eq() { fn partial_eq() {
let mut x: HistoryBuffer<u8, 3> = HistoryBuffer::new(); let mut x: HistoryBuf<u8, 3> = HistoryBuf::new();
let mut y: HistoryBuffer<u8, 3> = HistoryBuffer::new(); let mut y: HistoryBuf<u8, 3> = HistoryBuf::new();
assert_eq!(x, y); assert_eq!(x, y);
x.write(1); x.write(1);
assert_ne!(x, y); assert_ne!(x, y);
@ -969,7 +970,7 @@ mod tests {
} }
} }
let mut x: HistoryBuffer<DropCheck, 3> = HistoryBuffer::new(); let mut x: HistoryBuf<DropCheck, 3> = HistoryBuf::new();
x.write(DropCheck {}); x.write(DropCheck {});
x.write(DropCheck {}); x.write(DropCheck {});
x.write(DropCheck {}); x.write(DropCheck {});
@ -979,12 +980,12 @@ mod tests {
assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3); assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3);
} }
fn _test_variance<'a: 'b, 'b>(x: HistoryBuffer<&'a (), 42>) -> HistoryBuffer<&'b (), 42> { fn _test_variance<'a: 'b, 'b>(x: HistoryBuf<&'a (), 42>) -> HistoryBuf<&'b (), 42> {
x x
} }
fn _test_variance_view<'a: 'b, 'b, 'c>( fn _test_variance_view<'a: 'b, 'b, 'c>(
x: &'c HistoryBufferView<&'a ()>, x: &'c HistoryBufView<&'a ()>,
) -> &'c HistoryBufferView<&'b ()> { ) -> &'c HistoryBufView<&'b ()> {
x x
} }
} }

View File

@ -1,3 +1,4 @@
//! A fixed-capacity hash table where the iteration order is independent of the hash of the keys.
use core::{ use core::{
borrow::Borrow, borrow::Borrow,
fmt, fmt,
@ -18,7 +19,7 @@ use crate::Vec;
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// // A hash map with a capacity of 16 key-value pairs allocated on the stack /// // A hash map with a capacity of 16 key-value pairs allocated on the stack
/// let mut book_reviews = FnvIndexMap::<_, _, 16>::new(); /// let mut book_reviews = FnvIndexMap::<_, _, 16>::new();
@ -396,7 +397,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// // A hash map with a capacity of 16 key-value pairs allocated on the stack /// // A hash map with a capacity of 16 key-value pairs allocated on the stack
/// let mut book_reviews = FnvIndexMap::<_, _, 16>::new(); /// let mut book_reviews = FnvIndexMap::<_, _, 16>::new();
@ -424,7 +425,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// // A hash map with a capacity of 16 key-value pairs allocated on the stack /// // A hash map with a capacity of 16 key-value pairs allocated on the stack
/// let mut book_reviews = FnvIndexMap::<_, _, 16>::new(); /// let mut book_reviews = FnvIndexMap::<_, _, 16>::new();
@ -457,7 +458,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// // A hash map with a capacity of 16 key-value pairs allocated on the stack /// // A hash map with a capacity of 16 key-value pairs allocated on the stack
/// let mut book_reviews = FnvIndexMap::<_, _, 16>::new(); /// let mut book_reviews = FnvIndexMap::<_, _, 16>::new();
@ -483,7 +484,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// // A hash map with a capacity of 16 key-value pairs allocated on the stack /// // A hash map with a capacity of 16 key-value pairs allocated on the stack
/// let mut book_reviews = FnvIndexMap::<&str, &str, 16>::new(); /// let mut book_reviews = FnvIndexMap::<&str, &str, 16>::new();
@ -507,7 +508,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// // A hash map with a capacity of 16 key-value pairs allocated on the stack /// // A hash map with a capacity of 16 key-value pairs allocated on the stack
/// let mut book_reviews = FnvIndexMap::<_, _, 16>::new(); /// let mut book_reviews = FnvIndexMap::<_, _, 16>::new();
@ -544,7 +545,7 @@ where
/// ///
/// ``` /// ```
/// # fn main() { /// # fn main() {
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// let mut book_reviews = FnvIndexMap::<&str, Option<&str>, 16>::new(); /// let mut book_reviews = FnvIndexMap::<&str, Option<&str>, 16>::new();
/// ///
@ -677,7 +678,7 @@ where
/// for this example. /// for this example.
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// // A hash map with a capacity of 16 key-value pairs allocated on the stack /// // A hash map with a capacity of 16 key-value pairs allocated on the stack
/// let mut book_reviews = FnvIndexMap::<_, _, 16>::new(); /// let mut book_reviews = FnvIndexMap::<_, _, 16>::new();
@ -750,7 +751,7 @@ impl<K, V, S, const N: usize> IndexMap<K, V, S, N> {
/// Return an iterator over the keys of the map, in insertion order /// Return an iterator over the keys of the map, in insertion order
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// let mut map = FnvIndexMap::<_, _, 16>::new(); /// let mut map = FnvIndexMap::<_, _, 16>::new();
/// map.insert("a", 1).unwrap(); /// map.insert("a", 1).unwrap();
@ -770,7 +771,7 @@ impl<K, V, S, const N: usize> IndexMap<K, V, S, N> {
/// Return an iterator over the values of the map, in insertion order /// Return an iterator over the values of the map, in insertion order
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// let mut map = FnvIndexMap::<_, _, 16>::new(); /// let mut map = FnvIndexMap::<_, _, 16>::new();
/// map.insert("a", 1).unwrap(); /// map.insert("a", 1).unwrap();
@ -790,7 +791,7 @@ impl<K, V, S, const N: usize> IndexMap<K, V, S, N> {
/// Return an iterator over mutable references to the the values of the map, in insertion order /// Return an iterator over mutable references to the the values of the map, in insertion order
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// let mut map = FnvIndexMap::<_, _, 16>::new(); /// let mut map = FnvIndexMap::<_, _, 16>::new();
/// map.insert("a", 1).unwrap(); /// map.insert("a", 1).unwrap();
@ -814,7 +815,7 @@ impl<K, V, S, const N: usize> IndexMap<K, V, S, N> {
/// Return an iterator over the key-value pairs of the map, in insertion order /// Return an iterator over the key-value pairs of the map, in insertion order
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// let mut map = FnvIndexMap::<_, _, 16>::new(); /// let mut map = FnvIndexMap::<_, _, 16>::new();
/// map.insert("a", 1).unwrap(); /// map.insert("a", 1).unwrap();
@ -834,7 +835,7 @@ impl<K, V, S, const N: usize> IndexMap<K, V, S, N> {
/// Return an iterator over the key-value pairs of the map, in insertion order /// Return an iterator over the key-value pairs of the map, in insertion order
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// let mut map = FnvIndexMap::<_, _, 16>::new(); /// let mut map = FnvIndexMap::<_, _, 16>::new();
/// map.insert("a", 1).unwrap(); /// map.insert("a", 1).unwrap();
@ -900,7 +901,7 @@ impl<K, V, S, const N: usize> IndexMap<K, V, S, N> {
/// Computes in *O*(1) time. /// Computes in *O*(1) time.
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// let mut a = FnvIndexMap::<_, _, 16>::new(); /// let mut a = FnvIndexMap::<_, _, 16>::new();
/// assert_eq!(a.len(), 0); /// assert_eq!(a.len(), 0);
@ -916,7 +917,7 @@ impl<K, V, S, const N: usize> IndexMap<K, V, S, N> {
/// Computes in *O*(1) time. /// Computes in *O*(1) time.
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// let mut a = FnvIndexMap::<_, _, 16>::new(); /// let mut a = FnvIndexMap::<_, _, 16>::new();
/// assert!(a.is_empty()); /// assert!(a.is_empty());
@ -932,7 +933,7 @@ impl<K, V, S, const N: usize> IndexMap<K, V, S, N> {
/// Computes in *O*(1) time. /// Computes in *O*(1) time.
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// let mut a = FnvIndexMap::<_, _, 4>::new(); /// let mut a = FnvIndexMap::<_, _, 4>::new();
/// assert!(!a.is_full()); /// assert!(!a.is_full());
@ -951,7 +952,7 @@ impl<K, V, S, const N: usize> IndexMap<K, V, S, N> {
/// Computes in *O*(n) time. /// Computes in *O*(n) time.
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// let mut a = FnvIndexMap::<_, _, 16>::new(); /// let mut a = FnvIndexMap::<_, _, 16>::new();
/// a.insert(1, "a"); /// a.insert(1, "a");
@ -974,8 +975,8 @@ where
/* Public API */ /* Public API */
/// Returns an entry for the corresponding key /// Returns an entry for the corresponding key
/// ``` /// ```
/// use heapless::Entry; /// use heapless::index_map::Entry;
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// let mut map = FnvIndexMap::<_, _, 16>::new(); /// let mut map = FnvIndexMap::<_, _, 16>::new();
/// if let Entry::Vacant(v) = map.entry("a") { /// if let Entry::Vacant(v) = map.entry("a") {
/// v.insert(1).unwrap(); /// v.insert(1).unwrap();
@ -1013,7 +1014,7 @@ where
/// Computes in *O*(1) time (average). /// Computes in *O*(1) time (average).
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// let mut map = FnvIndexMap::<_, _, 16>::new(); /// let mut map = FnvIndexMap::<_, _, 16>::new();
/// map.insert(1, "a").unwrap(); /// map.insert(1, "a").unwrap();
@ -1039,7 +1040,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// let mut map = FnvIndexMap::<_, _, 8>::new(); /// let mut map = FnvIndexMap::<_, _, 8>::new();
/// map.insert(1, "a").unwrap(); /// map.insert(1, "a").unwrap();
@ -1064,7 +1065,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// let mut map = FnvIndexMap::<_, _, 8>::new(); /// let mut map = FnvIndexMap::<_, _, 8>::new();
/// map.insert(1, "a").unwrap(); /// map.insert(1, "a").unwrap();
@ -1092,7 +1093,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// let mut map = FnvIndexMap::<_, _, 16>::new(); /// let mut map = FnvIndexMap::<_, _, 16>::new();
/// map.insert(1, "a").unwrap(); /// map.insert(1, "a").unwrap();
@ -1113,7 +1114,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// let mut map = FnvIndexMap::<_, _, 8>::new(); /// let mut map = FnvIndexMap::<_, _, 8>::new();
/// map.insert(1, "a").unwrap(); /// map.insert(1, "a").unwrap();
@ -1139,7 +1140,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// let mut map = FnvIndexMap::<_, _, 8>::new(); /// let mut map = FnvIndexMap::<_, _, 8>::new();
/// map.insert(1, "a").unwrap(); /// map.insert(1, "a").unwrap();
@ -1173,7 +1174,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// let mut map = FnvIndexMap::<_, _, 8>::new(); /// let mut map = FnvIndexMap::<_, _, 8>::new();
/// assert_eq!(map.insert(37, "a"), Ok(None)); /// assert_eq!(map.insert(37, "a"), Ok(None));
@ -1198,7 +1199,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// let mut map = FnvIndexMap::<_, _, 8>::new(); /// let mut map = FnvIndexMap::<_, _, 8>::new();
/// map.insert(1, "a").unwrap(); /// map.insert(1, "a").unwrap();
@ -1249,7 +1250,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexMap; /// use heapless::index_map::FnvIndexMap;
/// ///
/// let mut map = FnvIndexMap::<_, _, 8>::new(); /// let mut map = FnvIndexMap::<_, _, 8>::new();
/// map.insert(3, "a").unwrap(); /// map.insert(3, "a").unwrap();
@ -1415,6 +1416,23 @@ where
} }
} }
/// An owning iterator over the entries of an `IndexMap`.
///
/// This `struct` is created by the [`into_iter`] method on [`IndexMap`]
/// (provided by the [`IntoIterator`] trait). See its documentation for more.
///
/// [`into_iter`]: IntoIterator::into_iter
///
/// # Example
///
/// ```
/// use heapless::index_map::FnvIndexMap;
///
/// let mut map = FnvIndexMap::<_, _, 16>::new();
/// map.insert("a", 1).unwrap();
///
/// let iter = map.into_iter();
/// ```
#[derive(Clone)] #[derive(Clone)]
pub struct IntoIter<K, V, const N: usize> { pub struct IntoIter<K, V, const N: usize> {
entries: Vec<Bucket<K, V>, N, usize>, entries: Vec<Bucket<K, V>, N, usize>,

View File

@ -1,3 +1,4 @@
//! A fixed-capacity hash set where the iteration order is independent of the hash values.
use core::{ use core::{
borrow::Borrow, borrow::Borrow,
fmt, fmt,
@ -6,7 +7,7 @@ use core::{
use hash32::{BuildHasherDefault, FnvHasher}; use hash32::{BuildHasherDefault, FnvHasher};
use crate::indexmap::{self, IndexMap}; use crate::index_map::{self, IndexMap};
/// An [`IndexSet`] using the default FNV hasher. /// An [`IndexSet`] using the default FNV hasher.
/// ///
@ -15,7 +16,7 @@ use crate::indexmap::{self, IndexMap};
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use heapless::FnvIndexSet; /// use heapless::index_set::FnvIndexSet;
/// ///
/// // A hash set with a capacity of 16 elements allocated on the stack /// // A hash set with a capacity of 16 elements allocated on the stack
/// let mut books = FnvIndexSet::<_, 16>::new(); /// let mut books = FnvIndexSet::<_, 16>::new();
@ -57,7 +58,7 @@ pub type FnvIndexSet<T, const N: usize> = IndexSet<T, BuildHasherDefault<FnvHash
/// for this example. /// for this example.
/// ///
/// ``` /// ```
/// use heapless::FnvIndexSet; /// use heapless::index_set::FnvIndexSet;
/// ///
/// // A hash set with a capacity of 16 elements allocated on the stack /// // A hash set with a capacity of 16 elements allocated on the stack
/// let mut books = FnvIndexSet::<_, 16>::new(); /// let mut books = FnvIndexSet::<_, 16>::new();
@ -103,7 +104,7 @@ impl<T, S, const N: usize> IndexSet<T, S, N> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexSet; /// use heapless::index_set::FnvIndexSet;
/// ///
/// let set = FnvIndexSet::<i32, 16>::new(); /// let set = FnvIndexSet::<i32, 16>::new();
/// assert_eq!(set.capacity(), 16); /// assert_eq!(set.capacity(), 16);
@ -117,7 +118,7 @@ impl<T, S, const N: usize> IndexSet<T, S, N> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexSet; /// use heapless::index_set::FnvIndexSet;
/// ///
/// let mut set = FnvIndexSet::<_, 16>::new(); /// let mut set = FnvIndexSet::<_, 16>::new();
/// set.insert("a").unwrap(); /// set.insert("a").unwrap();
@ -153,7 +154,7 @@ impl<T, S, const N: usize> IndexSet<T, S, N> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexSet; /// use heapless::index_set::FnvIndexSet;
/// ///
/// let mut v: FnvIndexSet<_, 16> = FnvIndexSet::new(); /// let mut v: FnvIndexSet<_, 16> = FnvIndexSet::new();
/// assert_eq!(v.len(), 0); /// assert_eq!(v.len(), 0);
@ -169,7 +170,7 @@ impl<T, S, const N: usize> IndexSet<T, S, N> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexSet; /// use heapless::index_set::FnvIndexSet;
/// ///
/// let mut v: FnvIndexSet<_, 16> = FnvIndexSet::new(); /// let mut v: FnvIndexSet<_, 16> = FnvIndexSet::new();
/// assert!(v.is_empty()); /// assert!(v.is_empty());
@ -185,7 +186,7 @@ impl<T, S, const N: usize> IndexSet<T, S, N> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexSet; /// use heapless::index_set::FnvIndexSet;
/// ///
/// let mut v: FnvIndexSet<_, 4> = FnvIndexSet::new(); /// let mut v: FnvIndexSet<_, 4> = FnvIndexSet::new();
/// assert!(!v.is_full()); /// assert!(!v.is_full());
@ -204,7 +205,7 @@ impl<T, S, const N: usize> IndexSet<T, S, N> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexSet; /// use heapless::index_set::FnvIndexSet;
/// ///
/// let mut v: FnvIndexSet<_, 16> = FnvIndexSet::new(); /// let mut v: FnvIndexSet<_, 16> = FnvIndexSet::new();
/// v.insert(1).unwrap(); /// v.insert(1).unwrap();
@ -227,7 +228,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexSet; /// use heapless::index_set::FnvIndexSet;
/// ///
/// let mut a: FnvIndexSet<_, 16> = [1, 2, 3].iter().cloned().collect(); /// let mut a: FnvIndexSet<_, 16> = [1, 2, 3].iter().cloned().collect();
/// let mut b: FnvIndexSet<_, 16> = [4, 2, 3, 4].iter().cloned().collect(); /// let mut b: FnvIndexSet<_, 16> = [4, 2, 3, 4].iter().cloned().collect();
@ -264,7 +265,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexSet; /// use heapless::index_set::FnvIndexSet;
/// ///
/// let mut a: FnvIndexSet<_, 16> = [1, 2, 3].iter().cloned().collect(); /// let mut a: FnvIndexSet<_, 16> = [1, 2, 3].iter().cloned().collect();
/// let mut b: FnvIndexSet<_, 16> = [4, 2, 3, 4].iter().cloned().collect(); /// let mut b: FnvIndexSet<_, 16> = [4, 2, 3, 4].iter().cloned().collect();
@ -296,7 +297,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexSet; /// use heapless::index_set::FnvIndexSet;
/// ///
/// let mut a: FnvIndexSet<_, 16> = [1, 2, 3].iter().cloned().collect(); /// let mut a: FnvIndexSet<_, 16> = [1, 2, 3].iter().cloned().collect();
/// let mut b: FnvIndexSet<_, 16> = [4, 2, 3, 4].iter().cloned().collect(); /// let mut b: FnvIndexSet<_, 16> = [4, 2, 3, 4].iter().cloned().collect();
@ -328,7 +329,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexSet; /// use heapless::index_set::FnvIndexSet;
/// ///
/// let mut a: FnvIndexSet<_, 16> = [1, 2, 3].iter().cloned().collect(); /// let mut a: FnvIndexSet<_, 16> = [1, 2, 3].iter().cloned().collect();
/// let mut b: FnvIndexSet<_, 16> = [4, 2, 3, 4].iter().cloned().collect(); /// let mut b: FnvIndexSet<_, 16> = [4, 2, 3, 4].iter().cloned().collect();
@ -359,7 +360,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexSet; /// use heapless::index_set::FnvIndexSet;
/// ///
/// let set: FnvIndexSet<_, 16> = [1, 2, 3].iter().cloned().collect(); /// let set: FnvIndexSet<_, 16> = [1, 2, 3].iter().cloned().collect();
/// assert_eq!(set.contains(&1), true); /// assert_eq!(set.contains(&1), true);
@ -379,7 +380,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexSet; /// use heapless::index_set::FnvIndexSet;
/// ///
/// let a: FnvIndexSet<_, 16> = [1, 2, 3].iter().cloned().collect(); /// let a: FnvIndexSet<_, 16> = [1, 2, 3].iter().cloned().collect();
/// let mut b = FnvIndexSet::<_, 16>::new(); /// let mut b = FnvIndexSet::<_, 16>::new();
@ -403,7 +404,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexSet; /// use heapless::index_set::FnvIndexSet;
/// ///
/// let sup: FnvIndexSet<_, 16> = [1, 2, 3].iter().cloned().collect(); /// let sup: FnvIndexSet<_, 16> = [1, 2, 3].iter().cloned().collect();
/// let mut set = FnvIndexSet::<_, 16>::new(); /// let mut set = FnvIndexSet::<_, 16>::new();
@ -427,7 +428,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexSet; /// use heapless::index_set::FnvIndexSet;
/// ///
/// let sub: FnvIndexSet<_, 16> = [1, 2].iter().cloned().collect(); /// let sub: FnvIndexSet<_, 16> = [1, 2].iter().cloned().collect();
/// let mut set = FnvIndexSet::<_, 16>::new(); /// let mut set = FnvIndexSet::<_, 16>::new();
@ -457,7 +458,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexSet; /// use heapless::index_set::FnvIndexSet;
/// ///
/// let mut set = FnvIndexSet::<_, 16>::new(); /// let mut set = FnvIndexSet::<_, 16>::new();
/// ///
@ -480,7 +481,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use heapless::FnvIndexSet; /// use heapless::index_set::FnvIndexSet;
/// ///
/// let mut set = FnvIndexSet::<_, 16>::new(); /// let mut set = FnvIndexSet::<_, 16>::new();
/// ///
@ -610,7 +611,7 @@ where
/// This `struct` is created by the [`iter`](IndexSet::iter) method on [`IndexSet`]. See its /// This `struct` is created by the [`iter`](IndexSet::iter) method on [`IndexSet`]. See its
/// documentation for more. /// documentation for more.
pub struct Iter<'a, T> { pub struct Iter<'a, T> {
iter: indexmap::Iter<'a, T, ()>, iter: index_map::Iter<'a, T, ()>,
} }
impl<'a, T> Iterator for Iter<'a, T> { impl<'a, T> Iterator for Iter<'a, T> {
@ -629,6 +630,9 @@ impl<T> Clone for Iter<'_, T> {
} }
} }
/// An iterator over the difference of two `IndexSet`s.
///
/// This is created by the [`IndexSet::difference`] method.
pub struct Difference<'a, T, S, const N: usize> pub struct Difference<'a, T, S, const N: usize>
where where
S: BuildHasher, S: BuildHasher,
@ -655,6 +659,9 @@ where
} }
} }
/// An iterator over the intersection of two `IndexSet`s.
///
/// This is created by the [`IndexSet::intersection`] method.
pub struct Intersection<'a, T, S, const N: usize> pub struct Intersection<'a, T, S, const N: usize>
where where
S: BuildHasher, S: BuildHasher,

View File

@ -113,7 +113,7 @@
)] )]
//! - [`BinaryHeap`] -- priority queue //! - [`BinaryHeap`] -- priority queue
//! - [Deque] -- double-ended queue //! - [Deque] -- double-ended queue
//! - [`HistoryBuffer`] -- similar to a write-only ring buffer //! - [`HistoryBuf`] -- similar to a write-only ring buffer
//! - [`IndexMap`] -- hash table //! - [`IndexMap`] -- hash table
//! - [`IndexSet`] -- hash set //! - [`IndexSet`] -- hash set
//! - [`LinearMap`] //! - [`LinearMap`]
@ -158,13 +158,9 @@ extern crate alloc;
pub use binary_heap::BinaryHeap; pub use binary_heap::BinaryHeap;
pub use deque::Deque; pub use deque::Deque;
pub use histbuf::{HistoryBuffer, OldestOrdered}; pub use history_buf::{HistoryBuf, OldestOrdered};
pub use indexmap::{ pub use index_map::IndexMap;
Bucket, Entry, FnvIndexMap, IndexMap, Iter as IndexMapIter, IterMut as IndexMapIterMut, pub use index_set::IndexSet;
Keys as IndexMapKeys, OccupiedEntry, Pos, VacantEntry, Values as IndexMapValues,
ValuesMut as IndexMapValuesMut,
};
pub use indexset::{FnvIndexSet, IndexSet, Iter as IndexSetIter};
pub use len_type::LenType; pub use len_type::LenType;
pub use linear_map::LinearMap; pub use linear_map::LinearMap;
pub use string::String; pub use string::String;
@ -176,9 +172,9 @@ pub use vec::{Vec, VecView};
mod test_helpers; mod test_helpers;
pub mod deque; pub mod deque;
pub mod histbuf; pub mod history_buf;
mod indexmap; pub mod index_map;
mod indexset; pub mod index_set;
mod len_type; mod len_type;
pub mod linear_map; pub mod linear_map;
mod slice; mod slice;

View File

@ -17,9 +17,9 @@
//! use cortex_m::{asm, peripheral::syst::SystClkSource}; //! use cortex_m::{asm, peripheral::syst::SystClkSource};
//! use cortex_m_rt::{entry, exception}; //! use cortex_m_rt::{entry, exception};
//! use cortex_m_semihosting::hprintln; //! use cortex_m_semihosting::hprintln;
//! use heapless::mpmc::Q2; //! use heapless::mpmc::Queue::<_, 2>;
//! //!
//! static Q: Q2<u8> = Q2::new(); //! static Q: Queue::<_, 2><u8> = Q2::new();
//! //!
//! #[entry] //! #[entry]
//! fn main() -> ! { //! fn main() -> ! {
@ -112,29 +112,11 @@ type IntSize = isize;
#[cfg(not(feature = "mpmc_large"))] #[cfg(not(feature = "mpmc_large"))]
type IntSize = i8; type IntSize = i8;
/// MPMC queue with a capability for 2 elements. /// Base struct for [`Queue`] and [`QueueView`], generic over the [`Storage`].
pub type Q2<T> = MpMcQueue<T, 2>;
/// MPMC queue with a capability for 4 elements.
pub type Q4<T> = MpMcQueue<T, 4>;
/// MPMC queue with a capability for 8 elements.
pub type Q8<T> = MpMcQueue<T, 8>;
/// MPMC queue with a capability for 16 elements.
pub type Q16<T> = MpMcQueue<T, 16>;
/// MPMC queue with a capability for 32 elements.
pub type Q32<T> = MpMcQueue<T, 32>;
/// MPMC queue with a capability for 64 elements.
pub type Q64<T> = MpMcQueue<T, 64>;
/// Base struct for [`MpMcQueue`] and [`MpMcQueueView`], generic over the [`Storage`].
/// ///
/// In most cases you should use [`MpMcQueue`] or [`MpMcQueueView`] directly. Only use this /// In most cases you should use [`Queue`] or [`QueueView`] directly. Only use this
/// struct if you want to write code that's generic over both. /// struct if you want to write code that's generic over both.
pub struct MpMcQueueInner<T, S: Storage> { pub struct QueueInner<T, S: Storage> {
dequeue_pos: AtomicTargetSize, dequeue_pos: AtomicTargetSize,
enqueue_pos: AtomicTargetSize, enqueue_pos: AtomicTargetSize,
buffer: UnsafeCell<S::Buffer<Cell<T>>>, buffer: UnsafeCell<S::Buffer<Cell<T>>>,
@ -143,14 +125,14 @@ pub struct MpMcQueueInner<T, S: Storage> {
/// MPMC queue with a capacity for N elements /// MPMC queue with a capacity for N elements
/// N must be a power of 2 /// N must be a power of 2
/// The max value of N is `u8::MAX` - 1 if `mpmc_large` feature is not enabled. /// The max value of N is `u8::MAX` - 1 if `mpmc_large` feature is not enabled.
pub type MpMcQueue<T, const N: usize> = MpMcQueueInner<T, OwnedStorage<N>>; pub type Queue<T, const N: usize> = QueueInner<T, OwnedStorage<N>>;
/// MPMC queue with a capacity for N elements /// MPMC queue with a capacity for N elements
/// N must be a power of 2 /// N must be a power of 2
/// The max value of N is `u8::MAX` - 1 if `mpmc_large` feature is not enabled. /// The max value of N is `u8::MAX` - 1 if `mpmc_large` feature is not enabled.
pub type MpMcQueueView<T> = MpMcQueueInner<T, ViewStorage>; pub type QueueView<T> = QueueInner<T, ViewStorage>;
impl<T, const N: usize> MpMcQueue<T, N> { impl<T, const N: usize> Queue<T, N> {
/// Creates an empty queue /// Creates an empty queue
pub const fn new() -> Self { pub const fn new() -> Self {
const { const {
@ -175,54 +157,54 @@ impl<T, const N: usize> MpMcQueue<T, N> {
} }
/// Used in `Storage` implementation /// Used in `Storage` implementation
pub(crate) fn as_view_private(&self) -> &MpMcQueueView<T> { pub(crate) fn as_view_private(&self) -> &QueueView<T> {
self self
} }
/// Used in `Storage` implementation /// Used in `Storage` implementation
pub(crate) fn as_view_mut_private(&mut self) -> &mut MpMcQueueView<T> { pub(crate) fn as_view_mut_private(&mut self) -> &mut QueueView<T> {
self self
} }
} }
impl<T, S: Storage> MpMcQueueInner<T, S> { impl<T, S: Storage> QueueInner<T, S> {
/// Get a reference to the `MpMcQueue`, erasing the `N` const-generic. /// Get a reference to the `Queue`, erasing the `N` const-generic.
/// ///
/// ///
/// ```rust /// ```rust
/// # use heapless::mpmc::{MpMcQueue, MpMcQueueView}; /// # use heapless::mpmc::{Queue, QueueView};
/// let queue: MpMcQueue<u8, 2> = MpMcQueue::new(); /// let queue: Queue<u8, 2> = Queue::new();
/// let view: &MpMcQueueView<u8> = queue.as_view(); /// let view: &QueueView<u8> = queue.as_view();
/// ``` /// ```
/// ///
/// It is often preferable to do the same through type coerction, since `MpMcQueue<T, N>` implements `Unsize<MpMcQueueView<T>>`: /// It is often preferable to do the same through type coerction, since `Queue<T, N>` implements `Unsize<QueueView<T>>`:
/// ///
/// ```rust /// ```rust
/// # use heapless::mpmc::{MpMcQueue, MpMcQueueView}; /// # use heapless::mpmc::{Queue, QueueView};
/// let queue: MpMcQueue<u8, 2> = MpMcQueue::new(); /// let queue: Queue<u8, 2> = Queue::new();
/// let view: &MpMcQueueView<u8> = &queue; /// let view: &QueueView<u8> = &queue;
/// ``` /// ```
#[inline] #[inline]
pub fn as_view(&self) -> &MpMcQueueView<T> { pub fn as_view(&self) -> &QueueView<T> {
S::as_mpmc_view(self) S::as_mpmc_view(self)
} }
/// Get a mutable reference to the `MpMcQueue`, erasing the `N` const-generic. /// Get a mutable reference to the `Queue`, erasing the `N` const-generic.
/// ///
/// ```rust /// ```rust
/// # use heapless::mpmc::{MpMcQueue, MpMcQueueView}; /// # use heapless::mpmc::{Queue, QueueView};
/// let mut queue: MpMcQueue<u8, 2> = MpMcQueue::new(); /// let mut queue: Queue<u8, 2> = Queue::new();
/// let view: &mut MpMcQueueView<u8> = queue.as_mut_view(); /// let view: &mut QueueView<u8> = queue.as_mut_view();
/// ``` /// ```
/// ///
/// It is often preferable to do the same through type coerction, since `MpMcQueue<T, N>` implements `Unsize<MpMcQueueView<T>>`: /// It is often preferable to do the same through type coerction, since `Queue<T, N>` implements `Unsize<QueueView<T>>`:
/// ///
/// ```rust /// ```rust
/// # use heapless::mpmc::{MpMcQueue, MpMcQueueView}; /// # use heapless::mpmc::{Queue, QueueView};
/// let mut queue: MpMcQueue<u8, 2> = MpMcQueue::new(); /// let mut queue: Queue<u8, 2> = Queue::new();
/// let view: &mut MpMcQueueView<u8> = &mut queue; /// let view: &mut QueueView<u8> = &mut queue;
/// ``` /// ```
#[inline] #[inline]
pub fn as_mut_view(&mut self) -> &mut MpMcQueueView<T> { pub fn as_mut_view(&mut self) -> &mut QueueView<T> {
S::as_mpmc_mut_view(self) S::as_mpmc_mut_view(self)
} }
@ -250,20 +232,20 @@ impl<T, S: Storage> MpMcQueueInner<T, S> {
} }
} }
impl<T, const N: usize> Default for MpMcQueue<T, N> { impl<T, const N: usize> Default for Queue<T, N> {
fn default() -> Self { fn default() -> Self {
Self::new() Self::new()
} }
} }
impl<T, S: Storage> Drop for MpMcQueueInner<T, S> { impl<T, S: Storage> Drop for QueueInner<T, S> {
fn drop(&mut self) { fn drop(&mut self) {
// drop all contents currently in the queue // drop all contents currently in the queue
while self.dequeue().is_some() {} while self.dequeue().is_some() {}
} }
} }
unsafe impl<T, S: Storage> Sync for MpMcQueueInner<T, S> where T: Send {} unsafe impl<T, S: Storage> Sync for QueueInner<T, S> where T: Send {}
struct Cell<T> { struct Cell<T> {
data: MaybeUninit<T>, data: MaybeUninit<T>,
@ -370,16 +352,16 @@ unsafe fn enqueue<T>(
mod tests { mod tests {
use static_assertions::assert_not_impl_any; use static_assertions::assert_not_impl_any;
use super::{MpMcQueue, Q2}; use super::Queue;
// Ensure a `MpMcQueue` containing `!Send` values stays `!Send` itself. // Ensure a `Queue` containing `!Send` values stays `!Send` itself.
assert_not_impl_any!(MpMcQueue<*const (), 4>: Send); assert_not_impl_any!(Queue<*const (), 4>: Send);
#[test] #[test]
fn memory_leak() { fn memory_leak() {
droppable!(); droppable!();
let q = Q2::new(); let q = Queue::<_, 2>::new();
q.enqueue(Droppable::new()).unwrap_or_else(|_| panic!()); q.enqueue(Droppable::new()).unwrap_or_else(|_| panic!());
q.enqueue(Droppable::new()).unwrap_or_else(|_| panic!()); q.enqueue(Droppable::new()).unwrap_or_else(|_| panic!());
drop(q); drop(q);
@ -389,7 +371,7 @@ mod tests {
#[test] #[test]
fn sanity() { fn sanity() {
let q = Q2::new(); let q = Queue::<_, 2>::new();
q.enqueue(0).unwrap(); q.enqueue(0).unwrap();
q.enqueue(1).unwrap(); q.enqueue(1).unwrap();
assert!(q.enqueue(2).is_err()); assert!(q.enqueue(2).is_err());
@ -401,7 +383,7 @@ mod tests {
#[test] #[test]
fn drain_at_pos255() { fn drain_at_pos255() {
let q = Q2::new(); let q = Queue::<_, 2>::new();
for _ in 0..255 { for _ in 0..255 {
assert!(q.enqueue(0).is_ok()); assert!(q.enqueue(0).is_ok());
assert_eq!(q.dequeue(), Some(0)); assert_eq!(q.dequeue(), Some(0));
@ -413,7 +395,7 @@ mod tests {
#[test] #[test]
fn full_at_wrapped_pos0() { fn full_at_wrapped_pos0() {
let q = Q2::new(); let q = Queue::<_, 2>::new();
for _ in 0..254 { for _ in 0..254 {
assert!(q.enqueue(0).is_ok()); assert!(q.enqueue(0).is_ok());
assert_eq!(q.dequeue(), Some(0)); assert_eq!(q.dequeue(), Some(0));
@ -432,7 +414,7 @@ mod tests {
#[cfg(feature = "mpmc_large")] #[cfg(feature = "mpmc_large")]
const CAPACITY: usize = 256; const CAPACITY: usize = 256;
let q: MpMcQueue<u8, CAPACITY> = MpMcQueue::new(); let q: Queue<u8, CAPACITY> = Queue::new();
for _ in 0..CAPACITY { for _ in 0..CAPACITY {
q.enqueue(0xAA).unwrap(); q.enqueue(0xAA).unwrap();

View File

@ -3,7 +3,7 @@ use core::hash::{BuildHasher, Hash};
use crate::{ use crate::{
binary_heap::{BinaryHeapInner, Kind as BinaryHeapKind}, binary_heap::{BinaryHeapInner, Kind as BinaryHeapKind},
deque::DequeInner, deque::DequeInner,
histbuf::{HistBufStorage, HistoryBufferInner}, history_buf::{HistoryBufInner, HistoryBufStorage},
len_type::LenType, len_type::LenType,
linear_map::{LinearMapInner, LinearMapStorage}, linear_map::{LinearMapInner, LinearMapStorage},
string::{StringInner, StringStorage}, string::{StringInner, StringStorage},
@ -81,7 +81,7 @@ where
} }
} }
impl<T, S: HistBufStorage<T> + ?Sized> Serialize for HistoryBufferInner<T, S> impl<T, S: HistoryBufStorage<T> + ?Sized> Serialize for HistoryBufInner<T, S>
where where
T: Serialize, T: Serialize,
{ {

View File

@ -14,7 +14,7 @@ use crate::spsc;
all(feature = "mpmc_large", target_has_atomic = "ptr"), all(feature = "mpmc_large", target_has_atomic = "ptr"),
all(not(feature = "mpmc_large"), target_has_atomic = "8") all(not(feature = "mpmc_large"), target_has_atomic = "8")
))] ))]
use crate::mpmc::{MpMcQueue, MpMcQueueInner, MpMcQueueView}; use crate::mpmc;
pub(crate) trait SealedStorage { pub(crate) trait SealedStorage {
type Buffer<T>: ?Sized + Borrow<[T]> + BorrowMut<[T]>; type Buffer<T>: ?Sized + Borrow<[T]> + BorrowMut<[T]>;
@ -30,7 +30,7 @@ pub(crate) trait SealedStorage {
all(feature = "mpmc_large", target_has_atomic = "ptr"), all(feature = "mpmc_large", target_has_atomic = "ptr"),
all(not(feature = "mpmc_large"), target_has_atomic = "8") all(not(feature = "mpmc_large"), target_has_atomic = "8")
))] ))]
fn as_mpmc_view<T>(this: &MpMcQueueInner<T, Self>) -> &MpMcQueueView<T> fn as_mpmc_view<T>(this: &mpmc::QueueInner<T, Self>) -> &mpmc::QueueView<T>
where where
Self: Storage + Sized; Self: Storage + Sized;
#[cfg(any( #[cfg(any(
@ -38,7 +38,7 @@ pub(crate) trait SealedStorage {
all(feature = "mpmc_large", target_has_atomic = "ptr"), all(feature = "mpmc_large", target_has_atomic = "ptr"),
all(not(feature = "mpmc_large"), target_has_atomic = "8") all(not(feature = "mpmc_large"), target_has_atomic = "8")
))] ))]
fn as_mpmc_mut_view<T>(this: &mut MpMcQueueInner<T, Self>) -> &mut MpMcQueueView<T> fn as_mpmc_mut_view<T>(this: &mut mpmc::QueueInner<T, Self>) -> &mut mpmc::QueueView<T>
where where
Self: Storage + Sized; Self: Storage + Sized;
@ -100,7 +100,7 @@ impl<const N: usize> SealedStorage for OwnedStorage<N> {
all(feature = "mpmc_large", target_has_atomic = "ptr"), all(feature = "mpmc_large", target_has_atomic = "ptr"),
all(not(feature = "mpmc_large"), target_has_atomic = "8") all(not(feature = "mpmc_large"), target_has_atomic = "8")
))] ))]
fn as_mpmc_view<T>(this: &MpMcQueue<T, N>) -> &MpMcQueueView<T> fn as_mpmc_view<T>(this: &mpmc::Queue<T, N>) -> &mpmc::QueueView<T>
where where
Self: Storage + Sized, Self: Storage + Sized,
{ {
@ -112,7 +112,7 @@ impl<const N: usize> SealedStorage for OwnedStorage<N> {
all(feature = "mpmc_large", target_has_atomic = "ptr"), all(feature = "mpmc_large", target_has_atomic = "ptr"),
all(not(feature = "mpmc_large"), target_has_atomic = "8") all(not(feature = "mpmc_large"), target_has_atomic = "8")
))] ))]
fn as_mpmc_mut_view<T>(this: &mut MpMcQueue<T, N>) -> &mut MpMcQueueView<T> fn as_mpmc_mut_view<T>(this: &mut mpmc::Queue<T, N>) -> &mut mpmc::QueueView<T>
where where
Self: Storage + Sized, Self: Storage + Sized,
{ {
@ -165,7 +165,7 @@ impl SealedStorage for ViewStorage {
all(feature = "mpmc_large", target_has_atomic = "ptr"), all(feature = "mpmc_large", target_has_atomic = "ptr"),
all(not(feature = "mpmc_large"), target_has_atomic = "8") all(not(feature = "mpmc_large"), target_has_atomic = "8")
))] ))]
fn as_mpmc_view<T>(this: &MpMcQueueInner<T, Self>) -> &MpMcQueueView<T> fn as_mpmc_view<T>(this: &mpmc::QueueInner<T, Self>) -> &mpmc::QueueView<T>
where where
Self: Storage + Sized, Self: Storage + Sized,
{ {
@ -177,7 +177,7 @@ impl SealedStorage for ViewStorage {
all(feature = "mpmc_large", target_has_atomic = "ptr"), all(feature = "mpmc_large", target_has_atomic = "ptr"),
all(not(feature = "mpmc_large"), target_has_atomic = "8") all(not(feature = "mpmc_large"), target_has_atomic = "8")
))] ))]
fn as_mpmc_mut_view<T>(this: &mut MpMcQueueInner<T, Self>) -> &mut MpMcQueueView<T> fn as_mpmc_mut_view<T>(this: &mut mpmc::QueueInner<T, Self>) -> &mut mpmc::QueueView<T>
where where
Self: Storage + Sized, Self: Storage + Sized,
{ {

View File

@ -1,9 +1,9 @@
//! Collections of `Send`-able things are `Send` //! Collections of `Send`-able things are `Send`
use heapless::{ use heapless::{
histbuf::HistoryBufferView, history_buf::HistoryBufView,
spsc::{Consumer, ConsumerView, Producer, ProducerView, Queue, QueueView}, spsc::{Consumer, ConsumerView, Producer, ProducerView, Queue, QueueView},
HistoryBuffer, Vec, VecView, HistoryBuf, Vec, VecView,
}; };
#[test] #[test]
@ -26,6 +26,6 @@ fn send() {
is_send::<QueueView<IsSend>>(); is_send::<QueueView<IsSend>>();
is_send::<Vec<IsSend, 4>>(); is_send::<Vec<IsSend, 4>>();
is_send::<VecView<IsSend>>(); is_send::<VecView<IsSend>>();
is_send::<HistoryBuffer<IsSend, 4>>(); is_send::<HistoryBuf<IsSend, 4>>();
is_send::<HistoryBufferView<IsSend>>(); is_send::<HistoryBufView<IsSend>>();
} }

View File

@ -119,11 +119,11 @@ fn contention() {
fn mpmc_contention() { fn mpmc_contention() {
use std::sync::mpsc; use std::sync::mpsc;
use heapless::mpmc::Q64; use heapless::mpmc::Queue;
const N: u32 = 64; const N: u32 = 64;
static Q: Q64<u32> = Q64::new(); static Q: Queue<u32, 64> = Queue::new();
let (s, r) = mpsc::channel(); let (s, r) = mpsc::channel();
thread::scope(|scope| { thread::scope(|scope| {