diff --git a/src/App/Expression.cpp b/src/App/Expression.cpp index 9b42037db6..4311ab5c2e 100644 --- a/src/App/Expression.cpp +++ b/src/App/Expression.cpp @@ -1226,9 +1226,9 @@ void UnitExpression::setUnit(const Quantity &_quantity) } } -Expression *UnitExpression::simplify() const +ExpressionPtr UnitExpression::simplify() const { - return new NumberExpression(owner, quantity); + return std::make_unique(owner, quantity); } void UnitExpression::_toString(std::ostream &ss, bool,int) const @@ -1258,9 +1258,9 @@ NumberExpression::NumberExpression(const DocumentObject *_owner, const Quantity { } -Expression *NumberExpression::simplify() const +ExpressionPtr NumberExpression::simplify() const { - return copy().release(); + return copy(); } Expression *NumberExpression::_copy() const @@ -1439,19 +1439,17 @@ Py::Object OperatorExpression::_getPyValue() const { return calc(this,op,left,right,false); } -Expression *OperatorExpression::simplify() const +ExpressionPtr OperatorExpression::simplify() const { - Expression * v1 = left->simplify(); - Expression * v2 = right->simplify(); + ExpressionPtr v1 = left->simplify(); + ExpressionPtr v2 = right->simplify(); // Both arguments reduced to numerics? Then evaluate and return answer - if (freecad_cast(v1) && freecad_cast(v2)) { - delete v1; - delete v2; - return eval().release(); + if (freecad_cast(v1.get()) && freecad_cast(v2.get())) { + return eval(); } else - return new OperatorExpression(owner, v1, op, v2); + return std::make_unique(owner, v1.release(), op, v2.release()); } void OperatorExpression::_toString(std::ostream &s, bool persistent,int) const @@ -2587,18 +2585,19 @@ Py::Object FunctionExpression::_getPyValue() const { return evaluate(this,f,args); } -Expression *FunctionExpression::simplify() const +ExpressionPtr FunctionExpression::simplify() const { size_t numerics = 0; std::vector simplifiedArgs; // Try to simplify each argument to function for (auto it : args) { - Expression * v = it->simplify(); + ExpressionPtr v = it->simplify(); - if (freecad_cast(v)) + if (freecad_cast(v.get())) { ++numerics; - simplifiedArgs.push_back(v); + } + simplifiedArgs.push_back(v.release()); } if (numerics == args.size()) { @@ -2608,11 +2607,15 @@ Expression *FunctionExpression::simplify() const for (auto it : simplifiedArgs) delete it; - return eval().release(); + return eval(); } else - return new FunctionExpression(owner, f, std::string(fname), - std::move(simplifiedArgs)); + return std::make_unique( + owner, + f, + std::string(fname), + std::move(simplifiedArgs) + ); } void FunctionExpression::_toString(std::ostream &ss, bool persistent,int) const @@ -2878,9 +2881,9 @@ void VariableExpression::_toString(std::ostream &ss, bool persistent,int) const ss << var.toString(); } -Expression *VariableExpression::simplify() const +ExpressionPtr VariableExpression::simplify() const { - return copy().release(); + return copy(); } Expression *VariableExpression::_copy() const @@ -3083,9 +3086,9 @@ StringExpression::~StringExpression() { } } -Expression *StringExpression::simplify() const +ExpressionPtr StringExpression::simplify() const { - return copy().release(); + return copy(); } void StringExpression::_toString(std::ostream &ss, bool,int) const @@ -3131,18 +3134,26 @@ Py::Object ConditionalExpression::_getPyValue() const { return falseExpr->getPyValue(); } -Expression *ConditionalExpression::simplify() const +ExpressionPtr ConditionalExpression::simplify() const { - std::unique_ptr e(condition->simplify()); + ExpressionPtr e = condition->simplify(); NumberExpression * v = freecad_cast(e.get()); - if (!v) - return new ConditionalExpression(owner, condition->simplify(), trueExpr->simplify(), falseExpr->simplify()); + if (!v) { + return std::make_unique( + owner, + condition->simplify().release(), + trueExpr->simplify().release(), + falseExpr->simplify().release() + ); + } else { - if (fabs(v->getValue()) >= Base::Precision::Confusion()) + if (fabs(v->getValue()) >= Base::Precision::Confusion()) { return trueExpr->simplify(); - else + } + else { return falseExpr->simplify(); + } } } @@ -3270,9 +3281,9 @@ Expression *RangeExpression::_copy() const return new RangeExpression(owner, begin, end); } -Expression *RangeExpression::simplify() const +ExpressionPtr RangeExpression::simplify() const { - return copy().release(); + return copy(); } void RangeExpression::_getIdentifiers(std::map &deps) const @@ -3714,7 +3725,7 @@ std::unique_ptr ExpressionParser::parseUnit( throw ParserError("Unknown error in expression"); // Simplify expression - Expression * simplified = ScanResult->simplify(); + ExpressionPtr simplified = ScanResult->simplify(); if (!unitExpression) { auto* fraction = freecad_cast(ScanResult.get()); @@ -3730,19 +3741,14 @@ std::unique_ptr ExpressionParser::parseUnit( } ScanResult.reset(); - if (unitExpression) { - NumberExpression * num = freecad_cast(simplified); - - if (num) { - simplified = new UnitExpression(num->getOwner(), num->getQuantity()); - delete num; - } - return std::unique_ptr(freecad_cast(simplified)); - } - else { - delete simplified; + if (!unitExpression) { throw Expression::Exception("Expression is not a unit."); } + + if (auto num = freecad_cast(simplified.get()); num) { + return std::make_unique(num->getOwner(), num->getQuantity()); + } + return std::unique_ptr(freecad_cast(simplified.release())); } namespace { diff --git a/src/App/Expression.h b/src/App/Expression.h index 4f471bd5ab..1c496e370d 100644 --- a/src/App/Expression.h +++ b/src/App/Expression.h @@ -487,7 +487,7 @@ public: * * @return The simplified expression. */ - virtual Expression * simplify() const = 0; + virtual ExpressionPtr simplify() const = 0; /// Visit the expression with a visitor. void visit(ExpressionVisitor & v); diff --git a/src/App/ExpressionParser.h b/src/App/ExpressionParser.h index 67445c0909..84798abd2f 100644 --- a/src/App/ExpressionParser.h +++ b/src/App/ExpressionParser.h @@ -88,7 +88,7 @@ public: ~UnitExpression() override; - Expression* simplify() const override; + ExpressionPtr simplify() const override; void setUnit(const Base::Quantity& _quantity); @@ -144,7 +144,7 @@ public: explicit NumberExpression(const App::DocumentObject* _owner = nullptr, const Base::Quantity& quantity = Base::Quantity()); - Expression* simplify() const override; + ExpressionPtr simplify() const override; /** * @brief Negate the stored value. @@ -221,7 +221,7 @@ public: bool isTouched() const override; - Expression* simplify() const override; + ExpressionPtr simplify() const override; int priority() const override; @@ -274,7 +274,7 @@ public: bool isTouched() const override; - Expression* simplify() const override; + ExpressionPtr simplify() const override; int priority() const override; @@ -403,7 +403,7 @@ public: bool isTouched() const override; - Expression* simplify() const override; + ExpressionPtr simplify() const override; static Py::Object evaluate(const Expression* owner, int type, const std::vector& args); @@ -465,7 +465,7 @@ public: bool isTouched() const override; - Expression* simplify() const override; + ExpressionPtr simplify() const override; std::string name() const { @@ -540,9 +540,9 @@ public: void setPyValue(Py::Object pyobj); void setPyValue(PyObject* pyobj, bool owned = false); - Expression* simplify() const override + ExpressionPtr simplify() const override { - return copy().release(); + return copy(); } protected: @@ -568,7 +568,7 @@ public: const std::string& _text = std::string()); ~StringExpression() override; - Expression* simplify() const override; + ExpressionPtr simplify() const override; virtual std::string getText() const { @@ -602,7 +602,7 @@ public: bool isTouched() const override; - App::Expression* simplify() const override; + ExpressionPtr simplify() const override; Range getRange() const; diff --git a/tests/src/App/Expression.cpp b/tests/src/App/Expression.cpp index 56db683e03..4eed2370d7 100644 --- a/tests/src/App/Expression.cpp +++ b/tests/src/App/Expression.cpp @@ -372,7 +372,7 @@ TEST_F(Evaluate, test_evaluate_simple) TEST_F(Evaluate, test_simplify_simple) { App::ExpressionPtr e = App::ExpressionParser::parse(this_obj(), "1 + 2"); - App::Expression* simplified = e->simplify(); + App::ExpressionPtr simplified = e->simplify(); EXPECT_EQ(e->toString(), "1 + 2"); EXPECT_EQ(simplified->toString(), "3"); } @@ -388,7 +388,7 @@ TEST_F(Evaluate, test_evaluate_function) TEST_F(Evaluate, test_simplify_function) { App::ExpressionPtr e = App::ExpressionParser::parse(this_obj(), "sqrt(4)"); - App::Expression* simplified = e->simplify(); + App::ExpressionPtr simplified = e->simplify(); EXPECT_EQ(e->toString(), "sqrt(4)"); EXPECT_EQ(simplified->toString(), "2"); } @@ -408,7 +408,7 @@ TEST_F(Evaluate, test_simplify_refer_to_var) auto* prop = freecad_cast(this_obj()->addDynamicProperty("App::PropertyFloat", "Var")); prop->setValue(2.0); App::ExpressionPtr e = App::ExpressionParser::parse(this_obj(), "sqrt(2 + Var)"); - App::Expression* simplified = e->simplify(); + App::ExpressionPtr simplified = e->simplify(); EXPECT_EQ(e->toString(), "sqrt(2 + Var)"); EXPECT_EQ(simplified->toString(), "sqrt(2 + Var)"); }