From 282e2496da1e8f0d96d696ba2401002148b8195c Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Sat, 3 May 2025 02:19:33 +0800 Subject: [PATCH] [Chore] (UncertainBool.hpp): Add UncertainBool class. --- MG/MG_Include/UncertainBool.hpp | 127 ++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 MG/MG_Include/UncertainBool.hpp diff --git a/MG/MG_Include/UncertainBool.hpp b/MG/MG_Include/UncertainBool.hpp new file mode 100644 index 00000000..b7a52d93 --- /dev/null +++ b/MG/MG_Include/UncertainBool.hpp @@ -0,0 +1,127 @@ +// +// Created by BZLZHH on 2025/5/3. +// + +#pragma once +#include +#include +#include + +class UncertainBool { +public: + enum Value { False = 0, True = 1, Unknown = 2 }; + + UncertainBool() : value_(False), default_(false) {} + + explicit UncertainBool(bool b) : value_(b ? True : False), default_(false) {} + + UncertainBool(Value val, bool def) : value_(val), default_(def) { + validateValue(); + } + + UncertainBool(bool val, bool def) : value_(val ? True : False), default_(def) { + validateValue(); + } + + UncertainBool& operator=(Value val) { + value_ = val; + validateValue(); + return *this; + } + + UncertainBool& operator=(bool b) { + value_ = b ? True : False; + return *this; + } + + UncertainBool& operator=(std::initializer_list> init) { + if (init.size() != 1) throw std::invalid_argument("Invalid initializer"); + value_ = init.begin()->first ? True : False; + default_ = init.begin()->second; + return *this; + } + + explicit operator bool() const { + return toBool(); + } + + bool toBool() const { + if (value_ == True) return true; + else if (value_ == False) return false; + else return default_; + } + + UncertainBool operator!() const { + return {static_cast(*this) ? False : True, false}; + } + + bool operator==(const UncertainBool& rhs) const { + return static_cast(*this) == static_cast(rhs); + } + bool operator!=(const UncertainBool& rhs) const { return !(*this == rhs); } + + friend UncertainBool operator&&(const UncertainBool& lhs, const UncertainBool& rhs) { + bool actualDefault = lhs.default_ && rhs.default_; + if(lhs.value_ == False || rhs.value_ == False) return {False,actualDefault}; + else if(lhs.value_ == True && rhs.value_ == True) return {True,actualDefault}; + else return {Unknown, actualDefault}; + } + + friend UncertainBool operator||(const UncertainBool& lhs, const UncertainBool& rhs) { + bool actualDefault = lhs.default_ || rhs.default_; + if(lhs.value_ == True || rhs.value_ == True) return {True,actualDefault}; + else if(lhs.value_ == False && rhs.value_ == False) return {False,actualDefault}; + else return {Unknown, actualDefault}; + } + + friend UncertainBool operator&&(bool lhs,const UncertainBool& rhs){ + return UncertainBool(lhs, lhs) && rhs; + } + + friend UncertainBool operator||(bool lhs,const UncertainBool& rhs){ + return UncertainBool(lhs, lhs) || rhs; + } + + UncertainBool& operator&=(const UncertainBool& rhs) { + *this = *this && rhs; + return *this; + } + + UncertainBool& operator|=(const UncertainBool& rhs) { + *this = *this || rhs; + return *this; + } + + UncertainBool& operator=(std::initializer_list> init) { + if (init.size() != 1) throw std::invalid_argument("Invalid initializer"); + value_ = init.begin()->first; + default_ = init.begin()->second; + validateValue(); + return *this; + } + + Value getValue() const { return value_; } + bool getDefault() const { return default_; } + +private: + Value value_; + bool default_; + + void validateValue() { + if (value_ != False && value_ != True && value_ != Unknown) { + throw std::invalid_argument("Invalid value"); + } + } +}; + +inline UncertainBool operator!(const UncertainBool& lhs) { + return lhs.operator!(); +} + +inline bool operator==(bool lhs, const UncertainBool& rhs) { + return static_cast(rhs) == lhs; +} + +inline bool operator!=(bool lhs, const UncertainBool& rhs) { + return !(lhs == rhs); +} \ No newline at end of file