From 7b480cdec6d6c046dc3cd86020f3762e37558cd4 Mon Sep 17 00:00:00 2001 From: Charles Gleason Date: Tue, 1 Oct 2019 18:20:46 -0400 Subject: [PATCH 1/3] Implement Clone::clone_from for LinkedList --- src/liballoc/collections/linked_list.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index 816a71f255798..998bcb87393b1 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -1197,6 +1197,19 @@ impl Clone for LinkedList { fn clone(&self) -> Self { self.iter().cloned().collect() } + + fn clone_from(&mut self, other: &Self) { + let mut iter_other = other.iter(); + if self.len() > other.len() { + self.split_off(other.len()); + } + for elem in self.iter_mut() { + elem.clone_from(iter_other.next().unwrap()); + } + if !iter_other.is_empty() { + self.extend(iter_other.cloned()); + } + } } #[stable(feature = "rust1", since = "1.0.0")] From 5055d4b1c6d7dedaec015e4ba9d96c94b1d978fd Mon Sep 17 00:00:00 2001 From: Charles Gleason Date: Wed, 2 Oct 2019 11:29:12 -0400 Subject: [PATCH 2/3] Use zipped iterators in clone_from for LinkedList --- src/liballoc/collections/linked_list.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index 998bcb87393b1..702df250999fb 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -1203,8 +1203,8 @@ impl Clone for LinkedList { if self.len() > other.len() { self.split_off(other.len()); } - for elem in self.iter_mut() { - elem.clone_from(iter_other.next().unwrap()); + for (elem, elem_other) in self.iter_mut().zip(&mut iter_other) { + elem.clone_from(elem_other); } if !iter_other.is_empty() { self.extend(iter_other.cloned()); From 864e6feaf857f4a48ace3eafd2003a32ac46602b Mon Sep 17 00:00:00 2001 From: Charles Gleason Date: Wed, 2 Oct 2019 15:18:31 -0400 Subject: [PATCH 3/3] Add test for LinkedList clone_from --- src/liballoc/collections/linked_list/tests.rs | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/liballoc/collections/linked_list/tests.rs b/src/liballoc/collections/linked_list/tests.rs index ecb5948f11b36..1001f6bba3b82 100644 --- a/src/liballoc/collections/linked_list/tests.rs +++ b/src/liballoc/collections/linked_list/tests.rs @@ -110,6 +110,49 @@ fn test_append() { check_links(&n); } +#[test] +fn test_clone_from() { + // Short cloned from long + { + let v = vec![1, 2, 3, 4, 5]; + let u = vec![8, 7, 6, 2, 3, 4, 5]; + let mut m = list_from(&v); + let n = list_from(&u); + m.clone_from(&n); + check_links(&m); + assert_eq!(m, n); + for elt in u { + assert_eq!(m.pop_front(), Some(elt)) + } + } + // Long cloned from short + { + let v = vec![1, 2, 3, 4, 5]; + let u = vec![6, 7, 8]; + let mut m = list_from(&v); + let n = list_from(&u); + m.clone_from(&n); + check_links(&m); + assert_eq!(m, n); + for elt in u { + assert_eq!(m.pop_front(), Some(elt)) + } + } + // Two equal length lists + { + let v = vec![1, 2, 3, 4, 5]; + let u = vec![9, 8, 1, 2, 3]; + let mut m = list_from(&v); + let n = list_from(&u); + m.clone_from(&n); + check_links(&m); + assert_eq!(m, n); + for elt in u { + assert_eq!(m.pop_front(), Some(elt)) + } + } +} + #[test] fn test_insert_prev() { let mut m = list_from(&[0, 2, 4, 6, 8]);