26
26
//!
27
27
//! [`BinaryHeap`]: `crate::binary_heap::BinaryHeap`
28
28
29
+ use core:: borrow:: Borrow ;
29
30
use core:: cmp:: Ordering ;
30
31
use core:: fmt;
31
32
use core:: marker:: PhantomData ;
32
33
use core:: mem:: MaybeUninit ;
33
34
use core:: ops:: { Deref , DerefMut } ;
34
35
use core:: ptr;
35
36
37
+ use crate :: storage:: { OwnedStorage , Storage , ViewStorage } ;
38
+
36
39
/// Trait for defining an index for the linked list, never implemented by users.
37
40
pub trait SortedLinkedListIndex : Copy {
38
41
#[ doc( hidden) ]
@@ -83,17 +86,29 @@ pub struct Node<T, Idx> {
83
86
next : Idx ,
84
87
}
85
88
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 >
88
94
where
89
95
Idx : SortedLinkedListIndex ,
96
+ S : Storage ,
90
97
{
91
- list : [ Node < T , Idx > ; N ] ,
92
98
head : Idx ,
93
99
free : Idx ,
94
100
_kind : PhantomData < K > ,
101
+ list : S :: Buffer < Node < T , Idx > > ,
95
102
}
96
103
104
+ /// The linked list.
105
+ pub type SortedLinkedList < T , Idx , K : SortedLinkedListIndex , const N : usize > =
106
+ SortedLinkedListInner < T , Idx , K , OwnedStorage < N > > ;
107
+
108
+ /// The linked list.
109
+ pub type SortedLinkedListView < T , Idx , K : SortedLinkedListIndex > =
110
+ SortedLinkedListInner < T , Idx , K , ViewStorage > ;
111
+
97
112
// Internal macro for generating indexes for the linkedlist and const new for the linked list
98
113
macro_rules! impl_index_and_const_new {
99
114
( $name: ident, $ty: ty, $new_name: ident, $max_val: expr) => {
@@ -183,22 +198,23 @@ impl_index_and_const_new!(LinkedIndexU8, u8, new_u8, { u8::MAX as usize - 1 });
183
198
impl_index_and_const_new ! ( LinkedIndexU16 , u16 , new_u16, { u16 :: MAX as usize - 1 } ) ;
184
199
impl_index_and_const_new ! ( LinkedIndexUsize , usize , new_usize, { usize :: MAX - 1 } ) ;
185
200
186
- impl < T , Idx , K , const N : usize > SortedLinkedList < T , Idx , K , N >
201
+ impl < T , Idx , K , S > SortedLinkedListInner < T , Idx , K , S >
187
202
where
188
203
Idx : SortedLinkedListIndex ,
204
+ S : Storage ,
189
205
{
190
206
/// Internal access helper
191
207
#[ inline( always) ]
192
208
fn node_at ( & self , index : usize ) -> & Node < T , Idx > {
193
209
// Safety: The entire `self.list` is initialized in `new`, which makes this safe.
194
- unsafe { self . list . get_unchecked ( index) }
210
+ unsafe { self . list . borrow ( ) . get_unchecked ( index) }
195
211
}
196
212
197
213
/// Internal access helper
198
214
#[ inline( always) ]
199
215
fn node_at_mut ( & mut self , index : usize ) -> & mut Node < T , Idx > {
200
216
// Safety: The entire `self.list` is initialized in `new`, which makes this safe.
201
- unsafe { self . list . get_unchecked_mut ( index) }
217
+ unsafe { self . list . borrow ( ) . get_unchecked_mut ( index) }
202
218
}
203
219
204
220
/// Internal access helper
@@ -232,11 +248,12 @@ where
232
248
}
233
249
}
234
250
235
- impl < T , Idx , K , const N : usize > SortedLinkedList < T , Idx , K , N >
251
+ impl < T , Idx , K , S > SortedLinkedListInner < T , Idx , K , S >
236
252
where
237
253
T : Ord ,
238
254
Idx : SortedLinkedListIndex ,
239
255
K : Kind ,
256
+ S : Storage ,
240
257
{
241
258
/// Pushes a value onto the list without checking if the list is full.
242
259
///
@@ -335,8 +352,8 @@ where
335
352
/// assert_eq!(iter.next(), Some(&1));
336
353
/// assert_eq!(iter.next(), None);
337
354
/// ```
338
- pub fn iter ( & self ) -> Iter < ' _ , T , Idx , K , N > {
339
- Iter {
355
+ pub fn iter ( & self ) -> IterInner < ' _ , T , Idx , K , S > {
356
+ IterInner {
340
357
list : self ,
341
358
index : self . head ,
342
359
}
@@ -364,15 +381,15 @@ where
364
381
/// assert_eq!(ll.pop(), Ok(1));
365
382
/// assert_eq!(ll.pop(), Err(()));
366
383
/// ```
367
- pub fn find_mut < F > ( & mut self , mut f : F ) -> Option < FindMut < ' _ , T , Idx , K , N > >
384
+ pub fn find_mut < F > ( & mut self , mut f : F ) -> Option < FindMutInner < ' _ , T , Idx , K , S > >
368
385
where
369
386
F : FnMut ( & T ) -> bool ,
370
387
{
371
388
let head = self . head . option ( ) ?;
372
389
373
390
// Special-case, first element
374
391
if f ( self . read_data_in_node_at ( head) ) {
375
- return Some ( FindMut {
392
+ return Some ( FindMutInner {
376
393
is_head : true ,
377
394
prev_index : Idx :: none ( ) ,
378
395
index : self . head ,
@@ -385,7 +402,7 @@ where
385
402
386
403
while let Some ( next) = self . node_at ( current) . next . option ( ) {
387
404
if f ( self . read_data_in_node_at ( next) ) {
388
- return Some ( FindMut {
405
+ return Some ( FindMutInner {
389
406
is_head : false ,
390
407
prev_index : unsafe { Idx :: new_unchecked ( current) } ,
391
408
index : unsafe { Idx :: new_unchecked ( next) } ,
@@ -514,22 +531,32 @@ where
514
531
}
515
532
}
516
533
517
- /// Iterator for the linked list.
518
- pub struct Iter < ' a , T , Idx , K , const N : usize >
534
+ /// Base struct for [`Iter`] and [`IterView`], generic over the [`Storage`].
535
+ ///
536
+ /// In most cases you should use [`Iter`] or [`IterView`] directly. Only use this
537
+ /// struct if you want to write code that's generic over both.
538
+ pub struct IterInner < ' a , T , Idx , K , S >
519
539
where
520
540
T : Ord ,
521
541
Idx : SortedLinkedListIndex ,
522
542
K : Kind ,
543
+ S : Storage ,
523
544
{
524
- list : & ' a SortedLinkedList < T , Idx , K , N > ,
545
+ list : & ' a SortedLinkedListInner < T , Idx , K , S > ,
525
546
index : Idx ,
526
547
}
527
548
528
- impl < ' a , T , Idx , K , const N : usize > Iterator for Iter < ' a , T , Idx , K , N >
549
+ /// Iterator for the linked list.
550
+ pub type Iter < ' a , T , Idx , K , const N : usize > = IterInner < ' a , T , Idx , K , OwnedStorage < N > > ;
551
+ /// Iterator for the linked list.
552
+ pub type IterView < ' a , T , Idx , K , const N : usize > = IterInner < ' a , T , Idx , K , ViewStorage > ;
553
+
554
+ impl < ' a , T , Idx , K , S > Iterator for IterInner < ' a , T , Idx , K , S >
529
555
where
530
556
T : Ord ,
531
557
Idx : SortedLinkedListIndex ,
532
558
K : Kind ,
559
+ S : Storage ,
533
560
{
534
561
type Item = & ' a T ;
535
562
@@ -543,25 +570,35 @@ where
543
570
}
544
571
}
545
572
546
- /// Comes from [`SortedLinkedList::find_mut`].
547
- pub struct FindMut < ' a , T , Idx , K , const N : usize >
573
+ /// Base struct for [`FindMut`] and [`FindMutView`], generic over the [`Storage`].
574
+ ///
575
+ /// In most cases you should use [`FindMut`] or [`FindMutView`] directly. Only use this
576
+ /// struct if you want to write code that's generic over both.
577
+ pub struct FindMutInner < ' a , T , Idx , K , S >
548
578
where
549
579
T : Ord ,
550
580
Idx : SortedLinkedListIndex ,
551
581
K : Kind ,
582
+ S : Storage ,
552
583
{
553
- list : & ' a mut SortedLinkedList < T , Idx , K , N > ,
584
+ list : & ' a mut SortedLinkedListInner < T , Idx , K , S > ,
554
585
is_head : bool ,
555
586
prev_index : Idx ,
556
587
index : Idx ,
557
588
maybe_changed : bool ,
558
589
}
559
590
560
- impl < ' a , T , Idx , K , const N : usize > FindMut < ' a , T , Idx , K , N >
591
+ /// Comes from [`SortedLinkedList::find_mut`].
592
+ pub type FindMut < ' a , T , Idx , K , const N : usize > = FindMutInner < ' a , T , Idx , K , OwnedStorage < N > > ;
593
+ /// Comes from [`SortedLinkedList::find_mut`].
594
+ pub type FindMutView < ' a , T , Idx , K , const N : usize > = FindMutInner < ' a , T , Idx , K , ViewStorage > ;
595
+
596
+ impl < ' a , T , Idx , K , S > FindMutInner < ' a , T , Idx , K , S >
561
597
where
562
598
T : Ord ,
563
599
Idx : SortedLinkedListIndex ,
564
600
K : Kind ,
601
+ S : Storage ,
565
602
{
566
603
fn pop_internal ( & mut self ) -> T {
567
604
if self . is_head {
@@ -645,11 +682,12 @@ where
645
682
}
646
683
}
647
684
648
- impl < T , Idx , K , const N : usize > Drop for FindMut < ' _ , T , Idx , K , N >
685
+ impl < T , Idx , K , S > Drop for FindMutInner < ' _ , T , Idx , K , S >
649
686
where
650
687
T : Ord ,
651
688
Idx : SortedLinkedListIndex ,
652
689
K : Kind ,
690
+ S : Storage ,
653
691
{
654
692
fn drop ( & mut self ) {
655
693
// Only resort the list if the element has changed
@@ -660,11 +698,12 @@ where
660
698
}
661
699
}
662
700
663
- impl < T , Idx , K , const N : usize > Deref for FindMut < ' _ , T , Idx , K , N >
701
+ impl < T , Idx , K , S > Deref for FindMutInner < ' _ , T , Idx , K , S >
664
702
where
665
703
T : Ord ,
666
704
Idx : SortedLinkedListIndex ,
667
705
K : Kind ,
706
+ S : Storage ,
668
707
{
669
708
type Target = T ;
670
709
@@ -674,11 +713,12 @@ where
674
713
}
675
714
}
676
715
677
- impl < T , Idx , K , const N : usize > DerefMut for FindMut < ' _ , T , Idx , K , N >
716
+ impl < T , Idx , K , S > DerefMut for FindMutInner < ' _ , T , Idx , K , S >
678
717
where
679
718
T : Ord ,
680
719
Idx : SortedLinkedListIndex ,
681
720
K : Kind ,
721
+ S : Storage ,
682
722
{
683
723
fn deref_mut ( & mut self ) -> & mut Self :: Target {
684
724
self . maybe_changed = true ;
@@ -712,20 +752,22 @@ where
712
752
// }
713
753
// }
714
754
715
- impl < T , Idx , K , const N : usize > fmt:: Debug for SortedLinkedList < T , Idx , K , N >
755
+ impl < T , Idx , K , S > fmt:: Debug for SortedLinkedListInner < T , Idx , K , S >
716
756
where
717
757
T : Ord + core:: fmt:: Debug ,
718
758
Idx : SortedLinkedListIndex ,
719
759
K : Kind ,
760
+ S : Storage ,
720
761
{
721
762
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
722
763
f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
723
764
}
724
765
}
725
766
726
- impl < T , Idx , K , const N : usize > Drop for SortedLinkedList < T , Idx , K , N >
767
+ impl < T , Idx , K , S > Drop for SortedLinkedListInner < T , Idx , K , S >
727
768
where
728
769
Idx : SortedLinkedListIndex ,
770
+ S : Storage ,
729
771
{
730
772
fn drop ( & mut self ) {
731
773
let mut index = self . head ;
0 commit comments