Skip to content

Commit d1e286a

Browse files
authored
Rollup merge of #35447 - frewsxcv:vec-into-iter-as-slice, r=alexcrichton
Introduce `as_slice`/`as_mut_slice` methods on `std::vec::IntoIter` struct. Similar to the `as_slice` method on `core::slice::Iter` struct.
2 parents 78cbbd4 + 01a766e commit d1e286a

File tree

3 files changed

+75
-12
lines changed

3 files changed

+75
-12
lines changed

src/libcollections/vec.rs

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,13 +1446,12 @@ impl<T> IntoIterator for Vec<T> {
14461446
#[inline]
14471447
fn into_iter(mut self) -> IntoIter<T> {
14481448
unsafe {
1449-
let ptr = self.as_mut_ptr();
1450-
assume(!ptr.is_null());
1451-
let begin = ptr as *const T;
1449+
let begin = self.as_mut_ptr();
1450+
assume(!begin.is_null());
14521451
let end = if mem::size_of::<T>() == 0 {
1453-
arith_offset(ptr as *const i8, self.len() as isize) as *const T
1452+
arith_offset(begin as *const i8, self.len() as isize) as *const T
14541453
} else {
1455-
ptr.offset(self.len() as isize) as *const T
1454+
begin.offset(self.len() as isize) as *const T
14561455
};
14571456
let buf = ptr::read(&self.buf);
14581457
mem::forget(self);
@@ -1710,10 +1709,52 @@ impl<'a, T> FromIterator<T> for Cow<'a, [T]> where T: Clone {
17101709
#[stable(feature = "rust1", since = "1.0.0")]
17111710
pub struct IntoIter<T> {
17121711
_buf: RawVec<T>,
1713-
ptr: *const T,
1712+
ptr: *mut T,
17141713
end: *const T,
17151714
}
17161715

1716+
impl<T> IntoIter<T> {
1717+
/// Returns the remaining items of this iterator as a slice.
1718+
///
1719+
/// # Examples
1720+
///
1721+
/// ```rust
1722+
/// # #![feature(vec_into_iter_as_slice)]
1723+
/// let vec = vec!['a', 'b', 'c'];
1724+
/// let mut into_iter = vec.into_iter();
1725+
/// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
1726+
/// let _ = into_iter.next().unwrap();
1727+
/// assert_eq!(into_iter.as_slice(), &['b', 'c']);
1728+
/// ```
1729+
#[unstable(feature = "vec_into_iter_as_slice", issue = "35601")]
1730+
pub fn as_slice(&self) -> &[T] {
1731+
unsafe {
1732+
slice::from_raw_parts(self.ptr, self.len())
1733+
}
1734+
}
1735+
1736+
/// Returns the remaining items of this iterator as a mutable slice.
1737+
///
1738+
/// # Examples
1739+
///
1740+
/// ```rust
1741+
/// # #![feature(vec_into_iter_as_slice)]
1742+
/// let vec = vec!['a', 'b', 'c'];
1743+
/// let mut into_iter = vec.into_iter();
1744+
/// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
1745+
/// into_iter.as_mut_slice()[2] = 'z';
1746+
/// assert_eq!(into_iter.next().unwrap(), 'a');
1747+
/// assert_eq!(into_iter.next().unwrap(), 'b');
1748+
/// assert_eq!(into_iter.next().unwrap(), 'z');
1749+
/// ```
1750+
#[unstable(feature = "vec_into_iter_as_slice", issue = "35601")]
1751+
pub fn as_mut_slice(&self) -> &mut [T] {
1752+
unsafe {
1753+
slice::from_raw_parts_mut(self.ptr, self.len())
1754+
}
1755+
}
1756+
}
1757+
17171758
#[stable(feature = "rust1", since = "1.0.0")]
17181759
unsafe impl<T: Send> Send for IntoIter<T> {}
17191760
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1726,14 +1767,14 @@ impl<T> Iterator for IntoIter<T> {
17261767
#[inline]
17271768
fn next(&mut self) -> Option<T> {
17281769
unsafe {
1729-
if self.ptr == self.end {
1770+
if self.ptr as *const _ == self.end {
17301771
None
17311772
} else {
17321773
if mem::size_of::<T>() == 0 {
17331774
// purposefully don't use 'ptr.offset' because for
17341775
// vectors with 0-size elements this would return the
17351776
// same pointer.
1736-
self.ptr = arith_offset(self.ptr as *const i8, 1) as *const T;
1777+
self.ptr = arith_offset(self.ptr as *const i8, 1) as *mut T;
17371778

17381779
// Use a non-null pointer value
17391780
Some(ptr::read(EMPTY as *mut T))
@@ -1776,7 +1817,7 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
17761817
} else {
17771818
if mem::size_of::<T>() == 0 {
17781819
// See above for why 'ptr.offset' isn't used
1779-
self.end = arith_offset(self.end as *const i8, -1) as *const T;
1820+
self.end = arith_offset(self.end as *const i8, -1) as *mut T;
17801821

17811822
// Use a non-null pointer value
17821823
Some(ptr::read(EMPTY as *mut T))
@@ -1796,9 +1837,7 @@ impl<T> ExactSizeIterator for IntoIter<T> {}
17961837
#[stable(feature = "vec_into_iter_clone", since = "1.8.0")]
17971838
impl<T: Clone> Clone for IntoIter<T> {
17981839
fn clone(&self) -> IntoIter<T> {
1799-
unsafe {
1800-
slice::from_raw_parts(self.ptr, self.len()).to_owned().into_iter()
1801-
}
1840+
self.as_slice().to_owned().into_iter()
18021841
}
18031842
}
18041843

src/libcollectionstest/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#![feature(unboxed_closures)]
2929
#![feature(unicode)]
3030
#![feature(vec_deque_contains)]
31+
#![feature(vec_into_iter_as_slice)]
3132

3233
extern crate collections;
3334
extern crate test;

src/libcollectionstest/vec.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,29 @@ fn test_split_off() {
478478
assert_eq!(vec2, [5, 6]);
479479
}
480480

481+
#[test]
482+
fn test_into_iter_as_slice() {
483+
let vec = vec!['a', 'b', 'c'];
484+
let mut into_iter = vec.into_iter();
485+
assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
486+
let _ = into_iter.next().unwrap();
487+
assert_eq!(into_iter.as_slice(), &['b', 'c']);
488+
let _ = into_iter.next().unwrap();
489+
let _ = into_iter.next().unwrap();
490+
assert_eq!(into_iter.as_slice(), &[]);
491+
}
492+
493+
#[test]
494+
fn test_into_iter_as_mut_slice() {
495+
let vec = vec!['a', 'b', 'c'];
496+
let mut into_iter = vec.into_iter();
497+
assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
498+
into_iter.as_mut_slice()[0] = 'x';
499+
into_iter.as_mut_slice()[1] = 'y';
500+
assert_eq!(into_iter.next().unwrap(), 'x');
501+
assert_eq!(into_iter.as_slice(), &['y', 'c']);
502+
}
503+
481504
#[test]
482505
fn test_into_iter_count() {
483506
assert_eq!(vec![1, 2, 3].into_iter().count(), 3);

0 commit comments

Comments
 (0)