mirror of
https://github.com/rust-embedded/heapless.git
synced 2025-10-01 22:40:31 +00:00
Merge pull request #540 from pvdrz/keep-views-only
`SortedLinkedList`: Keep only the view versions of `Iter` and `FindMut`
This commit is contained in:
commit
da404c14fd
@ -79,6 +79,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
- `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::FindMut` and `sorted_linked_list::FindMutInner`.
|
||||||
|
|
||||||
## [v0.8.0] - 2023-11-07
|
## [v0.8.0] - 2023-11-07
|
||||||
|
|
||||||
|
@ -468,88 +468,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get an iterator over the sorted list.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use heapless::sorted_linked_list::{Max, SortedLinkedList};
|
|
||||||
/// let mut ll: SortedLinkedList<_, _, Max, 3> = SortedLinkedList::new_usize();
|
|
||||||
///
|
|
||||||
/// ll.push(1).unwrap();
|
|
||||||
/// ll.push(2).unwrap();
|
|
||||||
///
|
|
||||||
/// let mut iter = ll.iter();
|
|
||||||
///
|
|
||||||
/// assert_eq!(iter.next(), Some(&2));
|
|
||||||
/// assert_eq!(iter.next(), Some(&1));
|
|
||||||
/// assert_eq!(iter.next(), None);
|
|
||||||
/// ```
|
|
||||||
pub fn iter(&self) -> IterInner<'_, T, Idx, K, S> {
|
|
||||||
IterInner {
|
|
||||||
list: self,
|
|
||||||
index: self.head,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Find an element in the list that can be changed and resorted.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use heapless::sorted_linked_list::{Max, SortedLinkedList};
|
|
||||||
/// let mut ll: SortedLinkedList<_, _, Max, 3> = SortedLinkedList::new_usize();
|
|
||||||
///
|
|
||||||
/// ll.push(1).unwrap();
|
|
||||||
/// ll.push(2).unwrap();
|
|
||||||
/// ll.push(3).unwrap();
|
|
||||||
///
|
|
||||||
/// // Find a value and update it
|
|
||||||
/// let mut find = ll.find_mut(|v| *v == 2).unwrap();
|
|
||||||
/// *find += 1000;
|
|
||||||
/// find.finish();
|
|
||||||
///
|
|
||||||
/// assert_eq!(ll.pop(), Some(1002));
|
|
||||||
/// assert_eq!(ll.pop(), Some(3));
|
|
||||||
/// assert_eq!(ll.pop(), Some(1));
|
|
||||||
/// assert_eq!(ll.pop(), None);
|
|
||||||
/// ```
|
|
||||||
pub fn find_mut<F>(&mut self, mut f: F) -> Option<FindMutInner<'_, T, Idx, K, S>>
|
|
||||||
where
|
|
||||||
F: FnMut(&T) -> bool,
|
|
||||||
{
|
|
||||||
let head = self.head.option()?;
|
|
||||||
|
|
||||||
// Special-case, first element
|
|
||||||
if f(self.read_data_in_node_at(head)) {
|
|
||||||
return Some(FindMutInner {
|
|
||||||
is_head: true,
|
|
||||||
prev_index: Idx::none(),
|
|
||||||
index: self.head,
|
|
||||||
list: self,
|
|
||||||
maybe_changed: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut current = head;
|
|
||||||
|
|
||||||
while let Some(next) = self.node_at(current).next.option() {
|
|
||||||
if f(self.read_data_in_node_at(next)) {
|
|
||||||
return Some(FindMutInner {
|
|
||||||
is_head: false,
|
|
||||||
prev_index: unsafe { Idx::new_unchecked(current) },
|
|
||||||
index: unsafe { Idx::new_unchecked(next) },
|
|
||||||
list: self,
|
|
||||||
maybe_changed: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
current = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Peek at the first element.
|
/// Peek at the first element.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
@ -663,33 +581,112 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Base struct for [`Iter`] and [`IterView`], generic over the [`SortedLinkedListStorage`].
|
impl<T, Idx, K, S> SortedLinkedListInner<T, Idx, K, S>
|
||||||
///
|
|
||||||
/// In most cases you should use [`Iter`] or [`IterView`] directly. Only use this
|
|
||||||
/// struct if you want to write code that's generic over both.
|
|
||||||
pub struct IterInner<'a, T, Idx, K, S>
|
|
||||||
where
|
where
|
||||||
T: Ord,
|
T: Ord,
|
||||||
Idx: SortedLinkedListIndex,
|
Idx: SortedLinkedListIndex,
|
||||||
K: Kind,
|
K: Kind,
|
||||||
S: SortedLinkedListStorage<T, Idx> + ?Sized,
|
S: SortedLinkedListStorage<T, Idx> + ?Sized,
|
||||||
{
|
{
|
||||||
list: &'a SortedLinkedListInner<T, Idx, K, S>,
|
/// Get an iterator over the sorted list.
|
||||||
index: Idx,
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use heapless::sorted_linked_list::{Max, SortedLinkedList};
|
||||||
|
/// let mut ll: SortedLinkedList<_, _, Max, 3> = SortedLinkedList::new_usize();
|
||||||
|
///
|
||||||
|
/// ll.push(1).unwrap();
|
||||||
|
/// ll.push(2).unwrap();
|
||||||
|
///
|
||||||
|
/// let mut iter = ll.iter();
|
||||||
|
///
|
||||||
|
/// assert_eq!(iter.next(), Some(&2));
|
||||||
|
/// assert_eq!(iter.next(), Some(&1));
|
||||||
|
/// assert_eq!(iter.next(), None);
|
||||||
|
/// ```
|
||||||
|
pub fn iter(&self) -> IterView<'_, T, Idx, K> {
|
||||||
|
IterView {
|
||||||
|
list: S::as_view(self),
|
||||||
|
index: self.head,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Find an element in the list that can be changed and resorted.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use heapless::sorted_linked_list::{Max, SortedLinkedList};
|
||||||
|
/// let mut ll: SortedLinkedList<_, _, Max, 3> = SortedLinkedList::new_usize();
|
||||||
|
///
|
||||||
|
/// ll.push(1).unwrap();
|
||||||
|
/// ll.push(2).unwrap();
|
||||||
|
/// ll.push(3).unwrap();
|
||||||
|
///
|
||||||
|
/// // Find a value and update it
|
||||||
|
/// let mut find = ll.find_mut(|v| *v == 2).unwrap();
|
||||||
|
/// *find += 1000;
|
||||||
|
/// find.finish();
|
||||||
|
///
|
||||||
|
/// assert_eq!(ll.pop(), Some(1002));
|
||||||
|
/// assert_eq!(ll.pop(), Some(3));
|
||||||
|
/// assert_eq!(ll.pop(), Some(1));
|
||||||
|
/// assert_eq!(ll.pop(), None);
|
||||||
|
/// ```
|
||||||
|
pub fn find_mut<F>(&mut self, mut f: F) -> Option<FindMutView<'_, T, Idx, K>>
|
||||||
|
where
|
||||||
|
F: FnMut(&T) -> bool,
|
||||||
|
{
|
||||||
|
let head = self.head.option()?;
|
||||||
|
|
||||||
|
// Special-case, first element
|
||||||
|
if f(self.read_data_in_node_at(head)) {
|
||||||
|
return Some(FindMutView {
|
||||||
|
is_head: true,
|
||||||
|
prev_index: Idx::none(),
|
||||||
|
index: self.head,
|
||||||
|
list: S::as_mut_view(self),
|
||||||
|
maybe_changed: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut current = head;
|
||||||
|
|
||||||
|
while let Some(next) = self.node_at(current).next.option() {
|
||||||
|
if f(self.read_data_in_node_at(next)) {
|
||||||
|
return Some(FindMutView {
|
||||||
|
is_head: false,
|
||||||
|
prev_index: unsafe { Idx::new_unchecked(current) },
|
||||||
|
index: unsafe { Idx::new_unchecked(next) },
|
||||||
|
list: S::as_mut_view(self),
|
||||||
|
maybe_changed: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
current = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterator for the linked list.
|
/// Iterator for the linked list.
|
||||||
pub type Iter<'a, T, Idx, K, const N: usize> =
|
pub struct IterView<'a, T, Idx, K>
|
||||||
IterInner<'a, T, Idx, K, OwnedSortedLinkedListStorage<T, Idx, N>>;
|
where
|
||||||
/// Iterator for the linked list.
|
T: Ord,
|
||||||
pub type IterView<'a, T, Idx, K> = IterInner<'a, T, Idx, K, ViewSortedLinkedListStorage<T, Idx>>;
|
Idx: SortedLinkedListIndex,
|
||||||
|
K: Kind,
|
||||||
impl<'a, T, Idx, K, S> Iterator for IterInner<'a, T, Idx, K, S>
|
{
|
||||||
|
list: &'a SortedLinkedListInner<T, Idx, K, ViewSortedLinkedListStorage<T, Idx>>,
|
||||||
|
index: Idx,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T, Idx, K> Iterator for IterView<'a, T, Idx, K>
|
||||||
where
|
where
|
||||||
T: Ord,
|
T: Ord,
|
||||||
Idx: SortedLinkedListIndex,
|
Idx: SortedLinkedListIndex,
|
||||||
K: Kind,
|
K: Kind,
|
||||||
S: SortedLinkedListStorage<T, Idx> + ?Sized,
|
|
||||||
{
|
{
|
||||||
type Item = &'a T;
|
type Item = &'a T;
|
||||||
|
|
||||||
@ -703,37 +700,25 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Base struct for [`FindMut`] and [`FindMutView`], generic over the [`SortedLinkedListStorage`].
|
/// Comes from [`SortedLinkedList::find_mut`].
|
||||||
///
|
pub struct FindMutView<'a, T, Idx, K>
|
||||||
/// In most cases you should use [`FindMut`] or [`FindMutView`] directly. Only use this
|
|
||||||
/// struct if you want to write code that's generic over both.
|
|
||||||
pub struct FindMutInner<'a, T, Idx, K, S>
|
|
||||||
where
|
where
|
||||||
T: Ord,
|
T: Ord,
|
||||||
Idx: SortedLinkedListIndex,
|
Idx: SortedLinkedListIndex,
|
||||||
K: Kind,
|
K: Kind,
|
||||||
S: SortedLinkedListStorage<T, Idx> + ?Sized,
|
|
||||||
{
|
{
|
||||||
list: &'a mut SortedLinkedListInner<T, Idx, K, S>,
|
list: &'a mut SortedLinkedListView<T, Idx, K>,
|
||||||
is_head: bool,
|
is_head: bool,
|
||||||
prev_index: Idx,
|
prev_index: Idx,
|
||||||
index: Idx,
|
index: Idx,
|
||||||
maybe_changed: bool,
|
maybe_changed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Comes from [`SortedLinkedList::find_mut`].
|
impl<T, Idx, K> FindMutView<'_, T, Idx, K>
|
||||||
pub type FindMut<'a, T, Idx, K, const N: usize> =
|
|
||||||
FindMutInner<'a, T, Idx, K, OwnedSortedLinkedListStorage<T, Idx, N>>;
|
|
||||||
/// Comes from [`SortedLinkedList::find_mut`].
|
|
||||||
pub type FindMutView<'a, T, Idx, K, const N: usize> =
|
|
||||||
FindMutInner<'a, T, Idx, K, ViewSortedLinkedListStorage<T, Idx>>;
|
|
||||||
|
|
||||||
impl<T, Idx, K, S> FindMutInner<'_, T, Idx, K, S>
|
|
||||||
where
|
where
|
||||||
T: Ord,
|
T: Ord,
|
||||||
Idx: SortedLinkedListIndex,
|
Idx: SortedLinkedListIndex,
|
||||||
K: Kind,
|
K: Kind,
|
||||||
S: SortedLinkedListStorage<T, Idx> + ?Sized,
|
|
||||||
{
|
{
|
||||||
fn pop_internal(&mut self) -> T {
|
fn pop_internal(&mut self) -> T {
|
||||||
if self.is_head {
|
if self.is_head {
|
||||||
@ -817,12 +802,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Idx, K, S> Drop for FindMutInner<'_, T, Idx, K, S>
|
impl<T, Idx, K> Drop for FindMutView<'_, T, Idx, K>
|
||||||
where
|
where
|
||||||
T: Ord,
|
T: Ord,
|
||||||
Idx: SortedLinkedListIndex,
|
Idx: SortedLinkedListIndex,
|
||||||
K: Kind,
|
K: Kind,
|
||||||
S: SortedLinkedListStorage<T, Idx> + ?Sized,
|
|
||||||
{
|
{
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
// Only resort the list if the element has changed
|
// Only resort the list if the element has changed
|
||||||
@ -833,12 +817,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Idx, K, S> Deref for FindMutInner<'_, T, Idx, K, S>
|
impl<T, Idx, K> Deref for FindMutView<'_, T, Idx, K>
|
||||||
where
|
where
|
||||||
T: Ord,
|
T: Ord,
|
||||||
Idx: SortedLinkedListIndex,
|
Idx: SortedLinkedListIndex,
|
||||||
K: Kind,
|
K: Kind,
|
||||||
S: SortedLinkedListStorage<T, Idx> + ?Sized,
|
|
||||||
{
|
{
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
@ -848,12 +831,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Idx, K, S> DerefMut for FindMutInner<'_, T, Idx, K, S>
|
impl<T, Idx, K> DerefMut for FindMutView<'_, T, Idx, K>
|
||||||
where
|
where
|
||||||
T: Ord,
|
T: Ord,
|
||||||
Idx: SortedLinkedListIndex,
|
Idx: SortedLinkedListIndex,
|
||||||
K: Kind,
|
K: Kind,
|
||||||
S: SortedLinkedListStorage<T, Idx> + ?Sized,
|
|
||||||
{
|
{
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
self.maybe_changed = true;
|
self.maybe_changed = true;
|
||||||
@ -892,7 +874,7 @@ where
|
|||||||
T: Ord + core::fmt::Debug,
|
T: Ord + core::fmt::Debug,
|
||||||
Idx: SortedLinkedListIndex,
|
Idx: SortedLinkedListIndex,
|
||||||
K: Kind,
|
K: Kind,
|
||||||
S: SortedLinkedListStorage<T, Idx> + ?Sized,
|
S: ?Sized + SortedLinkedListStorage<T, Idx>,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_list().entries(self.iter()).finish()
|
f.debug_list().entries(self.iter()).finish()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user