If you want to check if all the supplied values are true
, you could make a variadic function template and do a fold over logical AND:
template<class... Args>
constexpr bool compute(Args&&... bools) {
return (... && static_cast<bool>(bools));
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ fold over &&
}
bool result = compute(true, true, true, true);
A 1D array version could look like this:
template<class some_type, std::size_t N>
constexpr bool compute(const some_type(&arr)[N]) {
return [&]<std::size_t... Is>(std::index_sequence<Is...>) {
return (... && static_cast<bool>(arr[Is]));
}(std::make_index_sequence<N>());
}
bool result = compute({true, true, true, true});
For arrays with an arbitraty number of dimensions:
template <class some_type, std::size_t N>
constexpr bool compute(const some_type (&arr)[N]) {
if constexpr (std::rank_v<some_type> == 0) {
// The same 1D array fold expression as above
return [&]<std::size_t... Is>(std::index_sequence<Is...>) {
return (... && static_cast<bool>(arr[Is]));
}(std::make_index_sequence<N>());
} else {
// More than 1 dimension:
return [&]<std::size_t... Is>(std::index_sequence<Is...>) {
// recursively unwrap dimensions
return (... && compute(arr[Is]));
}(std::make_index_sequence<N>());
}
}
some_type truth_table[2][3][6] = {{
{1, 1, 1, 1, 1, 1},
{0, 0, 0, 0, 1, 1},
{0, 0, 0, 1, 0, 1},
},
{
{1, 1, 1, 1, 1, 1},
{0, 0, 0, 0, 1, 1},
{0, 0, 0, 1, 0, 1},
}};
std::cout << compute(truth_table) << '\n';
Ideally, the class could "optimize" the truth table by avoiding unnecessary row evaluation.
All of the above makes use of short-circuit evaluation and will stop the comparison at the first false
encountered.