#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