Return SizedIteratorRanges from ranges::range for RandomAccessIteratorRanges and SizedIterables

The interface of `ranges::range` consists of:

- `ranges::range(Iterator, Sentinel, Size) -> sized_iterator_range`
- `ranges::range(Iterator, Sentinel) -> iterator_range`

However, when calling `ranges::range(Iterator, Sentinel)` with `RandomAccessIterator`s, we can 
compute the range size in `O(1)` and return a `sized_iterator_range`.

Furthermore, some containers like `std::list` provide only `BidirectionalIterator`s, but they have
an `O(1)` `size()` member function.

This patch changes `ranges::range` interface to: 

- `ranges::range(Iterator, Sentinel, Size) -> sized_iterator_range`
- `ranges::range(Iterator, Sentinel) -> sized_iterator_range` (if possible) / `iterator_range`
- `ranges::range(Iterable&) -> sized_iterator_range` (if possible) / `iterator_range`

The `ranges::range(Iterable&)` dispatches to a `sized_iterator_range` if the `Iterable` has `RandomAccessIterator`s or `ranges::size(Iterable&)` can compute its size (which is `O(1)`). Otherwise it returns an `iterator_range`.

Note:  the `algorithm/equal.cpp` test used to perform one comparison in the modified `CHECK` clause when comparing two `RandomAccessRange`s even tho they had different sizes. Now it doesn't need to perform any comparison at all. 
Then we should also have size for a pair of iterators. You don't think it runs into the same issue as list::size?

Sent from my iPhone

> On Sep 13, 2014, at 4:57 PM, Eric Niebler <notifications@github.com> wrote:
> 
> In include/range/v3/iterator_range.hpp:
> 
> >                  return {std::move(begin), std::move(end)};
> >              }
> >  
> > -            template<typename I, typename S, typename Size>
> > +            template<typename I, typename S,
> > +                     CONCEPT_REQUIRES_(IteratorRange<I, S>{} && RandomAccessIterator<I>{})>
> > +            static sized_iterator_range<I, S> invoke(range_fn, I begin, S end)
> > +            {
> > +                const auto s = static_cast<iterator_size_t<I>>(distance(begin, end));
> @sean-parent There is a size function for ranges. It "guarantees" O(1) -- insofar as that's possible.
> 
> —
> Reply to this email directly or view it on GitHub.