@@ -104,17 +104,23 @@ impl<T> Rawlink<T> {
104
104
}
105
105
106
106
/// Convert the `Rawlink` into an Option value
107
- fn resolve_immut < ' a > ( & self ) -> Option < & ' a T > {
108
- unsafe {
109
- self . p . as_ref ( )
110
- }
107
+ ///
108
+ /// **unsafe** because:
109
+ ///
110
+ /// - Dereference of raw pointer.
111
+ /// - Returns reference of arbitrary lifetime.
112
+ unsafe fn resolve < ' a > ( & self ) -> Option < & ' a T > {
113
+ self . p . as_ref ( )
111
114
}
112
115
113
116
/// Convert the `Rawlink` into an Option value
114
- fn resolve < ' a > ( & mut self ) -> Option < & ' a mut T > {
115
- unsafe {
116
- self . p . as_mut ( )
117
- }
117
+ ///
118
+ /// **unsafe** because:
119
+ ///
120
+ /// - Dereference of raw pointer.
121
+ /// - Returns reference of arbitrary lifetime.
122
+ unsafe fn resolve_mut < ' a > ( & mut self ) -> Option < & ' a mut T > {
123
+ self . p . as_mut ( )
118
124
}
119
125
120
126
/// Return the `Rawlink` and replace with `Rawlink::none()`
@@ -123,6 +129,15 @@ impl<T> Rawlink<T> {
123
129
}
124
130
}
125
131
132
+ impl < ' a , T > From < & ' a mut Link < T > > for Rawlink < Node < T > > {
133
+ fn from ( node : & ' a mut Link < T > ) -> Self {
134
+ match node. as_mut ( ) {
135
+ None => Rawlink :: none ( ) ,
136
+ Some ( ptr) => Rawlink :: some ( ptr) ,
137
+ }
138
+ }
139
+ }
140
+
126
141
impl < T > Clone for Rawlink < T > {
127
142
#[ inline]
128
143
fn clone ( & self ) -> Rawlink < T > {
@@ -134,12 +149,21 @@ impl<T> Node<T> {
134
149
fn new ( v : T ) -> Node < T > {
135
150
Node { value : v, next : None , prev : Rawlink :: none ( ) }
136
151
}
152
+
153
+ /// Update the `prev` link on `next`, then set self's next pointer.
154
+ ///
155
+ /// `self.next` should be `None` when you call this
156
+ /// (otherwise a Node is probably being dropped by mistake).
157
+ fn set_next ( & mut self , mut next : Box < Node < T > > ) {
158
+ debug_assert ! ( self . next. is_none( ) ) ;
159
+ next. prev = Rawlink :: some ( self ) ;
160
+ self . next = Some ( next) ;
161
+ }
137
162
}
138
163
139
- /// Set the .prev field on `next`, then return `Some(next)`
140
- fn link_with_prev < T > ( mut next : Box < Node < T > > , prev : Rawlink < Node < T > > )
141
- -> Link < T > {
142
- next. prev = prev;
164
+ /// Clear the .prev field on `next`, then return `Some(next)`
165
+ fn link_no_prev < T > ( mut next : Box < Node < T > > ) -> Link < T > {
166
+ next. prev = Rawlink :: none ( ) ;
143
167
Some ( next)
144
168
}
145
169
@@ -150,8 +174,8 @@ impl<T> LinkedList<T> {
150
174
fn push_front_node ( & mut self , mut new_head : Box < Node < T > > ) {
151
175
match self . list_head {
152
176
None => {
153
- self . list_tail = Rawlink :: some ( & mut * new_head) ;
154
- self . list_head = link_with_prev ( new_head , Rawlink :: none ( ) ) ;
177
+ self . list_head = link_no_prev ( new_head) ;
178
+ self . list_tail = Rawlink :: from ( & mut self . list_head ) ;
155
179
}
156
180
Some ( ref mut head) => {
157
181
new_head. prev = Rawlink :: none ( ) ;
@@ -169,7 +193,7 @@ impl<T> LinkedList<T> {
169
193
self . list_head . take ( ) . map ( |mut front_node| {
170
194
self . length -= 1 ;
171
195
match front_node. next . take ( ) {
172
- Some ( node) => self . list_head = link_with_prev ( node, Rawlink :: none ( ) ) ,
196
+ Some ( node) => self . list_head = link_no_prev ( node) ,
173
197
None => self . list_tail = Rawlink :: none ( )
174
198
}
175
199
front_node
@@ -178,12 +202,12 @@ impl<T> LinkedList<T> {
178
202
179
203
/// Add a Node last in the list
180
204
#[ inline]
181
- fn push_back_node ( & mut self , mut new_tail : Box < Node < T > > ) {
182
- match self . list_tail . resolve ( ) {
205
+ fn push_back_node ( & mut self , new_tail : Box < Node < T > > ) {
206
+ match unsafe { self . list_tail . resolve_mut ( ) } {
183
207
None => return self . push_front_node ( new_tail) ,
184
208
Some ( tail) => {
185
- self . list_tail = Rawlink :: some ( & mut * new_tail) ;
186
- tail . next = link_with_prev ( new_tail , Rawlink :: some ( tail) ) ;
209
+ tail . set_next ( new_tail) ;
210
+ self . list_tail = Rawlink :: from ( & mut tail. next ) ;
187
211
}
188
212
}
189
213
self . length += 1 ;
@@ -192,14 +216,16 @@ impl<T> LinkedList<T> {
192
216
/// Remove the last Node and return it, or None if the list is empty
193
217
#[ inline]
194
218
fn pop_back_node ( & mut self ) -> Option < Box < Node < T > > > {
195
- self . list_tail . resolve ( ) . map_or ( None , |tail| {
196
- self . length -= 1 ;
197
- self . list_tail = tail. prev ;
198
- match tail. prev . resolve ( ) {
199
- None => self . list_head . take ( ) ,
200
- Some ( tail_prev) => tail_prev. next . take ( )
201
- }
202
- } )
219
+ unsafe {
220
+ self . list_tail . resolve_mut ( ) . and_then ( |tail| {
221
+ self . length -= 1 ;
222
+ self . list_tail = tail. prev ;
223
+ match tail. prev . resolve_mut ( ) {
224
+ None => self . list_head . take ( ) ,
225
+ Some ( tail_prev) => tail_prev. next . take ( )
226
+ }
227
+ } )
228
+ }
203
229
}
204
230
}
205
231
@@ -246,7 +272,7 @@ impl<T> LinkedList<T> {
246
272
/// ```
247
273
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
248
274
pub fn append ( & mut self , other : & mut LinkedList < T > ) {
249
- match self . list_tail . resolve ( ) {
275
+ match unsafe { self . list_tail . resolve_mut ( ) } {
250
276
None => {
251
277
self . length = other. length ;
252
278
self . list_head = other. list_head . take ( ) ;
@@ -259,7 +285,7 @@ impl<T> LinkedList<T> {
259
285
match other. list_head . take ( ) {
260
286
None => return ,
261
287
Some ( node) => {
262
- tail. next = link_with_prev ( node, self . list_tail ) ;
288
+ tail. set_next ( node) ;
263
289
self . list_tail = o_tail;
264
290
self . length += o_length;
265
291
}
@@ -280,13 +306,9 @@ impl<T> LinkedList<T> {
280
306
#[ inline]
281
307
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
282
308
pub fn iter_mut ( & mut self ) -> IterMut < T > {
283
- let head_raw = match self . list_head {
284
- Some ( ref mut h) => Rawlink :: some ( & mut * * h) ,
285
- None => Rawlink :: none ( ) ,
286
- } ;
287
- IterMut {
309
+ IterMut {
288
310
nelem : self . len ( ) ,
289
- head : head_raw ,
311
+ head : Rawlink :: from ( & mut self . list_head ) ,
290
312
tail : self . list_tail ,
291
313
list : self
292
314
}
@@ -433,7 +455,9 @@ impl<T> LinkedList<T> {
433
455
#[ inline]
434
456
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
435
457
pub fn back ( & self ) -> Option < & T > {
436
- self . list_tail . resolve_immut ( ) . as_ref ( ) . map ( |tail| & tail. value )
458
+ unsafe {
459
+ self . list_tail . resolve ( ) . map ( |tail| & tail. value )
460
+ }
437
461
}
438
462
439
463
/// Provides a mutable reference to the back element, or `None` if the list
@@ -460,7 +484,9 @@ impl<T> LinkedList<T> {
460
484
#[ inline]
461
485
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
462
486
pub fn back_mut ( & mut self ) -> Option < & mut T > {
463
- self . list_tail . resolve ( ) . map ( |tail| & mut tail. value )
487
+ unsafe {
488
+ self . list_tail . resolve_mut ( ) . map ( |tail| & mut tail. value )
489
+ }
464
490
}
465
491
466
492
/// Adds an element first in the list.
@@ -603,44 +629,42 @@ impl<T> LinkedList<T> {
603
629
iter. tail
604
630
} ;
605
631
606
- let mut splitted_list = LinkedList {
607
- list_head : None ,
632
+ // The split node is the new tail node of the first part and owns
633
+ // the head of the second part.
634
+ let mut second_part_head;
635
+
636
+ unsafe {
637
+ second_part_head = split_node. resolve_mut ( ) . unwrap ( ) . next . take ( ) ;
638
+ match second_part_head {
639
+ None => { }
640
+ Some ( ref mut head) => head. prev = Rawlink :: none ( ) ,
641
+ }
642
+ }
643
+
644
+ let second_part = LinkedList {
645
+ list_head : second_part_head,
608
646
list_tail : self . list_tail ,
609
647
length : len - at
610
648
} ;
611
649
612
- // Swap split_node.next with list_head (which is None), nulling out split_node.next,
613
- // as it is the new tail.
614
- mem:: swap ( & mut split_node. resolve ( ) . unwrap ( ) . next , & mut splitted_list. list_head ) ;
615
- // Null out list_head.prev. Note this `unwrap` won't fail because if at == len
616
- // we already branched out at the top of the fn to return the empty list.
617
- splitted_list. list_head . as_mut ( ) . unwrap ( ) . prev = Rawlink :: none ( ) ;
618
- // Fix the tail ptr
650
+ // Fix the tail ptr of the first part
619
651
self . list_tail = split_node;
620
652
self . length = at;
621
653
622
- splitted_list
654
+ second_part
623
655
}
624
656
}
625
657
626
658
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
627
659
impl < T > Drop for LinkedList < T > {
628
660
fn drop ( & mut self ) {
629
- // Dissolve the linked_list in backwards direction
661
+ // Dissolve the linked_list in a loop.
630
662
// Just dropping the list_head can lead to stack exhaustion
631
663
// when length is >> 1_000_000
632
- let mut tail = self . list_tail ;
633
- loop {
634
- match tail. resolve ( ) {
635
- None => break ,
636
- Some ( prev) => {
637
- prev. next . take ( ) ; // release Box<Node<T>>
638
- tail = prev. prev ;
639
- }
640
- }
664
+ while let Some ( mut head_) = self . list_head . take ( ) {
665
+ self . list_head = head_. next . take ( ) ;
641
666
}
642
667
self . length = 0 ;
643
- self . list_head = None ;
644
668
self . list_tail = Rawlink :: none ( ) ;
645
669
}
646
670
}
@@ -674,11 +698,13 @@ impl<'a, A> DoubleEndedIterator for Iter<'a, A> {
674
698
if self . nelem == 0 {
675
699
return None ;
676
700
}
677
- self . tail . resolve_immut ( ) . as_ref ( ) . map ( |prev| {
678
- self . nelem -= 1 ;
679
- self . tail = prev. prev ;
680
- & prev. value
681
- } )
701
+ unsafe {
702
+ self . tail . resolve ( ) . map ( |prev| {
703
+ self . nelem -= 1 ;
704
+ self . tail = prev. prev ;
705
+ & prev. value
706
+ } )
707
+ }
682
708
}
683
709
}
684
710
@@ -693,14 +719,13 @@ impl<'a, A> Iterator for IterMut<'a, A> {
693
719
if self . nelem == 0 {
694
720
return None ;
695
721
}
696
- self . head . resolve ( ) . map ( |next| {
697
- self . nelem -= 1 ;
698
- self . head = match next. next {
699
- Some ( ref mut node) => Rawlink :: some ( & mut * * node) ,
700
- None => Rawlink :: none ( ) ,
701
- } ;
702
- & mut next. value
703
- } )
722
+ unsafe {
723
+ self . head . resolve_mut ( ) . map ( |next| {
724
+ self . nelem -= 1 ;
725
+ self . head = Rawlink :: from ( & mut next. next ) ;
726
+ & mut next. value
727
+ } )
728
+ }
704
729
}
705
730
706
731
#[ inline]
@@ -716,11 +741,13 @@ impl<'a, A> DoubleEndedIterator for IterMut<'a, A> {
716
741
if self . nelem == 0 {
717
742
return None ;
718
743
}
719
- self . tail . resolve ( ) . map ( |prev| {
720
- self . nelem -= 1 ;
721
- self . tail = prev. prev ;
722
- & mut prev. value
723
- } )
744
+ unsafe {
745
+ self . tail . resolve_mut ( ) . map ( |prev| {
746
+ self . nelem -= 1 ;
747
+ self . tail = prev. prev ;
748
+ & mut prev. value
749
+ } )
750
+ }
724
751
}
725
752
}
726
753
@@ -734,16 +761,16 @@ impl<'a, A> IterMut<'a, A> {
734
761
// previously yielded element and self.head.
735
762
//
736
763
// The inserted node will not appear in further iteration.
737
- match self . head . resolve ( ) {
764
+ match unsafe { self . head . resolve_mut ( ) } {
738
765
None => { self . list . push_back_node ( ins_node) ; }
739
766
Some ( node) => {
740
- let prev_node = match node. prev . resolve ( ) {
767
+ let prev_node = match unsafe { node. prev . resolve_mut ( ) } {
741
768
None => return self . list . push_front_node ( ins_node) ,
742
769
Some ( prev) => prev,
743
770
} ;
744
771
let node_own = prev_node. next . take ( ) . unwrap ( ) ;
745
- ins_node. next = link_with_prev ( node_own, Rawlink :: some ( & mut * ins_node ) ) ;
746
- prev_node. next = link_with_prev ( ins_node, Rawlink :: some ( prev_node ) ) ;
772
+ ins_node. set_next ( node_own) ;
773
+ prev_node. set_next ( ins_node) ;
747
774
self . list . length += 1 ;
748
775
}
749
776
}
@@ -803,7 +830,9 @@ impl<'a, A> IterMut<'a, A> {
803
830
if self . nelem == 0 {
804
831
return None
805
832
}
806
- self . head . resolve ( ) . map ( |head| & mut head. value )
833
+ unsafe {
834
+ self . head . resolve_mut ( ) . map ( |head| & mut head. value )
835
+ }
807
836
}
808
837
}
809
838
@@ -933,7 +962,7 @@ impl<A: Hash> Hash for LinkedList<A> {
933
962
#[ cfg( test) ]
934
963
mod tests {
935
964
use std:: clone:: Clone ;
936
- use std:: iter:: { Iterator , IntoIterator } ;
965
+ use std:: iter:: { Iterator , IntoIterator , Extend } ;
937
966
use std:: option:: Option :: { Some , None , self } ;
938
967
use std:: __rand:: { thread_rng, Rng } ;
939
968
use std:: thread;
@@ -955,7 +984,7 @@ mod tests {
955
984
Some ( ref node) => node_ptr = & * * node,
956
985
}
957
986
loop {
958
- match ( last_ptr, node_ptr. prev . resolve_immut ( ) ) {
987
+ match unsafe { ( last_ptr, node_ptr. prev . resolve ( ) ) } {
959
988
( None , None ) => { }
960
989
( None , _ ) => panic ! ( "prev link for list_head" ) ,
961
990
( Some ( p) , Some ( pptr) ) => {
@@ -1101,6 +1130,26 @@ mod tests {
1101
1130
assert_eq ! ( v1. iter( ) . collect:: <Vec <_>>( ) . len( ) , 3 ) ;
1102
1131
}
1103
1132
1133
+ #[ test]
1134
+ fn test_split_off ( ) {
1135
+ let mut v1 = LinkedList :: new ( ) ;
1136
+ v1. push_front ( 1u8 ) ;
1137
+ v1. push_front ( 1u8 ) ;
1138
+ v1. push_front ( 1u8 ) ;
1139
+ v1. push_front ( 1u8 ) ;
1140
+
1141
+ // test all splits
1142
+ for ix in 0 ..1 + v1. len ( ) {
1143
+ let mut a = v1. clone ( ) ;
1144
+ let b = a. split_off ( ix) ;
1145
+ check_links ( & a) ;
1146
+ check_links ( & b) ;
1147
+ a. extend ( b) ;
1148
+ assert_eq ! ( v1, a) ;
1149
+ }
1150
+ }
1151
+
1152
+
1104
1153
#[ cfg( test) ]
1105
1154
fn fuzz_test ( sz : i32 ) {
1106
1155
let mut m: LinkedList < _ > = LinkedList :: new ( ) ;
0 commit comments