Conditional statements

Code containing conditional statements poses a challenge. Conditional statement are created by invoking one of the following boolean operators, or their overloads where one size is a primitive number type.

    friend bool operator ==(const Symbol& lhs, const Symbol& rhs);
    friend bool operator !=(const Symbol& lhs, const Symbol& rhs);
    friend bool operator < (const Symbol& lhs, const Symbol& rhs);
    friend bool operator <=(const Symbol& lhs, const Symbol& rhs);
    friend bool operator > (const Symbol& lhs, const Symbol& rhs);
    friend bool operator >=(const Symbol& lhs, const Symbol& rhs);

Take for example the following function:

Scalar foo(Scalar x, Scalar y)
{
    if (y == 0)
        return x;

    return x/y < 0 ? -x/y : x/y;
}

We cannot evaluate this function by simply calling it once, since there are three different paths through the code depending how the expressions y == 0 and x/y < 0 evaluate. Trying to do so will cause a run time exception to be thrown:

int main()
{    
    Symbol x("x"), y("y");
    try
    {
        Symbol z = foo(x, y);
    }
    catch (const std::exception& ex)
    {
        std::cout << ex.what() << std::endl;
    }
    
EXCEPTION: Your code contains conditional branches, but you haven't created a boolean evaluator.
See http://cppcodegenvar.readthedocs.io/en/latest/conditional_example.html for details.

BooleanEvaluator to the rescue

Here is how to fix the above example:

    BooleanEvaluator evaluator;
    Symbol z;
    do
    {
        std::cout << ".";
        z |= foo(x, y);
    }
    while (!evaluator.isFullyEvaluated());
    std::cout << std::endl << "z = " << z << std::endl;
...
z = 0 == y ?
    x :
0 != y && x/y < 0 ?
    -x/y :
    x/y

You can find the full source code of this example here.