iterator: add DoubleEndedIterator concept

This also implements the trait for vector iterators, obsoleting the
reverse iterator types. The methods will stay, for implementing the
future reverse Iterable traits and convenience.

This can also be trivially implemented for circular buffers and other
variants of arrays.

The `DoubleEndedIterator` trait will allow for implementing algorithms
like in-place reverse on generic mutable iterators.

The naming (`Range` vs. `Iterator`, method naming) can be bikeshedded in
the future. D uses `BidirectionalRange` to refer to this, but
`DoubleEnded` seems somewhat clearer.