@@ -221,9 +221,12 @@ impl<T> DList<T> {
221
221
DList { list_head : None , list_tail : Rawlink :: none ( ) , length : 0 }
222
222
}
223
223
224
- /// Adds all elements from `other` to the end of the list.
224
+ /// Moves all elements from `other` to the end of the list.
225
225
///
226
- /// This operation should compute in O(1) time.
226
+ /// This reuses all the nodes from `other` and moves them into `self`. After
227
+ /// this operation, `other` becomes empty.
228
+ ///
229
+ /// This operation should compute in O(1) time and O(1) memory.
227
230
///
228
231
/// # Examples
229
232
///
@@ -237,16 +240,20 @@ impl<T> DList<T> {
237
240
/// b.push_back(3i);
238
241
/// b.push_back(4);
239
242
///
240
- /// a.append(b);
243
+ /// a.append(&mut b);
241
244
///
242
245
/// for e in a.iter() {
243
246
/// println!("{}", e); // prints 1, then 2, then 3, then 4
244
247
/// }
248
+ /// println!("{}", b.len()); // prints 0
245
249
/// ```
246
- #[ unstable = "append should be by-mutable-reference" ]
247
- pub fn append ( & mut self , mut other : DList < T > ) {
250
+ pub fn append ( & mut self , other : & mut DList < T > ) {
248
251
match self . list_tail . resolve ( ) {
249
- None => * self = other,
252
+ None => {
253
+ self . length = other. length ;
254
+ self . list_head = other. list_head . take ( ) ;
255
+ self . list_tail = other. list_tail . take ( ) ;
256
+ } ,
250
257
Some ( tail) => {
251
258
// Carefully empty `other`.
252
259
let o_tail = other. list_tail . take ( ) ;
@@ -261,6 +268,7 @@ impl<T> DList<T> {
261
268
}
262
269
}
263
270
}
271
+ other. length = 0 ;
264
272
}
265
273
266
274
/// Provides a forward iterator.
@@ -404,6 +412,51 @@ impl<T> DList<T> {
404
412
pub fn pop_back ( & mut self ) -> Option < T > {
405
413
self . pop_back_node ( ) . map ( |box Node { value, ..} | value)
406
414
}
415
+
416
+ /// Splits the list into two at the given index. Returns everything after the given index,
417
+ /// including the index.
418
+ ///
419
+ /// This operation should compute in O(n) time.
420
+ #[ stable]
421
+ pub fn split_off ( & mut self , at : uint ) -> DList < T > {
422
+ let len = self . len ( ) ;
423
+ assert ! ( at < len, "Cannot split off at a nonexistent index" ) ;
424
+ if at == 0 {
425
+ return mem:: replace ( self , DList :: new ( ) ) ;
426
+ }
427
+
428
+ // Below, we iterate towards the `i-1`th node, either from the start or the end,
429
+ // depending on which would be faster.
430
+ let mut split_node = if at - 1 <= len - 1 - ( at - 1 ) {
431
+ let mut iter = self . iter_mut ( ) ;
432
+ // instead of skipping using .skip() (which creates a new struct),
433
+ // we skip manually so we can access the head field without
434
+ // depending on implementation details of Skip
435
+ for _ in range ( 0 , at - 1 ) {
436
+ iter. next ( ) ;
437
+ }
438
+ iter. head
439
+ } else {
440
+ // better off starting from the end
441
+ let mut iter = self . iter_mut ( ) ;
442
+ for _ in range ( 0 , len - 1 - ( at - 1 ) ) {
443
+ iter. next_back ( ) ;
444
+ }
445
+ iter. tail
446
+ } ;
447
+
448
+ let mut splitted_list = DList {
449
+ list_head : None ,
450
+ list_tail : self . list_tail ,
451
+ length : len - at
452
+ } ;
453
+
454
+ mem:: swap ( & mut split_node. resolve ( ) . unwrap ( ) . next , & mut splitted_list. list_head ) ;
455
+ self . list_tail = split_node;
456
+ self . length = at;
457
+
458
+ splitted_list
459
+ }
407
460
}
408
461
409
462
#[ unsafe_destructor]
@@ -777,6 +830,108 @@ mod tests {
777
830
v. iter ( ) . map ( |x| ( * x) . clone ( ) ) . collect ( )
778
831
}
779
832
833
+ #[ test]
834
+ fn test_append ( ) {
835
+ // Empty to empty
836
+ {
837
+ let mut m: DList < int > = DList :: new ( ) ;
838
+ let mut n = DList :: new ( ) ;
839
+ m. append ( & mut n) ;
840
+ check_links ( & m) ;
841
+ assert_eq ! ( m. len( ) , 0 ) ;
842
+ assert_eq ! ( n. len( ) , 0 ) ;
843
+ }
844
+ // Non-empty to empty
845
+ {
846
+ let mut m = DList :: new ( ) ;
847
+ let mut n = DList :: new ( ) ;
848
+ n. push_back ( 2 i) ;
849
+ m. append ( & mut n) ;
850
+ check_links ( & m) ;
851
+ assert_eq ! ( m. len( ) , 1 ) ;
852
+ assert_eq ! ( m. pop_back( ) , Some ( 2 ) ) ;
853
+ assert_eq ! ( n. len( ) , 0 ) ;
854
+ check_links ( & m) ;
855
+ }
856
+ // Empty to non-empty
857
+ {
858
+ let mut m = DList :: new ( ) ;
859
+ let mut n = DList :: new ( ) ;
860
+ m. push_back ( 2 i) ;
861
+ m. append ( & mut n) ;
862
+ check_links ( & m) ;
863
+ assert_eq ! ( m. len( ) , 1 ) ;
864
+ assert_eq ! ( m. pop_back( ) , Some ( 2 ) ) ;
865
+ check_links ( & m) ;
866
+ }
867
+
868
+ // Non-empty to non-empty
869
+ let v = vec ! [ 1 i, 2 , 3 , 4 , 5 ] ;
870
+ let u = vec ! [ 9 i, 8 , 1 , 2 , 3 , 4 , 5 ] ;
871
+ let mut m = list_from ( v. as_slice ( ) ) ;
872
+ let mut n = list_from ( u. as_slice ( ) ) ;
873
+ m. append ( & mut n) ;
874
+ check_links ( & m) ;
875
+ let mut sum = v;
876
+ sum. push_all ( u. as_slice ( ) ) ;
877
+ assert_eq ! ( sum. len( ) , m. len( ) ) ;
878
+ for elt in sum. into_iter ( ) {
879
+ assert_eq ! ( m. pop_front( ) , Some ( elt) )
880
+ }
881
+ assert_eq ! ( n. len( ) , 0 ) ;
882
+ // let's make sure it's working properly, since we
883
+ // did some direct changes to private members
884
+ n. push_back ( 3 ) ;
885
+ assert_eq ! ( n. len( ) , 1 ) ;
886
+ assert_eq ! ( n. pop_front( ) , Some ( 3 ) ) ;
887
+ check_links ( & n) ;
888
+ }
889
+
890
+ #[ test]
891
+ fn test_split_off ( ) {
892
+ // singleton
893
+ {
894
+ let mut m = DList :: new ( ) ;
895
+ m. push_back ( 1 i) ;
896
+
897
+ let p = m. split_off ( 0 ) ;
898
+ assert_eq ! ( m. len( ) , 0 ) ;
899
+ assert_eq ! ( p. len( ) , 1 ) ;
900
+ assert_eq ! ( p. back( ) , Some ( & 1 ) ) ;
901
+ assert_eq ! ( p. front( ) , Some ( & 1 ) ) ;
902
+ }
903
+
904
+ // not singleton, forwards
905
+ {
906
+ let u = vec ! [ 1 i, 2 , 3 , 4 , 5 ] ;
907
+ let mut m = list_from ( u. as_slice ( ) ) ;
908
+ let mut n = m. split_off ( 2 ) ;
909
+ assert_eq ! ( m. len( ) , 2 ) ;
910
+ assert_eq ! ( n. len( ) , 3 ) ;
911
+ for elt in range ( 1 i, 3 ) {
912
+ assert_eq ! ( m. pop_front( ) , Some ( elt) ) ;
913
+ }
914
+ for elt in range ( 3 i, 6 ) {
915
+ assert_eq ! ( n. pop_front( ) , Some ( elt) ) ;
916
+ }
917
+ }
918
+ // not singleton, backwards
919
+ {
920
+ let u = vec ! [ 1 i, 2 , 3 , 4 , 5 ] ;
921
+ let mut m = list_from ( u. as_slice ( ) ) ;
922
+ let mut n = m. split_off ( 4 ) ;
923
+ assert_eq ! ( m. len( ) , 4 ) ;
924
+ assert_eq ! ( n. len( ) , 1 ) ;
925
+ for elt in range ( 1 i, 5 ) {
926
+ assert_eq ! ( m. pop_front( ) , Some ( elt) ) ;
927
+ }
928
+ for elt in range ( 5 i, 6 ) {
929
+ assert_eq ! ( n. pop_front( ) , Some ( elt) ) ;
930
+ }
931
+ }
932
+
933
+ }
934
+
780
935
#[ test]
781
936
fn test_iterator ( ) {
782
937
let m = generate_test ( ) ;
@@ -1065,41 +1220,6 @@ mod tests {
1065
1220
assert_eq ! ( i, v. len( ) ) ;
1066
1221
}
1067
1222
1068
- #[ allow( deprecated) ]
1069
- #[ test]
1070
- fn test_append ( ) {
1071
- {
1072
- let mut m = DList :: new ( ) ;
1073
- let mut n = DList :: new ( ) ;
1074
- n. push_back ( 2 i) ;
1075
- m. append ( n) ;
1076
- assert_eq ! ( m. len( ) , 1 ) ;
1077
- assert_eq ! ( m. pop_back( ) , Some ( 2 ) ) ;
1078
- check_links ( & m) ;
1079
- }
1080
- {
1081
- let mut m = DList :: new ( ) ;
1082
- let n = DList :: new ( ) ;
1083
- m. push_back ( 2 i) ;
1084
- m. append ( n) ;
1085
- assert_eq ! ( m. len( ) , 1 ) ;
1086
- assert_eq ! ( m. pop_back( ) , Some ( 2 ) ) ;
1087
- check_links ( & m) ;
1088
- }
1089
-
1090
- let v = vec ! [ 1 i, 2 , 3 , 4 , 5 ] ;
1091
- let u = vec ! [ 9 i, 8 , 1 , 2 , 3 , 4 , 5 ] ;
1092
- let mut m = list_from ( v. as_slice ( ) ) ;
1093
- m. append ( list_from ( u. as_slice ( ) ) ) ;
1094
- check_links ( & m) ;
1095
- let mut sum = v;
1096
- sum. push_all ( u. as_slice ( ) ) ;
1097
- assert_eq ! ( sum. len( ) , m. len( ) ) ;
1098
- for elt in sum. into_iter ( ) {
1099
- assert_eq ! ( m. pop_front( ) , Some ( elt) )
1100
- }
1101
- }
1102
-
1103
1223
#[ bench]
1104
1224
fn bench_collect_into ( b : & mut test:: Bencher ) {
1105
1225
let v = & [ 0 i; 64 ] ;
0 commit comments