Standard C++17 implementation of vector any
, all
:
template<class C, class T>
bool contains(const C& c, const T& value) {
return std::find(c.begin(), c.end(), value) != c.end();
}
template<class C, class... T>
bool any(const C& c, T&&... value) {
return (... || contains(c, value));
}
template<class C, class... T>
bool all(const C& c, T&&... value) {
return (... && contains(c, value));
}
for usage as in
std::array<int, 6> data0 = { 4, 6, 8, 10, 12, 14 };
assert( any(data0, 10, 55, 792));
assert( !any(data0, 11));
assert( all(data0, 6, 14, 8));
assert( !all(data0, 6, 7, 8));
Is there an analogous way to define only
, which returns true if and only if the set of unique values of the vector matches the input values? So the following asserts would hold
std::array<int, 6> data1 = { 1, 1, 2, 1, 2 };
assert( only(data1, 1, 2));
assert( !only(data1, 1));
template<class C, class...Ts>
bool only( C const& c, Ts&&...ts ) {
std::size_t count = (std::size_t(0) + ... + contains(c, ts));
return count == c.size();
}
this counts how many of the list ts...
are in c
, and returns true if the number you found ear equal to the elements of c
. Now this assumes uniqueness of c
and ts
.
We just move the counting into only
and test within the std algorithm:
template<class C, class...Ts>
bool only( C const& c, Ts&&...ts ) {
using std::begin; using std::end;
auto count = std::count_if( begin(c), end(c), [&](auto&& elem) {
return ((elem == ts) || ...);
} );
return count == c.size();
}
and bob is your uncle.
We could also do a notcontains
based only
algorithm, but I think that is more complex.