heapless/
sorted_linked_list.rs

1//! A fixed sorted priority linked list, similar to [`BinaryHeap`] but with different properties
2//! on `push`, `pop`, etc.
3//!
4//! For example, the sorting of the list will never `memcpy` the underlying value, so having large
5//! objects in the list will not cause a performance hit.
6//!
7//! # Examples
8//!
9//! ```
10//! use heapless::sorted_linked_list::{Max, SortedLinkedList};
11//! let mut ll: SortedLinkedList<_, Max, 3, u8> = SortedLinkedList::new_u8();
12//!
13//! // The largest value will always be first
14//! ll.push(1).unwrap();
15//! assert_eq!(ll.peek(), Some(&1));
16//!
17//! ll.push(2).unwrap();
18//! assert_eq!(ll.peek(), Some(&2));
19//!
20//! ll.push(3).unwrap();
21//! assert_eq!(ll.peek(), Some(&3));
22//!
23//! // This will not fit in the queue.
24//! assert_eq!(ll.push(4), Err(4));
25//! ```
26//!
27//! [`BinaryHeap`]: `crate::binary_heap::BinaryHeap`
28
29use core::{
30    cmp::Ordering,
31    fmt,
32    marker::PhantomData,
33    mem::MaybeUninit,
34    ops::{Deref, DerefMut},
35    ptr,
36};
37
38#[cfg(feature = "zeroize")]
39use zeroize::Zeroize;
40
41mod storage {
42    use super::{LenType, Node, SortedLinkedListInner, SortedLinkedListView};
43
44    /// Trait defining how data for a container is stored.
45    ///
46    /// There's two implementations available:
47    ///
48    /// - [`OwnedSortedLinkedListStorage`]: stores the data in an array `[T; N]` whose size is known
49    ///   at compile time.
50    /// - [`ViewSortedLinkedListStorage`]: stores the data in an unsized `[T]`.
51    ///
52    /// This allows [`SortedLinkedList`] to be generic over either sized or unsized storage. The
53    /// [`sorted_linked_list`](super) module contains a [`SortedLinkedListInner`] struct that's
54    /// generic on [`SortedLinkedListStorage`], and two type aliases for convenience:
55    ///
56    /// - [`SortedLinkedList<T, Idx, N>`](super::SortedLinkedList) = `SortedLinkedListInner<T,
57    ///   OwnedSortedLinkedListStorage<T, Idx, N>>`
58    /// - [`SortedLinkedListView<T, Idx>`](super::SortedLinkedListView) = `SortedLinkedListInner<T,
59    ///   ViewSortedLinkedListStorage<T, Idx>>`
60    ///
61    /// `SortedLinkedList` can be unsized into `SortedLinkedListView`, either by unsizing coercions
62    /// such as `&mut SortedLinkedList -> &mut SortedLinkedListView` or `Box<SortedLinkedList>
63    /// -> Box<SortedLinkedListView>`, or explicitly with
64    /// [`.as_view()`](super::SortedLinkedList::as_view) or
65    /// [`.as_mut_view()`](super::SortedLinkedList::as_mut_view).
66    ///
67    /// This trait is sealed, so you cannot implement it for your own types. You can only use
68    /// the implementations provided by this crate.
69    ///
70    /// [`SortedLinkedListInner`]: super::SortedLinkedListInner
71    /// [`SortedLinkedList`]: super::SortedLinkedList
72    /// [`SortedLinkedListView`]: super::SortedLinkedListView
73    #[allow(private_bounds)]
74    pub trait SortedLinkedListStorage<T, Idx>: SortedLinkedListSealedStorage<T, Idx> {}
75
76    pub trait SortedLinkedListSealedStorage<T, Idx> {
77        // part of the sealed trait so that no trait is publicly implemented by
78        // `OwnedSortedLinkedListStorage` besides `Storage`
79        fn borrow(&self) -> &[Node<T, Idx>];
80        fn borrow_mut(&mut self) -> &mut [Node<T, Idx>];
81        fn as_view<K>(
82            this: &SortedLinkedListInner<T, Idx, K, Self>,
83        ) -> &SortedLinkedListView<T, K, Idx>
84        where
85            Idx: LenType,
86            Self: SortedLinkedListStorage<T, Idx>;
87        fn as_mut_view<K>(
88            this: &mut SortedLinkedListInner<T, Idx, K, Self>,
89        ) -> &mut SortedLinkedListView<T, K, Idx>
90        where
91            Idx: LenType,
92            Self: SortedLinkedListStorage<T, Idx>;
93    }
94
95    // One sealed layer of indirection to hide the internal details (The MaybeUninit).
96    pub struct SortedLinkedListStorageInner<T: ?Sized> {
97        pub(crate) buffer: T,
98    }
99
100    /// Implementation of [`SortedLinkedListStorage`] that stores the data in an array `[T; N]`
101    /// whose size is known at compile time.
102    pub type OwnedSortedLinkedListStorage<T, Idx, const N: usize> =
103        SortedLinkedListStorageInner<[Node<T, Idx>; N]>;
104    /// Implementation of [`SortedLinkedListStorage`] that stores the data in an unsized `[T]`.
105    pub type ViewSortedLinkedListStorage<T, Idx> = SortedLinkedListStorageInner<[Node<T, Idx>]>;
106
107    impl<T, Idx, const N: usize> SortedLinkedListSealedStorage<T, Idx>
108        for OwnedSortedLinkedListStorage<T, Idx, N>
109    {
110        fn borrow(&self) -> &[Node<T, Idx>] {
111            &self.buffer
112        }
113        fn borrow_mut(&mut self) -> &mut [Node<T, Idx>] {
114            &mut self.buffer
115        }
116        fn as_view<K>(
117            this: &SortedLinkedListInner<T, Idx, K, Self>,
118        ) -> &SortedLinkedListView<T, K, Idx>
119        where
120            Self: SortedLinkedListStorage<T, Idx>,
121            Idx: LenType,
122        {
123            this
124        }
125        fn as_mut_view<K>(
126            this: &mut SortedLinkedListInner<T, Idx, K, Self>,
127        ) -> &mut SortedLinkedListView<T, K, Idx>
128        where
129            Self: SortedLinkedListStorage<T, Idx>,
130            Idx: LenType,
131        {
132            this
133        }
134    }
135    impl<T, Idx, const N: usize> SortedLinkedListStorage<T, Idx>
136        for OwnedSortedLinkedListStorage<T, Idx, N>
137    {
138    }
139
140    impl<T, Idx> SortedLinkedListSealedStorage<T, Idx> for ViewSortedLinkedListStorage<T, Idx> {
141        fn borrow(&self) -> &[Node<T, Idx>] {
142            &self.buffer
143        }
144        fn borrow_mut(&mut self) -> &mut [Node<T, Idx>] {
145            &mut self.buffer
146        }
147        fn as_view<K>(
148            this: &SortedLinkedListInner<T, Idx, K, Self>,
149        ) -> &SortedLinkedListView<T, K, Idx>
150        where
151            Self: SortedLinkedListStorage<T, Idx>,
152            Idx: LenType,
153        {
154            this
155        }
156        fn as_mut_view<K>(
157            this: &mut SortedLinkedListInner<T, Idx, K, Self>,
158        ) -> &mut SortedLinkedListView<T, K, Idx>
159        where
160            Self: SortedLinkedListStorage<T, Idx>,
161            Idx: LenType,
162        {
163            this
164        }
165    }
166    impl<T, Idx> SortedLinkedListStorage<T, Idx> for ViewSortedLinkedListStorage<T, Idx> {}
167}
168pub use storage::{
169    OwnedSortedLinkedListStorage, SortedLinkedListStorage, ViewSortedLinkedListStorage,
170};
171
172use crate::len_type::LenType;
173
174/// Marker for Min sorted [`SortedLinkedList`].
175pub struct Min;
176
177/// Marker for Max sorted [`SortedLinkedList`].
178pub struct Max;
179
180/// The linked list kind: min-list or max-list
181pub trait Kind: private::Sealed {
182    #[doc(hidden)]
183    fn ordering() -> Ordering;
184}
185
186impl Kind for Min {
187    fn ordering() -> Ordering {
188        Ordering::Less
189    }
190}
191
192impl Kind for Max {
193    fn ordering() -> Ordering {
194        Ordering::Greater
195    }
196}
197
198/// Sealed traits
199mod private {
200    pub trait Sealed {}
201}
202
203impl private::Sealed for Max {}
204impl private::Sealed for Min {}
205
206/// A node in the [`SortedLinkedList`].
207#[cfg_attr(feature = "zeroize", derive(Zeroize))]
208pub struct Node<T, Idx> {
209    val: MaybeUninit<T>,
210    next: Idx,
211}
212
213/// Base struct for [`SortedLinkedList`] and [`SortedLinkedListView`], generic over the
214/// [`SortedLinkedListStorage`].
215///
216/// In most cases you should use [`SortedLinkedList`] or [`SortedLinkedListView`] directly. Only use
217/// this struct if you want to write code that's generic over both.
218pub struct SortedLinkedListInner<T, Idx, K, S>
219where
220    Idx: LenType,
221    S: SortedLinkedListStorage<T, Idx> + ?Sized,
222{
223    head: Idx,
224    free: Idx,
225    phantom: PhantomData<(K, T)>,
226    list: S,
227}
228
229/// The linked list.
230pub type SortedLinkedList<T, K, const N: usize, Idx = usize> =
231    SortedLinkedListInner<T, Idx, K, OwnedSortedLinkedListStorage<T, Idx, N>>;
232
233/// The linked list.
234pub type SortedLinkedListView<T, K, Idx> =
235    SortedLinkedListInner<T, Idx, K, ViewSortedLinkedListStorage<T, Idx>>;
236
237macro_rules! impl_const_new {
238    ($ty:ty, $new_name:ident) => {
239        impl<T, K, const N: usize> SortedLinkedList<T, K, N, $ty> {
240            /// Create a new linked list.
241            pub const fn $new_name() -> Self {
242                const {
243                    assert!(
244                        (<$ty>::MAX as usize) >= (N + 1),
245                        "The capacity is larger than `LenT` can hold, increase the size of `LenT` or reduce the capacity"
246                    );
247                }
248
249                let mut list = SortedLinkedList {
250                    list: OwnedSortedLinkedListStorage {
251                        buffer: [const {
252                            Node {
253                                val: MaybeUninit::uninit(),
254                                next: <$ty>::MAX,
255                            }
256                        }; N],
257                    },
258                    head: <$ty>::MAX,
259                    free: 0,
260                    phantom: PhantomData,
261                };
262
263                if N == 0 {
264                    list.free = <$ty>::MAX;
265                    return list;
266                }
267
268                let mut free = 0;
269
270                // Initialize indexes
271                while free < N - 1 {
272                    list.list.buffer[free].next = free as $ty + 1;
273                    free += 1;
274                }
275
276                list
277            }
278        }
279    };
280}
281
282impl_const_new!(u8, new_u8);
283impl_const_new!(u16, new_u16);
284impl_const_new!(usize, new_usize);
285
286impl<T, Idx, K, S> SortedLinkedListInner<T, Idx, K, S>
287where
288    Idx: LenType,
289    S: SortedLinkedListStorage<T, Idx> + ?Sized,
290{
291    /// Get a reference to the `SortedLinkedList`, erasing the `N` const-generic.
292    pub fn as_view(&self) -> &SortedLinkedListView<T, K, Idx> {
293        S::as_view(self)
294    }
295
296    /// Get a mutable reference to the `Vec`, erasing the `N` const-generic.
297    pub fn as_mut_view(&mut self) -> &mut SortedLinkedListView<T, K, Idx> {
298        S::as_mut_view(self)
299    }
300
301    /// Internal access helper
302    #[inline(always)]
303    fn node_at(&self, index: usize) -> &Node<T, Idx> {
304        // Safety: The entire `self.list` is initialized in `new`, which makes this safe.
305        unsafe { self.list.borrow().get_unchecked(index) }
306    }
307
308    /// Internal access helper
309    #[inline(always)]
310    fn node_at_mut(&mut self, index: usize) -> &mut Node<T, Idx> {
311        // Safety: The entire `self.list` is initialized in `new`, which makes this safe.
312        unsafe { self.list.borrow_mut().get_unchecked_mut(index) }
313    }
314
315    /// Internal access helper
316    #[inline(always)]
317    fn write_data_in_node_at(&mut self, index: usize, data: T) {
318        // Safety: The entire `self.list` is initialized in `new`, which makes this safe.
319        unsafe {
320            self.node_at_mut(index).val.as_mut_ptr().write(data);
321        }
322    }
323
324    /// Internal access helper
325    #[inline(always)]
326    fn read_data_in_node_at(&self, index: usize) -> &T {
327        // Safety: The entire `self.list` is initialized in `new`, which makes this safe.
328        unsafe { &*self.node_at(index).val.as_ptr() }
329    }
330
331    /// Internal access helper
332    #[inline(always)]
333    fn read_mut_data_in_node_at(&mut self, index: usize) -> &mut T {
334        // Safety: The entire `self.list` is initialized in `new`, which makes this safe.
335        unsafe { &mut *self.node_at_mut(index).val.as_mut_ptr() }
336    }
337
338    /// Internal access helper
339    #[inline(always)]
340    fn extract_data_in_node_at(&mut self, index: usize) -> T {
341        // Safety: The entire `self.list` is initialized in `new`, which makes this safe.
342        unsafe { self.node_at(index).val.as_ptr().read() }
343    }
344}
345
346impl<T, Idx, K, S> SortedLinkedListInner<T, Idx, K, S>
347where
348    T: Ord,
349    Idx: LenType,
350    K: Kind,
351    S: SortedLinkedListStorage<T, Idx> + ?Sized,
352{
353    /// Pushes a value onto the list without checking if the list is full.
354    ///
355    /// Complexity is worst-case *O*(n).
356    ///
357    /// # Safety
358    ///
359    /// Assumes that the list is not full.
360    pub unsafe fn push_unchecked(&mut self, value: T) {
361        let new = self.free.into_usize();
362
363        // Store the data and update the next free spot
364        self.write_data_in_node_at(new, value);
365        self.free = self.node_at(new).next;
366
367        if let Some(head) = self.head.to_non_max() {
368            // Check if we need to replace head
369            if self
370                .read_data_in_node_at(head)
371                .cmp(self.read_data_in_node_at(new))
372                == K::ordering()
373            {
374                // It's not head, search the list for the correct placement
375                let mut current = head;
376
377                while let Some(next) = self.node_at(current).next.to_non_max() {
378                    if self
379                        .read_data_in_node_at(next)
380                        .cmp(self.read_data_in_node_at(new))
381                        != K::ordering()
382                    {
383                        break;
384                    }
385
386                    current = next;
387                }
388
389                self.node_at_mut(new).next = self.node_at(current).next;
390                self.node_at_mut(current).next = Idx::from_usize(new);
391            } else {
392                self.node_at_mut(new).next = self.head;
393                self.head = Idx::from_usize(new);
394            }
395        } else {
396            self.node_at_mut(new).next = self.head;
397            self.head = Idx::from_usize(new);
398        }
399    }
400
401    /// Pushes an element to the linked list and sorts it into place.
402    ///
403    /// Complexity is worst-case *O*(n).
404    ///
405    /// # Example
406    ///
407    /// ```
408    /// use heapless::sorted_linked_list::{Max, SortedLinkedList};
409    /// let mut ll: SortedLinkedList<_, Max, 3, u8> = SortedLinkedList::new_u8();
410    ///
411    /// // The largest value will always be first
412    /// ll.push(1).unwrap();
413    /// assert_eq!(ll.peek(), Some(&1));
414    ///
415    /// ll.push(2).unwrap();
416    /// assert_eq!(ll.peek(), Some(&2));
417    ///
418    /// ll.push(3).unwrap();
419    /// assert_eq!(ll.peek(), Some(&3));
420    ///
421    /// // This will not fit in the queue.
422    /// assert_eq!(ll.push(4), Err(4));
423    /// ```
424    pub fn push(&mut self, value: T) -> Result<(), T> {
425        if self.is_full() {
426            Err(value)
427        } else {
428            unsafe { self.push_unchecked(value) }
429            Ok(())
430        }
431    }
432
433    /// Peek at the first element.
434    ///
435    /// # Example
436    ///
437    /// ```
438    /// use heapless::sorted_linked_list::{Max, Min, SortedLinkedList};
439    /// let mut ll_max: SortedLinkedList<_, Max, 3, u8> = SortedLinkedList::new_u8();
440    ///
441    /// // The largest value will always be first
442    /// ll_max.push(1).unwrap();
443    /// assert_eq!(ll_max.peek(), Some(&1));
444    /// ll_max.push(2).unwrap();
445    /// assert_eq!(ll_max.peek(), Some(&2));
446    /// ll_max.push(3).unwrap();
447    /// assert_eq!(ll_max.peek(), Some(&3));
448    ///
449    /// let mut ll_min: SortedLinkedList<_, Min, 3, u8> = SortedLinkedList::new_u8();
450    ///
451    /// // The Smallest value will always be first
452    /// ll_min.push(3).unwrap();
453    /// assert_eq!(ll_min.peek(), Some(&3));
454    /// ll_min.push(2).unwrap();
455    /// assert_eq!(ll_min.peek(), Some(&2));
456    /// ll_min.push(1).unwrap();
457    /// assert_eq!(ll_min.peek(), Some(&1));
458    /// ```
459    pub fn peek(&self) -> Option<&T> {
460        self.head
461            .to_non_max()
462            .map(|head| self.read_data_in_node_at(head))
463    }
464
465    /// Pop an element from the list without checking so the list is not empty.
466    ///
467    /// # Safety
468    ///
469    /// Assumes that the list is not empty.
470    pub unsafe fn pop_unchecked(&mut self) -> T {
471        let head = self.head.into_usize();
472        let current = head;
473        self.head = self.node_at(head).next;
474        self.node_at_mut(current).next = self.free;
475        self.free = Idx::from_usize(current);
476
477        self.extract_data_in_node_at(current)
478    }
479
480    /// Pops the first element in the list.
481    ///
482    /// Complexity is worst-case *O*(1).
483    ///
484    /// # Example
485    ///
486    /// ```
487    /// use heapless::sorted_linked_list::{Max, SortedLinkedList};
488    /// let mut ll: SortedLinkedList<_, Max, 3, u8> = SortedLinkedList::new_u8();
489    ///
490    /// ll.push(1).unwrap();
491    /// ll.push(2).unwrap();
492    ///
493    /// assert_eq!(ll.pop(), Some(2));
494    /// assert_eq!(ll.pop(), Some(1));
495    /// assert_eq!(ll.pop(), None);
496    /// ```
497    pub fn pop(&mut self) -> Option<T> {
498        if self.is_empty() {
499            None
500        } else {
501            Some(unsafe { self.pop_unchecked() })
502        }
503    }
504
505    /// Checks if the linked list is full.
506    ///
507    /// # Example
508    ///
509    /// ```
510    /// use heapless::sorted_linked_list::{Max, SortedLinkedList};
511    /// let mut ll: SortedLinkedList<_, Max, 3, u8> = SortedLinkedList::new_u8();
512    ///
513    /// assert_eq!(ll.is_full(), false);
514    ///
515    /// ll.push(1).unwrap();
516    /// assert_eq!(ll.is_full(), false);
517    /// ll.push(2).unwrap();
518    /// assert_eq!(ll.is_full(), false);
519    /// ll.push(3).unwrap();
520    /// assert_eq!(ll.is_full(), true);
521    /// ```
522    #[inline]
523    pub fn is_full(&self) -> bool {
524        self.free.to_non_max().is_none()
525    }
526
527    /// Checks if the linked list is empty.
528    ///
529    /// # Example
530    ///
531    /// ```
532    /// use heapless::sorted_linked_list::{Max, SortedLinkedList};
533    /// let mut ll: SortedLinkedList<_, Max, 3, u8> = SortedLinkedList::new_u8();
534    ///
535    /// assert_eq!(ll.is_empty(), true);
536    ///
537    /// ll.push(1).unwrap();
538    /// assert_eq!(ll.is_empty(), false);
539    /// ```
540    #[inline]
541    pub fn is_empty(&self) -> bool {
542        self.head.to_non_max().is_none()
543    }
544}
545
546impl<T, Idx, K, S> SortedLinkedListInner<T, Idx, K, S>
547where
548    T: Ord,
549    Idx: LenType,
550    K: Kind,
551    S: SortedLinkedListStorage<T, Idx> + ?Sized,
552{
553    /// Get an iterator over the sorted list.
554    ///
555    /// # Example
556    ///
557    /// ```
558    /// use heapless::sorted_linked_list::{Max, SortedLinkedList};
559    /// let mut ll: SortedLinkedList<_, Max, 3, u8> = SortedLinkedList::new_u8();
560    ///
561    /// ll.push(1).unwrap();
562    /// ll.push(2).unwrap();
563    ///
564    /// let mut iter = ll.iter();
565    ///
566    /// assert_eq!(iter.next(), Some(&2));
567    /// assert_eq!(iter.next(), Some(&1));
568    /// assert_eq!(iter.next(), None);
569    /// ```
570    pub fn iter(&self) -> IterView<'_, T, Idx, K> {
571        IterView {
572            list: S::as_view(self),
573            index: self.head,
574        }
575    }
576
577    /// Find an element in the list that can be changed and resorted.
578    ///
579    /// # Example
580    ///
581    /// ```
582    /// use heapless::sorted_linked_list::{Max, SortedLinkedList};
583    /// let mut ll: SortedLinkedList<_, Max, 3, u8> = SortedLinkedList::new_u8();
584    ///
585    /// ll.push(1).unwrap();
586    /// ll.push(2).unwrap();
587    /// ll.push(3).unwrap();
588    ///
589    /// // Find a value and update it
590    /// let mut find = ll.find_mut(|v| *v == 2).unwrap();
591    /// *find += 1000;
592    /// find.finish();
593    ///
594    /// assert_eq!(ll.pop(), Some(1002));
595    /// assert_eq!(ll.pop(), Some(3));
596    /// assert_eq!(ll.pop(), Some(1));
597    /// assert_eq!(ll.pop(), None);
598    /// ```
599    pub fn find_mut<F>(&mut self, mut f: F) -> Option<FindMutView<'_, T, Idx, K>>
600    where
601        F: FnMut(&T) -> bool,
602    {
603        let head = self.head.to_non_max()?;
604
605        // Special-case, first element
606        if f(self.read_data_in_node_at(head)) {
607            return Some(FindMutView {
608                is_head: true,
609                prev_index: Idx::MAX,
610                index: self.head,
611                list: S::as_mut_view(self),
612                maybe_changed: false,
613            });
614        }
615
616        let mut current = head;
617
618        while let Some(next) = self.node_at(current).next.to_non_max() {
619            if f(self.read_data_in_node_at(next)) {
620                return Some(FindMutView {
621                    is_head: false,
622                    prev_index: Idx::from_usize(current),
623                    index: Idx::from_usize(next),
624                    list: S::as_mut_view(self),
625                    maybe_changed: false,
626                });
627            }
628
629            current = next;
630        }
631
632        None
633    }
634}
635
636/// Iterator for the linked list.
637pub struct IterView<'a, T, Idx, K>
638where
639    T: Ord,
640    Idx: LenType,
641    K: Kind,
642{
643    list: &'a SortedLinkedListInner<T, Idx, K, ViewSortedLinkedListStorage<T, Idx>>,
644    index: Idx,
645}
646
647impl<'a, T, Idx, K> Iterator for IterView<'a, T, Idx, K>
648where
649    T: Ord,
650    Idx: LenType,
651    K: Kind,
652{
653    type Item = &'a T;
654
655    fn next(&mut self) -> Option<Self::Item> {
656        let index = self.index.to_non_max()?;
657
658        let node = self.list.node_at(index);
659        self.index = node.next;
660
661        Some(self.list.read_data_in_node_at(index))
662    }
663}
664
665/// Comes from [`SortedLinkedList::find_mut`].
666pub struct FindMutView<'a, T, Idx, K>
667where
668    T: Ord,
669    Idx: LenType,
670    K: Kind,
671{
672    list: &'a mut SortedLinkedListView<T, K, Idx>,
673    is_head: bool,
674    prev_index: Idx,
675    index: Idx,
676    maybe_changed: bool,
677}
678
679impl<T, Idx, K> FindMutView<'_, T, Idx, K>
680where
681    T: Ord,
682    Idx: LenType,
683    K: Kind,
684{
685    fn pop_internal(&mut self) -> T {
686        if self.is_head {
687            // If it is the head element, we can do a normal pop
688            unsafe { self.list.pop_unchecked() }
689        } else {
690            // Somewhere in the list
691            let prev = self.prev_index.into_usize();
692            let curr = self.index.into_usize();
693
694            // Re-point the previous index
695            self.list.node_at_mut(prev).next = self.list.node_at_mut(curr).next;
696
697            // Release the index into the free queue
698            self.list.node_at_mut(curr).next = self.list.free;
699            self.list.free = self.index;
700
701            self.list.extract_data_in_node_at(curr)
702        }
703    }
704
705    /// This will pop the element from the list.
706    ///
707    /// Complexity is worst-case *O*(1).
708    ///
709    /// # Example
710    ///
711    /// ```
712    /// use heapless::sorted_linked_list::{Max, SortedLinkedList};
713    /// let mut ll: SortedLinkedList<_, Max, 3, u8> = SortedLinkedList::new_u8();
714    ///
715    /// ll.push(1).unwrap();
716    /// ll.push(2).unwrap();
717    /// ll.push(3).unwrap();
718    ///
719    /// // Find a value and update it
720    /// let mut find = ll.find_mut(|v| *v == 2).unwrap();
721    /// find.pop();
722    ///
723    /// assert_eq!(ll.pop(), Some(3));
724    /// assert_eq!(ll.pop(), Some(1));
725    /// assert_eq!(ll.pop(), None);
726    /// ```
727    #[inline]
728    pub fn pop(mut self) -> T {
729        self.pop_internal()
730    }
731
732    /// This will resort the element into the correct position in the list if needed. The resorting
733    /// will only happen if the element has been accessed mutably.
734    ///
735    /// Same as calling `drop`.
736    ///
737    /// Complexity is worst-case *O*(n).
738    ///
739    /// # Example
740    ///
741    /// ```
742    /// use heapless::sorted_linked_list::{Max, SortedLinkedList};
743    /// let mut ll: SortedLinkedList<_, Max, 3, u8> = SortedLinkedList::new_u8();
744    ///
745    /// ll.push(1).unwrap();
746    /// ll.push(2).unwrap();
747    /// ll.push(3).unwrap();
748    ///
749    /// let mut find = ll.find_mut(|v| *v == 2).unwrap();
750    /// find.finish(); // No resort, we did not access the value.
751    ///
752    /// let mut find = ll.find_mut(|v| *v == 2).unwrap();
753    /// *find += 1000;
754    /// find.finish(); // Will resort, we accessed (and updated) the value.
755    ///
756    /// assert_eq!(ll.pop(), Some(1002));
757    /// assert_eq!(ll.pop(), Some(3));
758    /// assert_eq!(ll.pop(), Some(1));
759    /// assert_eq!(ll.pop(), None);
760    /// ```
761    #[inline]
762    pub fn finish(self) {
763        drop(self);
764    }
765}
766
767impl<T, Idx, K> Drop for FindMutView<'_, T, Idx, K>
768where
769    T: Ord,
770    Idx: LenType,
771    K: Kind,
772{
773    fn drop(&mut self) {
774        // Only resort the list if the element has changed
775        if self.maybe_changed {
776            let val = self.pop_internal();
777            unsafe { self.list.push_unchecked(val) };
778        }
779    }
780}
781
782impl<T, Idx, K> Deref for FindMutView<'_, T, Idx, K>
783where
784    T: Ord,
785    Idx: LenType,
786    K: Kind,
787{
788    type Target = T;
789
790    fn deref(&self) -> &Self::Target {
791        self.list.read_data_in_node_at(self.index.into_usize())
792    }
793}
794
795impl<T, Idx, K> DerefMut for FindMutView<'_, T, Idx, K>
796where
797    T: Ord,
798    Idx: LenType,
799    K: Kind,
800{
801    fn deref_mut(&mut self) -> &mut Self::Target {
802        self.maybe_changed = true;
803        self.list.read_mut_data_in_node_at(self.index.into_usize())
804    }
805}
806
807// /// Useful for debug during development.
808// impl<T, Idx, K, const N: usize> fmt::Debug for FindMut<'_, T, Idx, K, N>
809// where
810//     T: Ord + core::fmt::Debug,
811//     Idx: LenType,
812//     K: Kind,
813// {
814//     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
815//         f.debug_struct("FindMut")
816//             .field("prev_index", &self.prev_index.to_non_max())
817//             .field("index", &self.index.to_non_max())
818//             .field(
819//                 "prev_value",
820//                 &self
821//                     .list
822//                     .read_data_in_node_at(self.prev_index.to_non_max().unwrap()),
823//             )
824//             .field(
825//                 "value",
826//                 &self.list.read_data_in_node_at(self.index.to_non_max().unwrap()),
827//             )
828//             .finish()
829//     }
830// }
831
832impl<T, Idx, K, S> fmt::Debug for SortedLinkedListInner<T, Idx, K, S>
833where
834    T: Ord + core::fmt::Debug,
835    Idx: LenType,
836    K: Kind,
837    S: ?Sized + SortedLinkedListStorage<T, Idx>,
838{
839    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
840        f.debug_list().entries(self.iter()).finish()
841    }
842}
843
844impl<T, Idx, K, S> Drop for SortedLinkedListInner<T, Idx, K, S>
845where
846    Idx: LenType,
847    S: SortedLinkedListStorage<T, Idx> + ?Sized,
848{
849    fn drop(&mut self) {
850        let mut index = self.head;
851
852        while let Some(i) = index.to_non_max() {
853            let node = self.node_at_mut(i);
854            index = node.next;
855
856            unsafe {
857                ptr::drop_in_place(node.val.as_mut_ptr());
858            }
859        }
860    }
861}
862
863#[cfg(feature = "zeroize")]
864impl<T, Idx, K, S> Zeroize for SortedLinkedListInner<T, Idx, K, S>
865where
866    T: Ord + Zeroize,
867    Idx: LenType + Zeroize,
868    K: Kind,
869    S: SortedLinkedListStorage<T, Idx> + ?Sized,
870{
871    fn zeroize(&mut self) {
872        while let Some(mut item) = self.pop() {
873            item.zeroize();
874        }
875
876        let buffer = self.list.borrow_mut();
877        for elem in buffer {
878            elem.zeroize();
879        }
880    }
881}
882
883#[cfg(test)]
884mod tests {
885    use static_assertions::assert_not_impl_any;
886
887    use super::*;
888
889    // Ensure a `SortedLinkedList` containing `!Send` values stays `!Send` itself.
890    assert_not_impl_any!(SortedLinkedList<*const (), (), 4>: Send);
891
892    #[test]
893    fn const_new() {
894        static mut _V1: SortedLinkedList<u32, Max, 100, u8> = SortedLinkedList::new_u8();
895        static mut _V2: SortedLinkedList<u32, Max, 10_000, u16> = SortedLinkedList::new_u16();
896        static mut _V3: SortedLinkedList<u32, Max, 100_000, usize> = SortedLinkedList::new_usize();
897    }
898
899    #[test]
900    fn test_peek() {
901        let mut ll: SortedLinkedList<u32, Max, 3, u8> = SortedLinkedList::new_u8();
902
903        ll.push(1).unwrap();
904        assert_eq!(ll.peek().unwrap(), &1);
905
906        ll.push(2).unwrap();
907        assert_eq!(ll.peek().unwrap(), &2);
908
909        ll.push(3).unwrap();
910        assert_eq!(ll.peek().unwrap(), &3);
911
912        let mut ll: SortedLinkedList<u32, Min, 3, u8> = SortedLinkedList::new_u8();
913
914        ll.push(2).unwrap();
915        assert_eq!(ll.peek().unwrap(), &2);
916
917        ll.push(1).unwrap();
918        assert_eq!(ll.peek().unwrap(), &1);
919
920        ll.push(3).unwrap();
921        assert_eq!(ll.peek().unwrap(), &1);
922    }
923
924    #[test]
925    fn test_full() {
926        let mut ll: SortedLinkedList<u32, Max, 3, u8> = SortedLinkedList::new_u8();
927        ll.push(1).unwrap();
928        ll.push(2).unwrap();
929        ll.push(3).unwrap();
930
931        assert!(ll.is_full());
932    }
933
934    #[test]
935    fn test_empty() {
936        let ll: SortedLinkedList<u32, Max, 3, u8> = SortedLinkedList::new_u8();
937
938        assert!(ll.is_empty());
939    }
940
941    #[test]
942    fn test_zero_size() {
943        let ll: SortedLinkedList<u32, Max, 0, u8> = SortedLinkedList::new_u8();
944
945        assert!(ll.is_empty());
946        assert!(ll.is_full());
947    }
948
949    #[test]
950    fn test_rejected_push() {
951        let mut ll: SortedLinkedList<u32, Max, 3, u8> = SortedLinkedList::new_u8();
952        ll.push(1).unwrap();
953        ll.push(2).unwrap();
954        ll.push(3).unwrap();
955
956        // This won't fit
957        let r = ll.push(4);
958
959        assert_eq!(r, Err(4));
960    }
961
962    #[test]
963    fn test_updating() {
964        let mut ll: SortedLinkedList<u32, Max, 3, u8> = SortedLinkedList::new_u8();
965        ll.push(1).unwrap();
966        ll.push(2).unwrap();
967        ll.push(3).unwrap();
968
969        let mut find = ll.find_mut(|v| *v == 2).unwrap();
970
971        *find += 1000;
972        find.finish();
973
974        assert_eq!(ll.peek().unwrap(), &1002);
975
976        let mut find = ll.find_mut(|v| *v == 3).unwrap();
977
978        *find += 1000;
979        find.finish();
980
981        assert_eq!(ll.peek().unwrap(), &1003);
982
983        // Remove largest element
984        ll.find_mut(|v| *v == 1003).unwrap().pop();
985
986        assert_eq!(ll.peek().unwrap(), &1002);
987    }
988
989    #[test]
990    fn test_updating_1() {
991        let mut ll: SortedLinkedList<u32, Max, 3, u8> = SortedLinkedList::new_u8();
992        ll.push(1).unwrap();
993
994        let v = ll.pop().unwrap();
995
996        assert_eq!(v, 1);
997    }
998
999    #[test]
1000    fn test_updating_2() {
1001        let mut ll: SortedLinkedList<u32, Max, 3, u8> = SortedLinkedList::new_u8();
1002        ll.push(1).unwrap();
1003
1004        let mut find = ll.find_mut(|v| *v == 1).unwrap();
1005
1006        *find += 1000;
1007        find.finish();
1008
1009        assert_eq!(ll.peek().unwrap(), &1001);
1010    }
1011
1012    #[test]
1013    #[cfg(feature = "zeroize")]
1014    fn test_sorted_linked_list_zeroize() {
1015        use zeroize::Zeroize;
1016
1017        let mut list: SortedLinkedList<u8, Max, 8, u8> = SortedLinkedList::new_u8();
1018        for i in 1..=8 {
1019            list.push(i).unwrap();
1020        }
1021
1022        assert_eq!(list.is_empty(), false);
1023        assert!(list.is_full());
1024        assert_eq!(list.peek(), Some(&8));
1025
1026        list.pop();
1027        list.pop();
1028        list.push(100).unwrap();
1029
1030        assert_eq!(list.peek(), Some(&100));
1031
1032        list.zeroize();
1033
1034        assert_eq!(list.peek(), None);
1035        assert!(list.is_empty());
1036
1037        unsafe {
1038            for node in &list.list.buffer {
1039                assert_eq!(node.val.assume_init(), 0);
1040            }
1041        }
1042    }
1043
1044    fn _test_variance<'a: 'b, 'b>(
1045        x: SortedLinkedList<&'a (), Max, 42, u8>,
1046    ) -> SortedLinkedList<&'b (), Max, 42, u8> {
1047        x
1048    }
1049    fn _test_variance_view<'a: 'b, 'b, 'c>(
1050        x: &'c SortedLinkedListView<&'a (), Max, u8>,
1051    ) -> &'c SortedLinkedListView<&'b (), Max, u8> {
1052        x
1053    }
1054}