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) => {
@@ -186,19 +201,35 @@ impl_index_and_const_new!(LinkedIndexUsize, usize, new_usize, { usize::MAX - 1 }
186
201
impl < T , Idx , K , const N : usize > SortedLinkedList < T , Idx , K , N >
187
202
where
188
203
Idx : SortedLinkedListIndex ,
204
+ {
205
+ /// Get a reference to the `SortedLinkedList`, erasing the `N` const-generic.
206
+ pub fn as_view ( & self ) -> & SortedLinkedListView < T , Idx , K > {
207
+ self
208
+ }
209
+
210
+ /// Get a mutable reference to the `Vec`, erasing the `N` const-generic.
211
+ pub fn as_mut_view ( & mut self ) -> & mut SortedLinkedListView < T , Idx , K > {
212
+ self
213
+ }
214
+ }
215
+
216
+ impl < T , Idx , K , S > SortedLinkedListInner < T , Idx , K , S >
217
+ where
218
+ Idx : SortedLinkedListIndex ,
219
+ S : Storage ,
189
220
{
190
221
/// Internal access helper
191
222
#[ inline( always) ]
192
223
fn node_at ( & self , index : usize ) -> & Node < T , Idx > {
193
224
// Safety: The entire `self.list` is initialized in `new`, which makes this safe.
194
- unsafe { self . list . get_unchecked ( index) }
225
+ unsafe { self . list . borrow ( ) . get_unchecked ( index) }
195
226
}
196
227
197
228
/// Internal access helper
198
229
#[ inline( always) ]
199
230
fn node_at_mut ( & mut self , index : usize ) -> & mut Node < T , Idx > {
200
231
// Safety: The entire `self.list` is initialized in `new`, which makes this safe.
201
- unsafe { self . list . get_unchecked_mut ( index) }
232
+ unsafe { self . list . borrow ( ) . get_unchecked_mut ( index) }
202
233
}
203
234
204
235
/// Internal access helper
@@ -232,11 +263,12 @@ where
232
263
}
233
264
}
234
265
235
- impl < T , Idx , K , const N : usize > SortedLinkedList < T , Idx , K , N >
266
+ impl < T , Idx , K , S > SortedLinkedListInner < T , Idx , K , S >
236
267
where
237
268
T : Ord ,
238
269
Idx : SortedLinkedListIndex ,
239
270
K : Kind ,
271
+ S : Storage ,
240
272
{
241
273
/// Pushes a value onto the list without checking if the list is full.
242
274
///
@@ -335,8 +367,8 @@ where
335
367
/// assert_eq!(iter.next(), Some(&1));
336
368
/// assert_eq!(iter.next(), None);
337
369
/// ```
338
- pub fn iter ( & self ) -> Iter < ' _ , T , Idx , K , N > {
339
- Iter {
370
+ pub fn iter ( & self ) -> IterInner < ' _ , T , Idx , K , S > {
371
+ IterInner {
340
372
list : self ,
341
373
index : self . head ,
342
374
}
@@ -364,15 +396,15 @@ where
364
396
/// assert_eq!(ll.pop(), Ok(1));
365
397
/// assert_eq!(ll.pop(), Err(()));
366
398
/// ```
367
- pub fn find_mut < F > ( & mut self , mut f : F ) -> Option < FindMut < ' _ , T , Idx , K , N > >
399
+ pub fn find_mut < F > ( & mut self , mut f : F ) -> Option < FindMutInner < ' _ , T , Idx , K , S > >
368
400
where
369
401
F : FnMut ( & T ) -> bool ,
370
402
{
371
403
let head = self . head . option ( ) ?;
372
404
373
405
// Special-case, first element
374
406
if f ( self . read_data_in_node_at ( head) ) {
375
- return Some ( FindMut {
407
+ return Some ( FindMutInner {
376
408
is_head : true ,
377
409
prev_index : Idx :: none ( ) ,
378
410
index : self . head ,
@@ -385,7 +417,7 @@ where
385
417
386
418
while let Some ( next) = self . node_at ( current) . next . option ( ) {
387
419
if f ( self . read_data_in_node_at ( next) ) {
388
- return Some ( FindMut {
420
+ return Some ( FindMutInner {
389
421
is_head : false ,
390
422
prev_index : unsafe { Idx :: new_unchecked ( current) } ,
391
423
index : unsafe { Idx :: new_unchecked ( next) } ,
@@ -514,22 +546,32 @@ where
514
546
}
515
547
}
516
548
517
- /// Iterator for the linked list.
518
- pub struct Iter < ' a , T , Idx , K , const N : usize >
549
+ /// Base struct for [`Iter`] and [`IterView`], generic over the [`Storage`].
550
+ ///
551
+ /// In most cases you should use [`Iter`] or [`IterView`] directly. Only use this
552
+ /// struct if you want to write code that's generic over both.
553
+ pub struct IterInner < ' a , T , Idx , K , S >
519
554
where
520
555
T : Ord ,
521
556
Idx : SortedLinkedListIndex ,
522
557
K : Kind ,
558
+ S : Storage ,
523
559
{
524
- list : & ' a SortedLinkedList < T , Idx , K , N > ,
560
+ list : & ' a SortedLinkedListInner < T , Idx , K , S > ,
525
561
index : Idx ,
526
562
}
527
563
528
- impl < ' a , T , Idx , K , const N : usize > Iterator for Iter < ' a , T , Idx , K , N >
564
+ /// Iterator for the linked list.
565
+ pub type Iter < ' a , T , Idx , K , const N : usize > = IterInner < ' a , T , Idx , K , OwnedStorage < N > > ;
566
+ /// Iterator for the linked list.
567
+ pub type IterView < ' a , T , Idx , K , const N : usize > = IterInner < ' a , T , Idx , K , ViewStorage > ;
568
+
569
+ impl < ' a , T , Idx , K , S > Iterator for IterInner < ' a , T , Idx , K , S >
529
570
where
530
571
T : Ord ,
531
572
Idx : SortedLinkedListIndex ,
532
573
K : Kind ,
574
+ S : Storage ,
533
575
{
534
576
type Item = & ' a T ;
535
577
@@ -543,25 +585,35 @@ where
543
585
}
544
586
}
545
587
546
- /// Comes from [`SortedLinkedList::find_mut`].
547
- pub struct FindMut < ' a , T , Idx , K , const N : usize >
588
+ /// Base struct for [`FindMut`] and [`FindMutView`], generic over the [`Storage`].
589
+ ///
590
+ /// In most cases you should use [`FindMut`] or [`FindMutView`] directly. Only use this
591
+ /// struct if you want to write code that's generic over both.
592
+ pub struct FindMutInner < ' a , T , Idx , K , S >
548
593
where
549
594
T : Ord ,
550
595
Idx : SortedLinkedListIndex ,
551
596
K : Kind ,
597
+ S : Storage ,
552
598
{
553
- list : & ' a mut SortedLinkedList < T , Idx , K , N > ,
599
+ list : & ' a mut SortedLinkedListInner < T , Idx , K , S > ,
554
600
is_head : bool ,
555
601
prev_index : Idx ,
556
602
index : Idx ,
557
603
maybe_changed : bool ,
558
604
}
559
605
560
- impl < ' a , T , Idx , K , const N : usize > FindMut < ' a , T , Idx , K , N >
606
+ /// Comes from [`SortedLinkedList::find_mut`].
607
+ pub type FindMut < ' a , T , Idx , K , const N : usize > = FindMutInner < ' a , T , Idx , K , OwnedStorage < N > > ;
608
+ /// Comes from [`SortedLinkedList::find_mut`].
609
+ pub type FindMutView < ' a , T , Idx , K , const N : usize > = FindMutInner < ' a , T , Idx , K , ViewStorage > ;
610
+
611
+ impl < ' a , T , Idx , K , S > FindMutInner < ' a , T , Idx , K , S >
561
612
where
562
613
T : Ord ,
563
614
Idx : SortedLinkedListIndex ,
564
615
K : Kind ,
616
+ S : Storage ,
565
617
{
566
618
fn pop_internal ( & mut self ) -> T {
567
619
if self . is_head {
@@ -645,11 +697,12 @@ where
645
697
}
646
698
}
647
699
648
- impl < T , Idx , K , const N : usize > Drop for FindMut < ' _ , T , Idx , K , N >
700
+ impl < T , Idx , K , S > Drop for FindMutInner < ' _ , T , Idx , K , S >
649
701
where
650
702
T : Ord ,
651
703
Idx : SortedLinkedListIndex ,
652
704
K : Kind ,
705
+ S : Storage ,
653
706
{
654
707
fn drop ( & mut self ) {
655
708
// Only resort the list if the element has changed
@@ -660,11 +713,12 @@ where
660
713
}
661
714
}
662
715
663
- impl < T , Idx , K , const N : usize > Deref for FindMut < ' _ , T , Idx , K , N >
716
+ impl < T , Idx , K , S > Deref for FindMutInner < ' _ , T , Idx , K , S >
664
717
where
665
718
T : Ord ,
666
719
Idx : SortedLinkedListIndex ,
667
720
K : Kind ,
721
+ S : Storage ,
668
722
{
669
723
type Target = T ;
670
724
@@ -674,11 +728,12 @@ where
674
728
}
675
729
}
676
730
677
- impl < T , Idx , K , const N : usize > DerefMut for FindMut < ' _ , T , Idx , K , N >
731
+ impl < T , Idx , K , S > DerefMut for FindMutInner < ' _ , T , Idx , K , S >
678
732
where
679
733
T : Ord ,
680
734
Idx : SortedLinkedListIndex ,
681
735
K : Kind ,
736
+ S : Storage ,
682
737
{
683
738
fn deref_mut ( & mut self ) -> & mut Self :: Target {
684
739
self . maybe_changed = true ;
@@ -712,20 +767,22 @@ where
712
767
// }
713
768
// }
714
769
715
- impl < T , Idx , K , const N : usize > fmt:: Debug for SortedLinkedList < T , Idx , K , N >
770
+ impl < T , Idx , K , S > fmt:: Debug for SortedLinkedListInner < T , Idx , K , S >
716
771
where
717
772
T : Ord + core:: fmt:: Debug ,
718
773
Idx : SortedLinkedListIndex ,
719
774
K : Kind ,
775
+ S : Storage ,
720
776
{
721
777
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
722
778
f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
723
779
}
724
780
}
725
781
726
- impl < T , Idx , K , const N : usize > Drop for SortedLinkedList < T , Idx , K , N >
782
+ impl < T , Idx , K , S > Drop for SortedLinkedListInner < T , Idx , K , S >
727
783
where
728
784
Idx : SortedLinkedListIndex ,
785
+ S : Storage ,
729
786
{
730
787
fn drop ( & mut self ) {
731
788
let mut index = self . head ;
0 commit comments