Skip to content

Instantly share code, notes, and snippets.

@kikairoya
Created December 11, 2010 07:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kikairoya/737235 to your computer and use it in GitHub Desktop.
Save kikairoya/737235 to your computer and use it in GitHub Desktop.
#ifndef TRIBOOL_HPP
#define TRIBOOL_HPP
#include <boost/config.hpp>
namespace logic {
struct indeterminate_t;
struct tribool {
enum tribool_value_t {
false_value = false,
true_value = true,
indeterminate_value = static_cast<int>(true) + 1
};
tribool(): value(false_value) { }
tribool(bool b): value(static_cast<tribool_value_t>(b)) { }
tribool(tribool_value_t b): value(b) { }
tribool(const indeterminate_t &): value(indeterminate_value) { }
tribool_value_t value;
bool false_p() const { return value == false_value; }
bool true_p() const { return value == true_value; }
bool indeterminate_p() const { return value == indeterminate_value; }
tribool operator !() const {
return false_p() ? tribool(true) : true_p() ? tribool(false) : tribool(indeterminate_value);
}
#ifdef BOOST_NO_EXPLICIT_CONVERSION_OPERATORS
private:
struct dummy { void nonnull() {}; };
typedef void (dummy::*safe_bool)();
public:
operator safe_bool() const { return value == true_value ? &dummy::nonnull : 0; }
#else
explicit operator bool() const { return value == true_value; }
#endif
};
static const struct indeterminate_t {
operator bool() const { return false; }
tribool operator !() const { return tribool(indeterminate_t()); }
bool operator ()(indeterminate_t) const { return true; }
bool operator ()(tribool b) const { return b.value == tribool::indeterminate_value; }
} indeterminate = { };
inline tribool operator ==(tribool x, tribool y) {
return (x.indeterminate_p() || y.indeterminate_p()) ? indeterminate : tribool(x.value == y.value) ;
}
inline tribool operator ==(tribool x, bool y) { return x == tribool(y); }
inline tribool operator ==(bool x, tribool y) { return y == x; }
inline tribool operator ==(tribool, indeterminate_t) { return indeterminate; }
inline tribool operator ==(indeterminate_t, tribool) { return indeterminate; }
inline tribool operator ==(bool, indeterminate_t) { return indeterminate; }
inline tribool operator ==(indeterminate_t, bool) { return indeterminate; }
inline tribool operator !=(tribool x, tribool y) {
return (x.indeterminate_p() || y.indeterminate_p()) ? indeterminate : tribool(x.value != y.value) ;
}
inline tribool operator !=(tribool x, bool y) { return x != tribool(y); }
inline tribool operator !=(bool x, tribool y) { return y != x; }
inline tribool operator !=(tribool, indeterminate_t) { return indeterminate; }
inline tribool operator !=(indeterminate_t, tribool) { return indeterminate; }
inline tribool operator !=(bool, indeterminate_t) { return indeterminate; }
inline tribool operator !=(indeterminate_t, bool) { return indeterminate; }
inline tribool operator &&(tribool x, tribool y) {
return (x.false_p() || y.false_p()) ? tribool(false)
: (x.indeterminate_p() || y.indeterminate_p()) ? indeterminate
: tribool(true);
}
inline tribool operator &&(tribool x, bool y) { return y ? x : tribool(false); }
inline tribool operator &&(bool x, tribool y) { return y && x; }
inline tribool operator &&(tribool x, indeterminate_t) { return x.false_p() ? tribool(false) : indeterminate; }
inline tribool operator &&(indeterminate_t, tribool x) { return x && indeterminate; }
inline tribool operator &&(bool x, indeterminate_t) { return tribool(x) && indeterminate; }
inline tribool operator &&(indeterminate_t, bool x) { return x && indeterminate; }
inline tribool operator ||(tribool x, tribool y) {
return (x.true_p() || y.true_p()) ? tribool(true)
: (x.indeterminate_p() || y.indeterminate_p()) ? indeterminate
: tribool(false);
}
inline tribool operator ||(tribool x, bool y) { return y ? tribool(true) : x; }
inline tribool operator ||(bool x, tribool y) { return y || x; }
inline tribool operator ||(tribool x, indeterminate_t) { return x.true_p() ? tribool(true) : indeterminate; }
inline tribool operator ||(indeterminate_t, tribool x) { return x || indeterminate; }
inline tribool operator ||(bool x, indeterminate_t) { return tribool(x) || indeterminate; }
inline tribool operator ||(indeterminate_t, bool x) { return x || indeterminate; }
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment