#pragma once #include #define JVALIDATE_TRIBOOL_TYPE(TypeName, True, False, Maybe) \ class TypeName { \ public: \ enum Enum { True, False, Maybe }; \ \ private: \ Enum state_; \ \ public: \ TypeName(bool state) : state_(state ? True : False) {} \ TypeName(Enum state) : state_(state) {} \ \ operator Enum() const { return state_; } \ explicit operator bool() const { return state_ != False; } \ \ friend TypeName operator!(TypeName val) { \ if (val.state_ == Maybe) { \ return Maybe; \ } \ return val.state_ == False ? True : False; \ } \ \ friend TypeName operator|(TypeName lhs, TypeName rhs) { \ if (lhs.state_ == Maybe && rhs.state_ == Maybe) { \ return Maybe; \ } \ if (lhs.state_ == True || rhs.state_ == True) { \ return True; \ } \ return False; \ } \ \ friend TypeName operator&(TypeName lhs, TypeName rhs) { \ if (lhs.state_ == Maybe && rhs.state_ == Maybe) { \ return Maybe; \ } \ if (lhs.state_ == False || rhs.state_ == False) { \ return False; \ } \ return True; \ } \ \ TypeName & operator&=(TypeName rhs) { return *this = *this & rhs; } \ TypeName & operator|=(TypeName rhs) { return *this = *this | rhs; } \ \ friend auto operator==(TypeName lhs, TypeName::Enum rhs) { \ return static_cast(lhs.state_) == static_cast(rhs); \ } \ friend auto operator!=(TypeName lhs, TypeName::Enum rhs) { \ return static_cast(lhs.state_) != static_cast(rhs); \ } \ friend auto operator<=>(TypeName lhs, TypeName rhs) { \ return static_cast(lhs.state_) <=> static_cast(rhs.state_); \ } \ }