diff --git a/src/ComputingTasks.cc b/src/ComputingTasks.cc index 01b848a3757d0adca1c9c47914df5032d0aa86bf..c54f5cedd05cd909911fe691cdc330a359406eb0 100644 --- a/src/ComputingTasks.cc +++ b/src/ComputingTasks.cc @@ -2231,22 +2231,16 @@ ModelComparisonStatement::writeJsonOutput(ostream &output) const output << "}"; } -PlannerObjectiveStatement::PlannerObjectiveStatement(StaticModel *model_tree_arg) : - model_tree(model_tree_arg), - computing_pass_called(false) +PlannerObjectiveStatement::PlannerObjectiveStatement(SymbolTable &symbol_table, NumericalConstants &num_constants, ExternalFunctionsTable &external_functions_table) : + model_tree{symbol_table, num_constants, external_functions_table} { } -PlannerObjectiveStatement::~PlannerObjectiveStatement() -{ - delete model_tree; -} - void PlannerObjectiveStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) { - assert(model_tree->equation_number() == 1); - if (model_tree->exoPresentInEqs()) + assert(model_tree.equation_number() == 1); + if (model_tree.exoPresentInEqs()) { cerr << "ERROR: You cannot include exogenous variables in the planner objective. Please " << "define an auxiliary endogenous variable like eps_aux=epsilon and use it instead " @@ -2256,8 +2250,8 @@ PlannerObjectiveStatement::checkPass(ModFileStructure &mod_file_struct, WarningC mod_file_struct.planner_objective_present = true; } -StaticModel * -PlannerObjectiveStatement::getPlannerObjective() const +StaticModel & +PlannerObjectiveStatement::getPlannerObjective() { return model_tree; } @@ -2265,14 +2259,14 @@ PlannerObjectiveStatement::getPlannerObjective() const void PlannerObjectiveStatement::computingPass() { - model_tree->computingPass({}, false, true, true, 0, false, false, false); + model_tree.computingPass({}, false, true, true, 0, false, false, false); computing_pass_called = true; } void PlannerObjectiveStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const { - model_tree->writeStaticFile(basename + ".objective", false, false, false, false); + model_tree.writeStaticFile(basename + ".objective", false, false, false, false); } void @@ -2281,9 +2275,9 @@ PlannerObjectiveStatement::writeJsonOutput(ostream &output) const output << "{\"statementName\": \"planner_objective\"" << ", "; if (computing_pass_called) - model_tree->writeJsonComputingPassOutput(output, false); + model_tree.writeJsonComputingPassOutput(output, false); else - model_tree->writeJsonOutput(output); + model_tree.writeJsonOutput(output); output << "}"; } diff --git a/src/ComputingTasks.hh b/src/ComputingTasks.hh index f6615f1dc0a4e510d2ab401453d79dcf4f9d2378..dda5b1981f9ad711b2becad304afaed027fff6b7 100644 --- a/src/ComputingTasks.hh +++ b/src/ComputingTasks.hh @@ -534,19 +534,15 @@ public: void writeJsonOutput(ostream &output) const override; }; -/*! \todo Make model_tree a member instead of a pointer */ class PlannerObjectiveStatement : public Statement { private: - StaticModel *model_tree; - bool computing_pass_called; + StaticModel model_tree; + bool computing_pass_called{false}; public: - //! Constructor - /*! \param model_tree_arg the model tree used to store the objective function. - It is owned by the PlannerObjectiveStatement, and will be deleted by its destructor */ - PlannerObjectiveStatement(StaticModel *model_tree_arg); - - ~PlannerObjectiveStatement() override; + PlannerObjectiveStatement(SymbolTable &symbol_table, + NumericalConstants &num_constants, + ExternalFunctionsTable &external_functions_table); /*! \todo check there are only endogenous variables at the current period in the objective (no exogenous, no lead/lag) */ void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) override; @@ -554,8 +550,8 @@ public: void computingPass() override; void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; void writeJsonOutput(ostream &output) const override; - //! Return the Planner Objective - StaticModel *getPlannerObjective() const; + //! Return a reference the Planner Objective model tree + StaticModel &getPlannerObjective(); }; class BVARDensityStatement : public Statement diff --git a/src/ModFile.cc b/src/ModFile.cc index cd8af1f9d8e5e70e3515386a1f27efa3e480e687..b62db9d039f632a905addcbc379ef6abf5e22dd4 100644 --- a/src/ModFile.cc +++ b/src/ModFile.cc @@ -466,14 +466,21 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const mod_file_struct.orig_eq_nbr = dynamic_model.equation_number(); if (mod_file_struct.ramsey_model_present) { - StaticModel *planner_objective = nullptr; + PlannerObjectiveStatement *pos = nullptr; for (auto & statement : statements) { - auto *pos = dynamic_cast<PlannerObjectiveStatement *>(statement); - if (pos != nullptr) - planner_objective = pos->getPlannerObjective(); + auto pos2 = dynamic_cast<PlannerObjectiveStatement *>(statement); + if (pos2 != nullptr) + if (pos != nullptr) + { + cerr << "ERROR: there can only be one planner_objective statement" << endl; + exit(EXIT_FAILURE); + } + else + pos = pos2; } - assert(planner_objective != nullptr); + assert(pos != nullptr); + const StaticModel &planner_objective = pos->getPlannerObjective(); /* clone the model then clone the new equations back to the original because @@ -482,7 +489,7 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const if (linear) dynamic_model.cloneDynamic(orig_ramsey_dynamic_model); dynamic_model.cloneDynamic(ramsey_FOC_equations_dynamic_model); - ramsey_FOC_equations_dynamic_model.computeRamseyPolicyFOCs(*planner_objective, nopreprocessoroutput); + ramsey_FOC_equations_dynamic_model.computeRamseyPolicyFOCs(planner_objective, nopreprocessoroutput); ramsey_FOC_equations_dynamic_model.replaceMyEquations(dynamic_model); mod_file_struct.ramsey_eq_nbr = dynamic_model.equation_number() - mod_file_struct.orig_eq_nbr; } diff --git a/src/ParsingDriver.cc b/src/ParsingDriver.cc index 65b9b62cdc589ca45a38df922ee82c0686fbebad..9975f7469cc97853e3bc6b30dc5b1463a32e1276 100644 --- a/src/ParsingDriver.cc +++ b/src/ParsingDriver.cc @@ -2082,7 +2082,9 @@ ParsingDriver::run_model_comparison() void ParsingDriver::begin_planner_objective() { - set_current_data_tree(new StaticModel(mod_file->symbol_table, mod_file->num_constants, mod_file->external_functions_table)); + planner_objective_statement = new PlannerObjectiveStatement(mod_file->symbol_table, mod_file->num_constants, mod_file->external_functions_table); + + set_current_data_tree(&planner_objective_statement->getPlannerObjective()); } void @@ -2092,7 +2094,8 @@ ParsingDriver::end_planner_objective(expr_t expr) expr_t eq = model_tree->AddEqual(expr, model_tree->Zero); model_tree->addEquation(eq, location.begin.line); - mod_file->addStatement(new PlannerObjectiveStatement(dynamic_cast<StaticModel *>(model_tree))); + mod_file->addStatement(planner_objective_statement); + planner_objective_statement = nullptr; // The object is now owned by mod_file reset_data_tree(); } diff --git a/src/ParsingDriver.hh b/src/ParsingDriver.hh index 0c51e7c1cc9d5fe4fbeeeb8aff3bd15f80c05bd1..1b3de3349e17e58c80a44b8584ff16a3fd0616a5 100644 --- a/src/ParsingDriver.hh +++ b/src/ParsingDriver.hh @@ -110,7 +110,12 @@ private: //! Stores temporary symbol table SymbolList symbol_list; + //! Temporary store for the planner objective + PlannerObjectiveStatement *planner_objective_statement; + //! The data tree in which to add expressions currently parsed + /*! The object pointed to is not owned by the parsing driver. It is essentially a + reference. */ DataTree *data_tree; //! The model tree in which to add expressions currently parsed