mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-11-14 10:39:05 +00:00
191 lines
6.6 KiB
C++
191 lines
6.6 KiB
C++
#ifndef SPROUT_LOGIC_TRIBOOL_TRIBOOL_HPP
|
|
#define SPROUT_LOGIC_TRIBOOL_TRIBOOL_HPP
|
|
|
|
#include <sprout/config.hpp>
|
|
#include <sprout/logic/tribool/tribool_fwd.hpp>
|
|
|
|
namespace sprout {
|
|
namespace logic {
|
|
namespace detail {
|
|
struct indeterminate_t {};
|
|
} // namespace detail
|
|
|
|
//
|
|
// indeterminate_keyword_t
|
|
//
|
|
typedef bool (*indeterminate_keyword_t)(sprout::logic::tribool, sprout::logic::detail::indeterminate_t);
|
|
|
|
//
|
|
// tribool
|
|
//
|
|
class tribool {
|
|
private:
|
|
struct dummy {
|
|
public:
|
|
void nonnull() {}
|
|
};
|
|
typedef void (dummy::*safe_bool)();
|
|
public:
|
|
enum value_t {
|
|
false_value,
|
|
true_value,
|
|
indeterminate_value
|
|
};
|
|
public:
|
|
value_t value;
|
|
public:
|
|
SPROUT_CONSTEXPR tribool()
|
|
: value(false_value)
|
|
{}
|
|
SPROUT_CONSTEXPR tribool(bool initial_value)
|
|
: value(initial_value? true_value : false_value)
|
|
{}
|
|
SPROUT_CONSTEXPR tribool(sprout::logic::indeterminate_keyword_t)
|
|
: value(indeterminate_value)
|
|
{}
|
|
SPROUT_CONSTEXPR operator safe_bool() const {
|
|
return value == true_value ? &dummy::nonnull : 0;
|
|
}
|
|
};
|
|
|
|
//
|
|
// indeterminate
|
|
//
|
|
inline SPROUT_CONSTEXPR bool
|
|
indeterminate(sprout::logic::tribool x, sprout::logic::detail::indeterminate_t = sprout::logic::detail::indeterminate_t()) {
|
|
return x.value == sprout::logic::tribool::indeterminate_value;
|
|
}
|
|
|
|
//
|
|
// operator!
|
|
//
|
|
inline SPROUT_CONSTEXPR sprout::logic::tribool
|
|
operator!(sprout::logic::tribool x) {
|
|
return x.value == sprout::logic::tribool::false_value ? sprout::logic::tribool(true)
|
|
: x.value == sprout::logic::tribool::true_value ? sprout::logic::tribool(false)
|
|
: sprout::logic::tribool(sprout::logic::indeterminate)
|
|
;
|
|
}
|
|
|
|
//
|
|
// operator&&
|
|
//
|
|
inline SPROUT_CONSTEXPR sprout::logic::tribool
|
|
operator&&(sprout::logic::tribool lhs, sprout::logic::tribool rhs) {
|
|
return static_cast<bool>(!lhs) || static_cast<bool>(!rhs) ? sprout::logic::tribool(false)
|
|
: static_cast<bool>(lhs) && static_cast<bool>(rhs) ? sprout::logic::tribool(true)
|
|
: sprout::logic::tribool(sprout::logic::indeterminate)
|
|
;
|
|
}
|
|
inline SPROUT_CONSTEXPR sprout::logic::tribool
|
|
operator&&(tribool lhs, bool rhs) {
|
|
return rhs ? lhs : sprout::logic::tribool(false);
|
|
}
|
|
|
|
inline SPROUT_CONSTEXPR sprout::logic::tribool
|
|
operator&&(bool lhs, sprout::logic::tribool rhs) {
|
|
return lhs ? rhs : sprout::logic::tribool(false);
|
|
}
|
|
|
|
inline SPROUT_CONSTEXPR sprout::logic::tribool
|
|
operator&&(sprout::logic::indeterminate_keyword_t, sprout::logic::tribool lhs) {
|
|
return !lhs ? sprout::logic::tribool(false) : sprout::logic::tribool(sprout::logic::indeterminate);
|
|
}
|
|
inline SPROUT_CONSTEXPR sprout::logic::tribool
|
|
operator&&(sprout::logic::tribool lhs, sprout::logic::indeterminate_keyword_t) {
|
|
return !lhs ? sprout::logic::tribool(false) : sprout::logic::tribool(indeterminate);
|
|
}
|
|
|
|
//
|
|
// operator||
|
|
//
|
|
inline SPROUT_CONSTEXPR sprout::logic::tribool
|
|
operator||(sprout::logic::tribool lhs, sprout::logic::tribool rhs) {
|
|
return static_cast<bool>(!lhs) && static_cast<bool>(!rhs) ? sprout::logic::tribool(false)
|
|
: static_cast<bool>(lhs) || static_cast<bool>(rhs) ? sprout::logic::tribool(true)
|
|
: sprout::logic::tribool(sprout::logic::indeterminate)
|
|
;
|
|
}
|
|
inline SPROUT_CONSTEXPR sprout::logic::tribool
|
|
operator||(sprout::logic::tribool lhs, bool rhs) {
|
|
return rhs ? sprout::logic::tribool(true) : lhs;
|
|
}
|
|
inline SPROUT_CONSTEXPR sprout::logic::tribool
|
|
operator||(bool lhs, sprout::logic::tribool rhs) {
|
|
return lhs ? sprout::logic::tribool(true) : rhs;
|
|
}
|
|
inline SPROUT_CONSTEXPR sprout::logic::tribool
|
|
operator||(sprout::logic::indeterminate_keyword_t, sprout::logic::tribool lhs) {
|
|
return lhs ? sprout::logic::tribool(true) : sprout::logic::tribool(sprout::logic::indeterminate);
|
|
}
|
|
inline SPROUT_CONSTEXPR sprout::logic::tribool
|
|
operator||(sprout::logic::tribool lhs, sprout::logic::indeterminate_keyword_t) {
|
|
return lhs ? sprout::logic::tribool(true) : sprout::logic::tribool(sprout::logic::indeterminate);
|
|
}
|
|
|
|
//
|
|
// operator==
|
|
//
|
|
inline SPROUT_CONSTEXPR sprout::logic::tribool
|
|
operator==(sprout::logic::tribool lhs, sprout::logic::tribool rhs) {
|
|
return sprout::logic::indeterminate(lhs) || sprout::logic::indeterminate(rhs)
|
|
? sprout::logic::tribool(sprout::logic::indeterminate)
|
|
: (lhs && rhs) || (!lhs && !rhs)
|
|
;
|
|
}
|
|
inline SPROUT_CONSTEXPR sprout::logic::tribool
|
|
operator==(sprout::logic::tribool lhs, bool rhs) {
|
|
return lhs == sprout::logic::tribool(rhs);
|
|
}
|
|
inline SPROUT_CONSTEXPR sprout::logic::tribool
|
|
operator==(bool lhs, sprout::logic::tribool rhs) {
|
|
return sprout::logic::tribool(lhs) == rhs;
|
|
}
|
|
inline SPROUT_CONSTEXPR sprout::logic::tribool
|
|
operator==(sprout::logic::indeterminate_keyword_t, sprout::logic::tribool lhs) {
|
|
return sprout::logic::tribool(sprout::logic::indeterminate) == lhs;
|
|
}
|
|
inline SPROUT_CONSTEXPR sprout::logic::tribool
|
|
operator==(sprout::logic::tribool lhs, sprout::logic::indeterminate_keyword_t) {
|
|
return sprout::logic::tribool(sprout::logic::indeterminate) == lhs;
|
|
}
|
|
|
|
//
|
|
// operator!=
|
|
//
|
|
inline SPROUT_CONSTEXPR sprout::logic::tribool
|
|
operator!=(sprout::logic::tribool lhs, sprout::logic::tribool rhs) {
|
|
return sprout::logic::indeterminate(lhs) || sprout::logic::indeterminate(rhs)
|
|
? sprout::logic::tribool(sprout::logic::indeterminate)
|
|
: !((lhs && rhs) || (!lhs && !rhs))
|
|
;
|
|
}
|
|
inline SPROUT_CONSTEXPR sprout::logic::tribool
|
|
operator!=(sprout::logic::tribool lhs, bool rhs) {
|
|
return lhs != sprout::logic::tribool(rhs);
|
|
}
|
|
inline SPROUT_CONSTEXPR sprout::logic::tribool
|
|
operator!=(bool lhs, sprout::logic::tribool rhs) {
|
|
return sprout::logic::tribool(lhs) != rhs;
|
|
}
|
|
inline SPROUT_CONSTEXPR sprout::logic::tribool
|
|
operator!=(sprout::logic::indeterminate_keyword_t, sprout::logic::tribool lhs) {
|
|
return sprout::logic::tribool(sprout::logic::indeterminate) != lhs;
|
|
}
|
|
inline SPROUT_CONSTEXPR sprout::logic::tribool
|
|
operator!=(sprout::logic::tribool lhs, sprout::logic::indeterminate_keyword_t) {
|
|
return sprout::logic::tribool(sprout::logic::indeterminate) != lhs;
|
|
}
|
|
} // namespace logic
|
|
|
|
using sprout::logic::tribool;
|
|
using sprout::logic::indeterminate;
|
|
} // namespace sprout
|
|
|
|
#define SPROUT_TRIBOOL_THIRD_STATE(NAME) \
|
|
inline SPROUT_CONSTEXPR bool \
|
|
NAME(sprout::logic::tribool lhs, sprout::logic::detail::indeterminate_t = sprout::logic::detail::indeterminate_t()) { \
|
|
return lhs.value == sprout::logic::tribool::indeterminate_value; \
|
|
}
|
|
|
|
#endif // #ifndef SPROUT_LOGIC_TRIBOOL_TRIBOOL_HPP
|