@@ -221,9 +221,12 @@ impl<T> DList<T> {
221221 DList { list_head : None , list_tail : Rawlink :: none ( ) , length : 0 }
222222 }
223223
224- /// Adds all elements from `other` to the end of the list.
224+ /// Moves all elements from `other` to the end of the list.
225225 ///
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.
227230 ///
228231 /// # Examples
229232 ///
@@ -237,16 +240,20 @@ impl<T> DList<T> {
237240 /// b.push_back(3i);
238241 /// b.push_back(4);
239242 ///
240- /// a.append(b);
243+ /// a.append(&mut b);
241244 ///
242245 /// for e in a.iter() {
243246 /// println!("{}", e); // prints 1, then 2, then 3, then 4
244247 /// }
248+ /// println!("{}", b.len()); // prints 0
245249 /// ```
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 > ) {
248251 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+ } ,
250257 Some ( tail) => {
251258 // Carefully empty `other`.
252259 let o_tail = other. list_tail . take ( ) ;
@@ -261,6 +268,7 @@ impl<T> DList<T> {
261268 }
262269 }
263270 }
271+ other. length = 0 ;
264272 }
265273
266274 /// Provides a forward iterator.
@@ -404,6 +412,51 @@ impl<T> DList<T> {
404412 pub fn pop_back ( & mut self ) -> Option < T > {
405413 self . pop_back_node ( ) . map ( |box Node { value, ..} | value)
406414 }
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+ }
407460}
408461
409462#[ unsafe_destructor]
@@ -777,6 +830,108 @@ mod tests {
777830 v. iter ( ) . map ( |x| ( * x) . clone ( ) ) . collect ( )
778831 }
779832
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+
780935 #[ test]
781936 fn test_iterator ( ) {
782937 let m = generate_test ( ) ;
@@ -1065,41 +1220,6 @@ mod tests {
10651220 assert_eq ! ( i, v. len( ) ) ;
10661221 }
10671222
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-
11031223 #[ bench]
11041224 fn bench_collect_into ( b : & mut test:: Bencher ) {
11051225 let v = & [ 0 i; 64 ] ;
0 commit comments