#pragma once #include namespace ConditionType { enum type { NONE, isTuesday, isThursday, isAfterEight }; } namespace OperatorType { enum type { NONE, OR, AND }; } class Condition { public: Condition(ConditionType::type condition) : mCondition(condition) , mOperatorType(OperatorType::NONE) , mLCondition() , mRCondition() {} Condition(const Condition &left, OperatorType::type opType, const Condition &right) : mCondition(ConditionType::NONE) , mOperatorType(opType) , mLCondition(new Condition(left)) , mRCondition(new Condition(right)) {} Condition(const Condition &other) : mCondition(other.mCondition) , mOperatorType(other.mOperatorType) , mLCondition(other.mLCondition ? new Condition(*other.mLCondition) : nullptr) , mRCondition(other.mRCondition ? new Condition(*other.mRCondition) : nullptr) { } Condition &Condition::operator=(const Condition &other) { mCondition = other.mCondition; mOperatorType = other.mOperatorType; mLCondition.reset(other.mLCondition ? new Condition(*other.mLCondition) : nullptr); mRCondition.reset(other.mRCondition ? new Condition(*other.mRCondition) : nullptr); return *this; } operator bool() const { return evauluate(); } bool evauluate() const { if(mOperatorType == OperatorType::NONE) return passesValue(); else if(mOperatorType == OperatorType::AND) return mLCondition->evauluate() && mRCondition->evauluate(); else if(mOperatorType == OperatorType::OR) return mLCondition->evauluate() || mRCondition->evauluate(); return false; } Condition operator&&(const Condition &other) const { return Condition(*this, OperatorType::AND, other); } Condition operator||(const Condition &other) const { return Condition(*this, OperatorType::OR, other); } private: ConditionType::type mCondition; OperatorType::type mOperatorType; std::unique_ptr mLCondition; std::unique_ptr mRCondition; bool passesValue() const { switch (mCondition) { case ConditionType::isTuesday: return false; case ConditionType::isThursday: return true; case ConditionType::isAfterEight: return false; } return false; } };