Skip to content

Commit

Permalink
Rollup merge of rust-lang#58924 - cuviper:more-as_slice, r=dtolnay
Browse files Browse the repository at this point in the history
Add as_slice() to slice::IterMut and vec::Drain

In indexmap-rs/indexmap#88, we found that there was no easy way to implement
`Debug` for our `IterMut` and `Drain` iterators. Those are built on
`slice::IterMut` and `vec::Drain`, which implement `Debug` themselves,
but have no other way to access their data. With a new `as_slice()`
method, we can read the data and customize its presentation.
  • Loading branch information
Centril authored Mar 9, 2019
2 parents 5753b9e + e478cad commit eb77056
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/liballoc/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2468,6 +2468,25 @@ impl<T: fmt::Debug> fmt::Debug for Drain<'_, T> {
}
}

impl<'a, T> Drain<'a, T> {
/// Returns the remaining items of this iterator as a slice.
///
/// # Examples
///
/// ```
/// # #![feature(vec_drain_as_slice)]
/// let mut vec = vec!['a', 'b', 'c'];
/// let mut drain = vec.drain(..);
/// assert_eq!(drain.as_slice(), &['a', 'b', 'c']);
/// let _ = drain.next().unwrap();
/// assert_eq!(drain.as_slice(), &['b', 'c']);
/// ```
#[unstable(feature = "vec_drain_as_slice", reason = "recently added", issue = "58957")]
pub fn as_slice(&self) -> &[T] {
self.iter.as_slice()
}
}

#[stable(feature = "drain", since = "1.6.0")]
unsafe impl<T: Sync> Sync for Drain<'_, T> {}
#[stable(feature = "drain", since = "1.6.0")]
Expand Down
28 changes: 28 additions & 0 deletions src/libcore/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3288,6 +3288,34 @@ impl<'a, T> IterMut<'a, T> {
pub fn into_slice(self) -> &'a mut [T] {
unsafe { from_raw_parts_mut(self.ptr, len!(self)) }
}

/// Views the underlying data as a subslice of the original data.
///
/// To avoid creating `&mut [T]` references that alias, the returned slice
/// borrows its lifetime from the iterator the method is applied on.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # #![feature(slice_iter_mut_as_slice)]
/// let mut slice: &mut [usize] = &mut [1, 2, 3];
///
/// // First, we get the iterator:
/// let mut iter = slice.iter_mut();
/// // So if we check what the `as_slice` method returns here, we have "[1, 2, 3]":
/// assert_eq!(iter.as_slice(), &[1, 2, 3]);
///
/// // Next, we move to the second element of the slice:
/// iter.next();
/// // Now `as_slice` returns "[2, 3]":
/// assert_eq!(iter.as_slice(), &[2, 3]);
/// ```
#[unstable(feature = "slice_iter_mut_as_slice", reason = "recently added", issue = "58957")]
pub fn as_slice(&self) -> &[T] {
self.make_slice()
}
}

iterator!{struct IterMut -> *mut T, &'a mut T, mut, {mut}, {}}
Expand Down

0 comments on commit eb77056

Please sign in to comment.