
On Sun, Jun 24, 2012 at 3:52 AM, Neil Groves <neil@grovescomputing.com>wrote:
On 24/06/12 10:51, Michel Morin wrote:
Now I'm curious: what are the advantages and disadvantages of implementing
reverse_range<R> as a pair of reverse_iterator< R::iterator >'s (I'm being sloppy here, but based on your above assertion, this is the present implementation) versus as a wrapper around an R (held by reference or value) directly? In the latter case, for example, reverse_range<R>::begin would return reverse_iterator< R::iterator >(boost::end(r)) (where r is the wrapped range of type R).
Below, I say boost::begin(r) and boost::end(r) as the underlying iterators.
Your range adaptors are "lazy adaptors": * Pipe operators does not adapt the underlying iterators in effect. * The underlying iterators are adapted only when begin/end is called. And each time begin/end of your range adaptors is called, the underlying iterators needs to be adapted.
As a general idiom the use of lazily adapting upon the invocation of begin/end would mix two responsibilities. If one considers the complications involved with managing functor and predicate state being delayed until the invocation of begin/end it appears to be a considerably more complex solution.
I don't understand what you mean here. Surely adapted iterators must likewise manage "functor and predicate state"? Can you elaborate? I do not perceive a compensating advantage for this approach. Of course, I
may well be missing the advantage and invite correction.
As Michael points out, it helps solve the temporary lifetime issue in for loops...and I guess it allows one to return adapted ranges from functions? And, ultimately, if there's ultimately just one call to begin/end on the final adapted range (the common case?), both the present implementation of the Boost.Range adaptors and a lazy implementation would go through the same sequence of iterator constructions, right? - Jeff