Skip to content

Commit 201852e

Browse files
author
Ulrik Sverdrup
committed
linked_list: Cleanup code in split_off
1 parent 289d5db commit 201852e

File tree

1 file changed

+37
-13
lines changed

1 file changed

+37
-13
lines changed

src/libcollections/linked_list.rs

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -615,25 +615,29 @@ impl<T> LinkedList<T> {
615615
iter.tail
616616
};
617617

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,
620632
list_tail: self.list_tail,
621633
length: len - at
622634
};
623635

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
633637
self.list_tail = split_node;
634638
self.length = at;
635639

636-
splitted_list
640+
second_part
637641
}
638642
}
639643

@@ -947,7 +951,7 @@ impl<A: Hash> Hash for LinkedList<A> {
947951
#[cfg(test)]
948952
mod tests {
949953
use std::clone::Clone;
950-
use std::iter::{Iterator, IntoIterator};
954+
use std::iter::{Iterator, IntoIterator, Extend};
951955
use std::option::Option::{Some, None, self};
952956
use std::__rand::{thread_rng, Rng};
953957
use std::thread;
@@ -1115,6 +1119,26 @@ mod tests {
11151119
assert_eq!(v1.iter().collect::<Vec<_>>().len(), 3);
11161120
}
11171121

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+
11181142
#[cfg(test)]
11191143
fn fuzz_test(sz: i32) {
11201144
let mut m: LinkedList<_> = LinkedList::new();

0 commit comments

Comments
 (0)