@@ -615,25 +615,29 @@ impl<T> LinkedList<T> {
615
615
iter. tail
616
616
} ;
617
617
618
- let mut splitted_list = LinkedList {
619
- list_head : None ,
618
+ // The split node is the new tail node of the first part and owns
619
+ // the head of the second part.
620
+ let mut second_part_head;
621
+
622
+ unsafe {
623
+ second_part_head = split_node. resolve_mut ( ) . unwrap ( ) . next . take ( ) ;
624
+ match second_part_head {
625
+ None => { }
626
+ Some ( ref mut head) => head. prev = Rawlink :: none ( ) ,
627
+ }
628
+ }
629
+
630
+ let second_part = LinkedList {
631
+ list_head : second_part_head,
620
632
list_tail : self . list_tail ,
621
633
length : len - at
622
634
} ;
623
635
624
- unsafe {
625
- // Swap split_node.next with list_head (which is None), nulling out split_node.next,
626
- // as it is the new tail.
627
- mem:: swap ( & mut split_node. resolve_mut ( ) . unwrap ( ) . next , & mut splitted_list. list_head ) ;
628
- // Null out list_head.prev. Note this `unwrap` won't fail because if at == len
629
- // we already branched out at the top of the fn to return the empty list.
630
- splitted_list. list_head . as_mut ( ) . unwrap ( ) . prev = Rawlink :: none ( ) ;
631
- }
632
- // Fix the tail ptr
636
+ // Fix the tail ptr of the first part
633
637
self . list_tail = split_node;
634
638
self . length = at;
635
639
636
- splitted_list
640
+ second_part
637
641
}
638
642
}
639
643
@@ -947,7 +951,7 @@ impl<A: Hash> Hash for LinkedList<A> {
947
951
#[ cfg( test) ]
948
952
mod tests {
949
953
use std:: clone:: Clone ;
950
- use std:: iter:: { Iterator , IntoIterator } ;
954
+ use std:: iter:: { Iterator , IntoIterator , Extend } ;
951
955
use std:: option:: Option :: { Some , None , self } ;
952
956
use std:: __rand:: { thread_rng, Rng } ;
953
957
use std:: thread;
@@ -1115,6 +1119,26 @@ mod tests {
1115
1119
assert_eq ! ( v1. iter( ) . collect:: <Vec <_>>( ) . len( ) , 3 ) ;
1116
1120
}
1117
1121
1122
+ #[ test]
1123
+ fn test_split_off ( ) {
1124
+ let mut v1 = LinkedList :: new ( ) ;
1125
+ v1. push_front ( 1u8 ) ;
1126
+ v1. push_front ( 1u8 ) ;
1127
+ v1. push_front ( 1u8 ) ;
1128
+ v1. push_front ( 1u8 ) ;
1129
+
1130
+ // test all splits
1131
+ for ix in 0 ..1 + v1. len ( ) {
1132
+ let mut a = v1. clone ( ) ;
1133
+ let b = a. split_off ( ix) ;
1134
+ check_links ( & a) ;
1135
+ check_links ( & b) ;
1136
+ a. extend ( b) ;
1137
+ assert_eq ! ( v1, a) ;
1138
+ }
1139
+ }
1140
+
1141
+
1118
1142
#[ cfg( test) ]
1119
1143
fn fuzz_test ( sz : i32 ) {
1120
1144
let mut m: LinkedList < _ > = LinkedList :: new ( ) ;
0 commit comments