I have some vector, and want to navigate there +1/-1 directions, and when the end of array reached, switch to the begin of index (on next) and same for back action - but to the last one (e.g. by len).
As found in docs, I should create new Iterator for every new session, but I won't
Is any completed trait to not implement my own bugs for this trivial feature?
p.s. rev is not an option for back action because reorder the index, when I want just to make search in text buffer like Firefox does by cmd+F action.
assert_eq!(it.next(), Some(&1)); // user at #1 position (by next)
let mut it = a.iter().rev().cycle(); // user activates back
assert_eq!(it.next(), Some(&3)); // index always started from end, not from #1 to #0
don't know how to explain, but I need the prev as opposite to next, not reverse all the index..
You probably want to implement your own DoubleEndedIterator for the indices. Or at least, I don't know a way to do it with what's in std offhand. (And I didn't check itertools.)
I'm not sure what the exact behaviors you want are though.
// Say we're cycling through 0..3
assert_eq!(iter.next_back(), Some(three_or_zero));
// ...
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next_back(), Some(two_or_one));
Yes, meant something like increment/decrement for the current state
DoubleEndedIterator is finitive, and return None on iteration complete. I exactly would like to use Cycle as 99% does that I want, but not the back/next_back method.
Thoughts make 2 holders for Cycle - 1 default and 1 reverse, plus current object copy:
struct Iter {
next: Cycle<IntoIter<Value>>,
prev: Cycle<IntoIter<Value>>, // reverse
state: Value // current
}
impl Iter {
fn forward(&self) {} // do `next()` for `next` until current Value, then `next` one more
fn back(&self) {} // same for `prev`
}
maybe screwed idea, because newbie, I think it's trash, but.. should work
Thanks for your links.
Maybe iterator trait is just low-level trait, and I should extend it with the app logic as above, even it looks trivial to be not implemented yet.
Actually, you've found one of the biggest difference of fundamental concepts between C++ and Rust!
Conceptually in C++ iterators are cursors pointing something in somewhere. You can move the cursor forward, sometimes backward, and get the value currently pointed by the cursor.
But in Rust iterators are some kind of queue conceptually. You can pop values from its front, sometimes from its back. It doesn't make sense to get the value the iterator currently pointing as the queue logically holds the entire values not popped yet. You can't pop same value twice from the queue as it may violate the ownership rule.
I don’t know any particular trait to set an example… but as one point of comparison, you could look at the (unstable) cursor API of std::collections::linked_list, I guess?
I think the closest counterpart to Rust iterators in C++ is the ranges library. Although it still uses the begin/end "cursor" interface at the lowest levels, as far as I understand.