
Mathias Gaunard skrev:
Eric Niebler wrote:
And that's my point exactly. I feel that this:
boost::find( rng | filtered(pred) )
is more obscure than this:
boost::find_if( rng, pred );
Not only that, but I presume their return types are different, too. The first would return filtered iterators, the second the original iterators. Isn't that right?
Indeed.
Which is why I suggested that boost::find return a [it, end[ range, rather than just the `it' iterator.
I was of the impression that find() already returned a range, like unique(). Or is the default just different?. IMO, most algorithms returning a single iterator would benefit from this, but I guess we might need to discuss each algorithms in isolation to be sure.
That way you can do
boost::empty(boost::find(rng | filtered(pred)));
instead of
auto rng2 = rng | filtered(pred); boost::find(rng2) != boost::end(rng2);
That would be find with me. I guess the crucial qustion is: - is the main purpose of std::find() to locate an element for the purpose of a. test containment b. partition the sequence somehow c. use the element For cases a. and b., a range return would be fine. For c. a single iterator would be best. As for the different return type, then calling .base() should not be too bad: iterator i = boost::find<return_found>( rng | filtered( pred ) ).base(). But this is still not as elegant as the find_if() overload. I'm wondering if the correct return type can somehow be inferred, or if we can define another adaptor that unwraps some arbitrary expression to the inner most iterators, or to some level defined by the user: iterator i = boost::find( rng | reversed | filtered( pred ) ) | unwrapped(2); // or just "| unwrapped" Having to name range return type would be slightly wierd iterator_range<iterator> r = find( rng | filtered( pred ) ) | unwrapped; but doable. -Thorsten