@@ -92,6 +92,11 @@ impl<T> Rawlink<T> {
92
92
Some ( unsafe { cast:: transmute ( self . p ) } )
93
93
}
94
94
}
95
+
96
+ /// Return the `Rawlink` and replace with `Rawlink::none()`
97
+ fn take ( & mut self ) -> Rawlink < T > {
98
+ util:: replace ( self , Rawlink :: none ( ) )
99
+ }
95
100
}
96
101
97
102
impl < T > Clone for Rawlink < T > {
@@ -280,13 +285,16 @@ impl<T> DList<T> {
280
285
/// Add all elements from `other` to the end of the list
281
286
///
282
287
/// O(1)
283
- pub fn append ( & mut self , other : DList < T > ) {
288
+ pub fn append ( & mut self , mut other : DList < T > ) {
284
289
match self . list_tail . resolve ( ) {
285
290
None => * self = other,
286
291
Some ( tail) => {
287
- match other {
288
- DList { list_head : None , _} => return ,
289
- DList { list_head : Some ( node) , list_tail : o_tail, length : o_length} => {
292
+ // Carefully empty `other`.
293
+ let o_tail = other. list_tail . take ( ) ;
294
+ let o_length = other. length ;
295
+ match other. list_head . take ( ) {
296
+ None => return ,
297
+ Some ( node) => {
290
298
tail. next = link_with_prev ( node, self . list_tail ) ;
291
299
self . list_tail = o_tail;
292
300
self . length += o_length;
@@ -404,6 +412,32 @@ impl<T: Ord> DList<T> {
404
412
}
405
413
}
406
414
415
+ #[ unsafe_destructor]
416
+ impl < T > Drop for DList < T > {
417
+ fn drop ( & self ) {
418
+ let mut_self = unsafe {
419
+ cast:: transmute_mut ( self )
420
+ } ;
421
+ // Dissolve the dlist in backwards direction
422
+ // Just dropping the list_head can lead to stack exhaustion
423
+ // when length is >> 1_000_000
424
+ let mut tail = mut_self. list_tail ;
425
+ loop {
426
+ match tail. resolve ( ) {
427
+ None => break ,
428
+ Some ( prev) => {
429
+ prev. next . take ( ) ; // release ~Node<T>
430
+ tail = prev. prev ;
431
+ }
432
+ }
433
+ }
434
+ mut_self. length = 0 ;
435
+ mut_self. list_head = None ;
436
+ mut_self. list_tail = Rawlink :: none ( ) ;
437
+ }
438
+ }
439
+
440
+
407
441
impl < ' self , A > Iterator < & ' self A > for DListIterator < ' self , A > {
408
442
#[ inline]
409
443
fn next ( & mut self ) -> Option < & ' self A > {
0 commit comments