Boost logo

Boost :

From: Thorsten Ottosen (tottosen_at_[hidden])
Date: 2006-02-02 14:44:43


David Abrahams wrote:
> Thorsten Ottosen <tottosen_at_[hidden]> writes:

>>1. leave the return type as it is.
>>
>>2. return an iterator_range describing the range [found,end)
>>this allows us to do stuff like
>>
>> namespace br = boost::ranges;
>> br::erase( rng, br::unique(rng) );
>>
>>3. inspired by John Torjo's range lib, provide a whole list of possible
>> return values:

[snip]

> 2 is the answer for me.
>
>
>>the default would be the range [found,end), but the you can pick
>>different slices or simply iterators. In the above scheme, "found" is
>>the iterator normally returnes by the algorithm, "next" means
>>boost::next(found) and "prior" means boost::prior(found).
>
>
> And that works for ranges without bidirectional iterators, e.g. slist?

"prior" can of course not work with bidirectional iterators.

>>The advantage of the latter approach is
>>
>>- flexibility/power
>>- safety (we can tjeck that next(found) and prior(found) stays in range)
>>
>>The disadvantage is that it will require twice as many overloads in
>>C++03 (since we can't put defaults template arguments in function
>>templates).
>
>
> And it's complex.

implementation wise or interface wise?

> I'm wary of introducing any such complexity without a strong catalog
> of use cases.

basically it makes splitting of ranges way easier and safer.

assume I want to find the first occurence of 5 and then copy the
range [begin,found] (that is, [begin,next(found)) ) somewhere:

        std::vector<int> v = ...;
        std::vector<int>::iterator i = find( v, 5 );
        if( i != v.end() )
         {
             ++i;
           copy( v.begin(), i, out );
         }

vs

        copy( find<return_begin_next>( v, 5 ), out ); (*)

If found == v.end(), the returned ranges are empty and so you completely
avoid forgetting about checking for the end iterator.

Having only (2) we can still, however, do a little better than above:

        copy( find( c, 5 ).advance_end(1), out )

but now we can't be sure we don't iterator past the end. Thus we would
be forced to create a temporary.

-Thorsten

(*) without much extra work, I could probably get a generalized
version like

   xx_next<N>
   xx_prior<N>

to work.


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