This C++23 implementation is based on the pre C++98 sample code in the book. import std; using String = std::string; template using TreeMap = std::map; template using UniquePtr = std::unique_ptr; class BooleanExpression { public: BooleanExpression() = default; virtual ~BooleanExpression() = default; virtual bool evaluate(Context&) = 0; virtual UniquePtr replace(String&, BooleanExpression&) = 0; virtual UniquePtr copy() const = 0; }; class VariableExpression; class Context { private: TreeMap m; public: Context() = default;
nodiscard bool lookup(const VariableExpression* key) const { return m.at(key); } void assign(VariableExpression* key, bool value) { m[key] = value; } }; class VariableExpression : public BooleanExpression { private: String name; public: VariableExpression(const String& name): name{name} {} virtual ~VariableExpression() = default;
nodiscard virtual bool evaluate(Context& context) const { return context.lookup(this); }
nodiscard virtual UniquePtr replace(const String& name, BooleanExpression& exp) { if (this->name == name) { return std::make_unique(exp.copy()); } else { return std::make_unique(name); } }
nodiscard virtual UniquePtr copy() const { return std::make_unique(name); } VariableExpression(const VariableExpression&) = delete; VariableExpression& operator=(const VariableExpression&) = delete; }; class AndExpression : public BooleanExpression { private: UniquePtr operand1; UniquePtr operand2; public: AndExpression(UniquePtr op1, UniquePtr op2): operand1{std::move(op1)}, operand{std::move(op2)} {} virtual ~AndExpression() = default;
nodiscard virtual bool evaluate(Context& context) const { return operand1->evaluate(context) && operand2->evaluate(context); }
nodiscard virtual UniquePtr replace(const String& name, BooleanExpression& exp) const { return std::make_unique( operand1->replace(name, exp), operand2->replace(name, exp) ); }
nodiscard virtual UniquePtr copy() const { return std::make_unique(operand1->copy(), operand2->copy()); } AndExpression(const AndExpression&) = delete; AndExpression& operator=(const AndExpression&) = delete; }; int main(int argc, char* argv[]) { UniquePtr expression; Context context; UniquePtr x = std::make_unique("X"); UniquePtr y = std::make_unique("Y"); UniquePtr expression; = std::make_unique(x, y); context.assign(x.get(), false); context.assign(y.get(), true); bool result = expression->evaluate(context); std::println("{}", result); context.assign(x.get(), true); context.assign(y.get(), true); result = expression->evaluate(context); std::println("{}", result); return 0; } The program output is: 0 1 == See also ==