tags:

views:

100

answers:

4

Is there anything approximating Haskell's all or any functions as part of the STL? If not, is the below a good implementation (I noticed the sgi STL performed partial specialization if the iterators were random access, though I have not bothered with this)?

template <typename InputIterator, typename Predicate>
inline bool all(InputIterator first, InputIterator last, Predicate pred) {
  while (first != last) {
    if (!pred(*first)) {
      return false;
    }
    ++first;
  }
  return true;
}

Similarly, how would this best be transformed to iterate two sequences, and return true where a BinaryPredicate returns true for all, and false otherwise? I know this is relatively trivial, but it seems like this should be provided by algorithm, and I want to make sure I'm not overlooking something.

+6  A: 

There are not all or any algorithms in C++ currently, but C++0x adds std::all_of and std::any_of algorithms to the C++ standard library. Your implementation may support these already.

Since both of these algorithms need to test every element in the range (at least until they find a match or mismatch), there isn't any reason to specialize them for different types of iterators: the performance when used with forward iterators should be the same as the performance when used with random access iterators.

Your implementation of all is fine; the Visual C++ all_of implementation is effectively the same, except that it uses a for loop instead of a while loop.

how would this best be transformed to iterate two sequences, and return true where a BinaryPredicate returns true for all, and false otherwise?

This is what std::equal does. You'll need to check the sizes of the ranges first to ensure that they are of the same size.

James McNellis
I shall also point toward `std::mismatch`, which returns a pair of iterators indicating the first difference in the two sequences.
Matthieu M.
+1  A: 

You can use std::find_if like, which returns Iterator last if the predicate returns false for all elements, otherwise it returns the element that it returns true for.

Iterator it = std::find_if (container.begin (), container.end (), predicate);
if (it != container.end ())
    // One of them doesn't match
Joe D
Instead of "one of them doesn't match," it should be "one of them matches," right? You can implement `any` this way, but you would need to negate the predicate to implement `all` this way.
James McNellis
std::find_if() is a good candidate for an alternate implementation (one that I would prefer if I was writing the functions), but it is not equivalent in that it doesn't return a Boolean result, as apparently the Haskell functions do.
gregg
+4  A: 

This looks almost equivalent to std::find_if with the predicate inverted to me.

Mark B
+1: Why reinvent the wheel here when we already have a perfectly good wheel?
John Dibling
@John Dibling: Because I want to build my blue wheel here as nobody else can build a good wheel. ;-)
Martin York
A: 

How about foreach from BOOST ? it's not STL but available for any platform.

Mee
Doesn't do what OP wants. FOREACH iterates over the entire sequence. OP wants to iterate over the sequence until something is evaluated as true, then stop.
John Dibling