mozilla/rust — pull request #14271 by erickt (2014-05-18 02:48:36+00:00)
Title: Add an `Iterator::batch` transformer and explicit size hints for `FromIterator` and `Extend`

This pull request is focused on adding a `Iterator::batch` transformer. `batch` allows you to batch up multiple values from a stream into one value. For example, this can be used for transforming a stream of a monotonically increasing infinite iterator like `count(0, 1)` into a stream of `vec!(0, 1, 2)`, `vec!(3, 4, 5)`, and etc. It can also be seen as a low level transformer primitive that could be used to implement a variety of iterator transformers, as you could use it to implement `map`, `filter`, `reduce`, and more.

Along the way this also adds support for passing an explicit size hints to `.collect()`, `.from_iter()` and `.extend()` in the form of `.collect_with_capacity()`, `.from_iter_with_capacity()` and `.extend_with_capacity()`. Iterator size hints and `.collect()` calls are generally conservative in the size of collections they preallocate. For example, a filter call like `let xs: Vec = range(1, 5).filter(|x| x != 3).collect()` would initially allocate a zero-sized `Vec` because the `.filter()` gives a lower bound of `0`, and `collect` always uses the lower bounds. There is no way for the user to inform `.collect()` to preallocate space for 4 items. Similarly, there isn't a way to overallocate a collection with `.collect()`. These new methods allow the user to have better control over the memory allocation while still using generic methods.

I have to admit though, I'm not sure if it's better to create methods like `.collect_with_capacity()`, or if we should rename `.size_hint()` to `.size_bounds()`, provide a new `Iterator.size_hint()` that may be outside the bounds of the values, and a `.sized_by()` transformer that lets a user to provide a different hint than the lower bounds.

Finally, it also adds some `.reserve_additional` methods on some collections, and cleans up some dead code.