GrahamS
GrahamS

Reputation: 10350

Is there an STL/boost algorithm to check all elements in a container match a value?

Is there an STL/boost algorithm that will test if all the elements between two iterators match a given value? Or alternatively that a predicate returns true for all of them?

i.e. something like

template<class InputIterator, class T>
InputIterator all_match (InputIterator first, InputIterator last, const T& value)
{
    bool allMatch = true;
    while(allMatch && first!=last)
        allMatch = (value == *first++);
    return allMatch;
}

Or

template <class InputIterator, class Predicate>
bool all_true (InputIterator first, InputIterator last, Predicate pred)
{
    bool allTrue = true;
    while (allTrue && first != last) 
        allTrue = pred(*first++);
    return allTrue;
}

Upvotes: 16

Views: 3452

Answers (5)

fredoverflow
fredoverflow

Reputation: 263118

C++11 introduces std::all_of.

Upvotes: 21

MSalters
MSalters

Reputation: 179799

Often you can just count them:

template<class FwdIterator, class T>
InputIterator all_match (FwdIterator first, FwdIterator last, const T& value)
{
   return std::count(first, last, value) == std::distance(first, last);
}

Inefficient when the iterator isn't random, or when it returns false. Doesn't work for input iterators.

Upvotes: 1

CashCow
CashCow

Reputation: 31435

If you can negate the predicate you can use std::find / std::find_if and see if it returns the end element of your sequence. If not then it returns the one that does match.

You can adapt an function with std::not1 or std::not_equal_to so by doing combined with std::find_if you can indeed do so using STL without writing a loop.

bool allMatch = seq.end() == std::find_if( seq.begin(), seq.end(), 
    std::not_equal_to(val) );
bool allPass = seq.end() == std::find_if( seq.begin(), seq.end(), 
    std::not1(pred) );

Upvotes: 22

Naveen
Naveen

Reputation: 73443

You can use std::equal with the predicate. Something like:

using namespace std;
using namespace boost::lambda;

int main()
{
    vector<int> a;
    a.push_back(1);
    a.push_back(1);
    a.push_back(2);
    a.push_back(2);
    a.push_back(3);
    bool allMatch = equal(a.begin(), a.begin() + 2, a.begin(), _1 == 1);
    return 0;
}

Upvotes: 2

frast
frast

Reputation: 2740

You could use std:find ord std::find_if to do this.

template <class T>
struct pred {
    T t_;

    pred(const T& value) : t_(value) {}

    bool operator()(const T &t)
    {
        return t != t_;
    }
};

if (e.cend() == std::find_if(c.cbegin(), c.cend(), pred<T>(value)))
    print("all match value");

Upvotes: 2

Related Questions