c++truthtable

A standard/popular class to easily manage truth tables in C++?


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.


Solution

  • 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.