From 1135cab36576c7b8ae361a963a2294d9ea73c63c Mon Sep 17 00:00:00 2001 From: Hanif Bin Ariffin Date: Sat, 29 Aug 2020 18:56:17 -0400 Subject: [PATCH 1/3] Overload last for `Vec`. Simply use the fact that `IntoIter` stores the end pointer and we can perform pointer arithmetic. --- library/alloc/src/vec.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/library/alloc/src/vec.rs b/library/alloc/src/vec.rs index 8526f15288fa4..6441467e3dc52 100644 --- a/library/alloc/src/vec.rs +++ b/library/alloc/src/vec.rs @@ -2955,6 +2955,12 @@ impl Iterator for IntoIter { unsafe { if mem::size_of::() == 0 { mem::zeroed() } else { ptr::read(self.ptr.add(i)) } } + #[inline] + fn last(self) -> Option + where + Self: Sized, + { + if self.ptr == self.end { None } else { unsafe { Some(ptr::read(self.end.offset(-1))) } } } } From a9919e0faeaae81a5befbc819d497b3d89af8de4 Mon Sep 17 00:00:00 2001 From: Hanif Bin Ariffin Date: Sun, 30 Aug 2020 08:54:18 -0400 Subject: [PATCH 2/3] Changed the implementation of IntoIter::last() Simply does what next() does except it goes straight to the end of the array. Woopsie --- library/alloc/src/vec.rs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/library/alloc/src/vec.rs b/library/alloc/src/vec.rs index 6441467e3dc52..4787c80aa494f 100644 --- a/library/alloc/src/vec.rs +++ b/library/alloc/src/vec.rs @@ -2956,11 +2956,23 @@ impl Iterator for IntoIter { if mem::size_of::() == 0 { mem::zeroed() } else { ptr::read(self.ptr.add(i)) } } #[inline] - fn last(self) -> Option - where - Self: Sized, - { - if self.ptr == self.end { None } else { unsafe { Some(ptr::read(self.end.offset(-1))) } } + fn last(mut self) -> Option { + unsafe { + if self.ptr as *const _ == self.end { + None + } else { + if mem::size_of::() == 0 { + // Immediately marches to end of the iterator. + self.ptr = self.end; + // Make up a value of this ZST. + Some(mem::zeroed()) + } else { + // Immediately marches to end of the iterator. + self.ptr = self.end; + Some(ptr::read(self.ptr.offset(-1))) + } + } + } } } From 91984e7b7078c2a56d89e8e00cd8567579a508ea Mon Sep 17 00:00:00 2001 From: Hanif Bin Ariffin Date: Fri, 23 Oct 2020 14:19:59 +0800 Subject: [PATCH 3/3] Simplify the implementation of IntoIter::last() a bit. Suggested by @pickfire. Signed-off-by: Hanif Bin Ariffin --- library/alloc/src/vec.rs | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/library/alloc/src/vec.rs b/library/alloc/src/vec.rs index 4787c80aa494f..4cad873190f6b 100644 --- a/library/alloc/src/vec.rs +++ b/library/alloc/src/vec.rs @@ -2955,24 +2955,11 @@ impl Iterator for IntoIter { unsafe { if mem::size_of::() == 0 { mem::zeroed() } else { ptr::read(self.ptr.add(i)) } } + } + #[inline] fn last(mut self) -> Option { - unsafe { - if self.ptr as *const _ == self.end { - None - } else { - if mem::size_of::() == 0 { - // Immediately marches to end of the iterator. - self.ptr = self.end; - // Make up a value of this ZST. - Some(mem::zeroed()) - } else { - // Immediately marches to end of the iterator. - self.ptr = self.end; - Some(ptr::read(self.ptr.offset(-1))) - } - } - } + self.next_back() } }