26
26
//!
27
27
//! [`BinaryHeap`]: `crate::binary_heap::BinaryHeap`
28
28
29
+ use core:: borrow:: { Borrow , BorrowMut } ;
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,28 @@ 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 , 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
+
97
111
// Internal macro for generating indexes for the linkedlist and const new for the linked list
98
112
macro_rules! impl_index_and_const_new {
99
113
( $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 }
186
200
impl < T , Idx , K , const N : usize > SortedLinkedList < T , Idx , K , N >
187
201
where
188
202
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 ,
189
219
{
190
220
/// Internal access helper
191
221
#[ inline( always) ]
192
222
fn node_at ( & self , index : usize ) -> & Node < T , Idx > {
193
223
// 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) }
195
225
}
196
226
197
227
/// Internal access helper
198
228
#[ inline( always) ]
199
229
fn node_at_mut ( & mut self , index : usize ) -> & mut Node < T , Idx > {
200
230
// 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) }
202
232
}
203
233
204
234
/// Internal access helper
@@ -232,11 +262,12 @@ where
232
262
}
233
263
}
234
264
235
- impl < T , Idx , K , const N : usize > SortedLinkedList < T , Idx , K , N >
265
+ impl < T , Idx , K , S > SortedLinkedListInner < T , Idx , K , S >
236
266
where
237
267
T : Ord ,
238
268
Idx : SortedLinkedListIndex ,
239
269
K : Kind ,
270
+ S : Storage ,
240
271
{
241
272
/// Pushes a value onto the list without checking if the list is full.
242
273
///
@@ -335,8 +366,8 @@ where
335
366
/// assert_eq!(iter.next(), Some(&1));
336
367
/// assert_eq!(iter.next(), None);
337
368
/// ```
338
- pub fn iter ( & self ) -> Iter < ' _ , T , Idx , K , N > {
339
- Iter {
369
+ pub fn iter ( & self ) -> IterInner < ' _ , T , Idx , K , S > {
370
+ IterInner {
340
371
list : self ,
341
372
index : self . head ,
342
373
}
@@ -364,15 +395,15 @@ where
364
395
/// assert_eq!(ll.pop(), Ok(1));
365
396
/// assert_eq!(ll.pop(), Err(()));
366
397
/// ```
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 > >
368
399
where
369
400
F : FnMut ( & T ) -> bool ,
370
401
{
371
402
let head = self . head . option ( ) ?;
372
403
373
404
// Special-case, first element
374
405
if f ( self . read_data_in_node_at ( head) ) {
375
- return Some ( FindMut {
406
+ return Some ( FindMutInner {
376
407
is_head : true ,
377
408
prev_index : Idx :: none ( ) ,
378
409
index : self . head ,
@@ -385,7 +416,7 @@ where
385
416
386
417
while let Some ( next) = self . node_at ( current) . next . option ( ) {
387
418
if f ( self . read_data_in_node_at ( next) ) {
388
- return Some ( FindMut {
419
+ return Some ( FindMutInner {
389
420
is_head : false ,
390
421
prev_index : unsafe { Idx :: new_unchecked ( current) } ,
391
422
index : unsafe { Idx :: new_unchecked ( next) } ,
@@ -514,22 +545,32 @@ where
514
545
}
515
546
}
516
547
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 >
519
553
where
520
554
T : Ord ,
521
555
Idx : SortedLinkedListIndex ,
522
556
K : Kind ,
557
+ S : Storage ,
523
558
{
524
- list : & ' a SortedLinkedList < T , Idx , K , N > ,
559
+ list : & ' a SortedLinkedListInner < T , Idx , K , S > ,
525
560
index : Idx ,
526
561
}
527
562
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 >
529
569
where
530
570
T : Ord ,
531
571
Idx : SortedLinkedListIndex ,
532
572
K : Kind ,
573
+ S : Storage ,
533
574
{
534
575
type Item = & ' a T ;
535
576
@@ -543,25 +584,35 @@ where
543
584
}
544
585
}
545
586
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 >
548
592
where
549
593
T : Ord ,
550
594
Idx : SortedLinkedListIndex ,
551
595
K : Kind ,
596
+ S : Storage ,
552
597
{
553
- list : & ' a mut SortedLinkedList < T , Idx , K , N > ,
598
+ list : & ' a mut SortedLinkedListInner < T , Idx , K , S > ,
554
599
is_head : bool ,
555
600
prev_index : Idx ,
556
601
index : Idx ,
557
602
maybe_changed : bool ,
558
603
}
559
604
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 >
561
611
where
562
612
T : Ord ,
563
613
Idx : SortedLinkedListIndex ,
564
614
K : Kind ,
615
+ S : Storage ,
565
616
{
566
617
fn pop_internal ( & mut self ) -> T {
567
618
if self . is_head {
@@ -645,11 +696,12 @@ where
645
696
}
646
697
}
647
698
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 >
649
700
where
650
701
T : Ord ,
651
702
Idx : SortedLinkedListIndex ,
652
703
K : Kind ,
704
+ S : Storage ,
653
705
{
654
706
fn drop ( & mut self ) {
655
707
// Only resort the list if the element has changed
@@ -660,11 +712,12 @@ where
660
712
}
661
713
}
662
714
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 >
664
716
where
665
717
T : Ord ,
666
718
Idx : SortedLinkedListIndex ,
667
719
K : Kind ,
720
+ S : Storage ,
668
721
{
669
722
type Target = T ;
670
723
@@ -674,11 +727,12 @@ where
674
727
}
675
728
}
676
729
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 >
678
731
where
679
732
T : Ord ,
680
733
Idx : SortedLinkedListIndex ,
681
734
K : Kind ,
735
+ S : Storage ,
682
736
{
683
737
fn deref_mut ( & mut self ) -> & mut Self :: Target {
684
738
self . maybe_changed = true ;
@@ -712,20 +766,22 @@ where
712
766
// }
713
767
// }
714
768
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 >
716
770
where
717
771
T : Ord + core:: fmt:: Debug ,
718
772
Idx : SortedLinkedListIndex ,
719
773
K : Kind ,
774
+ S : Storage ,
720
775
{
721
776
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
722
777
f. debug_list ( ) . entries ( self . iter ( ) ) . finish ( )
723
778
}
724
779
}
725
780
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 >
727
782
where
728
783
Idx : SortedLinkedListIndex ,
784
+ S : Storage ,
729
785
{
730
786
fn drop ( & mut self ) {
731
787
let mut index = self . head ;
0 commit comments