rust-itertools / itertools

Extra iterator adaptors, iterator methods, free functions, and macros.
https://docs.rs/itertools/
Apache License 2.0
2.72k stars 309 forks source link

&mut Iterator wrapper like rciter #804

Closed tower120 closed 11 months ago

tower120 commented 11 months ago

Motivation

Have C++ 20/23 Ranges base() iterator access -like functionality.

This may be needed when base iterator type provide some additional functionality.

Request

By having iterator wrapper around &mut impl Iterator we can wrap some iterator into any kind of adapter (for example Skip), use that adapted iterator (next-ing), and then still have access to base iterator, without Rc RefCell overhead.

struct IterWrapper<'a, I: Iterator> {
    iter: &'a mut I,
}

impl<'a, I: Iterator> IterWrapper<'a, I> {
    fn new(iter: &'a mut I) -> Self {
        IterWrapper { iter }
    }
}

impl<'a, I: Iterator> Iterator for IterWrapper<'a, I> {
    type Item = I::Item;

    fn next(&mut self) -> Option<Self::Item> {
        self.iter.next()
    }
}

let vec = vec![1, 2, 3, 4, 5];
let mut iter = vec.iter();
let mut wrapper = IterWrapper::new(&mut iter);

assert_eq!(wrapper.skip(2).next().unwrap(), &3);
assert_eq!(iter.next().unwrap(), &4);
Philippe-Cholet commented 11 months ago

If I do let wrapper = &mut iter; (or let wrapper = iter.by_ref();) then the code works the exact same way. So I don't see the interest of this wrapper if it has the same behavior as &mut I. Am I missing something here?

jswrenn commented 11 months ago

I think you might be looking for Iterator::by_ref. Does that fit your use-case?

tower120 commented 11 months ago

You're right! I was not aware about by_ref iterator idiom in Rust.