C++ binary predicate version of std::all_of()?

Viewed 296

Given two std::vector<T>s, vec_a and vec_b, does the standard library include a function to test if every element in vec_a is less than its positionally corresponding element in vec_b, assuming the binary operator< is defined for operands of type T?

I would think something like a binary predicate version of std::all_of would do the trick perfectly, but I'm not sure if it exists, or what it would be called if it did. Perhaps also some combination of std::all_of applied to the output of another function which performs elementwise comparison would work, if such a thing exists.


Example of desired functionality:

std::vector<int> vec_a{1, 2, 3};
std::vector<int> vec_b{2, 3, 4};

bool all_less = vec_a.size() == vec_b.size();
for (size_t i = 0; all_less && (i < vec_a.size()); ++i) {
    all_less = vec_a[i] < vec_b[i];
}

// all_less now holds desired result
1 Answers

You can use std::mismatch, although it's a bit harder to comprehend (but is a one liner, yay)

std::vector<int> vec_a{1, 2, 3};
std::vector<int> vec_b{2, 3, 4};

bool all_less = std::mismatch(vec_a.begin(), vec_a.end(), vec_b.begin(), vec_b.end(), std::less<>{}) == std::make_pair(vec_a.end(), vec_b.end());

You can help it a bit by introducing a function for containers and not ranges. I.e

template<typename Container>
bool is_all_less(const Container& c1, const Container& c2)
{
    return std::mismatch(c1.begin(), c2.end(), c1.begin(), c2.end(), std::less<>{}) == std::make_pair(c1.end(), c2.end());
}

and then

bool all_less = is_all_less(vec_a, vec_b);

Edit

If you are sure that containers are of the same size, you can also do this

bool all_less = std::mismatch(vec_a.begin(), vec_a.end(), vec_b.begin(), std::less<>{}).first == vec_a.end();
Related