Skip to content

Instantly share code, notes, and snippets.

@spacejam
Last active March 29, 2019 07:46
Show Gist options
  • Save spacejam/82ce1784f3a61c9f2ee6a0a5c822d1bb to your computer and use it in GitHub Desktop.
Save spacejam/82ce1784f3a61c9f2ee6a0a5c822d1bb to your computer and use it in GitHub Desktop.
mutable iterator
struct MutableIter<'a, A> {
// reference to underlying buffer
inner: &'a mut [A],
// state to keep track of how far along we are
index: usize,
}
impl<'a, A> Iterator for MutableIter<'a, A> {
// associated types
type Item = &'a mut A;
// required methods
fn next(&mut self) -> Option<Self::Item> {
// optionally return the next item in the inner slice
let i = self.index;
self.index += 1;
self.inner.get_mut(i).map(|item| {
let ptr = item as *mut _;
// we need to use unsafe here due to a
// current limitation in the compiler:
// http://smallcultfollowing.com/babysteps/blog/2013/10/24/iterators-yielding-mutable-references/
unsafe { &mut *ptr }
})
}
}
fn iter<'a, A>(over: &'a mut [A]) -> MutableIter<'a, A> {
MutableIter {
inner: over,
index: 0,
}
}
fn main() {
let mut s = vec![1, 2, 3, 4];
for item in iter(&mut s) {
*item *= 2;
println!("item: {}", item);
}
println!("after: {:?}", s);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment