From d099e30e48a20eea36a76ab968b8bd9001e0e1fa Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sun, 7 Aug 2016 00:30:17 -0400 Subject: [PATCH 1/2] Introduce `as_slice` method on `std::vec::IntoIter` struct. Similar to the `as_slice` method on `core::slice::Iter` struct. --- src/libcollections/vec.rs | 25 ++++++++++++++++++++++--- src/libcollectionstest/lib.rs | 1 + src/libcollectionstest/vec.rs | 12 ++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 8b4fce158de46..696ce3a2a03e9 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1714,6 +1714,27 @@ pub struct IntoIter { end: *const T, } +impl IntoIter { + /// Returns the remaining items of this iterator as a slice. + /// + /// # Examples + /// + /// ```rust + /// # #![feature(vec_into_iter_as_slice)] + /// let vec = vec!['a', 'b', 'c']; + /// let mut into_iter = vec.into_iter(); + /// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']); + /// let _ = into_iter.next().unwrap(); + /// assert_eq!(into_iter.as_slice(), &['b', 'c']); + /// ``` + #[unstable(feature = "vec_into_iter_as_slice", issue = "35601")] + pub fn as_slice(&self) -> &[T] { + unsafe { + slice::from_raw_parts(self.ptr, self.len()) + } + } +} + #[stable(feature = "rust1", since = "1.0.0")] unsafe impl Send for IntoIter {} #[stable(feature = "rust1", since = "1.0.0")] @@ -1796,9 +1817,7 @@ impl ExactSizeIterator for IntoIter {} #[stable(feature = "vec_into_iter_clone", since = "1.8.0")] impl Clone for IntoIter { fn clone(&self) -> IntoIter { - unsafe { - slice::from_raw_parts(self.ptr, self.len()).to_owned().into_iter() - } + self.as_slice().to_owned().into_iter() } } diff --git a/src/libcollectionstest/lib.rs b/src/libcollectionstest/lib.rs index 8ae63808f2740..ab3231b2b9955 100644 --- a/src/libcollectionstest/lib.rs +++ b/src/libcollectionstest/lib.rs @@ -28,6 +28,7 @@ #![feature(unboxed_closures)] #![feature(unicode)] #![feature(vec_deque_contains)] +#![feature(vec_into_iter_as_slice)] extern crate collections; extern crate test; diff --git a/src/libcollectionstest/vec.rs b/src/libcollectionstest/vec.rs index 7a6bd958a5f8c..0302b180aff56 100644 --- a/src/libcollectionstest/vec.rs +++ b/src/libcollectionstest/vec.rs @@ -478,6 +478,18 @@ fn test_split_off() { assert_eq!(vec2, [5, 6]); } +#[test] +fn test_into_iter_as_slice() { + let vec = vec!['a', 'b', 'c']; + let mut into_iter = vec.into_iter(); + assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']); + let _ = into_iter.next().unwrap(); + assert_eq!(into_iter.as_slice(), &['b', 'c']); + let _ = into_iter.next().unwrap(); + let _ = into_iter.next().unwrap(); + assert_eq!(into_iter.as_slice(), &[]); +} + #[test] fn test_into_iter_count() { assert_eq!(vec![1, 2, 3].into_iter().count(), 3); From 01a766e5210157546a2b6c673700b9959289eff9 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sun, 7 Aug 2016 10:08:40 -0400 Subject: [PATCH 2/2] Introduce `as_mut_slice` method on `std::vec::IntoIter` struct. --- src/libcollections/vec.rs | 38 ++++++++++++++++++++++++++--------- src/libcollectionstest/vec.rs | 11 ++++++++++ 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 696ce3a2a03e9..a6f817a89624c 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1446,13 +1446,12 @@ impl IntoIterator for Vec { #[inline] fn into_iter(mut self) -> IntoIter { unsafe { - let ptr = self.as_mut_ptr(); - assume(!ptr.is_null()); - let begin = ptr as *const T; + let begin = self.as_mut_ptr(); + assume(!begin.is_null()); let end = if mem::size_of::() == 0 { - arith_offset(ptr as *const i8, self.len() as isize) as *const T + arith_offset(begin as *const i8, self.len() as isize) as *const T } else { - ptr.offset(self.len() as isize) as *const T + begin.offset(self.len() as isize) as *const T }; let buf = ptr::read(&self.buf); mem::forget(self); @@ -1710,7 +1709,7 @@ impl<'a, T> FromIterator for Cow<'a, [T]> where T: Clone { #[stable(feature = "rust1", since = "1.0.0")] pub struct IntoIter { _buf: RawVec, - ptr: *const T, + ptr: *mut T, end: *const T, } @@ -1733,6 +1732,27 @@ impl IntoIter { slice::from_raw_parts(self.ptr, self.len()) } } + + /// Returns the remaining items of this iterator as a mutable slice. + /// + /// # Examples + /// + /// ```rust + /// # #![feature(vec_into_iter_as_slice)] + /// let vec = vec!['a', 'b', 'c']; + /// let mut into_iter = vec.into_iter(); + /// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']); + /// into_iter.as_mut_slice()[2] = 'z'; + /// assert_eq!(into_iter.next().unwrap(), 'a'); + /// assert_eq!(into_iter.next().unwrap(), 'b'); + /// assert_eq!(into_iter.next().unwrap(), 'z'); + /// ``` + #[unstable(feature = "vec_into_iter_as_slice", issue = "35601")] + pub fn as_mut_slice(&self) -> &mut [T] { + unsafe { + slice::from_raw_parts_mut(self.ptr, self.len()) + } + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1747,14 +1767,14 @@ impl Iterator for IntoIter { #[inline] fn next(&mut self) -> Option { unsafe { - if self.ptr == self.end { + if self.ptr as *const _ == self.end { None } else { if mem::size_of::() == 0 { // purposefully don't use 'ptr.offset' because for // vectors with 0-size elements this would return the // same pointer. - self.ptr = arith_offset(self.ptr as *const i8, 1) as *const T; + self.ptr = arith_offset(self.ptr as *const i8, 1) as *mut T; // Use a non-null pointer value Some(ptr::read(EMPTY as *mut T)) @@ -1797,7 +1817,7 @@ impl DoubleEndedIterator for IntoIter { } else { if mem::size_of::() == 0 { // See above for why 'ptr.offset' isn't used - self.end = arith_offset(self.end as *const i8, -1) as *const T; + self.end = arith_offset(self.end as *const i8, -1) as *mut T; // Use a non-null pointer value Some(ptr::read(EMPTY as *mut T)) diff --git a/src/libcollectionstest/vec.rs b/src/libcollectionstest/vec.rs index 0302b180aff56..9556174bd2294 100644 --- a/src/libcollectionstest/vec.rs +++ b/src/libcollectionstest/vec.rs @@ -490,6 +490,17 @@ fn test_into_iter_as_slice() { assert_eq!(into_iter.as_slice(), &[]); } +#[test] +fn test_into_iter_as_mut_slice() { + let vec = vec!['a', 'b', 'c']; + let mut into_iter = vec.into_iter(); + assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']); + into_iter.as_mut_slice()[0] = 'x'; + into_iter.as_mut_slice()[1] = 'y'; + assert_eq!(into_iter.next().unwrap(), 'x'); + assert_eq!(into_iter.as_slice(), &['y', 'c']); +} + #[test] fn test_into_iter_count() { assert_eq!(vec![1, 2, 3].into_iter().count(), 3);