2 use smallvec::{Array, SmallVec};
4 pub trait MoveMap<T>: Sized {
5 fn move_map<F>(self, mut f: F) -> Self where F: FnMut(T) -> T {
6 self.move_flat_map(|e| Some(f(e)))
9 fn move_flat_map<F, I>(self, f: F) -> Self
10 where F: FnMut(T) -> I,
11 I: IntoIterator<Item=T>;
14 impl<T> MoveMap<T> for Vec<T> {
15 fn move_flat_map<F, I>(mut self, mut f: F) -> Self
16 where F: FnMut(T) -> I,
17 I: IntoIterator<Item=T>
22 let mut old_len = self.len();
23 self.set_len(0); // make sure we just leak elements in case of panic
25 while read_i < old_len {
26 // move the read_i'th item out of the vector and map it
28 let e = ptr::read(self.get_unchecked(read_i));
29 let iter = f(e).into_iter();
34 ptr::write(self.get_unchecked_mut(write_i), e);
37 // If this is reached we ran out of space
38 // in the middle of the vector.
39 // However, the vector is in a valid state here,
40 // so we just do a somewhat inefficient insert.
41 self.set_len(old_len);
42 self.insert(write_i, e);
53 // write_i tracks the number of actually written new items.
54 self.set_len(write_i);
61 impl<T> MoveMap<T> for ::ptr::P<[T]> {
62 fn move_flat_map<F, I>(self, f: F) -> Self
63 where F: FnMut(T) -> I,
64 I: IntoIterator<Item=T>
66 ::ptr::P::from_vec(self.into_vec().move_flat_map(f))
70 impl<T, A: Array<Item = T>> MoveMap<T> for SmallVec<A> {
71 fn move_flat_map<F, I>(mut self, mut f: F) -> Self
72 where F: FnMut(T) -> I,
73 I: IntoIterator<Item=T>
78 let mut old_len = self.len();
79 self.set_len(0); // make sure we just leak elements in case of panic
81 while read_i < old_len {
82 // move the read_i'th item out of the vector and map it
84 let e = ptr::read(self.get_unchecked(read_i));
85 let iter = f(e).into_iter();
90 ptr::write(self.get_unchecked_mut(write_i), e);
93 // If this is reached we ran out of space
94 // in the middle of the vector.
95 // However, the vector is in a valid state here,
96 // so we just do a somewhat inefficient insert.
97 self.set_len(old_len);
98 self.insert(write_i, e);
100 old_len = self.len();
109 // write_i tracks the number of actually written new items.
110 self.set_len(write_i);