Skip to content

Commit fa0c85c

Browse files
Added to_vec_mapped_mut.
1 parent 6d2eb5e commit fa0c85c

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

src/iterators/mod.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ macro_rules! outer_iter_split_at_impl {
718718
{
719719
assert!(index <= self.iter.len);
720720
let right_ptr = if index != self.iter.len {
721-
unsafe { self.iter.offset(index) }
721+
unsafe { self.iter.offset(index) }
722722
}
723723
else {
724724
self.iter.ptr
@@ -1219,3 +1219,27 @@ pub fn to_vec_mapped<I, F, B>(iter: I, mut f: F) -> Vec<B>
12191219
debug_assert_eq!(size, result.len());
12201220
result
12211221
}
1222+
1223+
/// Like Iterator::collect, but only for trusted length iterators
1224+
pub fn to_vec_mapped_mut<I, F, B>(iter: I, mut f: F) -> Vec<B>
1225+
where I: TrustedIterator + ExactSizeIterator,
1226+
F: FnMut(&mut I::Item) -> B,
1227+
{
1228+
// Use an `unsafe` block to do this efficiently.
1229+
// We know that iter will produce exactly .size() elements,
1230+
// and the loop can vectorize if it's clean (without branch to grow the vector).
1231+
let (size, _) = iter.size_hint();
1232+
let mut result = Vec::with_capacity(size);
1233+
let mut out_ptr = result.as_mut_ptr();
1234+
let mut len = 0;
1235+
iter.fold((), |(), elt| {
1236+
unsafe {
1237+
ptr::write(out_ptr, f(&mut elt));
1238+
len += 1;
1239+
result.set_len(len);
1240+
out_ptr = out_ptr.offset(1);
1241+
}
1242+
});
1243+
debug_assert_eq!(size, result.len());
1244+
result
1245+
}

0 commit comments

Comments
 (0)