tristate.hpp

Back to Three-state logic

pastel/sys/tristate/

#ifndef PASTELSYS_TRISTATE_HPP
#define PASTELSYS_TRISTATE_HPP

#include "pastel/sys/tristate.h"

#include <algorithm>

namespace Pastel
{

    inline void swap(TriState& left, TriState& right)
    {
        std::swap(left, right);
    }

    inline TriState triNot(TriState that)
    {
        TriState result = TriState::Maybe;

        if (that == TriState::True)
        {
            result = TriState::False;
        }
        else if (that == TriState::False)
        {
            result = TriState::True;
        }

        return result;
    }

    inline TriState triMix(TriState left, TriState right)
    {
        TriState result = TriState::Maybe;

        if (left == right &&
            left != TriState::Maybe)
        {
            result = left;
        }

        return result;
    }

    inline TriState triEqual(TriState left, TriState right)
    {
        TriState result = TriState::Maybe;

        // Note:
        // equal(TriState::Maybe, TriState::Maybe) = TriState::Maybe

        if (left == right)
        {
            result = TriState::True;
        }
        else if (left != TriState::Maybe &&
            right != TriState::Maybe)
        {
            result = TriState::False;
        }

        return result;
    }

    inline TriState triNotEqual(TriState left, TriState right)
    {
        TriState result = TriState::Maybe;

        // Note:
        // notEqual(TriState::Maybe, TriState::Maybe) = TriState::Maybe

        if (left == right)
        {
            result = TriState::False;
        }
        else if (left != TriState::Maybe &&
            right != TriState::Maybe)
        {
            result = TriState::True;
        }

        return result;
    }

    inline TriState triAnd(TriState left, TriState right)
    {
        TriState result = TriState::True;

        if (left == TriState::False || right == TriState::False)
        {
            result = TriState::False;
        }
        else if (left == TriState::Maybe || right == TriState::Maybe)
        {
            result = TriState::Maybe;
        }

        return result;
    }

    inline TriState triOr(
        TriState left, TriState right)
    {
        TriState result = TriState::False;

        if (left == TriState::True || right == TriState::True)
        {
            result = TriState::True;
        }
        else if (left == TriState::Maybe || right == TriState::Maybe)
        {
            result = TriState::Maybe;
        }

        return result;
    }

    inline TriState triXor(TriState left, TriState right)
    {
        TriState result = TriState::True;

        if (left == TriState::Maybe || right == TriState::Maybe)
        {
            result = TriState::Maybe;
        }
        else
        {
            if (left == right)
            {
                result = TriState::False;
            }
        }

        return result;
    }

    template <typename Type>
    TriState triLess(
        const Type& left, const Type& right)
    {
        if (left < right)
        {
            return TriState::True;
        }

        if (right < left)
        {
            return TriState::False;
        }

        return TriState::Both;
    }

}

#endif