2626//!
2727//! [`BinaryHeap`]: `crate::binary_heap::BinaryHeap`
2828
29+ use core:: borrow:: { Borrow , BorrowMut } ;
2930use core:: cmp:: Ordering ;
3031use core:: fmt;
3132use core:: marker:: PhantomData ;
3233use core:: mem:: MaybeUninit ;
3334use core:: ops:: { Deref , DerefMut } ;
3435use core:: ptr;
3536
37+ use crate :: storage:: { OwnedStorage , Storage , ViewStorage } ;
38+
3639/// Trait for defining an index for the linked list, never implemented by users.
3740pub trait SortedLinkedListIndex : Copy {
3841 #[ doc( hidden) ]
@@ -83,17 +86,28 @@ pub struct Node<T, Idx> {
8386 next : Idx ,
8487}
8588
86- /// The linked list.
87- pub struct SortedLinkedList < T , Idx , K , const N : usize >
89+ /// Base struct for [`SortedLinkedList`] and [`SortedLinkedListView`], generic over the [`Storage`].
90+ ///
91+ /// In most cases you should use [`SortedLinkedList`] or [`SortedLinkedListView`] directly. Only use this
92+ /// struct if you want to write code that's generic over both.
93+ pub struct SortedLinkedListInner < T , Idx , K , S >
8894where
8995 Idx : SortedLinkedListIndex ,
96+ S : Storage ,
9097{
91- list : [ Node < T , Idx > ; N ] ,
9298 head : Idx ,
9399 free : Idx ,
94100 _kind : PhantomData < K > ,
101+ list : S :: Buffer < Node < T , Idx > > ,
95102}
96103
104+ /// The linked list.
105+ pub type SortedLinkedList < T , Idx , K , const N : usize > =
106+ SortedLinkedListInner < T , Idx , K , OwnedStorage < N > > ;
107+
108+ /// The linked list.
109+ pub type SortedLinkedListView < T , Idx , K > = SortedLinkedListInner < T , Idx , K , ViewStorage > ;
110+
97111// Internal macro for generating indexes for the linkedlist and const new for the linked list
98112macro_rules! impl_index_and_const_new {
99113 ( $name: ident, $ty: ty, $new_name: ident, $max_val: expr) => {
@@ -186,19 +200,35 @@ impl_index_and_const_new!(LinkedIndexUsize, usize, new_usize, { usize::MAX - 1 }
186200impl < T , Idx , K , const N : usize > SortedLinkedList < T , Idx , K , N >
187201where
188202 Idx : SortedLinkedListIndex ,
203+ {
204+ /// Get a reference to the `SortedLinkedList`, erasing the `N` const-generic.
205+ pub fn as_view ( & self ) -> & SortedLinkedListView < T , Idx , K > {
206+ self
207+ }
208+
209+ /// Get a mutable reference to the `Vec`, erasing the `N` const-generic.
210+ pub fn as_mut_view ( & mut self ) -> & mut SortedLinkedListView < T , Idx , K > {
211+ self
212+ }
213+ }
214+
215+ impl < T , Idx , K , S > SortedLinkedListInner < T , Idx , K , S >
216+ where
217+ Idx : SortedLinkedListIndex ,
218+ S : Storage ,
189219{
190220 /// Internal access helper
191221 #[ inline( always) ]
192222 fn node_at ( & self , index : usize ) -> & Node < T , Idx > {
193223 // Safety: The entire `self.list` is initialized in `new`, which makes this safe.
194- unsafe { self . list . get_unchecked ( index) }
224+ unsafe { self . list . borrow ( ) . get_unchecked ( index) }
195225 }
196226
197227 /// Internal access helper
198228 #[ inline( always) ]
199229 fn node_at_mut ( & mut self , index : usize ) -> & mut Node < T , Idx > {
200230 // Safety: The entire `self.list` is initialized in `new`, which makes this safe.
201- unsafe { self . list . get_unchecked_mut ( index) }
231+ unsafe { self . list . borrow_mut ( ) . get_unchecked_mut ( index) }
202232 }
203233
204234 /// Internal access helper
@@ -232,11 +262,12 @@ where
232262 }
233263}
234264
235- impl < T , Idx , K , const N : usize > SortedLinkedList < T , Idx , K , N >
265+ impl < T , Idx , K , S > SortedLinkedListInner < T , Idx , K , S >
236266where
237267 T : Ord ,
238268 Idx : SortedLinkedListIndex ,
239269 K : Kind ,
270+ S : Storage ,
240271{
241272 /// Pushes a value onto the list without checking if the list is full.
242273 ///
@@ -335,8 +366,8 @@ where
335366 /// assert_eq!(iter.next(), Some(&1));
336367 /// assert_eq!(iter.next(), None);
337368 /// ```
338- pub fn iter ( & self ) -> Iter < ' _ , T , Idx , K , N > {
339- Iter {
369+ pub fn iter ( & self ) -> IterInner < ' _ , T , Idx , K , S > {
370+ IterInner {
340371 list : self ,
341372 index : self . head ,
342373 }
@@ -364,15 +395,15 @@ where
364395 /// assert_eq!(ll.pop(), Ok(1));
365396 /// assert_eq!(ll.pop(), Err(()));
366397 /// ```
367- pub fn find_mut < F > ( & mut self , mut f : F ) -> Option < FindMut < ' _ , T , Idx , K , N > >
398+ pub fn find_mut < F > ( & mut self , mut f : F ) -> Option < FindMutInner < ' _ , T , Idx , K , S > >
368399 where
369400 F : FnMut ( & T ) -> bool ,
370401 {
371402 let head = self . head . option ( ) ?;
372403
373404 // Special-case, first element
374405 if f ( self . read_data_in_node_at ( head) ) {
375- return Some ( FindMut {
406+ return Some ( FindMutInner {
376407 is_head : true ,
377408 prev_index : Idx :: none ( ) ,
378409 index : self . head ,
@@ -385,7 +416,7 @@ where
385416
386417 while let Some ( next) = self . node_at ( current) . next . option ( ) {
387418 if f ( self . read_data_in_node_at ( next) ) {
388- return Some ( FindMut {
419+ return Some ( FindMutInner {
389420 is_head : false ,
390421 prev_index : unsafe { Idx :: new_unchecked ( current) } ,
391422 index : unsafe { Idx :: new_unchecked ( next) } ,
@@ -514,22 +545,32 @@ where
514545 }
515546}
516547
517- /// Iterator for the linked list.
518- pub struct Iter < ' a , T , Idx , K , const N : usize >
548+ /// Base struct for [`Iter`] and [`IterView`], generic over the [`Storage`].
549+ ///
550+ /// In most cases you should use [`Iter`] or [`IterView`] directly. Only use this
551+ /// struct if you want to write code that's generic over both.
552+ pub struct IterInner < ' a , T , Idx , K , S >
519553where
520554 T : Ord ,
521555 Idx : SortedLinkedListIndex ,
522556 K : Kind ,
557+ S : Storage ,
523558{
524- list : & ' a SortedLinkedList < T , Idx , K , N > ,
559+ list : & ' a SortedLinkedListInner < T , Idx , K , S > ,
525560 index : Idx ,
526561}
527562
528- impl < ' a , T , Idx , K , const N : usize > Iterator for Iter < ' a , T , Idx , K , N >
563+ /// Iterator for the linked list.
564+ pub type Iter < ' a , T , Idx , K , const N : usize > = IterInner < ' a , T , Idx , K , OwnedStorage < N > > ;
565+ /// Iterator for the linked list.
566+ pub type IterView < ' a , T , Idx , K , const N : usize > = IterInner < ' a , T , Idx , K , ViewStorage > ;
567+
568+ impl < ' a , T , Idx , K , S > Iterator for IterInner < ' a , T , Idx , K , S >
529569where
530570 T : Ord ,
531571 Idx : SortedLinkedListIndex ,
532572 K : Kind ,
573+ S : Storage ,
533574{
534575 type Item = & ' a T ;
535576
@@ -543,25 +584,35 @@ where
543584 }
544585}
545586
546- /// Comes from [`SortedLinkedList::find_mut`].
547- pub struct FindMut < ' a , T , Idx , K , const N : usize >
587+ /// Base struct for [`FindMut`] and [`FindMutView`], generic over the [`Storage`].
588+ ///
589+ /// In most cases you should use [`FindMut`] or [`FindMutView`] directly. Only use this
590+ /// struct if you want to write code that's generic over both.
591+ pub struct FindMutInner < ' a , T , Idx , K , S >
548592where
549593 T : Ord ,
550594 Idx : SortedLinkedListIndex ,
551595 K : Kind ,
596+ S : Storage ,
552597{
553- list : & ' a mut SortedLinkedList < T , Idx , K , N > ,
598+ list : & ' a mut SortedLinkedListInner < T , Idx , K , S > ,
554599 is_head : bool ,
555600 prev_index : Idx ,
556601 index : Idx ,
557602 maybe_changed : bool ,
558603}
559604
560- impl < ' a , T , Idx , K , const N : usize > FindMut < ' a , T , Idx , K , N >
605+ /// Comes from [`SortedLinkedList::find_mut`].
606+ pub type FindMut < ' a , T , Idx , K , const N : usize > = FindMutInner < ' a , T , Idx , K , OwnedStorage < N > > ;
607+ /// Comes from [`SortedLinkedList::find_mut`].
608+ pub type FindMutView < ' a , T , Idx , K , const N : usize > = FindMutInner < ' a , T , Idx , K , ViewStorage > ;
609+
610+ impl < ' a , T , Idx , K , S > FindMutInner < ' a , T , Idx , K , S >
561611where
562612 T : Ord ,
563613 Idx : SortedLinkedListIndex ,
564614 K : Kind ,
615+ S : Storage ,
565616{
566617 fn pop_internal ( & mut self ) -> T {
567618 if self . is_head {
@@ -645,11 +696,12 @@ where
645696 }
646697}
647698
648- impl < T , Idx , K , const N : usize > Drop for FindMut < ' _ , T , Idx , K , N >
699+ impl < T , Idx , K , S > Drop for FindMutInner < ' _ , T , Idx , K , S >
649700where
650701 T : Ord ,
651702 Idx : SortedLinkedListIndex ,
652703 K : Kind ,
704+ S : Storage ,
653705{
654706 fn drop ( & mut self ) {
655707 // Only resort the list if the element has changed
@@ -660,11 +712,12 @@ where
660712 }
661713}
662714
663- impl < T , Idx , K , const N : usize > Deref for FindMut < ' _ , T , Idx , K , N >
715+ impl < T , Idx , K , S > Deref for FindMutInner < ' _ , T , Idx , K , S >
664716where
665717 T : Ord ,
666718 Idx : SortedLinkedListIndex ,
667719 K : Kind ,
720+ S : Storage ,
668721{
669722 type Target = T ;
670723
@@ -674,11 +727,12 @@ where
674727 }
675728}
676729
677- impl < T , Idx , K , const N : usize > DerefMut for FindMut < ' _ , T , Idx , K , N >
730+ impl < T , Idx , K , S > DerefMut for FindMutInner < ' _ , T , Idx , K , S >
678731where
679732 T : Ord ,
680733 Idx : SortedLinkedListIndex ,
681734 K : Kind ,
735+ S : Storage ,
682736{
683737 fn deref_mut ( & mut self ) -> & mut Self :: Target {
684738 self . maybe_changed = true ;
@@ -712,20 +766,22 @@ where
712766// }
713767// }
714768
715- impl < T , Idx , K , const N : usize > fmt:: Debug for SortedLinkedList < T , Idx , K , N >
769+ impl < T , Idx , K , S > fmt:: Debug for SortedLinkedListInner < T , Idx , K , S >
716770where
717771 T : Ord + core:: fmt:: Debug ,
718772 Idx : SortedLinkedListIndex ,
719773 K : Kind ,
774+ S : Storage ,
720775{
721776 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
722777 f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
723778 }
724779}
725780
726- impl < T , Idx , K , const N : usize > Drop for SortedLinkedList < T , Idx , K , N >
781+ impl < T , Idx , K , S > Drop for SortedLinkedListInner < T , Idx , K , S >
727782where
728783 Idx : SortedLinkedListIndex ,
784+ S : Storage ,
729785{
730786 fn drop ( & mut self ) {
731787 let mut index = self . head ;
0 commit comments