Skip to content

Commit 01a766e

Browse files
committed
Introduce as_mut_slice method on std::vec::IntoIter struct.
1 parent d099e30 commit 01a766e

File tree

2 files changed

+40
-9
lines changed

2 files changed

+40
-9
lines changed

src/libcollections/vec.rs

Lines changed: 29 additions & 9 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,7 +1709,7 @@ 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

@@ -1733,6 +1732,27 @@ impl<T> IntoIter<T> {
17331732
slice::from_raw_parts(self.ptr, self.len())
17341733
}
17351734
}
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+
}
17361756
}
17371757

17381758
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1747,14 +1767,14 @@ impl<T> Iterator for IntoIter<T> {
17471767
#[inline]
17481768
fn next(&mut self) -> Option<T> {
17491769
unsafe {
1750-
if self.ptr == self.end {
1770+
if self.ptr as *const _ == self.end {
17511771
None
17521772
} else {
17531773
if mem::size_of::<T>() == 0 {
17541774
// purposefully don't use 'ptr.offset' because for
17551775
// vectors with 0-size elements this would return the
17561776
// same pointer.
1757-
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;
17581778

17591779
// Use a non-null pointer value
17601780
Some(ptr::read(EMPTY as *mut T))
@@ -1797,7 +1817,7 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
17971817
} else {
17981818
if mem::size_of::<T>() == 0 {
17991819
// See above for why 'ptr.offset' isn't used
1800-
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;
18011821

18021822
// Use a non-null pointer value
18031823
Some(ptr::read(EMPTY as *mut T))

src/libcollectionstest/vec.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,17 @@ fn test_into_iter_as_slice() {
490490
assert_eq!(into_iter.as_slice(), &[]);
491491
}
492492

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+
493504
#[test]
494505
fn test_into_iter_count() {
495506
assert_eq!(vec![1, 2, 3].into_iter().count(), 3);

0 commit comments

Comments
 (0)