Change:
Now that has re-emerged as a single trait, it's possible to override default methods like , and for iterators on slices, vectors, and so on. We should audit the applicable iterators and take advantage of overrides when possible. libcore: [x] slice::Iter(Mut): count, last, nth [x] slice::Windows: count, last, nth [x] slice::Chunks(Mut): count, last, nth [ ] char::{EscapeDefault, EscapeUnicode}: count, last, nth (techically but probably not worth it) [ ] str::Bytes: count, last, nth [x] iter::Chain: count, last, nth [x] iter::Enumerate: count, nth [x] iter::Peekable: count, last, nth [x] iter::Skip: count, last, next (should call nth), nth [x] iter::Take: nth [x] iter::Fuse: count, last, nth
I'd be happy to mentor work on this bug.
I would be interested in working on this.
Me too.
Also interested in working on this. Anything left to do?
Any word on this?
Also, I'm curious if methods like are required to actually call n tines, or if they are allowed to "jump ahead" on random-access iterators. (Maybe that sort of trick will have to wait for specialization in the language, to avoid composing that with e.g. a or other potentially side-effectful iterator
can call on the underlying iterator and the underlying iterator can optimize if possible.
I think that is my point: You say "the underlying iterator can optimize if possible", but I claim to allow that would require changing the specification of , which currently is specified as "going through iterations", which I interpret as "calls the method times" -- a side-effectful iterator chain (e.g. one using ) can observe the difference between that or jumping ahead steps when given a random-access iterator.
Oh dear, I seem to've lost track of this thread, sorry to everyone who was waiting on me to organize things! I think probably the first place to start is just to get a list of the public iterators in std, which we can turn into a checklist and track assignees for. Part of the work will just be figuring out which cases are actually opportunities for doing better. Anyone interested in putting such a list together? I'd be glad to help coordinate.
(And if no one is in a position to make a list, I can put one together tomorrow.)
It doesn't because: can assume that the underlying iterator correctly implements . iterators (e.g. ) have side-effect-free methods. These iterators can implement optimized functions. So can have a constant time skip given an optimized method. Unfortunately, as implemented, ranges can't optimize this way because they are generic.
Here's core: slice::Iter(Mut): count, last, nth slice::Windows: count, last, nth slice::Chunks(Mut): count, last, nth char::{EscapeDefault, EscapeUnicode}: count, last, nth (techically but probably not worth it) str::Bytes: count, last, nth iter::Chain: count, last, nth iter::Enumerate: count, nth iter::Peekable: count, last, nth iter::Skip: count, last, next (should call nth), nth iter::Take: nth iter::Fuse: count, last, nth
Thanks I've this as a checklist to the top of the issue. Anyone on thread: feel free to let me know if you want to take on a particular module/crate and I can put your name next to the item to "claim" it.
I'm interested in this would I just fork the repo and work on master or should I make a separate branch like or something?
It usually works best to fork, and then create a branch in your local copy that tracks the master branch on this repo. We use the "fork and pull" model . Once you get cooking, write a comment here to say which modules you're taking so we can avoid overlap. Thanks!
I have one for . However, I'm not happy with the performance of nth (see the inline comment). Issue linked above ^. I also have implementations for the iterator adapters but I'm getting an ICE on compile (code: ) ICE: Which I believe is:
To add to the list, should be overridden in the by_ref iterators (
wrote: I think I see. So you are saying would provide the optimized (and thus could be used in an optimized fashion by an call), while and would be forced to fall back to calling n times, right? Update: (seems obvious in hindsight. ah well.)
Exactly. It should also be possible to optimize methods like any, all, min, max, etc. by avoiding bounds checks but I don't know if it's worth it. However, it probably is worthwhile to optimize those methods for the Bytes/Chars iterators because doing so will allow us to read in large chunks instead of byte-by-byte.
Note that in the long run, we'll need full "specialization" in order to optimize chained cases -- so this issue is primarily about the lowest-hanging fruit that we can tackle with today's trait system.
Additional iterators to consider optimizing: path::Iter: last path::Components: last io::{Bytes, Chars}: count, last, nth, partition, fold, all, any, max, min, maxby, minby, unzip, sum, product Implementing these methods could significantly reduce the number of system calls by reading in as much as possible. Is this worth it or should we just expect users to use a buffered reader? env::{Vars, VarsOs, Args, ArgsOs} count, nth, last Calls down to sys::os::{Env, Args}. sys::os::{Env, Args} count, nth, last vec::IntoIter <scount</s(done), nth, last These may not be worth it because we have to drop each element anyways...
One could still add a specialized path by inspecting the type for the element; see related discussion on (Doing so may or may not be a good idea.)
Are there still things to do for this issue? If there are and they're not assigned I'd like to work on this too.
I'm planning to take care of and . Let me know if you're working on this and I should redirect my attention to other items.
Willing to work on str::Bytes. Is it still up for grabs?
I think you would be safe taking a crack at it :smile:
All of the methods listed in the top comment seem to have been implemented with the exception of those for EscapeDefault and EscapeUnicode. I took an initial stab at them here: ; if they are desired, I will clean up the code and add proper commit messages. It might be a good idea to also audit iterators outside of libcore and add them to the to-do list.
can be checked. My PR was merged.
Just noticed can be checked as well.
From comments it appears this is done. Thanks all.

Discussion:
} #[test] <ins> fn test_bytesator_nth() { let s = "ศไทย中华Việt Nam"; let v = [ 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228, 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97, 109 ]; let mut b = s.bytes(); assert_eq!(b.nth(2).unwrap(), v[2]); assert_eq!(b.nth(10).unwrap(), v[10]); assert_eq!(b.nth(200), None); } #[test] fn test_bytesator_count() { let s = "ศไทย中华Việt Nam"; let b = s.bytes(); assert_eq!(b.count(), 28) } #[test] fn test_bytesator_last() { let s = "ศไทย中华Việt Nam"; let b = s.bytes(); assert_eq!(b.last().unwrap(), 109) } #[test] </ins> fn test_char_indicesator() { let s = "ศไทย中华Việt Nam"; let p = [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27];

fn size_hint(&self) -> (usize, Option<usize>) { self.0.size_hint() } <ins> #[inline] fn count(self) -> usize { self.0.count() } #[inline] fn last(self) -> Option<Self::Item> { self.0.last() } #[inline] fn nth(&mut self, n: usize) -> Option<Self::Item> { self.0.nth(n) } </ins> } #[stable(feature = "rust1", since = "1.0.0")]