Boost logo

Boost :

From: Richard Peters (r.a.peters_at_[hidden])
Date: 2004-11-10 11:34:34


David Abrahams writes:
> > "Robert Ramey" <ramey <at> rrsd.com> wrote in message
> > news:cmrl55$hng$1 <at> sea.gmane.org...
> > >
> > > I agree that iterators aren't that easy or intuitive to work with. So
our
> > > motivations have much in common. My view is that iterators can be
made
> > > easier to work with without changing their fundamental character and
> > > without
> > > the need to introduce what I see as a new concept (ranges) that is
"almost
> > > the same" as an existing concept - pair of iterators.
>
> Like Robert I am uncomfortable with a
> range concept that has iteration capabilities.
> For one thing, standard containers don't
> satisfy that concept, and it seems to me
> that a container ought to be a range without
> any special adaptation. Furthermore
> I have doubts about how well this "range/iterator"
> concept maps onto bidirectional
> and random access. That said...

I think it will be very difficult to have the standard containers satisfy a
range concept. Containers hold elements, and provide access to them via
iterators. Those two iterators model a range. Algorithms like for_each take
that range, and process the items element by element, by using the first
element, and shrinking the range by incrementing the first iterator. When
you view a container as a range, you can't shrink the range without deleting
elements. This would mean that when passing a container to an algorithm that
that algorithm either deletes items or has to copy the container. Ranges
live at the level of iterators, providing access. They do not live at the
level of containers, which store elements. Therefore, I think a container
does not need to satisfy the range concept.

If I were allowed to make changes to the standard library, I would add a
member function range() to containers, returning some range object holding a
begin and an end: Containers hold objects, and provide access to them by
representing those objects as a range. The range provides access to
individual elements using iterators. Of course, changes to the standard
library are not considered here. A make_range(container), however, comes
very close to this, and seems like a good solution to me.

As to the iteration capabilities: What would we loose if the iteration
capabilities are removed? Are for-loops the only place that would be
significantly changed?

    for ( crange<some_array_type> r(some_array); r; ++r)
         do_something( *r, some_data);

I think this syntax is a bit too short anyway. What about adding member
functions empty(), size(), front(), back()?

    for ( crange<some_array_type> r(some_array); !r.empty(); ...)
         do_something( r.front(), some_data);

Looks nice enough, IMHO. This leaves only the problem of shrinking the range
at the start. What do you think about range.begin() (non-const version)
returning a reference to its begin iterator? Then ++r.begin() would be the
equivalent of the current ++r. Similarly end() can return a reference,
making shortening the range at the end possible.
Another option I thought of was using pop_front(), but this has the
disadvantage that it doesn't do exactly what is says: it does resemble
list's pop_front, but no element is really erased.

best regards,

Richard Peters


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk