mirror of
https://github.com/rust-embedded/heapless.git
synced 2025-10-02 14:54:30 +00:00
Merge #38
38: Implement IntoIter for Vec r=japaric a=XOSplicer ~~This implementation uses vec::reverse and vec::pop to move the content of the vector out of it.~~ It might give more performance to avoid the `reverse` and read each element individually. In the end the unmoved items need to be dropped. Co-authored-by: Felix <stegmaier.felix@gmail.com> Co-authored-by: Felix Stegmaier <stegmaier.felix@gmail.com>
This commit is contained in:
commit
495cace695
127
src/vec.rs
127
src/vec.rs
@ -310,6 +310,66 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator that moves out of an [`Vec`][`Vec`].
|
||||
///
|
||||
/// This struct is created by calling the `into_iter` method on [`Vec`][`Vec`].
|
||||
///
|
||||
/// [`Vec`]: (https://doc.rust-lang.org/std/vec/struct.Vec.html)
|
||||
///
|
||||
pub struct IntoIter<T, N>
|
||||
where
|
||||
N: ArrayLength<T>,
|
||||
{
|
||||
vec: Vec<T, N>,
|
||||
next: usize,
|
||||
}
|
||||
|
||||
impl <T, N> Iterator for IntoIter<T, N>
|
||||
where
|
||||
N: ArrayLength<T>,
|
||||
{
|
||||
type Item = T;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.next < self.vec.len() {
|
||||
let buffer = self.vec.buffer.as_slice();
|
||||
let item = unsafe {ptr::read(buffer.get_unchecked(self.next))};
|
||||
self.next += 1;
|
||||
Some(item)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl <T, N> Drop for IntoIter<T, N>
|
||||
where
|
||||
N: ArrayLength<T>,
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
// Drop all the elements that have not been moved out of vec
|
||||
ptr::drop_in_place(&mut self.vec[self.next..]);
|
||||
// Prevent dropping of other elements
|
||||
self.vec.len = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl <T, N> IntoIterator for Vec<T, N>
|
||||
where
|
||||
N: ArrayLength<T>,
|
||||
{
|
||||
type Item = T;
|
||||
type IntoIter = IntoIter<T, N>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
IntoIter {
|
||||
vec: self,
|
||||
next: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A, B, N1, N2> PartialEq<Vec<B, N2>> for Vec<A, N1>
|
||||
where
|
||||
N1: ArrayLength<A>,
|
||||
@ -433,8 +493,8 @@ mod tests {
|
||||
use consts::*;
|
||||
use Vec;
|
||||
|
||||
#[test]
|
||||
fn drop() {
|
||||
macro_rules! droppable {
|
||||
() => (
|
||||
struct Droppable;
|
||||
impl Droppable {
|
||||
fn new() -> Self {
|
||||
@ -453,6 +513,13 @@ mod tests {
|
||||
}
|
||||
|
||||
static mut COUNT: i32 = 0;
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drop() {
|
||||
|
||||
droppable!();
|
||||
|
||||
{
|
||||
let mut v: Vec<Droppable, U2> = Vec::new();
|
||||
@ -533,6 +600,62 @@ mod tests {
|
||||
assert_eq!(items.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn iter_move() {
|
||||
let mut v: Vec<i32, U4> = Vec::new();
|
||||
v.push(0).unwrap();
|
||||
v.push(1).unwrap();
|
||||
v.push(2).unwrap();
|
||||
v.push(3).unwrap();
|
||||
|
||||
let mut items = v.into_iter();
|
||||
|
||||
assert_eq!(items.next(), Some(0));
|
||||
assert_eq!(items.next(), Some(1));
|
||||
assert_eq!(items.next(), Some(2));
|
||||
assert_eq!(items.next(), Some(3));
|
||||
assert_eq!(items.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn iter_move_drop() {
|
||||
|
||||
droppable!();
|
||||
|
||||
{
|
||||
let mut vec: Vec<Droppable, U2> = Vec::new();
|
||||
vec.push(Droppable::new()).ok().unwrap();
|
||||
vec.push(Droppable::new()).ok().unwrap();
|
||||
let mut items = vec.into_iter();
|
||||
// Move all
|
||||
let _ = items.next();
|
||||
let _ = items.next();
|
||||
}
|
||||
|
||||
assert_eq!(unsafe { COUNT }, 0);
|
||||
|
||||
{
|
||||
let mut vec: Vec<Droppable, U2> = Vec::new();
|
||||
vec.push(Droppable::new()).ok().unwrap();
|
||||
vec.push(Droppable::new()).ok().unwrap();
|
||||
let _items = vec.into_iter();
|
||||
// Move none
|
||||
}
|
||||
|
||||
assert_eq!(unsafe { COUNT }, 0);
|
||||
|
||||
{
|
||||
let mut vec: Vec<Droppable, U2> = Vec::new();
|
||||
vec.push(Droppable::new()).ok().unwrap();
|
||||
vec.push(Droppable::new()).ok().unwrap();
|
||||
let mut items = vec.into_iter();
|
||||
let _ = items.next(); // Move partly
|
||||
}
|
||||
|
||||
assert_eq!(unsafe { COUNT }, 0);
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn push_and_pop() {
|
||||
let mut v: Vec<i32, U4> = Vec::new();
|
||||
|
Loading…
x
Reference in New Issue
Block a user