diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e4ad61ada..645d403c42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -79,6 +79,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Removed - `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 diff --git a/src/sorted_linked_list.rs b/src/sorted_linked_list.rs index 60d2d3258b..093c52bbe8 100644 --- a/src/sorted_linked_list.rs +++ b/src/sorted_linked_list.rs @@ -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(&mut self, mut f: F) -> Option> - 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. /// /// # Example @@ -663,33 +581,112 @@ where } } -/// Base struct for [`Iter`] and [`IterView`], generic over the [`SortedLinkedListStorage`]. -/// -/// 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> +impl SortedLinkedListInner where T: Ord, Idx: SortedLinkedListIndex, K: Kind, S: SortedLinkedListStorage + ?Sized, { - list: &'a SortedLinkedListInner, - index: Idx, + /// 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) -> 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(&mut self, mut f: F) -> Option> + 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. -pub type Iter<'a, T, Idx, K, const N: usize> = - IterInner<'a, T, Idx, K, OwnedSortedLinkedListStorage>; -/// Iterator for the linked list. -pub type IterView<'a, T, Idx, K> = IterInner<'a, T, Idx, K, ViewSortedLinkedListStorage>; +pub struct IterView<'a, T, Idx, K> +where + T: Ord, + Idx: SortedLinkedListIndex, + K: Kind, +{ + list: &'a SortedLinkedListInner>, + index: Idx, +} -impl<'a, T, Idx, K, S> Iterator for IterInner<'a, T, Idx, K, S> +impl<'a, T, Idx, K> Iterator for IterView<'a, T, Idx, K> where T: Ord, Idx: SortedLinkedListIndex, K: Kind, - S: SortedLinkedListStorage + ?Sized, { type Item = &'a T; @@ -703,37 +700,25 @@ where } } -/// Base struct for [`FindMut`] and [`FindMutView`], generic over the [`SortedLinkedListStorage`]. -/// -/// 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> +/// Comes from [`SortedLinkedList::find_mut`]. +pub struct FindMutView<'a, T, Idx, K> where T: Ord, Idx: SortedLinkedListIndex, K: Kind, - S: SortedLinkedListStorage + ?Sized, { - list: &'a mut SortedLinkedListInner, + list: &'a mut SortedLinkedListView, is_head: bool, prev_index: Idx, index: Idx, maybe_changed: bool, } -/// Comes from [`SortedLinkedList::find_mut`]. -pub type FindMut<'a, T, Idx, K, const N: usize> = - FindMutInner<'a, T, Idx, K, OwnedSortedLinkedListStorage>; -/// Comes from [`SortedLinkedList::find_mut`]. -pub type FindMutView<'a, T, Idx, K, const N: usize> = - FindMutInner<'a, T, Idx, K, ViewSortedLinkedListStorage>; - -impl FindMutInner<'_, T, Idx, K, S> +impl FindMutView<'_, T, Idx, K> where T: Ord, Idx: SortedLinkedListIndex, K: Kind, - S: SortedLinkedListStorage + ?Sized, { fn pop_internal(&mut self) -> T { if self.is_head { @@ -817,12 +802,11 @@ where } } -impl Drop for FindMutInner<'_, T, Idx, K, S> +impl Drop for FindMutView<'_, T, Idx, K> where T: Ord, Idx: SortedLinkedListIndex, K: Kind, - S: SortedLinkedListStorage + ?Sized, { fn drop(&mut self) { // Only resort the list if the element has changed @@ -833,12 +817,11 @@ where } } -impl Deref for FindMutInner<'_, T, Idx, K, S> +impl Deref for FindMutView<'_, T, Idx, K> where T: Ord, Idx: SortedLinkedListIndex, K: Kind, - S: SortedLinkedListStorage + ?Sized, { type Target = T; @@ -848,12 +831,11 @@ where } } -impl DerefMut for FindMutInner<'_, T, Idx, K, S> +impl DerefMut for FindMutView<'_, T, Idx, K> where T: Ord, Idx: SortedLinkedListIndex, K: Kind, - S: SortedLinkedListStorage + ?Sized, { fn deref_mut(&mut self) -> &mut Self::Target { self.maybe_changed = true; @@ -892,7 +874,7 @@ where T: Ord + core::fmt::Debug, Idx: SortedLinkedListIndex, K: Kind, - S: SortedLinkedListStorage + ?Sized, + S: ?Sized + SortedLinkedListStorage, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.iter()).finish()