From 3915299334b35fac8d89f1252877b0b3d3c38a72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Fri, 19 Apr 2019 17:09:04 +0200 Subject: [PATCH] Dynare++ parser: various modernizations --- dynare++/parser/cc/atom_assignings.cc | 28 +- dynare++/parser/cc/atom_assignings.hh | 6 +- dynare++/parser/cc/atom_substitutions.cc | 70 +++-- dynare++/parser/cc/atom_substitutions.hh | 13 +- dynare++/parser/cc/csv_parser.cc | 13 +- dynare++/parser/cc/dynamic_atoms.cc | 141 ++++----- dynare++/parser/cc/dynamic_atoms.hh | 30 +- dynare++/parser/cc/fine_atoms.cc | 90 +++--- dynare++/parser/cc/fine_atoms.hh | 37 +-- dynare++/parser/cc/formula.yy | 30 +- dynare++/parser/cc/formula_parser.cc | 114 +++----- dynare++/parser/cc/formula_parser.hh | 39 +-- dynare++/parser/cc/matrix_parser.cc | 16 +- dynare++/parser/cc/matrix_parser.hh | 21 +- dynare++/parser/cc/namelist.cc | 10 +- dynare++/parser/cc/namelist.hh | 4 +- dynare++/parser/cc/parser_exception.cc | 69 +---- dynare++/parser/cc/parser_exception.hh | 19 +- dynare++/parser/cc/static_atoms.cc | 28 +- dynare++/parser/cc/static_atoms.hh | 4 +- dynare++/parser/cc/static_fine_atoms.cc | 30 +- dynare++/parser/cc/static_fine_atoms.hh | 12 +- dynare++/parser/cc/tree.cc | 352 +++++++++++------------ dynare++/parser/cc/tree.hh | 74 ++--- dynare++/src/dynare_model.cc | 241 ++++++++-------- dynare++/src/dynare_model.hh | 35 +-- dynare++/src/forw_subst_builder.cc | 4 +- dynare++/src/main.cc | 15 +- dynare++/src/planner_builder.cc | 20 +- 29 files changed, 668 insertions(+), 897 deletions(-) diff --git a/dynare++/parser/cc/atom_assignings.cc b/dynare++/parser/cc/atom_assignings.cc index 5d25864fa..eb1ffe810 100644 --- a/dynare++/parser/cc/atom_assignings.cc +++ b/dynare++/parser/cc/atom_assignings.cc @@ -10,6 +10,7 @@ #include #include +#include using namespace ogp; @@ -19,7 +20,7 @@ AtomAssignings::AtomAssignings(const AtomAssignings &aa, ogp::StaticAtoms &a) { // fill the lname2expr for (auto it : aa.lname2expr) - lname2expr.insert(Tvarintmap::value_type(left_names.query(it.first), it.second)); + lname2expr.emplace(left_names.query(it.first), it.second); } /** A global symbol for passing info to the AtomAssignings from @@ -36,16 +37,15 @@ extern location_type asgn_lloc; void AtomAssignings::parse(int length, const char *stream) { - auto *buffer = new char[length+2]; - strncpy(buffer, stream, length); + auto buffer = std::make_unique(length+2); + std::copy_n(stream, length, buffer.get()); buffer[length] = '\0'; buffer[length+1] = '\0'; asgn_lloc.off = 0; asgn_lloc.ll = 0; - void *p = asgn__scan_buffer(buffer, (unsigned int) length+2); + void *p = asgn__scan_buffer(buffer.get(), static_cast(length)+2); aparser = this; asgn_parse(); - delete [] buffer; asgn__destroy_buffer(p); } @@ -89,7 +89,7 @@ AtomAssignings::add_assignment_to_double(const char *name, double val) // register name of the left hand side and put to lname2expr const char *ss = left_names.insert(name); - lname2expr.insert(Tvarintmap::value_type(ss, order.size()-1)); + lname2expr.emplace(ss, order.size()-1); } void @@ -173,7 +173,7 @@ AtomAssignings::apply_subst(const AtomSubstitutions::Toldnamemap &mm) { const char *newname = itt.first; const char *nn = left_names.insert(newname); - lname2expr.insert(Tvarintmap::value_type(nn, expr.nformulas()-1)); + lname2expr.emplace(nn, expr.nformulas()-1); } } } @@ -182,11 +182,11 @@ AtomAssignings::apply_subst(const AtomSubstitutions::Toldnamemap &mm) void AtomAssignings::print() const { - printf("Atom Assignings\nExpressions:\n"); + std::cout << "Atom Assignings\nExpressions:\n"; expr.print(); - printf("Left names:\n"); + std::cout << "Left names:\n"; for (auto it : lname2expr) - printf("%s ==> %d (t=%d)\n", it.first, expr.formula(it.second), order[it.second]); + std::cout << it.first << u8" ⇒ " << expr.formula(it.second) << " (t=" << order[it.second] << ")\n"; } void @@ -207,7 +207,7 @@ AtomAsgnEvaluator::setValues(EvalTree &et) const if (it == user_values.end()) et.set_nulary(t, nan); else - et.set_nulary(t, (*it).second); + et.set_nulary(t, it->second); } } } @@ -220,9 +220,9 @@ AtomAsgnEvaluator::set_user_value(const char *name, double val) { auto it = user_values.find(t); if (it == user_values.end()) - user_values.insert(Tusrvalmap::value_type(t, val)); + user_values.emplace(t, val); else - (*it).second = val; + it->second = val; } } @@ -244,5 +244,5 @@ AtomAsgnEvaluator::get_value(const char *name) const if (it == aa.lname2expr.end()) return std::numeric_limits::quiet_NaN(); else - return operator[]((*it).second); + return operator[](it->second); } diff --git a/dynare++/parser/cc/atom_assignings.hh b/dynare++/parser/cc/atom_assignings.hh index 2b09b3a11..a7bb0b860 100644 --- a/dynare++/parser/cc/atom_assignings.hh +++ b/dynare++/parser/cc/atom_assignings.hh @@ -51,8 +51,7 @@ namespace ogp /** Make a copy with provided reference to (posibly different) * static atoms. */ AtomAssignings(const AtomAssignings &aa, StaticAtoms &a); - virtual ~AtomAssignings() - = default; + virtual ~AtomAssignings() = default; /** Parse the assignments from the given string. */ void parse(int length, const char *stream); /** Process a syntax error from bison. */ @@ -97,8 +96,7 @@ namespace ogp std::vector(a.expr.nformulas()), aa(a) { } - ~AtomAsgnEvaluator() - override = default; + ~AtomAsgnEvaluator() override = default; /** This sets all initial values to NaNs, all constants and * all values set by user by call set_value. This is called by * FormulaEvaluator::eval() method, which is called by eval() diff --git a/dynare++/parser/cc/atom_substitutions.cc b/dynare++/parser/cc/atom_substitutions.cc index e4c074bbb..c5622ea8e 100644 --- a/dynare++/parser/cc/atom_substitutions.cc +++ b/dynare++/parser/cc/atom_substitutions.cc @@ -15,16 +15,16 @@ AtomSubstitutions::AtomSubstitutions(const AtomSubstitutions &as, const FineAtom // fill new2old for (const auto & it : as.new2old) - new2old.insert(Tshiftmap::value_type(ns.query(it.first), - Tshiftname(ns.query(it.second.first), - it.second.second))); + new2old.emplace(ns.query(it.first), + Tshiftname(ns.query(it.second.first), + it.second.second)); // fill old2new for (const auto & it : as.old2new) { Tshiftnameset sset; for (const auto & itt : it.second) - sset.insert(Tshiftname(ns.query(itt.first), itt.second)); - old2new.insert(Toldnamemap::value_type(ns.query(it.first), sset)); + sset.emplace(ns.query(itt.first), itt.second); + old2new.emplace(ns.query(it.first), sset); } } @@ -34,21 +34,21 @@ AtomSubstitutions::add_substitution(const char *newname, const char *oldname, in // make sure the storage is from the new_atoms newname = new_atoms.get_name_storage().query(newname); oldname = new_atoms.get_name_storage().query(oldname); - if (newname == nullptr || oldname == nullptr) + if (!newname || !oldname) throw ogu::Exception(__FILE__, __LINE__, "Bad newname or oldname in AtomSubstitutions::add_substitution"); // insert to new2old map - new2old.insert(Tshiftmap::value_type(newname, Tshiftname(oldname, tshift))); + new2old.emplace(newname, Tshiftname(oldname, tshift)); // insert to old2new map auto it = old2new.find(oldname); if (it != old2new.end()) - (*it).second.insert(Tshiftname(newname, -tshift)); + it->second.emplace(newname, -tshift); else { Tshiftnameset snset; - snset.insert(Tshiftname(newname, -tshift)); - old2new.insert(Toldnamemap::value_type(oldname, snset)); + snset.emplace(newname, -tshift); + old2new.emplace(oldname, snset); } // put to info @@ -68,7 +68,7 @@ AtomSubstitutions::substitutions_finished(VarOrdering::ord_type ot) // add all new names derived from the old name Toldnamemap::const_iterator it = old2new.find(oname); if (it != old2new.end()) - for (const auto & itt : (*it).second) + for (const auto & itt : it->second) na_ext.push_back(itt.first); } @@ -82,7 +82,7 @@ AtomSubstitutions::get_new4old(const char *oldname, int tshift) const auto it = old2new.find(oldname); if (it != old2new.end()) { - const Tshiftnameset &sset = (*it).second; + const Tshiftnameset &sset = it->second; for (const auto & itt : sset) if (itt.second == -tshift) return itt.first; @@ -93,15 +93,14 @@ AtomSubstitutions::get_new4old(const char *oldname, int tshift) const void AtomSubstitutions::print() const { - printf("Atom Substitutions:\nOld ==> New:\n"); + std::cout << u8"Atom Substitutions:\nOld ⇒ New:\n"; for (const auto & it : old2new) - for (auto itt = it.second.begin(); - itt != it.second.end(); ++itt) - printf(" %s ==> [%s, %d]\n", it.first, (*itt).first, (*itt).second); + for (const auto &itt : it.second) + std::cout << " " << it.first << u8" ⇒ [" << itt.first << ", " << itt.second << "]\n"; - printf("Old <== New:\n"); + std::cout << u8"Old ⇐ New:\n"; for (const auto & it : new2old) - printf(" [%s, %d] <== %s\n", it.second.first, it.second.second, it.first); + std::cout << " [" << it.second.first << ", " << it.second.second << "] ⇐ " << it.first << '\n'; } void @@ -113,19 +112,19 @@ SAtoms::substituteAllLagsAndLeads(FormulaParser &fp, AtomSubstitutions &as) endovarspan(mlead, mlag); // substitute all endo lagged more than 1 - while (nullptr != (name = findEndoWithLeadInInterval(mlag, -2))) + while (name = findEndoWithLeadInInterval(mlag, -2)) makeAuxVariables(name, -1, -2, mlag, fp, as); // substitute all endo leaded more than 1 - while (nullptr != (name = findEndoWithLeadInInterval(2, mlead))) + while (name = findEndoWithLeadInInterval(2, mlead)) makeAuxVariables(name, 1, 2, mlead, fp, as); exovarspan(mlead, mlag); // substitute all lagged exo - while (nullptr != (name = findExoWithLeadInInterval(mlag, -1))) + while (name = findExoWithLeadInInterval(mlag, -1)) makeAuxVariables(name, -1, -1, mlag, fp, as); // substitute all leaded exo - while (nullptr != (name = findExoWithLeadInInterval(1, mlead))) + while (name = findExoWithLeadInInterval(1, mlead)) makeAuxVariables(name, 1, 1, mlead, fp, as); // notify that substitution have been finished @@ -141,16 +140,16 @@ SAtoms::substituteAllLagsAndExo1Leads(FormulaParser &fp, AtomSubstitutions &as) endovarspan(mlead, mlag); // substitute all endo lagged more than 1 - while (nullptr != (name = findEndoWithLeadInInterval(mlag, -2))) + while (name = findEndoWithLeadInInterval(mlag, -2)) makeAuxVariables(name, -1, -2, mlag, fp, as); exovarspan(mlead, mlag); // substitute all lagged exo - while (nullptr != (name = findExoWithLeadInInterval(mlag, -1))) + while (name = findExoWithLeadInInterval(mlag, -1)) makeAuxVariables(name, -1, -1, mlag, fp, as); // substitute all leaded exo by 1 - while (nullptr != (name = findExoWithLeadInInterval(1, 1))) + while (name = findExoWithLeadInInterval(1, 1)) makeAuxVariables(name, 1, 1, 1, fp, as); // notify that substitution have been finished @@ -181,8 +180,7 @@ void SAtoms::attemptAuxName(const char *str, int ll, string &out) const { char c = (ll >= 0) ? ((ll == 0) ? 'e' : 'p') : 'm'; - char absll[100]; - sprintf(absll, "%d", std::abs(ll)); + string absll = std::to_string(std::abs(ll)); int iter = 1; do { @@ -218,15 +216,13 @@ SAtoms::makeAuxVariables(const char *name, int step, int start, int limit_lead, // Comment to comments: name="a"; start=-3; step=-1; - char tmp[500]; - // recover tree index of a previous atom, i.e. set tprev to a tree // index of atom "a(-2)" int tprev = index(name, start-step); if (tprev == -1) { - sprintf(tmp, "%s(%d)", name, start-step); - tprev = fp.add_nulary(tmp); + string tmp = string{name} + '(' + std::to_string(start-step) + ')'; + tprev = fp.add_nulary(tmp.c_str()); } int ll = start; @@ -241,19 +237,19 @@ SAtoms::makeAuxVariables(const char *name, int step, int start, int limit_lead, const char *newname; string newname_str; int taux; - if (nullptr == (newname = as.get_new4old(name, ll-step))) + if (!(newname = as.get_new4old(name, ll-step))) { attemptAuxName(name, ll-step, newname_str); newname = newname_str.c_str(); register_uniq_endo(newname); newname = varnames.query(newname); - sprintf(tmp, "%s(0)", newname); - taux = fp.add_nulary(tmp); + string tmp = string{newname} + "(0)"; + taux = fp.add_nulary(tmp.c_str()); // add to substitutions as.add_substitution(newname, name, ll-step); // add equation "a_m2(0) = a(-2)", this is taux = tprev - fp.add_formula(fp.add_binary(MINUS, taux, tprev)); + fp.add_formula(fp.add_binary(code_t::MINUS, taux, tprev)); } else { @@ -273,8 +269,8 @@ SAtoms::makeAuxVariables(const char *name, int step, int start, int limit_lead, if (t == -1) { // no "a(-3)", make t <-> a_m2(-1) - sprintf(tmp, "%s(%d)", newname, step); - t = fp.add_nulary(tmp); + string tmp = string{newname} + '(' + std::to_string(step) + ')'; + t = fp.add_nulary(tmp.c_str()); } else { diff --git a/dynare++/parser/cc/atom_substitutions.hh b/dynare++/parser/cc/atom_substitutions.hh index 77c072b6b..88b156dd5 100644 --- a/dynare++/parser/cc/atom_substitutions.hh +++ b/dynare++/parser/cc/atom_substitutions.hh @@ -22,8 +22,7 @@ namespace ogp struct SubstInfo { int num_substs{0}; - SubstInfo() - = default; + SubstInfo() = default; }; /** This class tracks all atom substitutions during the job and @@ -72,8 +71,7 @@ namespace ogp * of old atoms and new atoms, which are supposed to be * semantically same as the atoms from as. */ AtomSubstitutions(const AtomSubstitutions &as, const FineAtoms &oa, FineAtoms &na); - virtual ~AtomSubstitutions() - = default; + virtual ~AtomSubstitutions() = default; /** This is called during the substitution job from the * substitution method of the new atoms. This says that the * new name, say "a_m3" is a substitution of old name "a" @@ -128,11 +126,8 @@ namespace ogp : FineAtoms() { } - SAtoms(const SAtoms &sa) - - = default; - ~SAtoms() - override = default; + SAtoms(const SAtoms &sa) = default; + ~SAtoms() override = default; /** This substitutes all lags and leads for all exogenous and * all lags and leads greater than 1 for all endogenous * variables. This is useful for perfect foresight problems diff --git a/dynare++/parser/cc/csv_parser.cc b/dynare++/parser/cc/csv_parser.cc index 5b53f47a2..0fa00eca7 100644 --- a/dynare++/parser/cc/csv_parser.cc +++ b/dynare++/parser/cc/csv_parser.cc @@ -2,7 +2,9 @@ #include "parser_exception.hh" #include "location.hh" #include "csv_tab.hh" -#include + +#include +#include using namespace ogp; @@ -28,17 +30,16 @@ void CSVParser::csv_parse(int length, const char *str) { // allocate temporary buffer and parse - auto *buffer = new char[length+2]; - strncpy(buffer, str, length); + auto buffer = std::make_unique(length+2); + std::copy_n(str, length, buffer.get()); buffer[length] = '\0'; buffer[length+1] = '\0'; csv_lloc.off = 0; csv_lloc.ll = 0; - parsed_string = buffer; - void *p = csv__scan_buffer(buffer, (unsigned int) length+2); + parsed_string = buffer.get(); + void *p = csv__scan_buffer(buffer.get(), static_cast(length)+2); csv_parser = this; ::csv_parse(); - delete [] buffer; csv__destroy_buffer(p); parsed_string = nullptr; } diff --git a/dynare++/parser/cc/dynamic_atoms.cc b/dynare++/parser/cc/dynamic_atoms.cc index 40d2cc35a..b31b63e39 100644 --- a/dynare++/parser/cc/dynamic_atoms.cc +++ b/dynare++/parser/cc/dynamic_atoms.cc @@ -59,7 +59,7 @@ void NameStorage::print() const { for (auto i : name_store) - printf("%s\n", i); + std::cout << i << '\n'; } void @@ -69,7 +69,7 @@ Constants::import_constants(const Constants &c, OperationTree &otree, Tintintmap { int told = it.first; int tnew = otree.add_nulary(); - tmap.insert(Tintintmap::value_type(told, tnew)); + tmap.emplace(told, tnew); add_constant(tnew, it.second); } } @@ -77,16 +77,15 @@ Constants::import_constants(const Constants &c, OperationTree &otree, Tintintmap void Constants::setValues(EvalTree &et) const { - Tconstantmap::const_iterator it; - for (it = cmap.begin(); it != cmap.end(); ++it) - et.set_nulary((*it).first, (*it).second); + for (const auto & it : cmap) + et.set_nulary(it.first, it.second); } void Constants::add_constant(int t, double val) { - cmap.insert(Tconstantmap::value_type(t, val)); - cinvmap.insert(Tconstantinvmap::value_type(val, t)); + cmap.emplace(t, val); + cinvmap.emplace(val, t); } bool @@ -103,7 +102,7 @@ Constants::get_constant_value(int t) const { auto it = cmap.find(t); if (it != cmap.end()) - return (*it).second; + return it->second; else { throw ogu::Exception(__FILE__, __LINE__, @@ -119,7 +118,7 @@ Constants::check(const char *str) const sscanf(str, "%lf", &d); auto it = cinvmap.find(d); if (it != cinvmap.end()) - return (*it).second; + return it->second; else return -1; } @@ -127,13 +126,11 @@ Constants::check(const char *str) const void Constants::print() const { - Tconstantmap::const_iterator it; - for (it = cmap.begin(); it != cmap.end(); ++it) - printf("$%d: %8.4g\n", (*it).first, (*it).second); + for (const auto &it : cmap) + printf("$%d: %8.4g\n", it.first, it.second); } -DynamicAtoms::DynamicAtoms() -= default; +DynamicAtoms::DynamicAtoms() = default; DynamicAtoms::DynamicAtoms(const DynamicAtoms &da) : Constants(da), @@ -142,12 +139,10 @@ DynamicAtoms::DynamicAtoms(const DynamicAtoms &da) { // copy vars for (const auto & var : da.vars) - vars.insert(Tvarmap::value_type(varnames.query(var.first), - var.second)); + vars.emplace(varnames.query(var.first), var.second); // copy indices for (auto indice : da.indices) - indices.insert(Tindexmap::value_type(indice.first, - varnames.query(indice.second))); + indices.emplace(indice.first, varnames.query(indice.second)); } int @@ -169,10 +164,10 @@ DynamicAtoms::check_variable(const char *name) const if (it != vars.end()) { - const Tlagmap &lmap = (*it).second; + const Tlagmap &lmap = it->second; auto itt = lmap.find(ll); if (itt != lmap.end()) - return (*itt).second; + return itt->second; } return -1; } @@ -218,19 +213,19 @@ DynamicAtoms::assign_variable(const char *varname, int ll, int t) auto it = vars.find(varname); if (it != vars.end()) { - Tlagmap &lmap = (*it).second; + Tlagmap &lmap = it->second; if (lmap.end() != lmap.find(ll)) throw ogu::Exception(__FILE__, __LINE__, "Attempt to assign already allocated variable"); - lmap.insert(Tlagmap::value_type(ll, t)); + lmap.emplace(ll, t); } else { Tlagmap lmap; - lmap.insert(Tlagmap::value_type(ll, t)); - vars.insert(Tvarmap::value_type(varname, lmap)); + lmap.emplace(ll, t); + vars.emplace(varname, lmap); } - indices.insert(Tindexmap::value_type(t, varname)); + indices.emplace(t, varname); nv++; if (ll < minlag) @@ -245,11 +240,11 @@ DynamicAtoms::unassign_variable(const char *varname, int ll, int t) auto it = vars.find(varname); if (it != vars.end()) { - Tlagmap &lmap = (*it).second; + Tlagmap &lmap = it->second; auto itt = lmap.find(ll); if (itt != lmap.end()) { - if ((*itt).second == t) + if (itt->second == t) { // erase it from the lagmap; if it becomes empty, // erase the lagmap from varmap @@ -281,18 +276,16 @@ DynamicAtoms::unassign_variable(const char *varname, int ll, int t) void DynamicAtoms::update_minmaxll() { - minlag = INT_MAX; - maxlead = INT_MIN; - for (Tvarmap::const_iterator it = vars.begin(); it != vars.end(); ++it) + minlag = std::numeric_limits::max(); + maxlead = std::numeric_limits::min(); + for (const auto &it : vars) { - const Tlagmap &lmap = (*it).second; + const Tlagmap &lmap = it.second; for (auto itt : lmap) { int ll = itt.first; - if (ll < minlag) - minlag = ll; - if (ll > maxlead) - maxlead = ll; + minlag = std::min(ll, minlag); + maxlead = std::max(ll, maxlead); } } } @@ -316,11 +309,11 @@ DynamicAtoms::varspan(int t, int &mlead, int &mlag) const auto it = indices.find(t); if (indices.end() == it) { - mlead = INT_MIN; - mlag = INT_MAX; + mlead = std::numeric_limits::min(); + mlag = std::numeric_limits::max(); return; } - varspan((*it).second, mlead, mlag); + varspan(it->second, mlead, mlag); } void @@ -329,30 +322,28 @@ DynamicAtoms::varspan(const char *name, int &mlead, int &mlag) const auto it = vars.find(name); if (vars.end() == it) { - mlead = INT_MIN; - mlag = INT_MAX; + mlead = std::numeric_limits::min(); + mlag = std::numeric_limits::max(); return; } - const Tlagmap &lmap = (*it).second; + const Tlagmap &lmap = it->second; auto beg = lmap.begin(); auto end = lmap.rbegin(); - mlag = (*beg).first; - mlead = (*end).first; + mlag = beg->first; + mlead = end->first; } void DynamicAtoms::varspan(const vector &names, int &mlead, int &mlag) const { - mlead = INT_MIN; - mlag = INT_MAX; + mlead = std::numeric_limits::min(); + mlag = std::numeric_limits::max(); for (auto name : names) { int lag, lead; varspan(name, lead, lag); - if (lead > mlead) - mlead = lead; - if (lag < mlag) - mlag = lag; + mlead = std::max(lead, mlead); + mlag = std::min(lag, mlag); } } @@ -368,10 +359,10 @@ DynamicAtoms::index(const char *name, int ll) const auto it = vars.find(name); if (vars.end() != it) { - const Tlagmap &lmap = (*it).second; + const Tlagmap &lmap = it->second; auto itt = lmap.find(ll); if (lmap.end() != itt) - return (*itt).second; + return itt->second; } return -1; } @@ -391,7 +382,7 @@ DynamicAtoms::lagmap(const char *name) const throw ogu::Exception(__FILE__, __LINE__, std::string("Couldn't find the name ") + name + " in DynamicAtoms::lagmap"); - return (*it).second; + return it->second; } const char * @@ -401,7 +392,7 @@ DynamicAtoms::name(int t) const if (indices.end() == it) throw ogu::Exception(__FILE__, __LINE__, "Couldn't find tree index in DynamicAtoms::name"); - return (*it).second; + return it->second; } int @@ -410,12 +401,12 @@ DynamicAtoms::lead(int t) const const char *nam = name(t); const Tlagmap &lmap = lagmap(nam); auto it = lmap.begin(); - while (it != lmap.end() && (*it).second != t) + while (it != lmap.end() && it->second != t) ++it; if (lmap.end() == it) throw ogu::Exception(__FILE__, __LINE__, "Couldn't find the three index in DynamicAtoms::lead"); - return (*it).first; + return it->first; } void @@ -434,7 +425,7 @@ DynamicAtoms::print() const } printf("indices:\n"); for (auto indice : indices) - printf("t=%d ==> %s\n", indice.first, indice.second); + printf(u8"t=%d ⇒ %s\n", indice.first, indice.second); } /** Note that the str has been parsed by the lexicographic @@ -467,7 +458,7 @@ VarOrdering::get_pos_of(int t) const auto it = positions.find(t); if (it != positions.end()) { - return (*it).second; + return it->second; } else { @@ -570,7 +561,7 @@ VarOrdering::do_general(ord_type ordering) if ((*ord)[j] != -1) { der_atoms.push_back((*ord)[j]); - positions.insert(std::pair((*ord)[j], off)); + positions.emplace((*ord)[j], off); } // set integer constants @@ -599,7 +590,7 @@ VarOrdering::do_increasing_time() // setup the matrix of tree indices, if there is no occurrence, // the index is set to -1 vector ll_init(varnames.size(), -1); - vector > tree_ind(mlead-mlag+1, ll_init); + vector> tree_ind(mlead-mlag+1, ll_init); for (unsigned int iv = 0; iv < varnames.size(); iv++) { try @@ -627,7 +618,7 @@ VarOrdering::do_increasing_time() { der_atoms.push_back(t); int pos = (ll-mlag)*varnames.size() + iv; - positions.insert(map::value_type(t, pos)); + positions.emplace(t, pos); } } @@ -644,31 +635,19 @@ VarOrdering::do_increasing_time() int mmlag, mmlead; atoms.varspan(varname, mmlead, mmlag); if (mmlead == 0 && mmlag == 0) - { - n_stat++; - } + n_stat++; else if (mmlead <= 0 && mmlag < 0) - { - n_pred++; - } + n_pred++; else if (mmlead > 0 && mmlag >= 0) - { - n_forw++; - } + n_forw++; else if (mmlead > 0 && mmlag < 0) - { - n_both++; - } + n_both++; else if (mmlead < mmlag) - { - // variable does not occur in the tree, cound as static - n_stat++; - } + // variable does not occur in the tree, cound as static + n_stat++; else - { - throw ogu::Exception(__FILE__, __LINE__, - "A wrong lag/lead of a variable in VarOrdering::do_increasing_time"); - } + throw ogu::Exception(__FILE__, __LINE__, + "A wrong lag/lead of a variable in VarOrdering::do_increasing_time"); } } @@ -681,7 +660,7 @@ VarOrdering::print() const printf(" %d", der_atom); printf("\nmap:\n"); for (auto position : positions) - printf(" [%d->%d]", position.first, position.second); + printf(u8" [%d→%d]", position.first, position.second); printf("\ny2outer:\n"); for (int i : y2outer) printf(" %d", i); diff --git a/dynare++/parser/cc/dynamic_atoms.hh b/dynare++/parser/cc/dynamic_atoms.hh index 495fb9fd5..06b362779 100644 --- a/dynare++/parser/cc/dynamic_atoms.hh +++ b/dynare++/parser/cc/dynamic_atoms.hh @@ -12,7 +12,8 @@ #include #include #include -#include +#include +#include namespace ogp { @@ -45,11 +46,9 @@ namespace ogp * allocated or not. */ set name_set; public: - NameStorage() - = default; + NameStorage() = default; NameStorage(const NameStorage &stor); - virtual - ~NameStorage(); + virtual ~NameStorage(); /** Query for the name. If the name has been stored, it * returns its address, otherwise 0. */ const char *query(const char *name) const; @@ -59,7 +58,7 @@ namespace ogp int num() const { - return (int) name_store.size(); + return static_cast(name_store.size()); } const char * get_name(int i) const @@ -80,8 +79,7 @@ namespace ogp /** Map mapping a tree index of a constant to its double value. */ Tconstantmap cmap; public: - Constants() - = default; + Constants() = default; /** Copy constructor. */ Constants(const Constants &c) : cmap(c.cmap), cinvmap(c.cinvmap) @@ -162,15 +160,14 @@ namespace ogp /** Number of variables. */ int nv{0}; /** Minimum lag, if there is at least one lag, than this is a negative number. */ - int minlag{INT_MAX}; + int minlag{std::numeric_limits::max()}; /** Maximum lead, if there is at least one lead, than this is a positive number. */ - int maxlead{INT_MIN}; + int maxlead{std::numeric_limits::min()}; public: /** Construct empty DynamicAtoms. */ DynamicAtoms(); DynamicAtoms(const DynamicAtoms &da); - ~DynamicAtoms() - override = default; + ~DynamicAtoms() override = default; /** Check the nulary term identified by its string * representation. The nulary term can be either a constant or * a variable. If constant, -1 is returned so that it could be @@ -326,7 +323,7 @@ namespace ogp * follows: y(t-1), x(t-1), z(t-1), [y(t)], [x(t)], z(t), * x(t+1), where a bracketed expresion means non-existent by * occupying a space. The map thus will look as follows: - * {5->0, 6->1, 3->2, 2->5, 3->6}. Note that nothing is mapped + * {5→0, 6→1, 3→2, 2→5, 3→6}. Note that nothing is mapped * to positions 3 and 4. */ map positions; /** This maps an ordering of the list of variables in @@ -358,11 +355,10 @@ namespace ogp VarOrdering(const VarOrdering &vo, const vector &vnames, const DynamicAtoms &a); VarOrdering(const VarOrdering &vo) = delete; - virtual VarOrdering *clone(const vector &vnames, - const DynamicAtoms &a) const = 0; + virtual std::unique_ptr clone(const vector &vnames, + const DynamicAtoms &a) const = 0; /** Destructor does nothing here. */ - virtual ~VarOrdering() - = default; + virtual ~VarOrdering() = default; /** This is the method setting the ordering and the map. A * subclass must reimplement it, possibly using a * preimplemented ordering. This method must be called by the diff --git a/dynare++/parser/cc/fine_atoms.cc b/dynare++/parser/cc/fine_atoms.cc index 607160abb..67962fb24 100644 --- a/dynare++/parser/cc/fine_atoms.cc +++ b/dynare++/parser/cc/fine_atoms.cc @@ -31,12 +31,12 @@ AllvarOuterOrdering::AllvarOuterOrdering(const vector &allvar_oute { auto it = atoms.endo_outer_map.find(allvar[i]); if (it != atoms.endo_outer_map.end()) - endo2all[(*it).second] = i; + endo2all[it->second] = i; else { it = atoms.exo_outer_map.find(allvar[i]); if (it != atoms.exo_outer_map.end()) - exo2all[(*it).second] = i; + exo2all[it->second] = i; else throw ogu::Exception(__FILE__, __LINE__, string("Name ") + allvar[i] + " is neither endogenous nor exogenous variable in AllvarOuterOrdering constructor"); @@ -89,7 +89,7 @@ FineAtoms::FineAtoms(const FineAtoms &fa) throw ogu::Exception(__FILE__, __LINE__, string("Parameter ") + param + " does not exist in FineAtoms copy cosntructor"); params.push_back(s); - param_outer_map.insert(Tvarintmap::value_type(s, params.size()-1)); + param_outer_map.emplace(s, params.size()-1); } // fill in endovars for (auto endovar : fa.endovars) @@ -99,7 +99,7 @@ FineAtoms::FineAtoms(const FineAtoms &fa) throw ogu::Exception(__FILE__, __LINE__, string("Endo variable ") + endovar + " does not exist in FineAtoms copy constructor"); endovars.push_back(s); - endo_outer_map.insert(Tvarintmap::value_type(s, endovars.size()-1)); + endo_outer_map.emplace(s, endovars.size()-1); } // fill in exovars for (auto exovar : fa.exovars) @@ -109,7 +109,7 @@ FineAtoms::FineAtoms(const FineAtoms &fa) throw ogu::Exception(__FILE__, __LINE__, string("Exo variable ") + exovar + " does not exist in FineAtoms copy cosntructor"); exovars.push_back(s); - exo_outer_map.insert(Tvarintmap::value_type(s, exovars.size()-1)); + exo_outer_map.emplace(s, exovars.size()-1); } if (fa.endo_order) @@ -119,7 +119,7 @@ FineAtoms::FineAtoms(const FineAtoms &fa) exo_order = fa.exo_order->clone(exovars, *this); if (fa.allvar_order) - allvar_order = new AllvarOuterOrdering(*(fa.allvar_order), *this); + allvar_order = std::make_unique(*(fa.allvar_order), *this); } int @@ -156,9 +156,7 @@ FineAtoms::parsing_finished(VarOrdering::ord_type ot) allvar_tmp.insert(allvar_tmp.end(), endovars.begin(), endovars.end()); allvar_tmp.insert(allvar_tmp.end(), exovars.begin(), exovars.end()); - if (allvar_order) - delete allvar_order; - allvar_order = new AllvarOuterOrdering(allvar_tmp, *this); + allvar_order = std::make_unique(allvar_tmp, *this); } void @@ -166,9 +164,7 @@ FineAtoms::parsing_finished(VarOrdering::ord_type ot, const vector allvar) { make_internal_orderings(ot); - if (allvar_order) - delete allvar_order; - allvar_order = new AllvarOuterOrdering(allvar, *this); + allvar_order = std::make_unique(allvar, *this); } const vector & @@ -205,14 +201,12 @@ vector FineAtoms::variables() const { if (endo_order) - { - return der_atoms; - } + return der_atoms; else { throw ogu::Exception(__FILE__, __LINE__, "FineAtoms::variables called before parsing_finished"); - return vector(); + return {}; } } @@ -220,9 +214,7 @@ int FineAtoms::nstat() const { if (endo_order) - { - return endo_order->nstat(); - } + return endo_order->nstat(); else { throw ogu::Exception(__FILE__, __LINE__, @@ -235,9 +227,7 @@ int FineAtoms::npred() const { if (endo_order) - { - return endo_order->npred(); - } + return endo_order->npred(); else { throw ogu::Exception(__FILE__, __LINE__, @@ -250,9 +240,7 @@ int FineAtoms::nboth() const { if (endo_order) - { - return endo_order->nboth(); - } + return endo_order->nboth(); else { throw ogu::Exception(__FILE__, __LINE__, @@ -265,9 +253,7 @@ int FineAtoms::nforw() const { if (endo_order) - { - return endo_order->nforw(); - } + return endo_order->nforw(); else { throw ogu::Exception(__FILE__, __LINE__, @@ -280,9 +266,7 @@ int FineAtoms::get_pos_of_endo(int t) const { if (endo_order) - { - return endo_order->get_pos_of(t); - } + return endo_order->get_pos_of(t); else { throw ogu::Exception(__FILE__, __LINE__, @@ -295,9 +279,7 @@ int FineAtoms::get_pos_of_exo(int t) const { if (exo_order) - { - return exo_order->get_pos_of(t); - } + return exo_order->get_pos_of(t); else { throw ogu::Exception(__FILE__, __LINE__, @@ -391,7 +373,7 @@ FineAtoms::name2outer_param(const char *name) const if (it == param_outer_map.end()) throw ogu::Exception(__FILE__, __LINE__, "Name is not a parameter in FineAtoms::name2outer_param"); - return (*it).second; + return it->second; } int @@ -401,7 +383,7 @@ FineAtoms::name2outer_endo(const char *name) const if (it == endo_outer_map.end()) throw ogu::Exception(__FILE__, __LINE__, "Name is not an endogenous variable in FineAtoms::name2outer_endo"); - return (*it).second; + return it->second; } int @@ -411,7 +393,7 @@ FineAtoms::name2outer_exo(const char *name) const if (it == exo_outer_map.end()) throw ogu::Exception(__FILE__, __LINE__, "Name is not an exogenous variable in FineAtoms::name2outer_exo"); - return (*it).second; + return it->second; } int @@ -423,12 +405,12 @@ FineAtoms::name2outer_allvar(const char *name) const auto it = endo_outer_map.find(name); if (it != endo_outer_map.end()) - return allvar_order->get_endo2all()[(*it).second]; + return allvar_order->get_endo2all()[it->second]; else { it = exo_outer_map.find(name); if (it != exo_outer_map.end()) - return allvar_order->get_exo2all()[(*it).second]; + return allvar_order->get_exo2all()[it->second]; } throw ogu::Exception(__FILE__, __LINE__, @@ -443,7 +425,7 @@ FineAtoms::register_uniq_endo(const char *name) throw ogp::ParserException(string("Endogenous variable <")+name+"> is not unique.", 0); const char *ss = varnames.insert(name); endovars.push_back(ss); - endo_outer_map.insert(Tvarintmap::value_type(ss, endovars.size()-1)); + endo_outer_map.emplace(ss, endovars.size()-1); } void @@ -453,7 +435,7 @@ FineAtoms::register_uniq_exo(const char *name) throw ogp::ParserException(string("Exogenous variable <")+name+"> is not unique.", 0); const char *ss = varnames.insert(name); exovars.push_back(ss); - exo_outer_map.insert(Tvarintmap::value_type(ss, exovars.size()-1)); + exo_outer_map.emplace(ss, exovars.size()-1); } void @@ -463,7 +445,7 @@ FineAtoms::register_uniq_param(const char *name) throw ogp::ParserException(string("Parameter <")+name+"> is not unique.", 0); const char *ss = varnames.insert(name); params.push_back(ss); - param_outer_map.insert(Tvarintmap::value_type(ss, params.size()-1)); + param_outer_map.emplace(ss, params.size()-1); } void @@ -479,12 +461,10 @@ FineAtoms::make_internal_orderings(VarOrdering::ord_type ot) if (mlag >= -1 && mlead <= 1) { // make endo ordering - if (endo_order) - delete endo_order; if (ot == VarOrdering::pbspbfbf) - endo_order = new EndoVarOrdering1(endovars, *this); + endo_order = std::make_unique(endovars, *this); else - endo_order = new EndoVarOrdering2(endovars, *this); + endo_order = std::make_unique(endovars, *this); endo_order->do_ordering(); endo_ordering_done = true; } @@ -493,9 +473,7 @@ FineAtoms::make_internal_orderings(VarOrdering::ord_type ot) if (mlag == 0 && mlead == 0) { // make exo ordering - if (exo_order) - delete exo_order; - exo_order = new ExoVarOrdering(exovars, *this); + exo_order = std::make_unique(exovars, *this); exo_order->do_ordering(); exo_ordering_done = true; } @@ -534,22 +512,20 @@ FineAtoms::print() const endo_order->print(); } else - { - printf("Endo ordering not created.\n"); - } + printf("Endo ordering not created.\n"); + if (exo_order) { printf("Exo ordering:\n"); exo_order->print(); } else - { - printf("Exo ordering not created.\n"); - } + printf("Exo ordering not created.\n"); + printf("endo atoms map:\n"); for (unsigned int i = 0; i < endo_atoms_map.size(); i++) - printf("%d --> %d\n", i, endo_atoms_map[i]); + printf(u8"%d → %d\n", i, endo_atoms_map[i]); printf("exo atoms map:\n"); for (unsigned int i = 0; i < exo_atoms_map.size(); i++) - printf("%d --> %d\n", i, exo_atoms_map[i]); + printf(u8"%d → %d\n", i, exo_atoms_map[i]); } diff --git a/dynare++/parser/cc/fine_atoms.hh b/dynare++/parser/cc/fine_atoms.hh index 448f01162..af440a66b 100644 --- a/dynare++/parser/cc/fine_atoms.hh +++ b/dynare++/parser/cc/fine_atoms.hh @@ -9,6 +9,7 @@ #include #include +#include namespace ogp { @@ -32,10 +33,10 @@ namespace ogp : VarOrdering(vo, vnames, a) { } - VarOrdering * + std::unique_ptr clone(const vector &vnames, const DynamicAtoms &a) const override { - return new EndoVarOrdering1(*this, vnames, a); + return std::make_unique(*this, vnames, a); } void do_ordering() override @@ -60,10 +61,10 @@ namespace ogp : VarOrdering(vo, vnames, a) { } - VarOrdering * + std::unique_ptr clone(const vector &vnames, const DynamicAtoms &a) const override { - return new EndoVarOrdering2(*this, vnames, a); + return std::make_unique(*this, vnames, a); } void do_ordering() override @@ -87,10 +88,10 @@ namespace ogp : VarOrdering(vo, vnames, a) { } - VarOrdering * + std::unique_ptr clone(const vector &vnames, const DynamicAtoms &a) const override { - return new ExoVarOrdering(*this, vnames, a); + return std::make_unique(*this, vnames, a); } void do_ordering() override @@ -201,14 +202,14 @@ namespace ogp * to endogenous variables. It is constructed by * parsing_finished() method, which should be called after all * parsing jobs have been finished. */ - VarOrdering *endo_order{nullptr}; + std::unique_ptr endo_order; /** This is the internal ordering of all atoms corresponding * to exogenous variables. It has the same handling as * endo_order. */ - VarOrdering *exo_order{nullptr}; + std::unique_ptr exo_order; /** This is the all variables outer ordering. It is * constructed by parsing finished. */ - AllvarOuterOrdering *allvar_order{nullptr}; + std::unique_ptr allvar_order; /** This vector defines a set of atoms as tree indices used * for differentiation. The order of the atoms in this vector * defines ordering of the derivative tensors. The ordering is @@ -228,20 +229,10 @@ namespace ogp * atoms of exogenous variables. */ vector exo_atoms_map; public: - FineAtoms() - - = default; + FineAtoms() = default; FineAtoms(const FineAtoms &fa); /** Deletes endo_order and exo_order. */ - ~FineAtoms() override - { - if (endo_order) - delete endo_order; - if (exo_order) - delete exo_order; - if (allvar_order) - delete allvar_order; - } + ~FineAtoms() override = default; /** Overrides DynamicAtoms::check_variable so that the error * would be raised if the variable name is not declared. A * variable is declared by inserting it to @@ -387,13 +378,13 @@ namespace ogp int nexo() const { - return (int) exovars.size(); + return static_cast(exovars.size()); } /** Return the number of parameters. */ int np() const { - return (int) (params.size()); + return static_cast(params.size()); } /** Register unique endogenous variable name. The order of * calls defines the endo outer ordering. The method is diff --git a/dynare++/parser/cc/formula.yy b/dynare++/parser/cc/formula.yy index 7b24e4fbf..e205bae3a 100644 --- a/dynare++/parser/cc/formula.yy +++ b/dynare++/parser/cc/formula.yy @@ -47,27 +47,27 @@ extern ogp::FormulaParser* fparser; equation_list : equation_list equation | equation ; equation : expression EQUAL_SIGN expression ';' - {fparser->add_formula(fparser->add_binary(ogp::MINUS,$1,$3));} + {fparser->add_formula(fparser->add_binary(ogp::code_t::MINUS,$1,$3));} | expression ';' {fparser->add_formula($1);} ; expression : '(' expression ')' { $$ = $2;} - | expression YPLUS expression {$$=fparser->add_binary(ogp::PLUS,$1,$3);} - | expression YMINUS expression {$$=fparser->add_binary(ogp::MINUS,$1,$3);} - | expression YTIMES expression {$$=fparser->add_binary(ogp::TIMES,$1,$3);} - | expression YDIVIDE expression {$$=fparser->add_binary(ogp::DIVIDE,$1,$3);} - | expression YPOWER expression {$$=fparser->add_binary(ogp::POWER,$1,$3);} - | YMINUS expression %prec YUMINUS {$$=fparser->add_unary(ogp::UMINUS,$2);} + | expression YPLUS expression {$$=fparser->add_binary(ogp::code_t::PLUS,$1,$3);} + | expression YMINUS expression {$$=fparser->add_binary(ogp::code_t::MINUS,$1,$3);} + | expression YTIMES expression {$$=fparser->add_binary(ogp::code_t::TIMES,$1,$3);} + | expression YDIVIDE expression {$$=fparser->add_binary(ogp::code_t::DIVIDE,$1,$3);} + | expression YPOWER expression {$$=fparser->add_binary(ogp::code_t::POWER,$1,$3);} + | YMINUS expression %prec YUMINUS {$$=fparser->add_unary(ogp::code_t::UMINUS,$2);} | YPLUS expression %prec YUPLUS {$$ = $2;} - | YSIN '(' expression ')' {$$=fparser->add_unary(ogp::SIN,$3);} - | YCOS '(' expression ')' {$$=fparser->add_unary(ogp::COS,$3);} - | YTAN '(' expression ')' {$$=fparser->add_unary(ogp::TAN,$3);} - | YEXP '(' expression ')' {$$=fparser->add_unary(ogp::EXP,$3);} - | YLOG '(' expression ')' {$$=fparser->add_unary(ogp::LOG,$3);} - | YSQRT '(' expression ')' {$$=fparser->add_unary(ogp::SQRT,$3);} - | YERF '(' expression ')' {$$=fparser->add_unary(ogp::ERF,$3);} - | YERFC '(' expression ')' {$$=fparser->add_unary(ogp::ERFC,$3);} + | YSIN '(' expression ')' {$$=fparser->add_unary(ogp::code_t::SIN,$3);} + | YCOS '(' expression ')' {$$=fparser->add_unary(ogp::code_t::COS,$3);} + | YTAN '(' expression ')' {$$=fparser->add_unary(ogp::code_t::TAN,$3);} + | YEXP '(' expression ')' {$$=fparser->add_unary(ogp::code_t::EXP,$3);} + | YLOG '(' expression ')' {$$=fparser->add_unary(ogp::code_t::LOG,$3);} + | YSQRT '(' expression ')' {$$=fparser->add_unary(ogp::code_t::SQRT,$3);} + | YERF '(' expression ')' {$$=fparser->add_unary(ogp::code_t::ERF,$3);} + | YERFC '(' expression ')' {$$=fparser->add_unary(ogp::code_t::ERFC,$3);} | YDIFF '(' expression ',' NAME ')' {$$=fparser->add_derivative($3, fparser->add_nulary($5));} | NAME {$$=fparser->add_nulary($1);} | DNUMBER {$$=fparser->add_nulary($1);} diff --git a/dynare++/parser/cc/formula_parser.cc b/dynare++/parser/cc/formula_parser.cc index ccc9ed7b0..97ca75934 100644 --- a/dynare++/parser/cc/formula_parser.cc +++ b/dynare++/parser/cc/formula_parser.cc @@ -11,7 +11,7 @@ #include "formula_tab.hh" #include -#include +#include using namespace ogp; @@ -21,29 +21,24 @@ FormulaParser::FormulaParser(const FormulaParser &fp, Atoms &a) : otree(fp.otree), atoms(a), formulas(fp.formulas), ders() { // create derivatives - for (auto der : fp.ders) - ders.push_back(new FormulaDerivatives(*der)); -} - -FormulaParser::~FormulaParser() -{ - destroy_derivatives(); + for (const auto &der : fp.ders) + ders.push_back(std::make_unique(*der)); } void FormulaParser::differentiate(int max_order) { - destroy_derivatives(); + ders.clear(); vector vars; vars = atoms.variables(); for (int formula : formulas) - ders.push_back(new FormulaDerivatives(otree, vars, formula, max_order)); + ders.push_back(std::make_unique(otree, vars, formula, max_order)); } const FormulaDerivatives & FormulaParser::derivatives(int i) const { - if (i < (int) ders.size()) + if (i < static_cast(ders.size())) return *(ders[i]); else throw ogu::Exception(__FILE__, __LINE__, @@ -108,11 +103,10 @@ FormulaParser::substitute_formulas(const map &smap) int f = add_substitution(formulas[i], smap); formulas[i] = f; // update the derivatives if any - if (i < (int) ders.size() && ders[i]) + if (i < static_cast(ders.size()) && ders[i]) { int order = ders[i]->get_order(); - delete ders[i]; - ders[i] = new FormulaDerivatives(otree, atoms.variables(), formulas[i], order); + ders[i] = std::make_unique(otree, atoms.variables(), formulas[i], order); } } } @@ -134,16 +128,15 @@ extern location_type fmla_lloc; void FormulaParser::parse(int length, const char *stream) { - auto *buffer = new char[length+2]; - strncpy(buffer, stream, length); + auto buffer = std::make_unique(length+2); + std::copy_n(stream, length, buffer.get()); buffer[length] = '\0'; buffer[length+1] = '\0'; fmla_lloc.off = 0; fmla_lloc.ll = 0; - void *p = fmla__scan_buffer(buffer, (unsigned int) length+2); + void *p = fmla__scan_buffer(buffer.get(), static_cast(length)+2); fparser = this; fmla_parse(); - delete [] buffer; fmla__destroy_buffer(p); } @@ -158,8 +151,7 @@ FormulaParser::last_formula() const { int res = -1; for (int formula : formulas) - if (res < formula) - res = formula; + res = std::max(res, formula); return std::max(res, otree.get_last_nulary()); } @@ -170,10 +162,7 @@ FormulaParser::pop_last_formula() return -1; int t = formulas.back(); if (formulas.size() == ders.size()) - { - delete ders.back(); - ders.pop_back(); - } + ders.pop_back(); formulas.pop_back(); return t; } @@ -194,16 +183,6 @@ FormulaParser::print() const } } -void -FormulaParser::destroy_derivatives() -{ - while (ders.size() > 0) - { - delete ders.back(); - ders.pop_back(); - } -} - /** This constructor makes a vector of indices for formulas * corresponding to derivatives of the given formula. The formula is * supposed to belong to the provided tree, the created derivatives @@ -254,13 +233,11 @@ FormulaDerivatives::FormulaDerivatives(OperationTree &otree, // build ind2der map for (unsigned int i = 0; i < indices.size(); i++) - ind2der.insert(Tfmiintmap::value_type(indices[i], i)); + ind2der.emplace(indices[i], i); } -FormulaDerivatives::FormulaDerivatives(const FormulaDerivatives &fd) - -= default; +FormulaDerivatives::FormulaDerivatives(const FormulaDerivatives &fd) = default; int FormulaDerivatives::derivative(const FoldMultiIndex &mi) const @@ -276,7 +253,7 @@ FormulaDerivatives::derivative(const FoldMultiIndex &mi) const if (it == ind2der.end()) return OperationTree::zero; else - return tder[(*it).second]; + return tder[it->second]; } void @@ -299,17 +276,17 @@ FormulaCustomEvaluator::eval(const AtomValues &av, FormulaEvalLoader &loader) for (unsigned int i = 0; i < terms.size(); i++) { double res = etree.eval(terms[i]); - loader.load((int) i, res); + loader.load(static_cast(i), res); } } FoldMultiIndex::FoldMultiIndex(int nv) - : nvar(nv), ord(0), data(new int[ord]) + : nvar(nv), ord(0), data(std::make_unique(ord)) { } FoldMultiIndex::FoldMultiIndex(int nv, int ordd, int ii) - : nvar(nv), ord(ordd), data(new int[ord]) + : nvar(nv), ord(ordd), data(std::make_unique(ord)) { for (int i = 0; i < ord; i++) data[i] = ii; @@ -318,7 +295,7 @@ FoldMultiIndex::FoldMultiIndex(int nv, int ordd, int ii) /** Note that a monotone sequence mapped by monotone mapping yields a * monotone sequence. */ FoldMultiIndex::FoldMultiIndex(int nv, const FoldMultiIndex &mi, const vector &mp) - : nvar(nv), ord(mi.ord), data(new int[ord]) + : nvar(nv), ord(mi.ord), data(std::make_unique(ord)) { for (int i = 0; i < ord; i++) { @@ -335,36 +312,31 @@ FoldMultiIndex::FoldMultiIndex(int nv, const FoldMultiIndex &mi, const vector(ord)) { - memcpy(data, fmi.data, fmi.ord*sizeof(int)); + std::copy_n(fmi.data.get(), fmi.ord, data.get()); int new_item = (fmi.ord > 0) ? fmi.data[fmi.ord-1] : 0; for (int i = fmi.ord; i < ord; i++) - { - data[i] = new_item; - } + data[i] = new_item; } FoldMultiIndex::FoldMultiIndex(const FoldMultiIndex &fmi) : nvar(fmi.nvar), ord(fmi.ord), - data(new int[fmi.ord]) + data(std::make_unique(ord)) { - memcpy(data, fmi.data, ord*sizeof(int)); + std::copy_n(fmi.data.get(), ord, data.get()); } const FoldMultiIndex & FoldMultiIndex::operator=(const FoldMultiIndex &fmi) { if (ord != fmi.ord) - { - delete [] data; - data = new int[fmi.ord]; - } + data = std::make_unique(fmi.ord); ord = fmi.ord; nvar = fmi.nvar; - memcpy(data, fmi.data, ord*sizeof(int)); + std::copy_n(fmi.data.get(), ord, data.get()); return *this; } @@ -427,13 +399,10 @@ int FoldMultiIndex::offset() const { // make copy for the recursions - auto *tmp = new int[ord]; - for (int i = 0; i < ord; i++) - tmp[i] = data[i]; + auto tmp = std::make_unique(ord); + std::copy_n(data.get(), ord, tmp.get()); // call the recursive algorithm - int res = offset_recurse(tmp, ord, nvar); - - delete [] tmp; + int res = offset_recurse(tmp.get(), ord, nvar); return res; } @@ -478,8 +447,8 @@ ltfmi::operator()(const FoldMultiIndex &i1, const FoldMultiIndex &i2) const FormulaDerEvaluator::FormulaDerEvaluator(const FormulaParser &fp) : etree(fp.otree, -1) { - for (auto der : fp.ders) - ders.push_back((const FormulaDerivatives *) der); + for (const auto &der : fp.ders) + ders.push_back(der.get()); der_atoms = fp.atoms.variables(); } @@ -498,28 +467,25 @@ FormulaDerEvaluator::eval(const AtomValues &av, FormulaDerEvalLoader &loader, in etree.reset_all(); av.setValues(etree); - auto *vars = new int[order]; + auto vars = std::make_unique(order); for (unsigned int i = 0; i < ders.size(); i++) { - for (auto it = ders[i]->ind2der.begin(); - it != ders[i]->ind2der.end(); ++it) + for (const auto &it : ders[i]->ind2der) { - const FoldMultiIndex &mi = (*it).first; + const FoldMultiIndex &mi = it.first; if (mi.order() == order) { // set vars from multiindex mi and variables for (int k = 0; k < order; k++) vars[k] = der_atoms[mi[k]]; // evaluate - double res = etree.eval(ders[i]->tder[(*it).second]); + double res = etree.eval(ders[i]->tder[it.second]); // load - loader.load(i, order, vars, res); + loader.load(i, order, vars.get(), res); } } } - - delete [] vars; } void @@ -531,7 +497,7 @@ FormulaDerEvaluator::eval(const vector &mp, const AtomValues &av, int nvar_glob = der_atoms.size(); int nvar = mp.size(); - auto *vars = new int[order]; + auto vars = std::make_unique(order); for (unsigned int i = 0; i < ders.size(); i++) { @@ -549,12 +515,10 @@ FormulaDerEvaluator::eval(const vector &mp, const AtomValues &av, // evaluate derivative double res = etree.eval(der); // load - loader.load(i, order, vars, res); + loader.load(i, order, vars.get(), res); } mi.increment(); } while (!mi.past_the_end()); } - - delete [] vars; } diff --git a/dynare++/parser/cc/formula_parser.hh b/dynare++/parser/cc/formula_parser.hh index c8427974a..b754314aa 100644 --- a/dynare++/parser/cc/formula_parser.hh +++ b/dynare++/parser/cc/formula_parser.hh @@ -4,6 +4,8 @@ #define OGP_FORMULA_PARSER_H #include +#include +#include #include "tree.hh" @@ -16,10 +18,8 @@ namespace ogp class Atoms { public: - Atoms() - = default; - virtual ~Atoms() - = default; + Atoms() = default; + virtual ~Atoms() = default; /** This returns previously assigned internal index to the * given atom, or returns -1 if the atom has not been assigned * yet. The method can raise an exception, if the Atoms @@ -48,8 +48,7 @@ namespace ogp class AtomValues { public: - virtual ~AtomValues() - = default; + virtual ~AtomValues() = default; virtual void setValues(EvalTree &et) const = 0; }; @@ -110,8 +109,7 @@ namespace ogp FormulaDerivatives(OperationTree &otree, const vector &vars, int f, int max_order); /** Copy constructor. */ FormulaDerivatives(const FormulaDerivatives &fd); - virtual ~FormulaDerivatives() - = default; + virtual ~FormulaDerivatives() = default; /** Random access to the derivatives via multiindex. */ int derivative(const FoldMultiIndex &mi) const; /** Return the order. */ @@ -151,7 +149,7 @@ namespace ogp vector formulas; /** The vector to derivatives, each vector corresponds to a * formula in the vector formulas. */ - vector ders; + vector> ders; public: /** Construct an empty formula parser. */ FormulaParser(Atoms &a) @@ -161,8 +159,7 @@ namespace ogp FormulaParser(const FormulaParser &fp) = delete; /** Copy constructor using a different instance of Atoms. */ FormulaParser(const FormulaParser &fp, Atoms &a); - virtual - ~FormulaParser(); + virtual ~FormulaParser() = default; /** Requires an addition of the formula; called from the * parser. */ @@ -267,7 +264,7 @@ namespace ogp int nformulas() const { - return (int) (formulas.size()); + return static_cast(formulas.size()); } /** This returns a reference to atoms. */ @@ -295,9 +292,6 @@ namespace ogp /** Debug print. */ void print() const; - private: - /** Destroy all derivatives. */ - void destroy_derivatives(); }; /** This is a pure virtual class defining an interface for all @@ -307,8 +301,7 @@ namespace ogp class FormulaEvalLoader { public: - virtual ~FormulaEvalLoader() - = default; + virtual ~FormulaEvalLoader() = default; /** Set the value res for the given formula. The formula is * identified by an index corresponding to the ordering in * which the formulas have been parsed (starting from @@ -368,8 +361,7 @@ namespace ogp class FormulaDerEvalLoader { public: - virtual ~FormulaDerEvalLoader() - = default; + virtual ~FormulaDerEvalLoader() = default; /** This loads the result of the derivative of the given * order. The semantics of i is the same as in * FormulaEvalLoader::load. The indices of variables with @@ -389,7 +381,7 @@ namespace ogp /** Dimension. */ int ord; /** The multiindex. */ - int *data; + std::unique_ptr data; public: /** Initializes to the zero derivative. Order is 0, data is * empty. */ @@ -407,10 +399,7 @@ namespace ogp /** Copy constructor. */ FoldMultiIndex(const FoldMultiIndex &fmi); /** Desctructor. */ - virtual ~FoldMultiIndex() - { - delete [] data; - } + virtual ~FoldMultiIndex() = default; /** Assignment operator. */ const FoldMultiIndex &operator=(const FoldMultiIndex &fmi); /** Operator < implementing lexicographic ordering within one @@ -443,7 +432,7 @@ namespace ogp const int * ind() const { - return data; + return data.get(); } /** Return true if the end of the tensor is reached. The * result of a subsequent increment should be considered diff --git a/dynare++/parser/cc/matrix_parser.cc b/dynare++/parser/cc/matrix_parser.cc index 59efb6776..7dc9cb5ec 100644 --- a/dynare++/parser/cc/matrix_parser.cc +++ b/dynare++/parser/cc/matrix_parser.cc @@ -6,7 +6,9 @@ #include "matrix_parser.hh" #include "location.hh" #include "matrix_tab.hh" -#include + +#include +#include using namespace ogp; @@ -29,16 +31,15 @@ MatrixParser::parse(int length, const char *stream) row_lengths.clear(); nc = 0; // allocate temporary buffer and parse - auto *buffer = new char[length+2]; - strncpy(buffer, stream, length); + auto buffer = std::make_unique(length+2); + std::copy_n(stream, length, buffer.get()); buffer[length] = '\0'; buffer[length+1] = '\0'; matrix_lloc.off = 0; matrix_lloc.ll = 0; - void *p = matrix__scan_buffer(buffer, (unsigned int) length+2); + void *p = matrix__scan_buffer(buffer.get(), static_cast(length)+2); mparser = this; matrix_parse(); - delete [] buffer; matrix__destroy_buffer(p); } @@ -49,8 +50,7 @@ MatrixParser::add_item(double v) if (row_lengths.size() == 0) row_lengths.push_back(0); (row_lengths.back())++; - if (row_lengths.back() > nc) - nc = row_lengths.back(); + nc = std::max(nc, row_lengths.back()); } void @@ -69,7 +69,7 @@ int MatrixParser::find_first_non_empty_row(int start) const { int r = start; - while (r < (int) row_lengths.size() && row_lengths[r] == 0) + while (r < static_cast(row_lengths.size()) && row_lengths[r] == 0) r++; return r; } diff --git a/dynare++/parser/cc/matrix_parser.hh b/dynare++/parser/cc/matrix_parser.hh index 89e954084..179751e4a 100644 --- a/dynare++/parser/cc/matrix_parser.hh +++ b/dynare++/parser/cc/matrix_parser.hh @@ -5,7 +5,6 @@ #ifndef OGP_MATRIX_PARSER #define OGP_MATRIX_PARSER -#include // For NULL #include namespace ogp @@ -33,19 +32,14 @@ namespace ogp /** Maximum number of row lengths. */ int nc{0}; public: - MatrixParser() - - = default; - MatrixParser(const MatrixParser &mp) - - = default; - virtual ~MatrixParser() - = default; + MatrixParser() = default; + MatrixParser(const MatrixParser &mp) = default; + virtual ~MatrixParser() = default; /** Return a number of read rows. */ int nrows() const { - return (int) row_lengths.size(); + return static_cast(row_lengths.size()); } /** Return a maximum number of items in the rows. */ int @@ -91,8 +85,7 @@ namespace ogp int r{0}; public: - MPIterator() - = default; + MPIterator() = default; /** Constructs an iterator pointing to the beginning of the * parsed matrix. */ MPIterator(const MatrixParser &mp); @@ -118,9 +111,7 @@ namespace ogp return c; } /** Assignment operator. */ - MPIterator & - operator=(const MPIterator &it) - = default; + MPIterator &operator=(const MPIterator &it) = default; /** Return true if the iterators are the same, this is if they * have the same underlying object and the same item index. */ bool diff --git a/dynare++/parser/cc/namelist.cc b/dynare++/parser/cc/namelist.cc index fb9d07482..3353831af 100644 --- a/dynare++/parser/cc/namelist.cc +++ b/dynare++/parser/cc/namelist.cc @@ -4,7 +4,8 @@ #include "namelist.hh" -#include +#include +#include using namespace ogp; @@ -19,13 +20,12 @@ void namelist_parse(); void NameListParser::namelist_parse(int length, const char *stream) { - auto *buffer = new char[length+2]; - strncpy(buffer, stream, length); + auto buffer = std::make_unique(length+2); + std::copy_n(str, length, buffer.get()); buffer[length] = '\0'; buffer[length+1] = '\0'; - void *p = namelist__scan_buffer(buffer, (unsigned int) length+2); + void *p = namelist__scan_buffer(buffer.get(), static_cast(length)+2); name_list_parser = this; ::namelist_parse(); - delete [] buffer; namelist__destroy_buffer(p); } diff --git a/dynare++/parser/cc/namelist.hh b/dynare++/parser/cc/namelist.hh index 8c2c416fc..db29dd1bc 100644 --- a/dynare++/parser/cc/namelist.hh +++ b/dynare++/parser/cc/namelist.hh @@ -7,7 +7,6 @@ namespace ogp { - /** Parent class of all parsers parsing a namelist. They must * implement add_name() method and error() method, which is called * when an parse error occurs. @@ -20,8 +19,7 @@ namespace ogp class NameListParser { public: - virtual ~NameListParser() - = default; + virtual ~NameListParser() = default; virtual void add_name(const char *name) = 0; virtual void namelist_error(const char *mes) = 0; void namelist_parse(int length, const char *text); diff --git a/dynare++/parser/cc/parser_exception.cc b/dynare++/parser/cc/parser_exception.cc index fe9f24931..c433990fa 100644 --- a/dynare++/parser/cc/parser_exception.cc +++ b/dynare++/parser/cc/parser_exception.cc @@ -3,61 +3,42 @@ // $Id: parser_exception.cpp 2269 2008-11-23 14:33:22Z michel $ #include "parser_exception.hh" -#include -#include using namespace ogp; -ParserException::ParserException(const char *m, int offset) - : mes(new char[strlen(m)+1]), off(offset), +ParserException::ParserException(string m, int offset) + : mes(std::move(m)), off(offset), aux_i1(-1), aux_i2(-1), aux_i3(-1) { - strcpy(mes, m); } -ParserException::ParserException(const string &m, int offset) - : mes(new char[m.size()+1]), off(offset), - aux_i1(-1), aux_i2(-1), aux_i3(-1) -{ - strncpy(mes, m.c_str(), m.size()); - mes[m.size()] = '\0'; -} - -ParserException::ParserException(const string &m, const char *dum, int i1) - : mes(new char[m.size()+1]), off(0), +ParserException::ParserException(string m, const char *dum, int i1) + : mes(std::move(m)), off(0), aux_i1(i1), aux_i2(-1), aux_i3(-1) { - strncpy(mes, m.c_str(), m.size()); - mes[m.size()] = '\0'; } -ParserException::ParserException(const string &m, const char *dum, int i1, int i2) - : mes(new char[m.size()+1]), off(0), +ParserException::ParserException(string m, const char *dum, int i1, int i2) + : mes(std::move(m)), off(0), aux_i1(i1), aux_i2(i2), aux_i3(-1) { - strncpy(mes, m.c_str(), m.size()); - mes[m.size()] = '\0'; } -ParserException::ParserException(const string &m, const char *dum, int i1, int i2, int i3) - : mes(new char[m.size()+1]), off(0), +ParserException::ParserException(string m, const char *dum, int i1, int i2, int i3) + : mes(std::move(m)), off(0), aux_i1(i1), aux_i2(i2), aux_i3(i3) { - strncpy(mes, m.c_str(), m.size()); - mes[m.size()] = '\0'; } ParserException::ParserException(const ParserException &m, int plus_offset) - : mes(nullptr), - aux_i1(-1), aux_i2(-1), aux_i3(-1) + : aux_i1(-1), aux_i2(-1), aux_i3(-1) { copy(m); off += plus_offset; } ParserException::ParserException(const ParserException &m, const char *dum, int i) - : mes(nullptr), - aux_i1(-1), aux_i2(-1), aux_i3(-1) + : aux_i1(-1), aux_i2(-1), aux_i3(-1) { copy(m); aux_i3 = m.aux_i2; @@ -66,8 +47,7 @@ ParserException::ParserException(const ParserException &m, const char *dum, int } ParserException::ParserException(const ParserException &m, const char *dum, int i1, int i2) - : mes(nullptr), - aux_i1(-1), aux_i2(-1), aux_i3(-1) + : aux_i1(-1), aux_i2(-1), aux_i3(-1) { copy(m); aux_i3 = m.aux_i1; @@ -76,8 +56,7 @@ ParserException::ParserException(const ParserException &m, const char *dum, int } ParserException::ParserException(const ParserException &m, const char *dum, int i1, int i2, int i3) - : mes(nullptr), - aux_i1(-1), aux_i2(-1), aux_i3(-1) + : aux_i1(-1), aux_i2(-1), aux_i3(-1) { copy(m); aux_i3 = i3; @@ -85,34 +64,12 @@ ParserException::ParserException(const ParserException &m, const char *dum, int aux_i1 = i1; } -ParserException::ParserException(const ParserException &e) - : mes(nullptr), - aux_i1(-1), aux_i2(-1), aux_i3(-1) -{ - copy(e); -} - -ParserException::~ParserException() -{ - delete [] mes; -} - void ParserException::copy(const ParserException &e) { - if (mes) - delete [] mes; - mes = new char[strlen(e.mes)+1]; - strcpy(mes, e.mes); + mes = e.mes; off = e.off; aux_i1 = e.aux_i1; aux_i2 = e.aux_i2; aux_i3 = e.aux_i3; } - -void -ParserException::print(FILE *fd) const -{ - // todo: to be refined - fprintf(fd, "%s: offset %d\n", mes, off); -} diff --git a/dynare++/parser/cc/parser_exception.hh b/dynare++/parser/cc/parser_exception.hh index be2109ed5..5a8fbd33a 100644 --- a/dynare++/parser/cc/parser_exception.hh +++ b/dynare++/parser/cc/parser_exception.hh @@ -21,17 +21,16 @@ namespace ogp class ParserException { protected: - char *mes; + string mes; int off; int aux_i1; int aux_i2; int aux_i3; public: - ParserException(const char *m, int offset); - ParserException(const string &m, int offset); - ParserException(const string &m, const char *dum, int i1); - ParserException(const string &m, const char *dum, int i1, int i2); - ParserException(const string &m, const char *dum, int i1, int i2, int i3); + ParserException(string m, int offset); + ParserException(string m, const char *dum, int i1); + ParserException(string m, const char *dum, int i1, int i2); + ParserException(string m, const char *dum, int i1, int i2, int i3); ParserException(const ParserException &e, int plus_offset); /** Makes a copy and pushes given integer to aux_i1 shuffling * others and forgetting the last. */ @@ -42,11 +41,9 @@ namespace ogp /** Makes a copy and pushes given three integers to aux_i1, aux_i2, aus_i3 shuffling * others and forgetting the last three. */ ParserException(const ParserException &e, const char *dum, int i1, int i2, int i3); - ParserException(const ParserException &e); - virtual - ~ParserException(); - void print(FILE *fd) const; - const char * + ParserException(const ParserException &e) = default; + virtual ~ParserException() = default; + const string & message() const { return mes; diff --git a/dynare++/parser/cc/static_atoms.cc b/dynare++/parser/cc/static_atoms.cc index 6b6ad7e3b..e7fe6e443 100644 --- a/dynare++/parser/cc/static_atoms.cc +++ b/dynare++/parser/cc/static_atoms.cc @@ -22,14 +22,14 @@ StaticAtoms::StaticAtoms(const StaticAtoms &a) for (auto var : a.vars) { const char *s = varnames.query(var.first); - vars.insert(Tvarmap::value_type(s, var.second)); + vars.emplace(s, var.second); } // fill indices for (auto indice : a.indices) { const char *s = varnames.query(indice.second); - indices.insert(Tinvmap::value_type(indice.first, s)); + indices.emplace(indice.first, s); } } @@ -50,7 +50,7 @@ StaticAtoms::import_atoms(const DynamicAtoms &da, OperationTree &otree, Tintintm for (auto it : lmap) { int told = it.second; - tmap.insert(Tintintmap::value_type(told, tnew)); + tmap.emplace(told, tnew); } } } @@ -60,13 +60,9 @@ int StaticAtoms::check(const char *name) const { if (DynamicAtoms::is_string_constant(name)) - { - return Constants::check(name); - } + return Constants::check(name); else - { - return check_variable(name); - } + return check_variable(name); } int @@ -76,7 +72,7 @@ StaticAtoms::index(const char *name) const if (it == vars.end()) return -1; else - return (*it).second; + return it->second; } const char * @@ -86,7 +82,7 @@ StaticAtoms::inv_index(int t) const if (it == indices.end()) return nullptr; else - return (*it).second; + return it->second; } void @@ -101,8 +97,8 @@ StaticAtoms::assign(const char *name, int t) else { const char *ss = varnames.insert(name); - vars.insert(Tvarmap::value_type(ss, t)); - indices.insert(Tinvmap::value_type(t, ss)); + vars.emplace(ss, t); + indices.emplace(t, ss); } } @@ -111,9 +107,7 @@ StaticAtoms::variables() const { vector res; for (auto var : vars) - { - res.push_back(var.second); - } + res.push_back(var.second); return res; } @@ -133,5 +127,5 @@ StaticAtoms::print() const varnames.print(); printf("map to tree indices:\n"); for (auto var : vars) - printf("%s\t->\t%d\n", var.first, var.second); + printf(u8"%s\t→\t%d\n", var.first, var.second); } diff --git a/dynare++/parser/cc/static_atoms.hh b/dynare++/parser/cc/static_atoms.hh index 40b26aeec..fefc823aa 100644 --- a/dynare++/parser/cc/static_atoms.hh +++ b/dynare++/parser/cc/static_atoms.hh @@ -9,7 +9,6 @@ namespace ogp { - class StaticAtoms : public Atoms, public Constants { protected: @@ -42,8 +41,7 @@ namespace ogp import_atoms(da, otree, tmap); } /* Destructor. */ - ~StaticAtoms() - override = default; + ~StaticAtoms() override = default; /** This imports atoms from dynamic atoms inserting the new * tree indices to the given tree (including constants). The * mapping from old atoms to new atoms is traced in tmap. */ diff --git a/dynare++/parser/cc/static_fine_atoms.cc b/dynare++/parser/cc/static_fine_atoms.cc index 367c94742..12e25a6e2 100644 --- a/dynare++/parser/cc/static_fine_atoms.cc +++ b/dynare++/parser/cc/static_fine_atoms.cc @@ -22,21 +22,21 @@ StaticFineAtoms::StaticFineAtoms(const StaticFineAtoms &sfa) { const char *name = varnames.query(sfa.params[i]); params.push_back(name); - param_outer_map.insert(Tvarintmap::value_type(name, i)); + param_outer_map.emplace(name, i); } for (unsigned int i = 0; i < sfa.endovars.size(); i++) { const char *name = varnames.query(sfa.endovars[i]); endovars.push_back(name); - endo_outer_map.insert(Tvarintmap::value_type(name, i)); + endo_outer_map.emplace(name, i); } for (unsigned int i = 0; i < sfa.exovars.size(); i++) { const char *name = varnames.query(sfa.exovars[i]); exovars.push_back(name); - exo_outer_map.insert(Tvarintmap::value_type(name, i)); + exo_outer_map.emplace(name, i); } } @@ -97,7 +97,7 @@ int StaticFineAtoms::check_variable(const char *name) const { const char *ss = varnames.query(name); - if (ss == nullptr) + if (!ss) throw ParserException(string("Variable <")+name+"> not declared.", 0); return index(name); } @@ -139,7 +139,7 @@ StaticFineAtoms::name2outer_param(const char *name) const if (it == param_outer_map.end()) throw ogu::Exception(__FILE__, __LINE__, "Name is not a parameter in StaticFineAtoms::name2outer_param"); - return (*it).second; + return it->second; } int @@ -149,7 +149,7 @@ StaticFineAtoms::name2outer_endo(const char *name) const if (it == endo_outer_map.end()) throw ogu::Exception(__FILE__, __LINE__, "Name is not an endogenous variable in StaticFineAtoms::name2outer_endo"); - return (*it).second; + return it->second; } int @@ -159,7 +159,7 @@ StaticFineAtoms::name2outer_exo(const char *name) const if (it == exo_outer_map.end()) throw ogu::Exception(__FILE__, __LINE__, "Name is not an exogenous variable in StaticFineAtoms::name2outer_exo"); - return (*it).second; + return it->second; } void @@ -195,10 +195,10 @@ StaticFineAtoms::print() const StaticAtoms::print(); printf("endo atoms map:\n"); for (unsigned int i = 0; i < endo_atoms_map.size(); i++) - printf("%d --> %d\n", i, endo_atoms_map[i]); + printf(u8"%d → %d\n", i, endo_atoms_map[i]); printf("exo atoms map:\n"); for (unsigned int i = 0; i < exo_atoms_map.size(); i++) - printf("%d --> %d\n", i, exo_atoms_map[i]); + printf(u8"%d → %d\n", i, exo_atoms_map[i]); printf("der atoms:\n"); for (unsigned int i = 0; i < der_atoms.size(); i++) printf("%d\t%d\n", i, der_atoms[i]); @@ -208,30 +208,30 @@ void StaticFineAtoms::register_endo(const char *name) { const char *ss = varnames.query(name); - if (ss == nullptr) + if (!ss) throw ogp::ParserException(string("Endogenous variable <") +name+"> not found in storage.", 0); endovars.push_back(ss); - endo_outer_map.insert(Tvarintmap::value_type(ss, endovars.size()-1)); + endo_outer_map.emplace(ss, endovars.size()-1); } void StaticFineAtoms::register_exo(const char *name) { const char *ss = varnames.query(name); - if (ss == nullptr) + if (!ss) throw ogp::ParserException(string("Exogenous variable <") +name+"> not found in storage.", 0); exovars.push_back(ss); - exo_outer_map.insert(Tvarintmap::value_type(ss, exovars.size()-1)); + exo_outer_map.emplace(ss, exovars.size()-1); } void StaticFineAtoms::register_param(const char *name) { const char *ss = varnames.query(name); - if (ss == nullptr) + if (!ss) throw ogp::ParserException(string("Parameter <")+name+"> not found in storage.", 0); params.push_back(ss); - param_outer_map.insert(Tvarintmap::value_type(ss, params.size()-1)); + param_outer_map.emplace(ss, params.size()-1); } diff --git a/dynare++/parser/cc/static_fine_atoms.hh b/dynare++/parser/cc/static_fine_atoms.hh index 12cbec8a0..2053a78a4 100644 --- a/dynare++/parser/cc/static_fine_atoms.hh +++ b/dynare++/parser/cc/static_fine_atoms.hh @@ -10,7 +10,6 @@ namespace ogp { - /** This class represents static atoms distinguishing between * parameters, endogenous and exogenous variables. The class * maintains also ordering of all three categories (referenced as @@ -61,8 +60,7 @@ namespace ogp * atoms of exogenous variables. */ vector exo_atoms_map; public: - StaticFineAtoms() - = default; + StaticFineAtoms() = default; /** Copy constructor making a new storage for atom names. */ StaticFineAtoms(const StaticFineAtoms &sfa); /** Conversion from dynamic FineAtoms taking its outer @@ -84,8 +82,7 @@ namespace ogp { StaticFineAtoms::import_atoms(fa, otree, tmap, dummy); } - ~StaticFineAtoms() - override = default; + ~StaticFineAtoms() override = default; /** This adds atoms from dynamic atoms inserting new tree * indices to the given tree and tracing the mapping from old * atoms to new atoms in tmap. The ordering of the static @@ -166,13 +163,13 @@ namespace ogp int nexo() const { - return (int) exovars.size(); + return static_cast(exovars.size()); } /** Return the number of parameters. */ int np() const { - return (int) (params.size()); + return static_cast(params.size()); } /** Register unique endogenous variable name. The order of * calls defines the endo outer ordering. The method is @@ -202,7 +199,6 @@ namespace ogp * storage. */ void register_param(const char *name); }; - }; #endif diff --git a/dynare++/parser/cc/tree.cc b/dynare++/parser/cc/tree.cc index 45ae9d68e..6430d0897 100644 --- a/dynare++/parser/cc/tree.cc +++ b/dynare++/parser/cc/tree.cc @@ -4,8 +4,6 @@ #include "tree.hh" -#include - #include #include @@ -25,13 +23,11 @@ int OperationTree::add_nulary() { int op = terms.size(); - Operation nulary; - terms.push_back(nulary); + terms.push_back({}); _Tintset s; s.insert(op); nul_incidence.push_back(s); - _Tderivmap empty; - derivatives.push_back(empty); + derivatives.push_back({}); last_nulary = op; return op; } @@ -40,21 +36,21 @@ int OperationTree::add_unary(code_t code, int op) { if (op == zero - && (code == UMINUS - || code == SIN - || code == TAN - || code == SQRT - || code == ERF)) + && (code == code_t::UMINUS + || code == code_t::SIN + || code == code_t::TAN + || code == code_t::SQRT + || code == code_t::ERF)) return zero; - if ((op == zero && code == LOG) || op == nan) + if ((op == zero && code == code_t::LOG) || op == nan) return nan; - if (op == zero && (code == EXP - || code == COS - || code == ERFC)) + if (op == zero && (code == code_t::EXP + || code == code_t::COS + || code == code_t::ERFC)) return one; Operation unary(code, op); - auto i = ((const _Topmap &) opmap).find(unary); + auto i = opmap.find(unary); if (i == opmap.end()) { int newop = terms.size(); @@ -63,13 +59,13 @@ OperationTree::add_unary(code_t code, int op) // copy incidence of the operand nul_incidence.push_back(nul_incidence[op]); // insert it to opmap - opmap.insert(_Topval(unary, newop)); + opmap.emplace(unary, newop); // add empty map of derivatives _Tderivmap empty; derivatives.push_back(empty); return newop; } - return (*i).second; + return i->second; } int @@ -79,7 +75,7 @@ OperationTree::add_binary(code_t code, int op1, int op2) if (op1 == nan || op2 == nan) return nan; // for plus - if (code == PLUS) + if (code == code_t::PLUS) { if (op1 == zero && op2 == zero) return zero; @@ -89,17 +85,17 @@ OperationTree::add_binary(code_t code, int op1, int op2) return op1; } // for minus - if (code == MINUS) + if (code == code_t::MINUS) { if (op1 == zero && op2 == zero) return zero; else if (op1 == zero) - return add_unary(UMINUS, op2); + return add_unary(code_t::UMINUS, op2); else if (op2 == zero) return op1; } // for times - if (code == TIMES) + if (code == code_t::TIMES) { if (op1 == zero || op2 == zero) return zero; @@ -109,7 +105,7 @@ OperationTree::add_binary(code_t code, int op1, int op2) return op1; } // for divide - if (code == DIVIDE) + if (code == code_t::DIVIDE) { if (op1 == op2) return one; @@ -119,7 +115,7 @@ OperationTree::add_binary(code_t code, int op1, int op2) return nan; } // for power - if (code == POWER) + if (code == code_t::POWER) { if (op1 == zero && op2 == zero) return nan; @@ -134,7 +130,7 @@ OperationTree::add_binary(code_t code, int op1, int op2) } // order operands of commutative operations - if (code == TIMES || code == PLUS) + if (code == code_t::TIMES || code == code_t::PLUS) if (op1 > op2) { int tmp = op1; @@ -144,7 +140,7 @@ OperationTree::add_binary(code_t code, int op1, int op2) // construct operation and check/add it Operation binary(code, op1, op2); - auto i = ((const _Topmap &) opmap).find(binary); + auto i = opmap.find(binary); if (i == opmap.end()) { int newop = terms.size(); @@ -153,164 +149,159 @@ OperationTree::add_binary(code_t code, int op1, int op2) nul_incidence.push_back(nul_incidence[op1]); nul_incidence.back().insert(nul_incidence[op2].begin(), nul_incidence[op2].end()); // add to opmap - opmap.insert(_Topval(binary, newop)); + opmap.emplace(binary, newop); // add empty map of derivatives _Tderivmap empty; derivatives.push_back(empty); return newop; } - return (*i).second; + return i->second; } int OperationTree::add_derivative(int t, int v) { - if (t < 0 || t >= (int) terms.size()) + if (t < 0 || t >= static_cast(terms.size())) throw ogu::Exception(__FILE__, __LINE__, "Wrong value for tree index in OperationTree::add_derivative"); // quick returns for nulary terms or empty incidence if (terms[t].nary() == 0 && t != v) - { - return zero; - } + return zero; + if (terms[t].nary() == 0 && t == v) - { - return one; - } + return one; + if (nul_incidence[t].end() == nul_incidence[t].find(v)) - { - return zero; - } + return zero; // quick return if the derivative has been registered - _Tderivmap::const_iterator i = derivatives[t].find(v); + auto i = derivatives[t].find(v); if (i != derivatives[t].end()) - return (*i).second; + return i->second; int res = -1; switch (terms[t].getCode()) { - - case UMINUS: + case code_t::UMINUS: { int tmp = add_derivative(terms[t].getOp1(), v); - res = add_unary(UMINUS, tmp); + res = add_unary(code_t::UMINUS, tmp); break; } - case LOG: + case code_t::LOG: { int tmp = add_derivative(terms[t].getOp1(), v); - res = add_binary(DIVIDE, tmp, terms[t].getOp1()); + res = add_binary(code_t::DIVIDE, tmp, terms[t].getOp1()); break; } - case EXP: + case code_t::EXP: { int tmp = add_derivative(terms[t].getOp1(), v); - res = add_binary(TIMES, t, tmp); + res = add_binary(code_t::TIMES, t, tmp); break; } - case SIN: + case code_t::SIN: { int tmp = add_derivative(terms[t].getOp1(), v); - res = add_binary(TIMES, add_unary(COS, terms[t].getOp1()), tmp); + res = add_binary(code_t::TIMES, add_unary(code_t::COS, terms[t].getOp1()), tmp); break; } - case COS: + case code_t::COS: { int tmp = add_derivative(terms[t].getOp1(), v); - res = add_unary(UMINUS, add_binary(TIMES, add_unary(SIN, terms[t].getOp1()), tmp)); + res = add_unary(code_t::UMINUS, add_binary(code_t::TIMES, add_unary(code_t::SIN, terms[t].getOp1()), tmp)); break; } - case TAN: + case code_t::TAN: { int tmp = add_derivative(terms[t].getOp1(), v); - int tmp2 = add_unary(COS, terms[t].getOp1()); - res = add_binary(DIVIDE, tmp, add_binary(TIMES, tmp2, tmp2)); + int tmp2 = add_unary(code_t::COS, terms[t].getOp1()); + res = add_binary(code_t::DIVIDE, tmp, add_binary(code_t::TIMES, tmp2, tmp2)); break; } - case SQRT: + case code_t::SQRT: { int tmp = add_derivative(terms[t].getOp1(), v); - res = add_binary(DIVIDE, tmp, - add_binary(PLUS, t, t)); + res = add_binary(code_t::DIVIDE, tmp, + add_binary(code_t::PLUS, t, t)); break; } - case ERF: + case code_t::ERF: { - int tmp = add_binary(TIMES, terms[t].getOp1(), terms[t].getOp1()); - tmp = add_unary(UMINUS, tmp); - tmp = add_unary(EXP, tmp); + int tmp = add_binary(code_t::TIMES, terms[t].getOp1(), terms[t].getOp1()); + tmp = add_unary(code_t::UMINUS, tmp); + tmp = add_unary(code_t::EXP, tmp); int der = add_derivative(terms[t].getOp1(), v); - tmp = add_binary(TIMES, tmp, der); - res = add_binary(TIMES, two_over_pi, tmp); + tmp = add_binary(code_t::TIMES, tmp, der); + res = add_binary(code_t::TIMES, two_over_pi, tmp); break; } - case ERFC: + case code_t::ERFC: { - int tmp = add_binary(TIMES, terms[t].getOp1(), terms[t].getOp1()); - tmp = add_unary(UMINUS, tmp); - tmp = add_unary(EXP, tmp); + int tmp = add_binary(code_t::TIMES, terms[t].getOp1(), terms[t].getOp1()); + tmp = add_unary(code_t::UMINUS, tmp); + tmp = add_unary(code_t::EXP, tmp); int der = add_derivative(terms[t].getOp1(), v); - tmp = add_binary(TIMES, tmp, der); - tmp = add_binary(TIMES, two_over_pi, tmp); - res = add_unary(UMINUS, tmp); + tmp = add_binary(code_t::TIMES, tmp, der); + tmp = add_binary(code_t::TIMES, two_over_pi, tmp); + res = add_unary(code_t::UMINUS, tmp); break; } - case PLUS: + case code_t::PLUS: { int tmp1 = add_derivative(terms[t].getOp1(), v); int tmp2 = add_derivative(terms[t].getOp2(), v); - res = add_binary(PLUS, tmp1, tmp2); + res = add_binary(code_t::PLUS, tmp1, tmp2); break; } - case MINUS: + case code_t::MINUS: { int tmp1 = add_derivative(terms[t].getOp1(), v); int tmp2 = add_derivative(terms[t].getOp2(), v); - res = add_binary(MINUS, tmp1, tmp2); + res = add_binary(code_t::MINUS, tmp1, tmp2); break; } - case TIMES: + case code_t::TIMES: { int tmp1 = add_derivative(terms[t].getOp1(), v); int tmp2 = add_derivative(terms[t].getOp2(), v); - int res1 = add_binary(TIMES, terms[t].getOp1(), tmp2); - int res2 = add_binary(TIMES, tmp1, terms[t].getOp2()); - res = add_binary(PLUS, res1, res2); + int res1 = add_binary(code_t::TIMES, terms[t].getOp1(), tmp2); + int res2 = add_binary(code_t::TIMES, tmp1, terms[t].getOp2()); + res = add_binary(code_t::PLUS, res1, res2); break; } - case DIVIDE: + case code_t::DIVIDE: { int tmp1 = add_derivative(terms[t].getOp1(), v); int tmp2 = add_derivative(terms[t].getOp2(), v); if (tmp2 == zero) - res = add_binary(DIVIDE, tmp1, terms[t].getOp2()); + res = add_binary(code_t::DIVIDE, tmp1, terms[t].getOp2()); else { - int nom = add_binary(MINUS, - add_binary(TIMES, tmp1, terms[t].getOp2()), - add_binary(TIMES, tmp2, terms[t].getOp1())); - int den = add_binary(TIMES, terms[t].getOp2(), terms[t].getOp2()); - res = add_binary(DIVIDE, nom, den); + int nom = add_binary(code_t::MINUS, + add_binary(code_t::TIMES, tmp1, terms[t].getOp2()), + add_binary(code_t::TIMES, tmp2, terms[t].getOp1())); + int den = add_binary(code_t::TIMES, terms[t].getOp2(), terms[t].getOp2()); + res = add_binary(code_t::DIVIDE, nom, den); } break; } - case POWER: + case code_t::POWER: { int tmp1 = add_derivative(terms[t].getOp1(), v); int tmp2 = add_derivative(terms[t].getOp2(), v); - int s1 = add_binary(TIMES, tmp2, - add_binary(TIMES, t, - add_unary(LOG, terms[t].getOp1()))); - int s2 = add_binary(TIMES, tmp1, - add_binary(TIMES, terms[t].getOp2(), - add_binary(POWER, terms[t].getOp1(), - add_binary(MINUS, terms[t].getOp2(), one)))); - res = add_binary(PLUS, s1, s2); + int s1 = add_binary(code_t::TIMES, tmp2, + add_binary(code_t::TIMES, t, + add_unary(code_t::LOG, terms[t].getOp1()))); + int s2 = add_binary(code_t::TIMES, tmp1, + add_binary(code_t::TIMES, terms[t].getOp2(), + add_binary(code_t::POWER, terms[t].getOp1(), + add_binary(code_t::MINUS, terms[t].getOp2(), one)))); + res = add_binary(code_t::PLUS, s1, s2); break; } - case NONE: + case code_t::NONE: break; } @@ -336,7 +327,7 @@ OperationTree::add_substitution(int t, const map &subst, // return substitution of t if it is in the map auto it = subst.find(t); if (subst.end() != it) - return (*it).second; + return it->second; int nary = otree.terms[t].nary(); if (nary == 2) @@ -391,7 +382,7 @@ void OperationTree::register_derivative(int t, int v, int tder) { // todo: might check that the insert inserts a new pair - derivatives[t].insert(_Tderivmap::value_type(v, tder)); + derivatives[t].emplace(v, tder); } unordered_set @@ -416,9 +407,7 @@ OperationTree::select_terms(int t, const opselector &sel, unordered_set &su select_terms(op.getOp2(), sel, subterms); } else if (op.nary() == 1) - { - select_terms(op.getOp1(), sel, subterms); - } + select_terms(op.getOp1(), sel, subterms); } unordered_set @@ -473,23 +462,23 @@ OperationTree::forget_derivative_maps() } void -OperationTree::print_operation_tree(int t, FILE *fd, OperationFormatter &f) const +OperationTree::print_operation_tree(int t, std::ostream &os, OperationFormatter &f) const { - f.format(terms[t], t, fd); + f.format(terms[t], t, os); } void OperationTree::print_operation(int t) const { DefaultOperationFormatter dof(*this); - print_operation_tree(t, stdout, dof); + print_operation_tree(t, std::cout, dof); } void OperationTree::update_nul_incidence_after_nularify(int t) { unordered_set updated; - for (int tnode = num_constants; tnode < (int) terms.size(); tnode++) + for (int tnode = num_constants; tnode < static_cast(terms.size()); tnode++) { const Operation &op = terms[tnode]; if (op.nary() == 2) @@ -535,12 +524,12 @@ OperationTree::update_nul_incidence_after_nularify(int t) EvalTree::EvalTree(const OperationTree &ot, int last) : otree(ot), - values(new double[(last == -1) ? ot.terms.size() : last+1]), - flags(new bool[(last == -1) ? ot.terms.size() : last+1]), + values(std::make_unique((last == -1) ? ot.terms.size() : last+1)), + flags(std::make_unique((last == -1) ? ot.terms.size() : last+1)), last_operation((last == -1) ? ot.terms.size()-1 : last) { if (last_operation < OperationTree::num_constants-1 - || last_operation > (int) ot.terms.size()-1) + || last_operation > static_cast(ot.terms.size())-1) throw ogu::Exception(__FILE__, __LINE__, "Wrong last in EvalTree constructor."); @@ -594,23 +583,23 @@ EvalTree::eval(int t) { double r1 = eval(op.getOp1()); double res; - if (op.getCode() == UMINUS) + if (op.getCode() == code_t::UMINUS) res = -r1; - else if (op.getCode() == LOG) + else if (op.getCode() == code_t::LOG) res = log(r1); - else if (op.getCode() == EXP) + else if (op.getCode() == code_t::EXP) res = exp(r1); - else if (op.getCode() == SIN) + else if (op.getCode() == code_t::SIN) res = sin(r1); - else if (op.getCode() == COS) + else if (op.getCode() == code_t::COS) res = cos(r1); - else if (op.getCode() == TAN) + else if (op.getCode() == code_t::TAN) res = tan(r1); - else if (op.getCode() == SQRT) + else if (op.getCode() == code_t::SQRT) res = sqrt(r1); - else if (op.getCode() == ERF) + else if (op.getCode() == code_t::ERF) res = erf(r1); - else if (op.getCode() == ERFC) + else if (op.getCode() == code_t::ERFC) res = erfc(r1); else { @@ -624,19 +613,19 @@ EvalTree::eval(int t) else if (op.nary() == 2) { double res; - if (op.getCode() == PLUS) + if (op.getCode() == code_t::PLUS) { double r1 = eval(op.getOp1()); double r2 = eval(op.getOp2()); res = r1 + r2; } - else if (op.getCode() == MINUS) + else if (op.getCode() == code_t::MINUS) { double r1 = eval(op.getOp1()); double r2 = eval(op.getOp2()); res = r1 - r2; } - else if (op.getCode() == TIMES) + else if (op.getCode() == code_t::TIMES) { // pickup less complex formula first unsigned int nul1 = otree.nulary_of_term(op.getOp1()).size(); @@ -664,7 +653,7 @@ EvalTree::eval(int t) } } } - else if (op.getCode() == DIVIDE) + else if (op.getCode() == code_t::DIVIDE) { double r1 = eval(op.getOp1()); if (r1 == 0) @@ -675,7 +664,7 @@ EvalTree::eval(int t) res = r1 / r2; } } - else if (op.getCode() == POWER) + else if (op.getCode() == code_t::POWER) { // suppose that more complex is the first op in average double r2 = eval(op.getOp2()); @@ -729,7 +718,7 @@ EvalTree::print() const } void -DefaultOperationFormatter::format(const Operation &op, int t, FILE *fd) +DefaultOperationFormatter::format(const Operation &op, int t, std::ostream &os) { // add to the stop_set if (stop_set.end() == stop_set.find(t)) @@ -745,68 +734,66 @@ DefaultOperationFormatter::format(const Operation &op, int t, FILE *fd) int t2 = op.getOp2(); const Operation &op2 = otree.terms[t2]; if (op1.nary() > 0) - format(op1, t1, fd); + format(op1, t1, os); if (op2.nary() > 0) - format(op2, t2, fd); + format(op2, t2, os); } if (op.nary() == 1) { int t1 = op.getOp1(); const Operation &op1 = otree.terms[t1]; if (op1.nary() > 0) - format(op1, t1, fd); + format(op1, t1, os); } // print 'term =' - format_term(t, fd); - fprintf(fd, " = "); + format_term(t, os); + os << " = "; if (op.nary() == 0) - { - format_nulary(t, fd); - } + format_nulary(t, os); else if (op.nary() == 1) { int t1 = op.getOp1(); const Operation &op1 = otree.terms[t1]; - const char *opname = "unknown"; + std::string opname = "unknown"; switch (op.getCode()) { - case UMINUS: + case code_t::UMINUS: opname = "-"; break; - case LOG: + case code_t::LOG: opname = "log"; break; - case EXP: + case code_t::EXP: opname = "exp"; break; - case SIN: + case code_t::SIN: opname = "sin"; break; - case COS: + case code_t::COS: opname = "cos"; break; - case TAN: + case code_t::TAN: opname = "tan"; break; - case SQRT: + case code_t::SQRT: opname = "sqrt"; break; - case ERF: + case code_t::ERF: opname = "erf"; break; - case ERFC: + case code_t::ERFC: opname = "erfc"; break; default: break; } - fprintf(fd, "%s(", opname); + os << opname << '('; if (op1.nary() == 0) - format_nulary(t1, fd); + format_nulary(t1, os); else - format_term(t1, fd); - fprintf(fd, ")"); + format_term(t1, os); + os << ")"; } else { @@ -814,65 +801,64 @@ DefaultOperationFormatter::format(const Operation &op, int t, FILE *fd) const Operation &op1 = otree.terms[t1]; int t2 = op.getOp2(); const Operation &op2 = otree.terms[t2]; - const char *opname = "unknown"; + std::string opname = "unknown"; switch (op.getCode()) { - case PLUS: + case code_t::PLUS: opname = "+"; break; - case MINUS: + case code_t::MINUS: opname = "-"; break; - case TIMES: + case code_t::TIMES: opname = "*"; break; - case DIVIDE: + case code_t::DIVIDE: opname = "/"; break; - case POWER: + case code_t::POWER: opname = "^"; break; default: break; } if (op1.nary() == 0) - format_nulary(t1, fd); + format_nulary(t1, os); else - format_term(t1, fd); - fprintf(fd, " %s ", opname); + format_term(t1, os); + os << ' ' << opname << ' '; if (op2.nary() == 0) - format_nulary(t2, fd); + format_nulary(t2, os); else - format_term(t2, fd); + format_term(t2, os); } - print_delim(fd); - + print_delim(os); } void -DefaultOperationFormatter::format_term(int t, FILE *fd) const +DefaultOperationFormatter::format_term(int t, std::ostream &os) const { - fprintf(fd, "$%d", t); + os << '$' << t; } void -DefaultOperationFormatter::format_nulary(int t, FILE *fd) const +DefaultOperationFormatter::format_nulary(int t, std::ostream &os) const { if (t == OperationTree::zero) - fprintf(fd, "0"); + os << '0'; else if (t == OperationTree::one) - fprintf(fd, "1"); + os << '1'; else if (t == OperationTree::nan) - fprintf(fd, "NaN"); + os << "NaN"; else - fprintf(fd, "$%d", t); + os << '$' << t; } void -DefaultOperationFormatter::print_delim(FILE *fd) const +DefaultOperationFormatter::print_delim(std::ostream &os) const { - fprintf(fd, ";\n"); + os << ";\n"; } std::string @@ -907,31 +893,31 @@ OperationStringConvertor::convert(const Operation &op, int t) const const char *opname = "unknown"; switch (op.getCode()) { - case UMINUS: + case code_t::UMINUS: opname = "-"; break; - case LOG: + case code_t::LOG: opname = "log"; break; - case EXP: + case code_t::EXP: opname = "exp"; break; - case SIN: + case code_t::SIN: opname = "sin"; break; - case COS: + case code_t::COS: opname = "cos"; break; - case TAN: + case code_t::TAN: opname = "tan"; break; - case SQRT: + case code_t::SQRT: opname = "sqrt"; break; - case ERF: + case code_t::ERF: opname = "erf"; break; - case ERFC: + case code_t::ERFC: opname = "erfc"; break; default: @@ -949,19 +935,19 @@ OperationStringConvertor::convert(const Operation &op, int t) const const char *opname = "unknown"; switch (op.getCode()) { - case PLUS: + case code_t::PLUS: opname = "+"; break; - case MINUS: + case code_t::MINUS: opname = "-"; break; - case TIMES: + case code_t::TIMES: opname = "*"; break; - case DIVIDE: + case code_t::DIVIDE: opname = "/"; break; - case POWER: + case code_t::POWER: opname = "^"; break; default: @@ -970,15 +956,15 @@ OperationStringConvertor::convert(const Operation &op, int t) const // decide about parenthesis bool op1_par = true; bool op2_par = true; - if (op.getCode() == PLUS) + if (op.getCode() == code_t::PLUS) { op1_par = false; op2_par = false; } - else if (op.getCode() == MINUS) + else if (op.getCode() == code_t::MINUS) { op1_par = false; - if (op2.getCode() != MINUS && op2.getCode() != PLUS) + if (op2.getCode() != code_t::MINUS && op2.getCode() != code_t::PLUS) op2_par = false; } else diff --git a/dynare++/parser/cc/tree.hh b/dynare++/parser/cc/tree.hh index 9cbbdcc7c..7b466f669 100644 --- a/dynare++/parser/cc/tree.hh +++ b/dynare++/parser/cc/tree.hh @@ -8,11 +8,11 @@ #include #include #include -#include +#include +#include namespace ogp { - using std::unordered_set; using std::unordered_map; using std::vector; @@ -24,15 +24,15 @@ namespace ogp * codes, he should update the code of #OperationTree::add_unary, * #OperationTree::add_binary, and of course * #OperationTree::add_derivative. */ - enum code_t {NONE, UMINUS, LOG, EXP, SIN, COS, TAN, SQRT, ERF, - ERFC, PLUS, MINUS, TIMES, DIVIDE, POWER}; + enum class code_t {NONE, UMINUS, LOG, EXP, SIN, COS, TAN, SQRT, ERF, + ERFC, PLUS, MINUS, TIMES, DIVIDE, POWER}; /** Class representing a nulary, unary, or binary operation. */ class Operation { protected: /** Code of the operation. */ - code_t code{NONE}; + code_t code{code_t::NONE}; /** First operand. If none, then it is -1. */ int op1{-1}; /** Second operand. If none, then it is -1. */ @@ -50,18 +50,12 @@ namespace ogp { } /** Constructs a nulary operation. */ - Operation() - - = default; + Operation() = default; /** A copy constructor. */ - Operation(const Operation &op) - - = default; + Operation(const Operation &op) = default; /** Operator =. */ - Operation & - operator=(const Operation &op) - = default; + Operation &operator=(const Operation &op) = default; /** Operator ==. */ bool operator==(const Operation &op) const @@ -86,7 +80,7 @@ namespace ogp size_t hashval() const { - return op2+1 + (op1+1)^15 + code^30; + return op2+1 + (op1+1)^15 + static_cast(code)^30; } code_t @@ -104,7 +98,6 @@ namespace ogp { return op2; } - }; /** This struct is a predicate for ordering of the operations in @@ -133,8 +126,7 @@ namespace ogp struct opselector { virtual bool operator()(int t) const = 0; - virtual ~opselector() - = default; + virtual ~opselector() = default; }; /** Forward declaration of OperationFormatter. */ @@ -182,7 +174,6 @@ namespace ogp /** This defines a type for a map mapping the unary and binary * operations to their indices. */ using _Topmap = unordered_map; - using _Topval = _Topmap::value_type; /** This is the map mapping the unary and binary operations to * the indices of the terms.*/ @@ -205,25 +196,18 @@ namespace ogp /** The tree index of the last nulary term. */ int last_nulary; public: - /** This is a number of constants set in the following - * enum. This number reserves space in a vector of terms for - * the constants. */ - static const int num_constants = 4; /** Enumeration for special terms. We need zero, one, nan and * 2/pi. These will be always first four terms having indices * zero, one and two, three. If adding anything to this - * enumeration, make sure you have updated num_constants above.*/ - enum {zero = 0, one = 1, nan = 2, two_over_pi = 3}; + * enumeration, make sure ‘num_constants’ remains the last one.*/ + enum {zero, one, nan, two_over_pi, num_constants}; /** The unique constructor which initializes the object to * contain only zero, one and nan and two_over_pi.*/ OperationTree(); /** Copy constructor. */ - OperationTree(const OperationTree &ot) - - - = default; + OperationTree(const OperationTree &ot) = default; /** Add a nulary operation. The caller is responsible for not * inserting two semantically equivalent nulary operations. @@ -323,7 +307,7 @@ namespace ogp /** This outputs the operation to the given file descriptor * using the given OperationFormatter. */ - void print_operation_tree(int t, FILE *fd, OperationFormatter &f) const; + void print_operation_tree(int t, std::ostream &os, OperationFormatter &f) const; /** Debug print of a given operation: */ void print_operation(int t) const; @@ -339,7 +323,7 @@ namespace ogp int get_num_op() const { - return (int) (terms.size()); + return static_cast(terms.size()); } private: /** This registers a calculated derivative of the term in the @@ -391,9 +375,9 @@ namespace ogp * are done. */ const OperationTree &otree; /** The array of values. */ - double *const values; + const std::unique_ptr values; /** The array of evaluation flags. */ - bool *const flags; + const std::unique_ptr flags; /** The index of last operation in the EvalTree. Length of * values and flags will be then last_operation+1. */ int last_operation; @@ -404,10 +388,7 @@ namespace ogp * (included). */ EvalTree(const OperationTree &otree, int last = -1); EvalTree(const EvalTree &) = delete; - virtual ~EvalTree() - { - delete [] values; delete [] flags; - } + virtual ~EvalTree() = default; /** Set evaluation flag to all terms (besides the first * special terms) to false. */ void reset_all(); @@ -431,8 +412,7 @@ namespace ogp { public: /** Empty virtual destructor. */ - virtual ~OperationFormatter() - = default; + virtual ~OperationFormatter() = default; /** Print the formatted operation op with a given tree index t * to a given descriptor. (See class OperationTree to know * what is a tree index.) This prints all the tree. This @@ -441,7 +421,7 @@ namespace ogp * term, the right hand side is a string representation of the * operation (which will refer to other string representation * of subterms). */ - virtual void format(const Operation &op, int t, FILE *fd) = 0; + virtual void format(const Operation &op, int t, std::ostream &os) = 0; }; /** The default formatter formats the formulas with a usual syntax @@ -460,23 +440,22 @@ namespace ogp { } /** Format the operation with the default syntax. */ - void format(const Operation &op, int t, FILE *fd) override; + void format(const Operation &op, int t, std::ostream &os) override; /** This prints a string represenation of the given term, for * example 'tmp10' for term 10. In this implementation it * prints $10. */ - virtual void format_term(int t, FILE *fd) const; + virtual void format_term(int t, std::ostream &os) const; /** Print a string representation of the nulary term. */ - virtual void format_nulary(int t, FILE *fd) const; + virtual void format_nulary(int t, std::ostream &os) const; /** Print a delimiter between two statements. By default it is * "\n". */ - virtual void print_delim(FILE *fd) const; + virtual void print_delim(std::ostream &os) const; }; class NularyStringConvertor { public: - virtual ~NularyStringConvertor() - = default; + virtual ~NularyStringConvertor() = default; /** Return the string representation of the atom with the tree * index t. */ virtual std::string convert(int t) const = 0; @@ -494,8 +473,7 @@ namespace ogp { } /** Empty virtual destructor. */ - virtual ~OperationStringConvertor() - = default; + virtual ~OperationStringConvertor() = default; /** Convert the operation to the string mathematical * representation. This does not write any equation, just * returns a string representation of the formula. */ diff --git a/dynare++/src/dynare_model.cc b/dynare++/src/dynare_model.cc index fa53e822b..b64e1ca23 100644 --- a/dynare++/src/dynare_model.cc +++ b/dynare++/src/dynare_model.cc @@ -14,6 +14,9 @@ #include #include #include +#include +#include +#include using namespace ogdyn; @@ -117,7 +120,7 @@ DynareModel::print() const { int tf = eqs.formula(i); printf("formula %d:\n", tf); - eqs.getTree().print_operation_tree(tf, stdout, dof); + eqs.getTree().print_operation_tree(tf, std::cout, dof); } } @@ -588,43 +591,40 @@ extern ogp::location_type dynglob_lloc; void DynareParser::parse_glob(int length, const char *stream) { - auto *buffer = new char[length+2]; - strncpy(buffer, stream, length); + auto buffer = std::make_unique(length+2); + std::copy_n(stream, length, buffer.get()); buffer[length] = '\0'; buffer[length+1] = '\0'; - void *p = dynglob__scan_buffer(buffer, (unsigned int) length+2); + void *p = dynglob__scan_buffer(buffer.get(), static_cast(length)+2); dynare_parser = this; dynglob_parse(); - delete [] buffer; dynglob__destroy_buffer(p); } int DynareParser::parse_order(int len, const char *str) { - auto *buf = new char[len+1]; - strncpy(buf, str, len); + auto buf = std::make_unique(len+1); + std::copy_n(str, len, buf.get()); buf[len] = '\0'; int res; - sscanf(buf, "%d", &res); - delete [] buf; + sscanf(buf.get(), "%d", &res); return res; } int DynareParser::parse_pldiscount(int len, const char *str) { - auto *buf = new char[len+1]; - strncpy(buf, str, len); + auto buf = std::make_unique(len+1); + std::copy_n(str, len, buf.get()); buf[len] = '\0'; - if (!atoms.is_type(buf, DynareDynamicAtoms::param)) - throw ogp::ParserException(std::string("Name ") + buf + " is not a parameter", 0); + if (!atoms.is_type(buf.get(), DynareDynamicAtoms::param)) + throw ogp::ParserException(std::string("Name ") + buf.get() + " is not a parameter", 0); - int t = atoms.index(buf, 0); + int t = atoms.index(buf.get(), 0); if (t == -1) - t = eqs.add_nulary(buf); + t = eqs.add_nulary(buf.get()); - delete [] buf; return t; } @@ -712,14 +712,14 @@ NLSelector::operator()(int t) const } else if (nary == 1) { - if (op.getCode() == ogp::UMINUS) + if (op.getCode() == ogp::code_t::UMINUS) return false; else return true; } else { - if (op.getCode() == ogp::TIMES) + if (op.getCode() == ogp::code_t::TIMES) // if at least one operand is constant, than the TIMES is linear if (model.is_constant_term(op.getOp1()) || model.is_constant_term(op.getOp2())) @@ -727,11 +727,11 @@ NLSelector::operator()(int t) const else return true; // both PLUS and MINUS are linear - if (op.getCode() == ogp::PLUS - || op.getCode() == ogp::MINUS) + if (op.getCode() == ogp::code_t::PLUS + || op.getCode() == ogp::code_t::MINUS) return false; // POWER is linear if exponent or base is 0 or one - if (op.getCode() == ogp::POWER + if (op.getCode() == ogp::code_t::POWER && (op.getOp1() == ogp::OperationTree::zero || op.getOp1() == ogp::OperationTree::one || op.getOp2() == ogp::OperationTree::zero @@ -741,7 +741,7 @@ NLSelector::operator()(int t) const return true; // DIVIDE is linear if the denominator is constant, or if // the nominator is zero - if (op.getCode() == ogp::DIVIDE + if (op.getCode() == ogp::code_t::DIVIDE && (op.getOp1() == ogp::OperationTree::zero || model.is_constant_term(op.getOp2()))) return false; @@ -792,23 +792,23 @@ DynareSPModel::DynareSPModel(const char **endo, int num_endo, } void -ModelSSWriter::write_der0(FILE *fd) +ModelSSWriter::write_der0(std::ostream &os) { - write_der0_preamble(fd); - write_atom_assignment(fd); + write_der0_preamble(os); + write_atom_assignment(os); stop_set.clear(); for (int fi = 0; fi < model.eqs.nformulas(); fi++) - otree.print_operation_tree(model.eqs.formula(fi), fd, *this); + otree.print_operation_tree(model.eqs.formula(fi), os, *this); - write_der0_assignment(fd); + write_der0_assignment(os); } void -ModelSSWriter::write_der1(FILE *fd) +ModelSSWriter::write_der1(std::ostream &os) { - write_der1_preamble(fd); - write_atom_assignment(fd); + write_der1_preamble(os); + write_atom_assignment(os); stop_set.clear(); @@ -821,11 +821,11 @@ ModelSSWriter::write_der1(FILE *fd) { int t = fder.derivative(ogp::FoldMultiIndex(variables.size(), 1, j)); if (t > 0) - otree.print_operation_tree(t, fd, *this); + otree.print_operation_tree(t, os, *this); } } - write_der1_assignment(fd); + write_der1_assignment(os); } MatlabSSWriter::MatlabSSWriter(const DynareModel &dm, const char *idd) @@ -835,115 +835,102 @@ MatlabSSWriter::MatlabSSWriter(const DynareModel &dm, const char *idd) } void -MatlabSSWriter::write_der0_preamble(FILE *fd) const +MatlabSSWriter::write_der0_preamble(std::ostream &os) const { - fprintf(fd, - "%% Usage:\n" - "%% out = %s_f(params, y)\n" - "%% where\n" - "%% out is a (%d,1) column vector of the residuals\n" - "%% of the static system\n", - id, model.getAtoms().ny()); - write_common1_preamble(fd); - fprintf(fd, - "function out = %s_f(params, y)\n", id); - write_common2_preamble(fd); + os << "% Usage:\n" + << "% out = " << id << "_f(params, y)\n" + << "% where\n" + << "% out is a (" << model.getAtoms().ny() << ",1) column vector of the residuals\n" + << "% of the static system\n"; + write_common1_preamble(os); + os << "function out = " << id << "_f(params, y)\n"; + write_common2_preamble(os); } void -MatlabSSWriter::write_der1_preamble(FILE *fd) const +MatlabSSWriter::write_der1_preamble(std::ostream &os) const { - fprintf(fd, - "%% Usage:\n" - "%% out = %s_ff(params, y)\n" - "%% where\n" - "%% out is a (%d,%d) matrix of the first order\n" - "%% derivatives of the static system residuals\n" - "%% columns correspond to endo variables in\n" - "%% the ordering as declared\n", - id, model.getAtoms().ny(), model.getAtoms().ny()); - write_common1_preamble(fd); - fprintf(fd, - "function out = %s_ff(params, y)\n", id); - write_common2_preamble(fd); + os << "% Usage:\n" + << "% out = " << id << "_ff(params, y)\n" + << "% where\n" + << "% out is a (" << model.getAtoms().ny() << "," << model.getAtoms().ny() << ") matrix of the first order\n" + << "% derivatives of the static system residuals\n" + << "% columns correspond to endo variables in\n" + << "% the ordering as declared\n"; + write_common1_preamble(os); + os << "function out = " << id << "_ff(params, y)\n"; + write_common2_preamble(os); } void -MatlabSSWriter::write_common1_preamble(FILE *fd) const +MatlabSSWriter::write_common1_preamble(std::ostream &os) const { - fprintf(fd, - "%% params is a (%d,1) vector of parameter values\n" - "%% in the ordering as declared\n" - "%% y is a (%d,1) vector of endogenous variables\n" - "%% in the ordering as declared\n" - "%%\n" - "%% Created by Dynare++ v. %s\n", model.getAtoms().np(), - model.getAtoms().ny(), DYNVERSION); + os << "% params is a (" << model.getAtoms().np() << ",1) vector of parameter values\n" + << "% in the ordering as declared\n" + << "% y is a (" << model.getAtoms().ny() << ",1) vector of endogenous variables\n" + << "% in the ordering as declared\n" + << "%\n" + << "% Created by Dynare++ v. " << DYNVERSION << "\n"; // write ordering of parameters - fprintf(fd, "\n%% params ordering\n%% =====================\n"); + os << "\n% params ordering\n% =====================\n"; for (auto parname : model.getAtoms().get_params()) - { - fprintf(fd, "%% %s\n", parname); - } + os << "% " << parname << "\n"; + // write endogenous variables - fprintf(fd, "%%\n%% y ordering\n%% =====================\n"); + os << "%\n% y ordering\n% =====================\n"; for (auto endoname : model.getAtoms().get_endovars()) - { - fprintf(fd, "%% %s\n", endoname); - } - fprintf(fd, "\n"); + os << "% " << endoname << "\n"; + os << "\n"; } void -MatlabSSWriter::write_common2_preamble(FILE *fd) const +MatlabSSWriter::write_common2_preamble(std::ostream &os) const { - fprintf(fd, "if size(y) ~= [%d,1]\n\terror('Wrong size of y, must be [%d,1]');\nend\n", - model.getAtoms().ny(), model.getAtoms().ny()); - fprintf(fd, "if size(params) ~= [%d,1]\n\terror('Wrong size of params, must be [%d,1]');\nend\n\n", - model.getAtoms().np(), model.getAtoms().np()); + os << "if size(y) ~= [" << model.getAtoms().ny() << ",1]\n" + << "\terror('Wrong size of y, must be [" << model.getAtoms().ny() << ",1]');\nend\n" + << "if size(params) ~= [" << model.getAtoms().np() << ",1]\n" + << "\terror('Wrong size of params, must be [" << model.getAtoms().np() << ",1]');\nend\n\n"; } void -MatlabSSWriter::write_atom_assignment(FILE *fd) const +MatlabSSWriter::write_atom_assignment(std::ostream &os) const { // write OperationTree::num_constants - fprintf(fd, "%% hardwired constants\n"); + os << "% hardwired constants\n"; ogp::EvalTree etree(model.getParser().getTree(), ogp::OperationTree::num_constants-1); for (int i = 0; i < ogp::OperationTree::num_constants; i++) { - format_nulary(i, fd); + format_nulary(i, os); double g = etree.eval(i); if (std::isnan(g)) - fprintf(fd, " = NaN;\n"); + os << " = NaN;\n"; else - fprintf(fd, " = %12.8g;\n", etree.eval(i)); + os << " = " << std::defaultfloat << std::setprecision(8) << etree.eval(i) << ";\n"; } // write numerical constants - fprintf(fd, "%% numerical constants\n"); + os << "% numerical constants\n"; const ogp::Constants::Tconstantmap &cmap = model.getAtoms().get_constantmap(); for (auto it : cmap) { - format_nulary(it.first, fd); - fprintf(fd, " = %12.8g;\n", it.second); + format_nulary(it.first, os); + os << " = " << std::defaultfloat << std::setprecision(8) << it.second << ";\n"; } // write parameters - fprintf(fd, "%% parameter values\n"); + os << "% parameter values\n"; for (unsigned int ip = 0; ip < model.getAtoms().get_params().size(); ip++) { const char *parname = model.getAtoms().get_params()[ip]; int t = model.getAtoms().index(parname, 0); if (t == -1) - { - fprintf(fd, "%% %s not used in the model\n", parname); - } + os << "% " << parname << " not used in the model\n"; else { - format_nulary(t, fd); - fprintf(fd, " = params(%d); %% %s\n", ip+1, parname); + format_nulary(t, os); + os << " = params(" << ip+1 << "); % " << parname << "\n"; } } // write exogenous variables - fprintf(fd, "%% exogenous variables to zeros\n"); + os << "% exogenous variables to zeros\n"; for (unsigned int ie = 0; ie < model.getAtoms().get_exovars().size(); ie++) { const char *exoname = model.getAtoms().get_exovars()[ie]; @@ -952,8 +939,8 @@ MatlabSSWriter::write_atom_assignment(FILE *fd) const const ogp::DynamicAtoms::Tlagmap &lmap = model.getAtoms().lagmap(exoname); for (auto it : lmap) { - format_nulary(it.second, fd); - fprintf(fd, " = 0.0; %% %s\n", exoname); + format_nulary(it.second, os); + os << " = 0.0; % " << exoname << "\n"; } } catch (const ogu::Exception &e) @@ -962,43 +949,43 @@ MatlabSSWriter::write_atom_assignment(FILE *fd) const } } // write endogenous variables - fprintf(fd, "%% endogenous variables to y\n"); + os << "% endogenous variables to y\n"; for (unsigned int ie = 0; ie < model.getAtoms().get_endovars().size(); ie++) { const char *endoname = model.getAtoms().get_endovars()[ie]; const ogp::DynamicAtoms::Tlagmap &lmap = model.getAtoms().lagmap(endoname); for (auto it : lmap) { - format_nulary(it.second, fd); - fprintf(fd, " = y(%d); %% %s\n", ie+1, endoname); + format_nulary(it.second, os); + os << " = y(" << ie+1 << "); % " << endoname << "\n"; } } - fprintf(fd, "\n"); + os << "\n"; } void -MatlabSSWriter::write_der0_assignment(FILE *fd) const +MatlabSSWriter::write_der0_assignment(std::ostream &os) const { // initialize out variable - fprintf(fd, "%% setting the output variable\n"); - fprintf(fd, "out = zeros(%d, 1);\n", model.getParser().nformulas()); + os << "% setting the output variable\n" + << "out = zeros(" << model.getParser().nformulas() << ", 1);\n"; // fill out with the terms for (int i = 0; i < model.getParser().nformulas(); i++) { - fprintf(fd, "out(%d) = ", i+1); - format_term(model.getParser().formula(i), fd); - fprintf(fd, ";\n"); + os << "out(" << i+1 << ") = "; + format_term(model.getParser().formula(i), os); + os << ";\n"; } } void -MatlabSSWriter::write_der1_assignment(FILE *fd) const +MatlabSSWriter::write_der1_assignment(std::ostream &os) const { // initialize out variable - fprintf(fd, "%% setting the output variable\n"); - fprintf(fd, "out = zeros(%d, %d);\n", model.getParser().nformulas(), model.getAtoms().ny()); + os << "% setting the output variable\n"; + os << "out = zeros(" << model.getParser().nformulas() << ", " << model.getAtoms().ny() << ");\n"; // fill out with the terms const vector &variables = model.getAtoms().variables(); @@ -1014,48 +1001,48 @@ MatlabSSWriter::write_der1_assignment(FILE *fd) const int t = fder.derivative(ogp::FoldMultiIndex(variables.size(), 1, j)); if (t != ogp::OperationTree::zero) { - fprintf(fd, "out(%d,%d) = out(%d,%d) + ", i+1, yi+1, i+1, yi+1); - format_term(t, fd); - fprintf(fd, "; %% %s(%d)\n", name, model.getAtoms().lead(tvar)); + os << "out(" << i+1 << "," << yi+1 << ") = out("<< i+1 << "," << yi+1 << ") + "; + format_term(t, os); + os << "; % " << name << "(" << model.getAtoms().lead(tvar) << ")\n"; } } } } void -MatlabSSWriter::format_term(int t, FILE *fd) const +MatlabSSWriter::format_term(int t, std::ostream &os) const { - fprintf(fd, "t%d", t); + os << 't' << t; } void -MatlabSSWriter::format_nulary(int t, FILE *fd) const +MatlabSSWriter::format_nulary(int t, std::ostream &os) const { - fprintf(fd, "a%d", t); + os << 'a' << t; } void -DebugOperationFormatter::format_nulary(int t, FILE *fd) const +DebugOperationFormatter::format_nulary(int t, std::ostream &os) const { const DynareDynamicAtoms &a = model.getAtoms(); if (t == ogp::OperationTree::zero) - fprintf(fd, "0"); + os << '0'; else if (t == ogp::OperationTree::one) - fprintf(fd, "1"); + os << '1'; else if (t == ogp::OperationTree::nan) - fprintf(fd, "NaN"); + os << "NaN"; else if (t == ogp::OperationTree::two_over_pi) - fprintf(fd, "2/sqrt(PI)"); + os << "2/sqrt(PI)"; else if (a.is_constant(t)) - fprintf(fd, "%g", a.get_constant_value(t)); + os << a.get_constant_value(t); else { int ll = a.lead(t); - const char *name = a.name(t); + std::string name{a.name(t)}; if (ll == 0) - fprintf(fd, "%s", name); + os << name; else - fprintf(fd, "%s(%d)", name, ll); + os << name << '(' << ll << ')'; } } diff --git a/dynare++/src/dynare_model.hh b/dynare++/src/dynare_model.hh index 74ad43a98..35f31b288 100644 --- a/dynare++/src/dynare_model.hh +++ b/dynare++/src/dynare_model.hh @@ -14,6 +14,7 @@ #include #include +#include namespace ogdyn { @@ -405,18 +406,18 @@ namespace ogdyn * virtual methods for writing a preamble, then assignment of * atoms, and then assignment for resulting object. These are * language dependent and are implemented in the subclass. */ - void write_der0(FILE *fd); + void write_der0(std::ostream &os); /** This writes the evaluation of the first order derivative of the system. It calls pure virtual methods for writing a preamble, assignment, and assignemnt of the resulting objects. */ - void write_der1(FILE *fd); + void write_der1(std::ostream &os); protected: - virtual void write_der0_preamble(FILE *fd) const = 0; - virtual void write_der1_preamble(FILE *fd) const = 0; - virtual void write_atom_assignment(FILE *fd) const = 0; - virtual void write_der0_assignment(FILE *fd) const = 0; - virtual void write_der1_assignment(FILE *fd) const = 0; + virtual void write_der0_preamble(std::ostream &os) const = 0; + virtual void write_der1_preamble(std::ostream &os) const = 0; + virtual void write_atom_assignment(std::ostream &os) const = 0; + virtual void write_der0_assignment(std::ostream &os) const = 0; + virtual void write_der1_assignment(std::ostream &os) const = 0; }; class MatlabSSWriter : public ModelSSWriter @@ -432,24 +433,24 @@ namespace ogdyn } protected: // from ModelSSWriter - void write_der0_preamble(FILE *fd) const override; - void write_der1_preamble(FILE *fd) const override; + void write_der0_preamble(std::ostream &os) const override; + void write_der1_preamble(std::ostream &os) const override; /** This writes atom assignments. We have four kinds of atoms * set here: endogenous vars coming from one parameter, * parameter values given by the second parameter, constants, * and the OperationTree::num_constants hardwired constants in * ogp::OperationTree. */ - void write_atom_assignment(FILE *fd) const override; - void write_der0_assignment(FILE *fd) const override; - void write_der1_assignment(FILE *fd) const override; + void write_atom_assignment(std::ostream &os) const override; + void write_der0_assignment(std::ostream &os) const override; + void write_der1_assignment(std::ostream &os) const override; /** This prints t10 for t=10. */ - void format_term(int t, FILE *fd) const override; + void format_term(int t, std::ostream &os) const override; /** This prints a10 for t=10. The atoms a10 are supposed to be * set by write_atom_assignments(). */ - void format_nulary(int t, FILE *fd) const override; + void format_nulary(int t, std::ostream &os) const override; private: - void write_common1_preamble(FILE *fd) const; - void write_common2_preamble(FILE *fd) const; + void write_common1_preamble(std::ostream &os) const; + void write_common2_preamble(std::ostream &os) const; }; /** This class implements OperationFormatter for debugging @@ -465,7 +466,7 @@ namespace ogdyn model(m) { } - void format_nulary(int t, FILE *fd) const override; + void format_nulary(int t, std::ostream &os) const override; }; }; diff --git a/dynare++/src/forw_subst_builder.cc b/dynare++/src/forw_subst_builder.cc index f35849b96..48d69e242 100644 --- a/dynare++/src/forw_subst_builder.cc +++ b/dynare++/src/forw_subst_builder.cc @@ -63,7 +63,7 @@ ForwSubstBuilder::substitute_for_term(int t, int i, int j) info.num_aux_variables++; const char *ss = model.atoms.get_name_storage().query(name); int auxt = model.eqs.add_nulary(name); - model.eqs.add_formula(model.eqs.add_binary(ogp::MINUS, auxt, lagt)); + model.eqs.add_formula(model.eqs.add_binary(ogp::code_t::MINUS, auxt, lagt)); aux_map.insert(Tsubstmap::value_type(ss, lagt)); // now add variables and equations // AUXLD_*_*_2 = AUXLD_*_*_1(+1) through @@ -80,7 +80,7 @@ ForwSubstBuilder::substitute_for_term(int t, int i, int j) ss = model.atoms.get_name_storage().query(name); auxt = model.eqs.add_nulary(name); // add AUXLD_*_*_{ll+1} = AUXLD_*_*_{ll}(+1) - model.eqs.add_formula(model.eqs.add_binary(ogp::MINUS, auxt, lastauxt_lead)); + model.eqs.add_formula(model.eqs.add_binary(ogp::code_t::MINUS, auxt, lastauxt_lead)); // add substitution to the map; todo: this // works well because in the context where // aux_map is used the timing doesn't matter, diff --git a/dynare++/src/main.cc b/dynare++/src/main.cc index 55b1a7786..f93c23996 100644 --- a/dynare++/src/main.cc +++ b/dynare++/src/main.cc @@ -11,6 +11,8 @@ #include "../kord/global_check.hh" #include "../kord/approximation.hh" +#include + int main(int argc, char **argv) { @@ -51,28 +53,29 @@ main(int argc, char **argv) irf_list_ind = ((const DynareNameList &) dynare.getExogNames()).selectIndices(params.irf_list); // write matlab files - FILE *mfd; std::string mfile1(params.basename); mfile1 += "_f.m"; - if (nullptr == (mfd = fopen(mfile1.c_str(), "w"))) + std::ofstream mfd{mfile1, std::ios::out | std::ios::trunc}; + if (mfd.fail()) { fprintf(stderr, "Couldn't open %s for writing.\n", mfile1.c_str()); exit(1); } ogdyn::MatlabSSWriter writer0(dynare.getModel(), params.basename.c_str()); writer0.write_der0(mfd); - fclose(mfd); + mfd.close(); std::string mfile2(params.basename); mfile2 += "_ff.m"; - if (nullptr == (mfd = fopen(mfile2.c_str(), "w"))) + mfd.open(mfile2, std::ios::out | std::ios::trunc); + if (mfd.fail()) { fprintf(stderr, "Couldn't open %s for writing.\n", mfile2.c_str()); exit(1); } ogdyn::MatlabSSWriter writer1(dynare.getModel(), params.basename.c_str()); writer1.write_der1(mfd); - fclose(mfd); + mfd.close(); // open mat file std::string matfile(params.basename); @@ -206,7 +209,7 @@ main(int argc, char **argv) } catch (const ogp::ParserException &e) { - printf("Caught parser exception: %s\n", e.message()); + std::cout << "Caught parser exception: " << e.message() << std::endl; return 255; } diff --git a/dynare++/src/planner_builder.cc b/dynare++/src/planner_builder.cc index 696c18baa..01b22d79c 100644 --- a/dynare++/src/planner_builder.cc +++ b/dynare++/src/planner_builder.cc @@ -188,11 +188,11 @@ PlannerBuilder::beta_multiply_b() { int beta_pow = ogp::OperationTree::one; for (int ll = 0; ll >= minlag; ll--, - beta_pow = model.eqs.add_binary(ogp::TIMES, beta_pow, tbeta)) + beta_pow = model.eqs.add_binary(ogp::code_t::TIMES, beta_pow, tbeta)) for (int yi = 0; yi < diff_b.nrows(); yi++) if (diff_b(yi, ll-minlag) != ogp::OperationTree::zero) diff_b(yi, ll-minlag) - = model.eqs.add_binary(ogp::TIMES, beta_pow, diff_b(yi, ll-minlag)); + = model.eqs.add_binary(ogp::code_t::TIMES, beta_pow, diff_b(yi, ll-minlag)); } void @@ -200,21 +200,21 @@ PlannerBuilder::beta_multiply_f() { int beta_pow = ogp::OperationTree::one; for (int ll = 0; ll <= maxlead; ll++, - beta_pow = model.eqs.add_binary(ogp::DIVIDE, beta_pow, tbeta)) + beta_pow = model.eqs.add_binary(ogp::code_t::DIVIDE, beta_pow, tbeta)) for (int yi = 0; yi < diff_f.dim1(); yi++) for (int fi = 0; fi < diff_f.dim2(); fi++) if (diff_f(yi, fi, ll-minlag) != ogp::OperationTree::zero) diff_f(yi, fi, ll-minlag) - = model.eqs.add_binary(ogp::TIMES, beta_pow, diff_f(yi, fi, ll-minlag)); + = model.eqs.add_binary(ogp::code_t::TIMES, beta_pow, diff_f(yi, fi, ll-minlag)); beta_pow = ogp::OperationTree::one; for (int ll = 0; ll >= minlag; ll--, - beta_pow = model.eqs.add_binary(ogp::TIMES, beta_pow, tbeta)) + beta_pow = model.eqs.add_binary(ogp::code_t::TIMES, beta_pow, tbeta)) for (int yi = 0; yi < diff_f.dim1(); yi++) for (int fi = 0; fi < diff_f.dim2(); fi++) if (diff_f(yi, fi, ll-minlag) != ogp::OperationTree::zero) diff_f(yi, fi, ll-minlag) - = model.eqs.add_binary(ogp::TIMES, beta_pow, diff_f(yi, fi, ll-minlag)); + = model.eqs.add_binary(ogp::code_t::TIMES, beta_pow, diff_f(yi, fi, ll-minlag)); } void @@ -271,7 +271,7 @@ PlannerBuilder::lagrange_mult_f() sprintf(mult_name, "MULT%d(%d)", fset[fi], -ll); int tm = model.eqs.add_nulary(mult_name); diff_f(yi, fi, ll-minlag) - = model.eqs.add_binary(ogp::TIMES, tm, diff_f(yi, fi, ll-minlag)); + = model.eqs.add_binary(ogp::code_t::TIMES, tm, diff_f(yi, fi, ll-minlag)); } } @@ -283,10 +283,10 @@ PlannerBuilder::form_equations() { int eq = ogp::OperationTree::zero; for (int ll = minlag; ll <= 0; ll++) - eq = model.eqs.add_binary(ogp::PLUS, eq, diff_b(yi, ll-minlag)); + eq = model.eqs.add_binary(ogp::code_t::PLUS, eq, diff_b(yi, ll-minlag)); for (int fi = 0; fi < diff_f.dim2(); fi++) for (int ll = minlag; ll <= maxlead; ll++) - eq = model.eqs.add_binary(ogp::PLUS, eq, diff_f(yi, fi, ll-minlag)); + eq = model.eqs.add_binary(ogp::code_t::PLUS, eq, diff_f(yi, fi, ll-minlag)); model.eqs.add_formula(eq); } @@ -295,7 +295,7 @@ PlannerBuilder::form_equations() it != aux_map.end(); ++it) { int t = model.atoms.index((*it).first, 0); - model.eqs.add_formula(model.eqs.add_binary(ogp::MINUS, t, (*it).second)); + model.eqs.add_formula(model.eqs.add_binary(ogp::code_t::MINUS, t, (*it).second)); } }