Given a truth table with 5 inputs and one output, with a function prototype like:
bool compute(bool in1, bool in2, bool in3, bool in4, bool in5);
Is there somewhere, in the STL or other library, a class that allows to easily and efficiently manage the implementation of such a function?
In particular, the idea would be to be able to easily code the truth table with a kind of array like this:
some_type truth_table = [[0,0,0,0,0,0],
[0,0,0,0,1,1],
[0,0,0,1,0,1]
...];
Ideally, the class could "optimize" the truth table by avoiding unnecessary row evaluation.
This post and this post start to answer the question but using custom macros/implems.
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.