diff --git a/dynare++/integ/src/quadrature-points.cc b/dynare++/integ/src/quadrature-points.cc index fd9589c5e..768302b34 100644 --- a/dynare++/integ/src/quadrature-points.cc +++ b/dynare++/integ/src/quadrature-points.cc @@ -29,7 +29,7 @@ struct QuadParams QuadParams(int argc, char **argv); void check_consistency() const; private: - enum {opt_max_level, opt_discard_weight, opt_vcov}; + enum class opt {max_level, discard_weight, vcov}; }; QuadParams::QuadParams(int argc, char **argv) @@ -45,9 +45,9 @@ QuadParams::QuadParams(int argc, char **argv) argc--; struct option const opts [] = { - {"max-level", required_argument, nullptr, opt_max_level}, - {"discard-weight", required_argument, nullptr, opt_discard_weight}, - {"vcov", required_argument, nullptr, opt_vcov}, + {"max-level", required_argument, nullptr, static_cast(opt::max_level)}, + {"discard-weight", required_argument, nullptr, static_cast(opt::discard_weight)}, + {"vcov", required_argument, nullptr, static_cast(opt::vcov)}, {nullptr, 0, nullptr, 0} }; @@ -55,29 +55,35 @@ QuadParams::QuadParams(int argc, char **argv) int index; while (-1 != (ret = getopt_long(argc, argv, "", opts, &index))) { - switch (ret) + if (ret == '?') { - case opt_max_level: + std::cerr << "Unknown option, ignored\n"; + continue; + } + + switch (static_cast(ret)) + { + case opt::max_level: try { - max_level = std::stoi(std::string{optarg}); + max_level = std::stoi(optarg); } catch (const std::invalid_argument &e) { std::cerr << "Couldn't parse integer " << optarg << ", ignored" << std::endl; } break; - case opt_discard_weight: + case opt::discard_weight: try { - discard_weight = std::stod(std::string{optarg}); + discard_weight = std::stod(optarg); } catch (const std::invalid_argument &e) { std::cerr << "Couldn't parse float " << optarg << ", ignored" << std::endl; } break; - case opt_vcov: + case opt::vcov: vcovname = optarg; break; } @@ -124,7 +130,7 @@ main(int argc, char **argv) // parse the vcov matrix ogp::MatrixParser mp; - mp.parse(contents.length(), contents.c_str()); + mp.parse(contents); if (mp.nrows() != mp.ncols()) throw ogu::Exception(__FILE__, __LINE__, "VCOV matrix not square"); diff --git a/dynare++/kord/decision_rule.cc b/dynare++/kord/decision_rule.cc index deee95946..ac265447c 100644 --- a/dynare++/kord/decision_rule.cc +++ b/dynare++/kord/decision_rule.cc @@ -105,7 +105,7 @@ SimResults::writeMat(const std::string &base, const std::string &lname) const mat_t *matfd = Mat_Create(matfile_name.c_str(), nullptr); if (matfd) { - writeMat(matfd, lname.c_str()); + writeMat(matfd, lname); Mat_Close(matfd); } } diff --git a/dynare++/kord/journal.cc b/dynare++/kord/journal.cc index 1c7f7fb55..96ba38688 100644 --- a/dynare++/kord/journal.cc +++ b/dynare++/kord/journal.cc @@ -186,8 +186,8 @@ Journal::printHeader() << "Dynare++ comes with ABSOLUTELY NO WARRANTY and is distributed under\n" << "GPL: modules integ, tl, kord, sylv, src, extern and documentation\n" << "LGPL: modules parser, utils\n" - << " for GPL see http://www.gnu.org/licenses/gpl.html\n" - << " for LGPL see http://www.gnu.org/licenses/lgpl.html\n" + << " for GPL see https://www.gnu.org/licenses/gpl.html\n" + << " for LGPL see https://www.gnu.org/licenses/lgpl.html\n" << "\n\n" << "System info: "; #ifndef _WIN32 diff --git a/dynare++/parser/cc/Makefile.am b/dynare++/parser/cc/Makefile.am index 915f5c5cc..6294c1cf3 100644 --- a/dynare++/parser/cc/Makefile.am +++ b/dynare++/parser/cc/Makefile.am @@ -1,16 +1,13 @@ noinst_LIBRARIES = libparser.a -GENERATED_FILES = assign_tab.cc csv_tab.cc formula_tab.cc matrix_tab.cc namelist_tab.cc assign_tab.hh csv_tab.hh formula_tab.hh matrix_tab.hh namelist_tab.hh assign_ll.cc csv_ll.cc formula_ll.cc matrix_ll.cc namelist_ll.cc +GENERATED_FILES = assign_tab.cc formula_tab.cc matrix_tab.cc assign_tab.hh formula_tab.hh matrix_tab.hh assign_ll.cc formula_ll.cc matrix_ll.cc libparser_a_SOURCES = \ location.hh \ - namelist.hh \ atom_assignings.cc \ atom_assignings.hh \ atom_substitutions.cc \ atom_substitutions.hh \ - csv_parser.cc \ - csv_parser.hh \ dynamic_atoms.cc \ dynamic_atoms.hh \ fine_atoms.cc \ @@ -33,7 +30,7 @@ libparser_a_CPPFLAGS = -I../.. $(BOOST_CPPFLAGS) BUILT_SOURCES = $(GENERATED_FILES) -EXTRA_DIST = assign.yy csv.yy formula.yy matrix.yy namelist.yy assign.ll csv.ll formula.ll matrix.ll namelist.ll +EXTRA_DIST = assign.yy formula.yy matrix.yy assign.ll formula.ll matrix.ll %_tab.cc %_tab.hh: %.yy $(YACC) -W -o$*_tab.cc $< diff --git a/dynare++/parser/cc/assign.yy b/dynare++/parser/cc/assign.yy index 94dd9c072..72d16d8d0 100644 --- a/dynare++/parser/cc/assign.yy +++ b/dynare++/parser/cc/assign.yy @@ -10,8 +10,9 @@ %code { #include "atom_assignings.hh" +#include -void asgn_error(const char*); +void asgn_error(std::string); int asgn_lex(); extern ogp::AtomAssignings* aparser; } @@ -51,7 +52,7 @@ space : space BLANK | BLANK; %% void -asgn_error(const char* mes) +asgn_error(std::string mes) { - aparser->error(mes); + aparser->error(std::move(mes)); } diff --git a/dynare++/parser/cc/atom_assignings.cc b/dynare++/parser/cc/atom_assignings.cc index eb1ffe810..853182f29 100644 --- a/dynare++/parser/cc/atom_assignings.cc +++ b/dynare++/parser/cc/atom_assignings.cc @@ -10,17 +10,15 @@ #include #include -#include +#include +#include using namespace ogp; AtomAssignings::AtomAssignings(const AtomAssignings &aa, ogp::StaticAtoms &a) : atoms(a), expr(aa.expr, atoms), left_names(aa.left_names), - order(aa.order) + lname2expr(aa.lname2expr), order(aa.order) { - // fill the lname2expr - for (auto it : aa.lname2expr) - lname2expr.emplace(left_names.query(it.first), it.second); } /** A global symbol for passing info to the AtomAssignings from @@ -29,34 +27,30 @@ AtomAssignings *aparser; /** The declaration of functions defined in asgn_ll.cc and asgn_tab.cc * generated from assign.lex assign.y */ -void *asgn__scan_buffer(char *, size_t); +void *asgn__scan_string(const char *); void asgn__destroy_buffer(void *); void asgn_parse(); extern location_type asgn_lloc; void -AtomAssignings::parse(int length, const char *stream) +AtomAssignings::parse(const string &stream) { - 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.get(), static_cast(length)+2); + void *p = asgn__scan_string(stream.c_str()); aparser = this; asgn_parse(); asgn__destroy_buffer(p); } void -AtomAssignings::error(const char *mes) +AtomAssignings::error(string mes) { - throw ParserException(mes, asgn_lloc.off); + throw ParserException(std::move(mes), asgn_lloc.off); } void -AtomAssignings::add_assignment_to_double(const char *name, double val) +AtomAssignings::add_assignment_to_double(string name, double val) { // if left hand side is a registered atom, insert it to tree int t; @@ -75,25 +69,26 @@ AtomAssignings::add_assignment_to_double(const char *name, double val) order.push_back(t); // add the double to the tree - char tmp[100]; - sprintf(tmp, "%30.25g", val); + std::ostringstream buf; + buf << std::setprecision(std::numeric_limits::max_digits10) + << val; try { - expr.parse(strlen(tmp), tmp); + expr.parse(buf.str()); } catch (const ParserException &e) { // should never happen - throw ParserException(string("Error parsing double ")+tmp+": "+e.message(), 0); + throw ParserException(string("Error parsing double ")+buf.str()+": "+e.message(), 0); } // register name of the left hand side and put to lname2expr - const char *ss = left_names.insert(name); - lname2expr.emplace(ss, order.size()-1); + left_names.insert(name); + lname2expr.emplace(std::move(name), order.size()-1); } void -AtomAssignings::add_assignment(int asgn_off, const char *str, int name_len, +AtomAssignings::add_assignment(int asgn_off, const string &str, int name_len, int right_off, int right_len) { // the order of doing things here is important: since the @@ -102,23 +97,21 @@ AtomAssignings::add_assignment(int asgn_off, const char *str, int name_len, // nulary term for the left hand side, it must be inserted to the // expression tree before the expression is parsed. - // find the name in the atoms, make copy of name to be able to put - // '\0' at the end - auto *buf = new char[name_len+1]; - strncpy(buf, str, name_len); - buf[name_len] = '\0'; + // find the name in the atoms + string name = str.substr(0, name_len); + // if left hand side is a registered atom, insert it to tree int t; try { - t = atoms.check(buf); + t = atoms.check(name); if (t == -1) - t = expr.add_nulary(buf); + t = expr.add_nulary(name); } catch (const ParserException &e) { - atoms.register_name(buf); - t = expr.add_nulary(buf); + atoms.register_name(name); + t = expr.add_nulary(name); } // register left hand side in order order.push_back(t); @@ -126,7 +119,7 @@ AtomAssignings::add_assignment(int asgn_off, const char *str, int name_len, // parse expression on the right try { - expr.parse(right_len, str+right_off); + expr.parse(str.substr(right_off, right_len)); } catch (const ParserException &e) { @@ -134,17 +127,14 @@ AtomAssignings::add_assignment(int asgn_off, const char *str, int name_len, } // register name of the left hand side and put to lname2expr - const char *ss = left_names.insert(buf); - if (lname2expr.find(ss) != lname2expr.end()) + left_names.insert(name); + if (lname2expr.find(name) != lname2expr.end()) { // Prevent the occurrence of #415 - std::cerr << "Changing the value of " << ss << " is not supported. Aborting." << std::endl; + std::cerr << "Changing the value of " << name << " is not supported. Aborting." << std::endl; exit(EXIT_FAILURE); } - lname2expr[ss] = order.size()-1; - - // delete name - delete [] buf; + lname2expr[name] = order.size()-1; } void @@ -154,7 +144,7 @@ AtomAssignings::apply_subst(const AtomSubstitutions::Toldnamemap &mm) // variables for (const auto & it : mm) { - const char *oldname = it.first; + const string &oldname = it.first; const AtomSubstitutions::Tshiftnameset &sset = it.second; if (!sset.empty()) { @@ -171,9 +161,9 @@ AtomAssignings::apply_subst(const AtomSubstitutions::Toldnamemap &mm) // reference to the newly added formula for (const auto & itt : sset) { - const char *newname = itt.first; - const char *nn = left_names.insert(newname); - lname2expr.emplace(nn, expr.nformulas()-1); + const string &newname = itt.first; + left_names.insert(newname); + lname2expr.emplace(newname, expr.nformulas()-1); } } } @@ -199,7 +189,7 @@ AtomAsgnEvaluator::setValues(EvalTree &et) const double nan = std::numeric_limits::quiet_NaN(); for (int i = 0; i < aa.atoms.nvar(); i++) { - const char *ss = aa.atoms.name(i); + const string &ss = aa.atoms.name(i); int t = aa.atoms.index(ss); if (t >= 0) { @@ -213,7 +203,7 @@ AtomAsgnEvaluator::setValues(EvalTree &et) const } void -AtomAsgnEvaluator::set_user_value(const char *name, double val) +AtomAsgnEvaluator::set_user_value(const string &name, double val) { int t = aa.atoms.index(name); if (t >= 0) @@ -238,7 +228,7 @@ AtomAsgnEvaluator::load(int i, double res) } double -AtomAsgnEvaluator::get_value(const char *name) const +AtomAsgnEvaluator::get_value(const string &name) const { auto it = aa.lname2expr.find(name); if (it == aa.lname2expr.end()) diff --git a/dynare++/parser/cc/atom_assignings.hh b/dynare++/parser/cc/atom_assignings.hh index a7bb0b860..e992aa680 100644 --- a/dynare++/parser/cc/atom_assignings.hh +++ b/dynare++/parser/cc/atom_assignings.hh @@ -14,7 +14,6 @@ namespace ogp { - class AtomAsgnEvaluator; /** This class represents atom assignments used in parameters @@ -26,7 +25,7 @@ namespace ogp { friend class AtomAsgnEvaluator; protected: - using Tvarintmap = std::map; + using Tvarintmap = std::map; /** All atoms which should be sufficient for formulas at the * right hand sides. The atoms should be filled with names * (preregistered). This is a responsibility of the caller. */ @@ -53,14 +52,14 @@ namespace ogp AtomAssignings(const AtomAssignings &aa, StaticAtoms &a); virtual ~AtomAssignings() = default; /** Parse the assignments from the given string. */ - void parse(int length, const char *stream); + void parse(const string &stream); /** Process a syntax error from bison. */ - void error(const char *mes); + void error(string mes); /** Add an assignment of the given name to the given * double. Can be called by a user, anytime. */ - void add_assignment_to_double(const char *name, double val); + void add_assignment_to_double(string name, double val); /** Add an assignment. Called from assign.y. */ - void add_assignment(int asgn_off, const char *str, int name_len, + void add_assignment(int asgn_off, const string &str, int name_len, int right_off, int right_len); /** This applies old2new map (possibly from atom * substitutions) to this object. It registers new variables @@ -107,7 +106,7 @@ namespace ogp * parameters are known and should be set to their values. In * constrast endogenous variables are set initially to NaNs by * AtomValues::setValues. */ - void set_user_value(const char *name, double val); + void set_user_value(const string &name, double val); /** This sets the result of i-th expression in aa to res, and * also checks whether the i-th expression is an atom. If so, * it sets the value of the atom in ogp::EvalTree @@ -126,9 +125,8 @@ namespace ogp /** This returns a value for a given name. If the name is not * found among atoms, or there is no assignment for the atom, * NaN is returned. */ - double get_value(const char *name) const; + double get_value(const string &name) const; }; - }; #endif diff --git a/dynare++/parser/cc/atom_substitutions.cc b/dynare++/parser/cc/atom_substitutions.cc index c5622ea8e..1f377191c 100644 --- a/dynare++/parser/cc/atom_substitutions.cc +++ b/dynare++/parser/cc/atom_substitutions.cc @@ -9,46 +9,24 @@ using namespace ogp; AtomSubstitutions::AtomSubstitutions(const AtomSubstitutions &as, const FineAtoms &oa, FineAtoms &na) - : old_atoms(oa), new_atoms(na) + : new2old(as.new2old), old2new(as.old2new), old_atoms(oa), new_atoms(na) { - const NameStorage &ns = na.get_name_storage(); - - // fill new2old - for (const auto & it : as.new2old) - 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.emplace(ns.query(itt.first), itt.second); - old2new.emplace(ns.query(it.first), sset); - } } void -AtomSubstitutions::add_substitution(const char *newname, const char *oldname, int tshift) +AtomSubstitutions::add_substitution(string newname, string oldname, int tshift) { - // 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 || !oldname) - throw ogu::Exception(__FILE__, __LINE__, - "Bad newname or oldname in AtomSubstitutions::add_substitution"); - // insert to new2old map new2old.emplace(newname, Tshiftname(oldname, tshift)); // insert to old2new map auto it = old2new.find(oldname); if (it != old2new.end()) - it->second.emplace(newname, -tshift); + it->second.emplace(std::move(newname), -tshift); else { Tshiftnameset snset; - snset.emplace(newname, -tshift); - old2new.emplace(oldname, snset); + snset.emplace(std::move(newname), -tshift); + old2new.emplace(std::move(oldname), snset); } // put to info @@ -59,14 +37,14 @@ void AtomSubstitutions::substitutions_finished(VarOrdering::ord_type ot) { // create an external ordering of new_atoms from old_atoms - const vector &oa_ext = old_atoms.get_allvar(); - vector na_ext; - for (auto oname : oa_ext) + const vector &oa_ext = old_atoms.get_allvar(); + vector na_ext; + for (const auto &oname : oa_ext) { // add the old name itself na_ext.push_back(oname); // add all new names derived from the old name - Toldnamemap::const_iterator it = old2new.find(oname); + auto it = old2new.find(oname); if (it != old2new.end()) for (const auto & itt : it->second) na_ext.push_back(itt.first); @@ -76,8 +54,8 @@ AtomSubstitutions::substitutions_finished(VarOrdering::ord_type ot) new_atoms.parsing_finished(ot, na_ext); } -const char * -AtomSubstitutions::get_new4old(const char *oldname, int tshift) const +string +AtomSubstitutions::get_new4old(const string &oldname, int tshift) const { auto it = old2new.find(oldname); if (it != old2new.end()) @@ -87,7 +65,7 @@ AtomSubstitutions::get_new4old(const char *oldname, int tshift) const if (itt.second == -tshift) return itt.first; } - return nullptr; + return ""; } void @@ -106,25 +84,25 @@ AtomSubstitutions::print() const void SAtoms::substituteAllLagsAndLeads(FormulaParser &fp, AtomSubstitutions &as) { - const char *name; + string name; int mlead, mlag; endovarspan(mlead, mlag); // substitute all endo lagged more than 1 - while (name = findEndoWithLeadInInterval(mlag, -2)) + while (!(name = findEndoWithLeadInInterval(mlag, -2)).empty()) makeAuxVariables(name, -1, -2, mlag, fp, as); // substitute all endo leaded more than 1 - while (name = findEndoWithLeadInInterval(2, mlead)) + while (!(name = findEndoWithLeadInInterval(2, mlead)).empty()) makeAuxVariables(name, 1, 2, mlead, fp, as); exovarspan(mlead, mlag); // substitute all lagged exo - while (name = findExoWithLeadInInterval(mlag, -1)) + while (!(name = findExoWithLeadInInterval(mlag, -1)).empty()) makeAuxVariables(name, -1, -1, mlag, fp, as); // substitute all leaded exo - while (name = findExoWithLeadInInterval(1, mlead)) + while (!(name = findExoWithLeadInInterval(1, mlead)).empty()) makeAuxVariables(name, 1, 1, mlead, fp, as); // notify that substitution have been finished @@ -134,30 +112,30 @@ SAtoms::substituteAllLagsAndLeads(FormulaParser &fp, AtomSubstitutions &as) void SAtoms::substituteAllLagsAndExo1Leads(FormulaParser &fp, AtomSubstitutions &as) { - const char *name; + string name; int mlead, mlag; endovarspan(mlead, mlag); // substitute all endo lagged more than 1 - while (name = findEndoWithLeadInInterval(mlag, -2)) + while (!(name = findEndoWithLeadInInterval(mlag, -2)).empty()) makeAuxVariables(name, -1, -2, mlag, fp, as); exovarspan(mlead, mlag); // substitute all lagged exo - while (name = findExoWithLeadInInterval(mlag, -1)) + while (!(name = findExoWithLeadInInterval(mlag, -1)).empty()) makeAuxVariables(name, -1, -1, mlag, fp, as); // substitute all leaded exo by 1 - while (name = findExoWithLeadInInterval(1, 1)) + while (!(name = findExoWithLeadInInterval(1, 1)).empty()) makeAuxVariables(name, 1, 1, 1, fp, as); // notify that substitution have been finished as.substitutions_finished(order_type); } -const char * -SAtoms::findNameWithLeadInInterval(const vector &names, +string +SAtoms::findNameWithLeadInInterval(const vector &names, int ll1, int ll2) const { for (auto name : names) @@ -165,7 +143,7 @@ SAtoms::findNameWithLeadInInterval(const vector &names, auto it = vars.find(name); if (it != vars.end()) { - const DynamicAtoms::Tlagmap &lmap = (*it).second; + const DynamicAtoms::Tlagmap &lmap = it->second; for (auto itt : lmap) if (itt.first >= ll1 && itt.first <= ll2) return name; @@ -173,29 +151,29 @@ SAtoms::findNameWithLeadInInterval(const vector &names, } // nothing found - return nullptr; + return ""; } void -SAtoms::attemptAuxName(const char *str, int ll, string &out) const +SAtoms::attemptAuxName(const string &str, int ll, string &out) const { char c = (ll >= 0) ? ((ll == 0) ? 'e' : 'p') : 'm'; string absll = std::to_string(std::abs(ll)); int iter = 1; do { - out = string(str) + '_'; + out = str + '_'; for (int i = 0; i < iter; i++) out += c; if (ll != 0) out += absll; iter++; } - while (varnames.query(out.c_str())); + while (varnames.query(out)); } void -SAtoms::makeAuxVariables(const char *name, int step, int start, int limit_lead, +SAtoms::makeAuxVariables(const string &name, int step, int start, int limit_lead, FormulaParser &fp, AtomSubstitutions &as) { if (!(step == 1 || step == -1)) @@ -220,10 +198,7 @@ SAtoms::makeAuxVariables(const char *name, int step, int start, int limit_lead, // index of atom "a(-2)" int tprev = index(name, start-step); if (tprev == -1) - { - string tmp = string{name} + '(' + std::to_string(start-step) + ')'; - tprev = fp.add_nulary(tmp.c_str()); - } + tprev = fp.add_nulary(name + '(' + std::to_string(start-step) + ')'); int ll = start; do @@ -234,17 +209,15 @@ SAtoms::makeAuxVariables(const char *name, int step, int start, int limit_lead, // check if "a_m2(0)" has not been already created (with // different step), in this case do not add equation "a_m2(0) // = a(-2)" - const char *newname; - string newname_str; + string newname, newname_str; int taux; - if (!(newname = as.get_new4old(name, ll-step))) + if ((newname = as.get_new4old(name, ll-step)).empty()) { attemptAuxName(name, ll-step, newname_str); - newname = newname_str.c_str(); + newname = newname_str; register_uniq_endo(newname); newname = varnames.query(newname); - string tmp = string{newname} + "(0)"; - taux = fp.add_nulary(tmp.c_str()); + taux = fp.add_nulary(newname + "(0)"); // add to substitutions as.add_substitution(newname, name, ll-step); @@ -269,8 +242,7 @@ SAtoms::makeAuxVariables(const char *name, int step, int start, int limit_lead, if (t == -1) { // no "a(-3)", make t <-> a_m2(-1) - string tmp = string{newname} + '(' + std::to_string(step) + ')'; - t = fp.add_nulary(tmp.c_str()); + t = fp.add_nulary(newname + '(' + std::to_string(step) + ')'); } else { diff --git a/dynare++/parser/cc/atom_substitutions.hh b/dynare++/parser/cc/atom_substitutions.hh index 88b156dd5..4a4d85c87 100644 --- a/dynare++/parser/cc/atom_substitutions.hh +++ b/dynare++/parser/cc/atom_substitutions.hh @@ -30,10 +30,10 @@ namespace ogp class AtomSubstitutions { public: - using Tshiftname = pair; - using Tshiftmap = map; + using Tshiftname = pair; + using Tshiftmap = map; using Tshiftnameset = set; - using Toldnamemap = map; + using Toldnamemap = map; protected: /** This maps a new name to a shifted old name. This is, one * entry looks as "a_m3 ==> a(-3)", saying that a variable @@ -76,15 +76,15 @@ namespace ogp * substitution method of the new atoms. This says that the * new name, say "a_m3" is a substitution of old name "a" * shifted by -3. */ - void add_substitution(const char *newname, const char *oldname, int tshift); + void add_substitution(string newname, string oldname, int tshift); /** This is called when all substitutions are finished. This * forms the new external ordering of the new atoms and calls * parsing_finished() for the new atoms with the given ordering type. */ void substitutions_finished(VarOrdering::ord_type ot); /** Returns a new name for old name and given tshift. For "a" * and tshift=-3, it returns "a_m3". If there is no such - * substitution, it returns NULL. */ - const char *get_new4old(const char *oldname, int tshift) const; + * substitution, it returns an empty string. */ + string get_new4old(const string &oldname, int tshift) const; /** Return new2old. */ const Tshiftmap & get_new2old() const @@ -127,7 +127,6 @@ namespace ogp { } 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 @@ -140,14 +139,14 @@ namespace ogp protected: /** This finds an endogenous variable name which occurs between * ll1 and ll2 included. */ - const char * + string findEndoWithLeadInInterval(int ll1, int ll2) const { return findNameWithLeadInInterval(get_endovars(), ll1, ll2); } /** This finds an exogenous variable name which occurs between * ll1 and ll2 included. */ - const char * + string findExoWithLeadInInterval(int ll1, int ll2) const { return findNameWithLeadInInterval(get_exovars(), ll1, ll2); @@ -159,7 +158,7 @@ namespace ogp * such form is already registered, one more character (either * 'p' or 'm') is added and the test is performed again. The * resulting name is returned in a string out. */ - void attemptAuxName(const char *str, int ll, string &out) const; + void attemptAuxName(const string &str, int ll, string &out) const; /** This makes auxiliary variables to eliminate all leads/lags * greater/less than or equal to start up to the limit_lead @@ -170,13 +169,13 @@ namespace ogp * atoms are created in this object. The auxiliary equations * are created in the given FormulaParser. The value of step * is allowed to be either -1 (lags) or +1 (leads). */ - void makeAuxVariables(const char *name, int step, int start, int limit_lead, + void makeAuxVariables(const string &name, int step, int start, int limit_lead, FormulaParser &fp, AtomSubstitutions &as); private: /** This is a worker routine for findEndoWithLeadInInterval * and findExoWithLeadInInterval. */ - const char *findNameWithLeadInInterval(const vector &names, - int ll1, int ll2) const; + string findNameWithLeadInInterval(const vector &names, + int ll1, int ll2) const; }; diff --git a/dynare++/parser/cc/csv.ll b/dynare++/parser/cc/csv.ll deleted file mode 100644 index 8d6ad494b..000000000 --- a/dynare++/parser/cc/csv.ll +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- C++ -*- */ -%{ -// Copyright © 2007-2011, Ondra Kamenik - -#include "location.hh" -#include "csv_tab.hh" - -#define YY_USER_ACTION SET_LLOC(csv_); -%} - -%option nounput -%option noyy_top_state -%option yylineno -%option prefix="csv_" -%option never-interactive - -%% - -, {return COMMA;} -\n {return NEWLINE;} -\r\n {return NEWLINE;} -[^,\n\r]+ {return ITEM;} - -%% - -int -csv_wrap() -{ - return 1; -} - -void -csv__destroy_buffer(void* p) -{ - csv__delete_buffer(static_cast(p)); -} diff --git a/dynare++/parser/cc/csv.yy b/dynare++/parser/cc/csv.yy deleted file mode 100644 index 5f0bc0485..000000000 --- a/dynare++/parser/cc/csv.yy +++ /dev/null @@ -1,53 +0,0 @@ -// -*- C++ -*- -%code requires -{ -#include "location.hh" -#define CSV_LTYPE ogp::location_type -} - -%code -{ -#include "csv_parser.hh" - -void csv_error(const char*); -int csv_lex(); -extern ogp::CSVParser* csv_parser; -} - -%union -{ - char* string; - int integer; -} - -%token COMMA NEWLINE BOGUS -%token ITEM - -%define api.prefix {csv_}; - -%locations -%defines -%define parse.error verbose - -%% - -csv_file : line_list | line_list line; - -line_list : line_list line newline | line newline | line_list newline | newline; - -line : line comma | line item | item | comma; - -comma : COMMA {csv_parser->nextcol();}; - -newline : NEWLINE {csv_parser->nextrow();}; - -item : ITEM {csv_parser->item(@1.off, @1.ll);}; - - -%% - -void -csv_error(const char* mes) -{ - csv_parser->csv_error(mes); -} diff --git a/dynare++/parser/cc/csv_parser.cc b/dynare++/parser/cc/csv_parser.cc deleted file mode 100644 index 0fa00eca7..000000000 --- a/dynare++/parser/cc/csv_parser.cc +++ /dev/null @@ -1,45 +0,0 @@ -#include "csv_parser.hh" -#include "parser_exception.hh" -#include "location.hh" -#include "csv_tab.hh" - -#include -#include - -using namespace ogp; - -/** A global symbol for passing info to the CSVParser from - * csv_parse(). */ -CSVParser *csv_parser; - -/** The declaration of functions defined in csv_ll.cc and - * csv_tab.cc generated from csv.lex and csv.y. */ -void *csv__scan_buffer(char *, unsigned int); -void csv__destroy_buffer(void *); -int csv_parse(); - -extern ogp::location_type csv_lloc; - -void -CSVParser::csv_error(const char *mes) -{ - throw ParserException(mes, csv_lloc.off); -} - -void -CSVParser::csv_parse(int length, const char *str) -{ - // allocate temporary buffer and parse - 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.get(); - void *p = csv__scan_buffer(buffer.get(), static_cast(length)+2); - csv_parser = this; - ::csv_parse(); - csv__destroy_buffer(p); - parsed_string = nullptr; -} diff --git a/dynare++/parser/cc/csv_parser.hh b/dynare++/parser/cc/csv_parser.hh deleted file mode 100644 index 9a8ac6dd7..000000000 --- a/dynare++/parser/cc/csv_parser.hh +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright © 2007, Ondra Kamenik - -// $Id$ - -#ifndef OGP_CSV_PARSER -#define OGP_CSV_PARSER - -namespace ogp -{ - - class CSVParserPeer - { - public: - virtual ~CSVParserPeer() - = default; - virtual void item(int irow, int icol, const char *str, int length) = 0; - }; - - class CSVParser - { - private: - CSVParserPeer &peer; - int row; - int col; - const char *parsed_string; - public: - CSVParser(CSVParserPeer &p) - : peer(p), row(0), col(0), parsed_string(nullptr) - { - } - CSVParser(const CSVParser &csvp) - - = default; - virtual ~CSVParser() - = default; - - void csv_error(const char *mes); - void csv_parse(int length, const char *str); - - void - nextrow() - { - row++; col = 0; - } - void - nextcol() - { - col++; - } - void - item(int off, int length) - { - peer.item(row, col, parsed_string+off, length); - } - }; -}; - -#endif diff --git a/dynare++/parser/cc/dynamic_atoms.cc b/dynare++/parser/cc/dynamic_atoms.cc index 27af3f35f..cb5de80da 100644 --- a/dynare++/parser/cc/dynamic_atoms.cc +++ b/dynare++/parser/cc/dynamic_atoms.cc @@ -7,51 +7,13 @@ using namespace ogp; -NameStorage::NameStorage(const NameStorage &stor) +void +NameStorage::insert(string name) { - for (auto i : stor.name_store) + if (!query(name)) { - auto *str = new char[strlen(i)+1]; - strcpy(str, i); - name_store.push_back(str); - name_set.insert(str); - } -} - -NameStorage::~NameStorage() -{ - while (name_store.size() > 0) - { - delete [] name_store.back(); - name_store.pop_back(); - } -} - -const char * -NameStorage::query(const char *name) const -{ - auto it = name_set.find(name); - if (it == name_set.end()) - return nullptr; - else - return (*it); -} - -const char * -NameStorage::insert(const char *name) -{ - auto it = name_set.find(name); - if (it == name_set.end()) - { - auto *str = new char[strlen(name)+1]; - strcpy(str, name); - name_store.push_back(str); - name_set.insert(str); - return str; - } - else - { - return (*it); + name_store.push_back(name); + name_set.insert(std::move(name)); } } @@ -104,15 +66,12 @@ Constants::get_constant_value(int t) const if (it != cmap.end()) return it->second; else - { - throw ogu::Exception(__FILE__, __LINE__, - "Tree index is not constant in Constants::get_constant_value"); - return 0; - } + throw ogu::Exception(__FILE__, __LINE__, + "Tree index is not constant in Constants::get_constant_value"); } int -Constants::check(const char *str) const +Constants::check(const string &str) const { double d = std::stod(str); auto it = cinvmap.find(d); @@ -126,26 +85,11 @@ void Constants::print() const { for (const auto &it : cmap) - printf("$%d: %8.4g\n", it.first, it.second); -} - -DynamicAtoms::DynamicAtoms() = default; - -DynamicAtoms::DynamicAtoms(const DynamicAtoms &da) - : Constants(da), - varnames(da.varnames), vars(), indices(), - nv(da.nv), minlag(da.minlag), maxlead(da.maxlead) -{ - // copy vars - for (const auto & var : da.vars) - vars.emplace(varnames.query(var.first), var.second); - // copy indices - for (auto indice : da.indices) - indices.emplace(indice.first, varnames.query(indice.second)); + std::cout << "$" << it.first << ": " << it.second << "\n"; } int -DynamicAtoms::check(const char *name) const +DynamicAtoms::check(const string &name) const { if (is_string_constant(name)) return Constants::check(name); @@ -154,12 +98,12 @@ DynamicAtoms::check(const char *name) const } int -DynamicAtoms::check_variable(const char *name) const +DynamicAtoms::check_variable(const string &name) const { string str; int ll; parse_variable(name, str, ll); - auto it = vars.find(str.c_str()); + auto it = vars.find(str); if (it != vars.end()) { @@ -172,7 +116,7 @@ DynamicAtoms::check_variable(const char *name) const } void -DynamicAtoms::assign(const char *name, int t) +DynamicAtoms::assign(const string &name, int t) { if (is_string_constant(name)) assign_constant(name, t); @@ -181,7 +125,7 @@ DynamicAtoms::assign(const char *name, int t) } void -DynamicAtoms::assign_constant(const char *name, int t) +DynamicAtoms::assign_constant(const string &name, int t) { double val = std::stod(name); add_constant(t, val); @@ -190,19 +134,19 @@ DynamicAtoms::assign_constant(const char *name, int t) // parse the name and then call assing_variable(varname, ll, t) void -DynamicAtoms::assign_variable(const char *name, int t) +DynamicAtoms::assign_variable(const string &name, int t) { int ll; string str; parse_variable(name, str, ll); // here str is just name without lead/lag - const char *ss = varnames.insert(str.c_str()); + varnames.insert(str); - assign_variable(ss, ll, t); + assign_variable(str, ll, t); } void -DynamicAtoms::assign_variable(const char *varname, int ll, int t) +DynamicAtoms::assign_variable(const string &varname, int ll, int t) { if (indices.end() != indices.find(t)) throw ogu::Exception(__FILE__, __LINE__, @@ -226,14 +170,12 @@ DynamicAtoms::assign_variable(const char *varname, int ll, int t) indices.emplace(t, varname); nv++; - if (ll < minlag) - minlag = ll; - if (ll > maxlead) - maxlead = ll; + minlag = std::min(ll, minlag); + maxlead = std::max(ll, maxlead); } void -DynamicAtoms::unassign_variable(const char *varname, int ll, int t) +DynamicAtoms::unassign_variable(const string &varname, int ll, int t) { auto it = vars.find(varname); if (it != vars.end()) @@ -315,7 +257,7 @@ DynamicAtoms::varspan(int t, int &mlead, int &mlag) const } void -DynamicAtoms::varspan(const char *name, int &mlead, int &mlag) const +DynamicAtoms::varspan(const string &name, int &mlead, int &mlag) const { auto it = vars.find(name); if (vars.end() == it) @@ -332,11 +274,11 @@ DynamicAtoms::varspan(const char *name, int &mlead, int &mlag) const } void -DynamicAtoms::varspan(const vector &names, int &mlead, int &mlag) const +DynamicAtoms::varspan(const vector &names, int &mlead, int &mlag) const { mlead = std::numeric_limits::min(); mlag = std::numeric_limits::max(); - for (auto name : names) + for (const auto &name : names) { int lag, lead; varspan(name, lead, lag); @@ -348,11 +290,11 @@ DynamicAtoms::varspan(const vector &names, int &mlead, int &mlag) bool DynamicAtoms::is_named_atom(int t) const { - return (indices.end() != indices.find(t)); + return indices.end() != indices.find(t); } int -DynamicAtoms::index(const char *name, int ll) const +DynamicAtoms::index(const string &name, int ll) const { auto it = vars.find(name); if (vars.end() != it) @@ -366,14 +308,13 @@ DynamicAtoms::index(const char *name, int ll) const } bool -DynamicAtoms::is_referenced(const char *name) const +DynamicAtoms::is_referenced(const string &name) const { - auto it = vars.find(name); - return it != vars.end(); + return vars.find(name) != vars.end(); } const DynamicAtoms::Tlagmap & -DynamicAtoms::lagmap(const char *name) const +DynamicAtoms::lagmap(const string &name) const { auto it = vars.find(name); if (vars.end() == it) @@ -383,7 +324,7 @@ DynamicAtoms::lagmap(const char *name) const return it->second; } -const char * +const string & DynamicAtoms::name(int t) const { auto it = indices.find(t); @@ -396,7 +337,7 @@ DynamicAtoms::name(int t) const int DynamicAtoms::lead(int t) const { - const char *nam = name(t); + const string &nam = name(t); const Tlagmap &lmap = lagmap(nam); auto it = lmap.begin(); while (it != lmap.end() && it->second != t) @@ -410,32 +351,32 @@ DynamicAtoms::lead(int t) const void DynamicAtoms::print() const { - printf("names:\n"); + std::cout << "names:\n"; varnames.print(); - printf("constants:\n"); + std::cout << "constants:\n"; Constants::print(); - printf("variables:\n"); + std::cout << "variables:\n"; for (const auto & var : vars) { const Tlagmap &lmap = var.second; for (auto itt : lmap) - printf("$%d: %s(%d)\n", itt.second, var.first, itt.first); + std::cout << "$" << itt.second << ": " << var.first << "(" << itt.first << ")\n"; } - printf("indices:\n"); + std::cout << "indices:\n"; for (auto indice : indices) - printf(u8"t=%d ⇒ %s\n", indice.first, indice.second); + std::cout << "t=" << indice.first << u8" ⇒ " << indice.second << "\n"; } /** Note that the str has been parsed by the lexicographic * analyzer. It can be either a variable or a double. So it is easy to * recognize it by the first character. */ bool -DynamicAtoms::is_string_constant(const char *str) +DynamicAtoms::is_string_constant(const string &str) { return str[0] == '.' || str[0] == '-' || (str[0] >= '0' && str[0] <= '9'); } -VarOrdering::VarOrdering(const VarOrdering &vo, const vector &vnames, +VarOrdering::VarOrdering(const VarOrdering &vo, const vector &vnames, const DynamicAtoms &a) : n_stat(vo.n_stat), n_pred(vo.n_pred), n_both(vo.n_both), n_forw(vo.n_forw), der_atoms(vo.der_atoms), positions(vo.positions), @@ -446,8 +387,7 @@ VarOrdering::VarOrdering(const VarOrdering &vo, const vector &vnam bool VarOrdering::check(int t) const { - auto it = positions.find(t); - return it != positions.end(); + return positions.find(t) != positions.end(); } int @@ -455,15 +395,10 @@ VarOrdering::get_pos_of(int t) const { auto it = positions.find(t); if (it != positions.end()) - { - return it->second; - } + return it->second; else - { - throw ogu::Exception(__FILE__, __LINE__, - "Couldn't find the tree index in VarOrdering::get_pos_of"); - return -1; - } + throw ogu::Exception(__FILE__, __LINE__, + "Couldn't find the tree index in VarOrdering::get_pos_of"); } void @@ -487,7 +422,7 @@ VarOrdering::do_general(ord_type ordering) for (unsigned int i = 0; i < varnames.size(); i++) { - const char *ss = varnames[i]; + const string &ss = varnames[i]; int lead; int lag; atoms.varspan(ss, lead, lag); @@ -516,10 +451,8 @@ VarOrdering::do_general(ord_type ordering) y2o_both.push_back(i); } else - { - throw ogu::Exception(__FILE__, __LINE__, - "A wrong lag/lead of a variable in VarOrdering::do_pbspbfbf"); - } + throw ogu::Exception(__FILE__, __LINE__, + "A wrong lag/lead of a variable in VarOrdering::do_pbspbfbf"); } // here we fill ords according to ordering @@ -546,11 +479,9 @@ VarOrdering::do_general(ord_type ordering) ords[6] = &pred_minus; ords[7] = &both_minus; } - else // BEWARE: when implementing a new ordering, check also a - {// code below setting y2outer - throw ogu::Exception(__FILE__, __LINE__, - "Ordering not implemented in VarOrdering::do_general"); - } + else // BEWARE: when implementing a new ordering, check also the code below setting y2outer + throw ogu::Exception(__FILE__, __LINE__, + "Ordering not implemented in VarOrdering::do_general"); // make der_atoms and positions int off = 0; @@ -652,18 +583,19 @@ VarOrdering::do_increasing_time() void VarOrdering::print() const { - printf("nstat=%d, npred=%d, nboth=%d, nforw=%d\n", n_stat, n_pred, n_both, n_forw); - printf("der_atoms:\n"); + std::cout << "nstat=" << n_stat << ", npred=" << n_pred << ", nboth=" << n_both + << ", nforw=" << n_forw << "\n" + << "der_atoms:\n"; for (int der_atom : der_atoms) - printf(" %d", der_atom); - printf("\nmap:\n"); + std::cout << " " << der_atom; + std::cout << "\nmap:\n"; for (auto position : positions) - printf(u8" [%d→%d]", position.first, position.second); - printf("\ny2outer:\n"); + std::cout << " [" << position.first << u8"→" << position.second << "]"; + std::cout << "\ny2outer:\n"; for (int i : y2outer) - printf(" %d", i); - printf("\nouter2y:\n"); + std::cout << " " << i; + std::cout << "\nouter2y:\n"; for (int i : outer2y) - printf(" %d", i); - printf("\n"); + std::cout << " " << i; + std::cout << "\n"; } diff --git a/dynare++/parser/cc/dynamic_atoms.hh b/dynare++/parser/cc/dynamic_atoms.hh index 06b362779..e717b59e0 100644 --- a/dynare++/parser/cc/dynamic_atoms.hh +++ b/dynare++/parser/cc/dynamic_atoms.hh @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -22,15 +21,6 @@ namespace ogp using std::set; using std::string; - struct ltstr - { - bool - operator()(const char *a1, const char *a2) const - { - return strcmp(a1, a2) < 0; - } - }; - /** Class storing names. We will keep names of variables in * various places, and all these pointers will point to one * storage, which will be responsible for allocation and @@ -41,26 +31,26 @@ namespace ogp { protected: /** Vector of names allocated, this is the storage. */ - vector name_store; + vector name_store; /** Map useful to quickly decide if the name is already * allocated or not. */ - set name_set; + set name_set; public: - NameStorage() = default; - NameStorage(const NameStorage &stor); - 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; - /** Insert the name if it has not been inserted yet, and - * return its new or old allocation. */ - const char *insert(const char *name); + * true, otherwise false. */ + bool + query(const string &name) const + { + return name_set.find(name) != name_set.end(); + } + /** Insert the name if it has not been inserted yet. */ + void insert(string name); int num() const { return static_cast(name_store.size()); } - const char * + const string & get_name(int i) const { return name_store[i]; @@ -112,7 +102,7 @@ namespace ogp /** Return -1 if the given string representation of a constant * is not among the constants (double represenations). If it * is, its tree index is returned. */ - int check(const char *str) const; + int check(const string &str) const; /** Debug print. */ void print() const; const Tconstantmap & @@ -141,9 +131,9 @@ namespace ogp using Tlagmap = map; protected: /** Definition of a type mapping names of the atoms to Tlagmap. */ - using Tvarmap = map; + using Tvarmap = map; /** Definition of a type mapping indices of variables to the variable names. */ - using Tindexmap = map; + using Tindexmap = map; /** This is just a storage for variable names, since all other * instances of a variable name just point to the memory * allocated by this object. */ @@ -165,9 +155,7 @@ namespace ogp int maxlead{std::numeric_limits::min()}; public: /** Construct empty DynamicAtoms. */ - DynamicAtoms(); - DynamicAtoms(const DynamicAtoms &da); - ~DynamicAtoms() override = default; + DynamicAtoms() = 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 @@ -175,11 +163,11 @@ namespace ogp * appeared or not. If variable, then -1 is returned only if * the variable has not been assigned an index, otherwise the * assigned index is returned. */ - int check(const char *name) const override; + int check(const string &name) const override; /** Assign the nulary term identified by its string * representation. This method should be called when check() * returns -1. */ - void assign(const char *name, int t) override; + void assign(const string &name, int t) override; /** Return a number of all variables. */ int nvar() const override @@ -196,9 +184,9 @@ namespace ogp /** Return max lead and min lag for a variable given by the * name (without lead, lag). The same is valid if the variable * name cannot be found. */ - void varspan(const char *name, int &mlead, int &mlag) const; + void varspan(const string &name, int &mlead, int &mlag) const; /** Return max lead and min lag for a vector of variables given by the names. */ - void varspan(const vector &names, int &mlead, int &mlag) const; + void varspan(const vector &names, int &mlead, int &mlag) const; /** Return true for all tree indices corresponding to a * variable in the sense of this class. (This is parameters, * exo and endo). Since the semantics of 'variable' will be @@ -207,15 +195,15 @@ namespace ogp bool is_named_atom(int t) const; /** Return index of the variable described by the variable * name and lag/lead. If it doesn't exist, return -1. */ - int index(const char *name, int ll) const; + int index(const string &name, int ll) const; /** Return true if a variable is referenced, i.e. it has lag * map. */ - bool is_referenced(const char *name) const; + bool is_referenced(const string &name) const; /** Return the lag map for the variable name. */ - const Tlagmap&lagmap(const char *name) const; + const Tlagmap &lagmap(const string &name) const; /** Return the variable name for the tree index. It throws an * exception if the tree index t is not a named atom. */ - const char *name(int t) const; + const string &name(int t) const; /** Return the lead/lag for the tree index. It throws an * exception if the tree index t is not a named atom. */ int lead(int t) const; @@ -242,25 +230,25 @@ namespace ogp * from the varnames storage. The method checks if the * variable iwht the given lead/lag is not assigned. If so, an * exception is thrown. */ - void assign_variable(const char *varname, int ll, int t); + void assign_variable(const string &varname, int ll, int t); /** Unassign the variable with a given lead and given tree * index. The tree index is only provided as a check. An * exception is thrown if the name, ll, and the tree index t * are not consistent. The method also updates nv, indices, * maxlead and minlag. The varname must be from the varnames * storage. */ - void unassign_variable(const char *varname, int ll, int t); + void unassign_variable(const string &varname, int ll, int t); /** Debug print. */ void print() const override; protected: /** Do the check for the variable. A subclass may need to * reimplement this so that it could raise an error if the * variable is not among a given list. */ - virtual int check_variable(const char *name) const; + virtual int check_variable(const string &name) const; /** Assign the constant. */ - void assign_constant(const char *name, int t); + void assign_constant(const string &name, int t); /** Assign the variable. */ - void assign_variable(const char *name, int t); + void assign_variable(const string &name, int t); /** The method just updates minlag or/and maxlead. Note that * when assigning variables, the update is done when inserting * to the maps, however, if removing a variable, we need to @@ -268,10 +256,10 @@ namespace ogp void update_minmaxll(); /** The method parses the string to recover a variable name * and lag/lead ll. The variable name doesn't contain a lead/lag. */ - virtual void parse_variable(const char *in, string &out, int &ll) const = 0; + virtual void parse_variable(const string &in, string &out, int &ll) const = 0; public: /** Return true if the str represents a double.*/ - static bool is_string_constant(const char *str); + static bool is_string_constant(const string &str); }; /** This class is a parent of all orderings of the dynamic atoms @@ -336,7 +324,7 @@ namespace ogp vector y2outer; /** This is just a reference for variable names to keep it * from constructor to do_ordering() implementations. */ - const vector &varnames; + const vector &varnames; /** This is just a reference to atoms to keep it from * constructor to do_ordering() implementations. */ const DynamicAtoms &atoms; @@ -348,14 +336,14 @@ namespace ogp * with their dynamic occurrences defined by the atoms. It * calls the virtual method do_ordering which can be * reimplemented. */ - VarOrdering(const vector &vnames, const DynamicAtoms &a) + VarOrdering(const vector &vnames, const DynamicAtoms &a) : n_stat(0), n_pred(0), n_both(0), n_forw(0), varnames(vnames), atoms(a) { } - VarOrdering(const VarOrdering &vo, const vector &vnames, + VarOrdering(const VarOrdering &vo, const vector &vnames, const DynamicAtoms &a); VarOrdering(const VarOrdering &vo) = delete; - virtual std::unique_ptr clone(const vector &vnames, + virtual std::unique_ptr clone(const vector &vnames, const DynamicAtoms &a) const = 0; /** Destructor does nothing here. */ virtual ~VarOrdering() = default; diff --git a/dynare++/parser/cc/fine_atoms.cc b/dynare++/parser/cc/fine_atoms.cc index 67962fb24..28b1fc511 100644 --- a/dynare++/parser/cc/fine_atoms.cc +++ b/dynare++/parser/cc/fine_atoms.cc @@ -9,21 +9,20 @@ using namespace ogp; -AllvarOuterOrdering::AllvarOuterOrdering(const vector &allvar_outer, +AllvarOuterOrdering::AllvarOuterOrdering(const vector &allvar_outer, const FineAtoms &a) : atoms(a), allvar(), endo2all(a.get_endovars().size(), -1), exo2all(a.get_exovars().size(), -1) { // fill in the allvar from allvar_outer - for (auto i : allvar_outer) + for (const auto &s : allvar_outer) { - const char *s = atoms.varnames.query(i); - if (s) + if (atoms.varnames.query(s)) allvar.push_back(s); else throw ogu::Exception(__FILE__, __LINE__, - string("Variable ") + i + " is not a declared symbol in AllvarOuterOrdering constructor"); + string("Variable ") + s + " is not a declared symbol in AllvarOuterOrdering constructor"); } // fill in endo2all and exo2all @@ -62,54 +61,44 @@ AllvarOuterOrdering::AllvarOuterOrdering(const vector &allvar_oute AllvarOuterOrdering::AllvarOuterOrdering(const AllvarOuterOrdering &avo, const FineAtoms &a) - : atoms(a), allvar(), + : atoms(a), allvar(avo.allvar), endo2all(avo.endo2all), exo2all(avo.exo2all) { - // fill in the allvar from avo.allvar - for (auto i : avo.allvar) - { - const char *s = atoms.varnames.query(i); - allvar.push_back(s); - } } FineAtoms::FineAtoms(const FineAtoms &fa) : DynamicAtoms(fa), params(), endovars(), exovars(), - endo_order(nullptr), exo_order(nullptr), allvar_order(nullptr), der_atoms(fa.der_atoms), endo_atoms_map(fa.endo_atoms_map), exo_atoms_map(fa.exo_atoms_map) { // fill in params - for (auto param : fa.params) + for (const auto ¶m : fa.params) { - const char *s = varnames.query(param); - if (!s) + if (!varnames.query(param)) throw ogu::Exception(__FILE__, __LINE__, string("Parameter ") + param + " does not exist in FineAtoms copy cosntructor"); - params.push_back(s); - param_outer_map.emplace(s, params.size()-1); + params.push_back(param); + param_outer_map.emplace(param, params.size()-1); } // fill in endovars - for (auto endovar : fa.endovars) + for (const auto &endovar : fa.endovars) { - const char *s = varnames.query(endovar); - if (!s) + if (!varnames.query(endovar)) throw ogu::Exception(__FILE__, __LINE__, string("Endo variable ") + endovar + " does not exist in FineAtoms copy constructor"); - endovars.push_back(s); - endo_outer_map.emplace(s, endovars.size()-1); + endovars.push_back(endovar); + endo_outer_map.emplace(endovar, endovars.size()-1); } // fill in exovars - for (auto exovar : fa.exovars) + for (const auto &exovar : fa.exovars) { - const char *s = varnames.query(exovar); - if (!s) + if (!varnames.query(exovar)) throw ogu::Exception(__FILE__, __LINE__, string("Exo variable ") + exovar + " does not exist in FineAtoms copy cosntructor"); - exovars.push_back(s); - exo_outer_map.emplace(s, exovars.size()-1); + exovars.push_back(exovar); + exo_outer_map.emplace(exovar, exovars.size()-1); } if (fa.endo_order) @@ -123,12 +112,12 @@ FineAtoms::FineAtoms(const FineAtoms &fa) } int -FineAtoms::check_variable(const char *name) const +FineAtoms::check_variable(const string &name) const { string str; int ll; parse_variable(name, str, ll); - if (varnames.query(str.c_str())) + if (varnames.query(str)) return DynamicAtoms::check_variable(name); else { @@ -152,7 +141,7 @@ FineAtoms::parsing_finished(VarOrdering::ord_type ot) // by default, concatenate outer endo and outer exo and make it as // allvar outer: - vector allvar_tmp; + vector allvar_tmp; allvar_tmp.insert(allvar_tmp.end(), endovars.begin(), endovars.end()); allvar_tmp.insert(allvar_tmp.end(), exovars.begin(), exovars.end()); @@ -161,13 +150,13 @@ FineAtoms::parsing_finished(VarOrdering::ord_type ot) void FineAtoms::parsing_finished(VarOrdering::ord_type ot, - const vector allvar) + const vector &allvar) { make_internal_orderings(ot); allvar_order = std::make_unique(allvar, *this); } -const vector & +const vector & FineAtoms::get_allvar() const { if (!allvar_order) @@ -367,7 +356,7 @@ FineAtoms::get_exo_atoms_map() const } int -FineAtoms::name2outer_param(const char *name) const +FineAtoms::name2outer_param(const string &name) const { auto it = param_outer_map.find(name); if (it == param_outer_map.end()) @@ -377,7 +366,7 @@ FineAtoms::name2outer_param(const char *name) const } int -FineAtoms::name2outer_endo(const char *name) const +FineAtoms::name2outer_endo(const string &name) const { auto it = endo_outer_map.find(name); if (it == endo_outer_map.end()) @@ -387,7 +376,7 @@ FineAtoms::name2outer_endo(const char *name) const } int -FineAtoms::name2outer_exo(const char *name) const +FineAtoms::name2outer_exo(const string &name) const { auto it = exo_outer_map.find(name); if (it == exo_outer_map.end()) @@ -397,7 +386,7 @@ FineAtoms::name2outer_exo(const char *name) const } int -FineAtoms::name2outer_allvar(const char *name) const +FineAtoms::name2outer_allvar(const string &name) const { if (!allvar_order) throw ogu::Exception(__FILE__, __LINE__, @@ -419,33 +408,33 @@ FineAtoms::name2outer_allvar(const char *name) const } void -FineAtoms::register_uniq_endo(const char *name) +FineAtoms::register_uniq_endo(string name) { if (varnames.query(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.emplace(ss, endovars.size()-1); + varnames.insert(name); + endovars.push_back(name); + endo_outer_map.emplace(std::move(name), endovars.size()-1); } void -FineAtoms::register_uniq_exo(const char *name) +FineAtoms::register_uniq_exo(string name) { if (varnames.query(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.emplace(ss, exovars.size()-1); + varnames.insert(name); + exovars.push_back(name); + exo_outer_map.emplace(std::move(name), exovars.size()-1); } void -FineAtoms::register_uniq_param(const char *name) +FineAtoms::register_uniq_param(string name) { if (varnames.query(name)) throw ogp::ParserException(string("Parameter <")+name+"> is not unique.", 0); - const char *ss = varnames.insert(name); - params.push_back(ss); - param_outer_map.emplace(ss, params.size()-1); + varnames.insert(name); + params.push_back(name); + param_outer_map.emplace(std::move(name), params.size()-1); } void @@ -508,24 +497,24 @@ FineAtoms::print() const DynamicAtoms::print(); if (endo_order) { - printf("Endo ordering:\n"); + std::cout << "Endo ordering:\n"; endo_order->print(); } else - printf("Endo ordering not created.\n"); + std::cout << "Endo ordering not created.\n"; if (exo_order) { - printf("Exo ordering:\n"); + std::cout << "Exo ordering:\n"; exo_order->print(); } else - printf("Exo ordering not created.\n"); + std::cout << "Exo ordering not created.\n"; - printf("endo atoms map:\n"); + std::cout << "endo atoms map:\n"; for (unsigned int i = 0; i < endo_atoms_map.size(); i++) - printf(u8"%d → %d\n", i, endo_atoms_map[i]); - printf("exo atoms map:\n"); + std::cout << i << u8" → " << endo_atoms_map[i] << "\n"; + std::cout << "exo atoms map:\n"; for (unsigned int i = 0; i < exo_atoms_map.size(); i++) - printf(u8"%d → %d\n", i, exo_atoms_map[i]); + std::cout << i << u8" → " << exo_atoms_map[i] << "\n"; } diff --git a/dynare++/parser/cc/fine_atoms.hh b/dynare++/parser/cc/fine_atoms.hh index 21723f537..10261129d 100644 --- a/dynare++/parser/cc/fine_atoms.hh +++ b/dynare++/parser/cc/fine_atoms.hh @@ -23,17 +23,17 @@ namespace ogp class EndoVarOrdering1 : public VarOrdering { public: - EndoVarOrdering1(const vector &vnames, const DynamicAtoms &a) + EndoVarOrdering1(const vector &vnames, const DynamicAtoms &a) : VarOrdering(vnames, a) { } - EndoVarOrdering1(const EndoVarOrdering1 &vo, const vector &vnames, + EndoVarOrdering1(const EndoVarOrdering1 &vo, const vector &vnames, const DynamicAtoms &a) : VarOrdering(vo, vnames, a) { } std::unique_ptr - clone(const vector &vnames, const DynamicAtoms &a) const override + clone(const vector &vnames, const DynamicAtoms &a) const override { return std::make_unique(*this, vnames, a); } @@ -51,17 +51,17 @@ namespace ogp class EndoVarOrdering2 : public VarOrdering { public: - EndoVarOrdering2(const vector &vnames, const DynamicAtoms &a) + EndoVarOrdering2(const vector &vnames, const DynamicAtoms &a) : VarOrdering(vnames, a) { } - EndoVarOrdering2(const EndoVarOrdering2 &vo, const vector &vnames, + EndoVarOrdering2(const EndoVarOrdering2 &vo, const vector &vnames, const DynamicAtoms &a) : VarOrdering(vo, vnames, a) { } std::unique_ptr - clone(const vector &vnames, const DynamicAtoms &a) const override + clone(const vector &vnames, const DynamicAtoms &a) const override { return std::make_unique(*this, vnames, a); } @@ -78,17 +78,17 @@ namespace ogp class ExoVarOrdering : public VarOrdering { public: - ExoVarOrdering(const vector &vnames, const DynamicAtoms &a) + ExoVarOrdering(const vector &vnames, const DynamicAtoms &a) : VarOrdering(vnames, a) { } - ExoVarOrdering(const ExoVarOrdering &vo, const vector &vnames, + ExoVarOrdering(const ExoVarOrdering &vo, const vector &vnames, const DynamicAtoms &a) : VarOrdering(vo, vnames, a) { } std::unique_ptr - clone(const vector &vnames, const DynamicAtoms &a) const override + clone(const vector &vnames, const DynamicAtoms &a) const override { return std::make_unique(*this, vnames, a); } @@ -109,12 +109,12 @@ namespace ogp { protected: /** Type for a map mapping a variable name to an integer. */ - using Tvarintmap = map; + using Tvarintmap = map; /** Reference to atoms. */ const FineAtoms &atoms; /** The vector of all endo and exo variables in outer * ordering. The pointers point to storage in atoms. */ - vector allvar; + vector allvar; /** The mapping from outer endogenous to outer all. For * example endo2all[0] is the order of the first outer * endogenous variable in the allvar ordering. */ @@ -129,7 +129,7 @@ namespace ogp * arbitrary storage, the storage is transformed to the atoms * storage. An exception is thrown if either the list is not * exhaustive, or some string is not a variable. */ - AllvarOuterOrdering(const vector &allvar_outer, const FineAtoms &a); + AllvarOuterOrdering(const vector &allvar_outer, const FineAtoms &a); /** Copy constructor using the storage of provided atoms. */ AllvarOuterOrdering(const AllvarOuterOrdering &allvar_outer, const FineAtoms &a); /** Return endo2all mapping. */ @@ -145,7 +145,7 @@ namespace ogp return exo2all; } /** Return the allvar ordering. */ - const vector & + const vector & get_allvar() const { return allvar; @@ -175,23 +175,23 @@ namespace ogp { friend class AllvarOuterOrdering; protected: - using Tvarintmap = map; + using Tvarintmap = map; private: /** The vector of parameters names. The order gives the order * the data is communicated with outside world. */ - vector params; + vector params; /** A map mapping a name of a parameter to an index in the outer * ordering. */ Tvarintmap param_outer_map; /** The vector of endogenous variables. This defines the order * like parameters. */ - vector endovars; + vector endovars; /** A map mapping a name of an endogenous variable to an index * in the outer ordering. */ Tvarintmap endo_outer_map; /** The vector of exogenous variables. Also defines the order * like parameters and endovars. */ - vector exovars; + vector exovars; /** A map mapping a name of an exogenous variable to an index * in the outer ordering. */ Tvarintmap exo_outer_map; @@ -237,7 +237,7 @@ namespace ogp * variable is declared by inserting it to * DynamicAtoms::varnames. This is a responsibility of a * subclass. */ - int check_variable(const char *name) const override; + int check_variable(const string &name) const override; /** This calculates min lag and max lead of endogenous variables. */ void endovarspan(int &mlead, int &mlag) const @@ -254,19 +254,19 @@ namespace ogp * one exogenous variable occurs. */ int num_exo_periods() const; /** Return an (external) ordering of parameters. */ - const vector & + const vector & get_params() const { return params; } /** Return an external ordering of endogenous variables. */ - const vector & + const vector & get_endovars() const { return endovars; } /** Return an external ordering of exogenous variables. */ - const vector & + const vector & get_exovars() const { return exovars; @@ -282,20 +282,20 @@ namespace ogp * inputing a different outer ordering of all variables. The * ordering is input as a list of strings, their storage can * be arbitrary. */ - void parsing_finished(VarOrdering::ord_type ot, const vector avo); + void parsing_finished(VarOrdering::ord_type ot, const vector &avo); /** Return the external ordering of all variables (endo and * exo). This is either the second argument to * parsing_finished or the default external ordering. This * must be called only after parsing_finished. */ - const vector&get_allvar() const; + const vector &get_allvar() const; /** Return the map from outer ordering of endo variables to * the allvar ordering. This must be called only after * parsing_finished. */ - const vector&outer_endo2all() const; + const vector &outer_endo2all() const; /** Return the map from outer ordering of exo variables to * the allvar ordering. This must be called only after * parsing_finished. */ - const vector&outer_exo2all() const; + const vector &outer_exo2all() const; /** Return the atoms with respect to which we are going to * differentiate. This must be called after * parsing_finished. */ @@ -340,20 +340,20 @@ namespace ogp /** Return an index in the outer ordering of a given * parameter. An exception is thrown if the name is not a * parameter. */ - int name2outer_param(const char *name) const; + int name2outer_param(const string &name) const; /** Return an index in the outer ordering of a given * endogenous variable. An exception is thrown if the name is not a * and endogenous variable. */ - int name2outer_endo(const char *name) const; + int name2outer_endo(const string &name) const; /** Return an index in the outer ordering of a given * exogenous variable. An exception is thrown if the name is not a * and exogenous variable. */ - int name2outer_exo(const char *name) const; + int name2outer_exo(const string &name) const; /** Return an index in the outer ordering of all variables * (endo and exo) for a given name. An exception is thrown if * the name is not a variable. This must be called only after * parsing_finished(). */ - int name2outer_allvar(const char *name) const; + int name2outer_allvar(const string &name) const; /** Return the number of endogenous variables at time t-1, these are state * variables. */ int @@ -389,17 +389,17 @@ namespace ogp * calls defines the endo outer ordering. The method is * virtual, since a superclass may want to do some additional * action. */ - virtual void register_uniq_endo(const char *name); + virtual void register_uniq_endo(string name); /** Register unique exogenous variable name. The order of * calls defines the exo outer ordering. The method is * virtual, since a superclass may want to do somem additional * action. */ - virtual void register_uniq_exo(const char *name); + virtual void register_uniq_exo(string name); /** Register unique parameter name. The order of calls defines * the param outer ordering. The method is * virtual, since a superclass may want to do somem additional * action. */ - virtual void register_uniq_param(const char *name); + virtual void register_uniq_param(string name); /** Debug print. */ void print() const override; private: diff --git a/dynare++/parser/cc/formula.yy b/dynare++/parser/cc/formula.yy index e205bae3a..f8ac65042 100644 --- a/dynare++/parser/cc/formula.yy +++ b/dynare++/parser/cc/formula.yy @@ -10,8 +10,9 @@ %code { #include "formula_parser.hh" +#include -void fmla_error(const char*); +void fmla_error(std::string); int fmla_lex(); extern ogp::FormulaParser* fparser; } @@ -76,7 +77,7 @@ extern ogp::FormulaParser* fparser; %% void -fmla_error(const char* s) +fmla_error(std::string s) { - fparser->error(s); + fparser->error(std::move(s)); } diff --git a/dynare++/parser/cc/formula_parser.cc b/dynare++/parser/cc/formula_parser.cc index 97ca75934..4498f8a1d 100644 --- a/dynare++/parser/cc/formula_parser.cc +++ b/dynare++/parser/cc/formula_parser.cc @@ -65,7 +65,7 @@ FormulaParser::add_unary(code_t code, int t) } int -FormulaParser::add_nulary(const char *str) +FormulaParser::add_nulary(const string &str) { int t = -1; try @@ -116,7 +116,7 @@ FormulaParser *fparser; /** The declarations of functions defined in formula_ll.cc and * formula_tab.cc generated from formula.lex and formula.y */ -void *fmla__scan_buffer(char *, size_t); +void *fmla__scan_string(const char *); void fmla__destroy_buffer(void *); int fmla_parse(); extern location_type fmla_lloc; @@ -126,24 +126,20 @@ extern location_type fmla_lloc; * the pointer returned from fmla_scan_buffer must be freed at the * end. */ void -FormulaParser::parse(int length, const char *stream) +FormulaParser::parse(const string &stream) { - 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.get(), static_cast(length)+2); + void *p = fmla__scan_string(stream.c_str()); fparser = this; fmla_parse(); fmla__destroy_buffer(p); } void -FormulaParser::error(const char *mes) const +FormulaParser::error(string mes) const { - throw ParserException(mes, fmla_lloc.off); + throw ParserException(std::move(mes), fmla_lloc.off); } int @@ -173,12 +169,12 @@ FormulaParser::print() const atoms.print(); for (int formula : formulas) { - printf("formula %d:\n", formula); + std::cout << "formula " << formula << ":\n"; otree.print_operation(formula); } for (unsigned int i = 0; i < ders.size(); i++) { - printf("derivatives for the formula %d:\n", formulas[i]); + std::cout << "derivatives for the formula " << formulas[i] << ":\n"; ders[i]->print(otree); } } @@ -261,9 +257,9 @@ FormulaDerivatives::print(const OperationTree &otree) const { for (const auto & it : ind2der) { - printf("derivative "); + std::cout << "derivative "; it.first.print(); - printf(" is formula %d\n", tder[it.second]); + std::cout << " is formula " << tder[it.second] << '\n'; otree.print_operation(tder[it.second]); } } @@ -409,10 +405,10 @@ FoldMultiIndex::offset() const void FoldMultiIndex::print() const { - printf("["); + std::cout << "["; for (int i = 0; i < ord; i++) - printf("%d ", data[i]); - printf("]"); + std::cout << data[i] << ' '; + std::cout << "]"; } int diff --git a/dynare++/parser/cc/formula_parser.hh b/dynare++/parser/cc/formula_parser.hh index b754314aa..c1f370bb3 100644 --- a/dynare++/parser/cc/formula_parser.hh +++ b/dynare++/parser/cc/formula_parser.hh @@ -25,11 +25,11 @@ namespace ogp * yet. The method can raise an exception, if the Atoms * implementation is strict and the name is not among * prescribed possible values. */ - virtual int check(const char *name) const = 0; + virtual int check(const std::string &name) const = 0; /** This method assigns an internal index to the nulary term * described by the name. The internal index is allocated by * OperationTree class. */ - virtual void assign(const char *name, int t) = 0; + virtual void assign(const std::string &name, int t) = 0; /** Returns a number of variables which will be used for * differentiations. */ virtual int nvar() const = 0; @@ -174,7 +174,7 @@ namespace ogp * string. The Atoms are consulted for uniquness and are given * an internal index generated by the OperationTree. This is * the channel through which the Atoms are filled. */ - int add_nulary(const char *str); + int add_nulary(const std::string &str); /** Adds a derivative to the tree. This just calls * OperationTree::add_derivative. */ @@ -228,9 +228,9 @@ namespace ogp /** Parse a given string containing one or more formulas. The * formulas are parsed and added to the OperationTree and to * the formulas vector. */ - void parse(int length, const char *stream); + void parse(const std::string &stream); /** Processes a syntax error from bison. */ - void error(const char *mes) const; + void error(std::string mes) const; /** Differentiate all the formulas up to the given order. The * variables with respect to which the derivatives are taken * are obtained by Atoms::variables(). If the derivates exist, diff --git a/dynare++/parser/cc/matrix.ll b/dynare++/parser/cc/matrix.ll index 57017c344..91bdb6486 100644 --- a/dynare++/parser/cc/matrix.ll +++ b/dynare++/parser/cc/matrix.ll @@ -2,10 +2,12 @@ %{ // Copyright © 2006-2011, Ondra Kamenik +#include + #include "location.hh" #include "matrix_tab.hh" -extern void matrix_error(const char*); +extern void matrix_error(std::string); #define YY_USER_ACTION SET_LLOC(matrix_); %} @@ -43,9 +45,7 @@ extern void matrix_error(const char*); } . { - char mes[300]; - sprintf(mes, "Unrecognized character %s", matrix_text); - matrix_error(mes); + matrix_error(std::string{"Unrecognized character "} + matrix_text); } %% diff --git a/dynare++/parser/cc/matrix.yy b/dynare++/parser/cc/matrix.yy index 83167edce..7d6cea5dd 100644 --- a/dynare++/parser/cc/matrix.yy +++ b/dynare++/parser/cc/matrix.yy @@ -11,7 +11,7 @@ { #include "matrix_parser.hh" -void matrix_error(const char*); +void matrix_error(std::string); int matrix_lex(); extern ogp::MatrixParser* mparser; } @@ -63,9 +63,9 @@ one_row : NEW_ROW {mparser->start_row();} lod; %% void -matrix_error(const char* s) +matrix_error(std::string s) { - mparser->error(s); + mparser->error(std::move(s)); } diff --git a/dynare++/parser/cc/matrix_parser.cc b/dynare++/parser/cc/matrix_parser.cc index 7dc9cb5ec..ae3ac67dc 100644 --- a/dynare++/parser/cc/matrix_parser.cc +++ b/dynare++/parser/cc/matrix_parser.cc @@ -7,7 +7,6 @@ #include "location.hh" #include "matrix_tab.hh" -#include #include using namespace ogp; @@ -18,26 +17,22 @@ MatrixParser *mparser; /** The declaration of functions defined in matrix_ll.cc and * matrix_tab.cc generated from matrix.lex and matrix.y. */ -void *matrix__scan_buffer(char *, size_t); +void *matrix__scan_string(const char *); void matrix__destroy_buffer(void *); int matrix_parse(); extern ogp::location_type matrix_lloc; void -MatrixParser::parse(int length, const char *stream) +MatrixParser::parse(const string &stream) { // reinitialize the object data.clear(); row_lengths.clear(); nc = 0; // allocate temporary buffer and parse - 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.get(), static_cast(length)+2); + void *p = matrix__scan_string(stream.c_str()); mparser = this; matrix_parse(); matrix__destroy_buffer(p); @@ -60,9 +55,9 @@ MatrixParser::start_row() } void -MatrixParser::error(const char *mes) const +MatrixParser::error(string mes) const { - throw ParserException(mes, matrix_lloc.off); + throw ParserException(std::move(mes), matrix_lloc.off); } int diff --git a/dynare++/parser/cc/matrix_parser.hh b/dynare++/parser/cc/matrix_parser.hh index 179751e4a..35dd58bd8 100644 --- a/dynare++/parser/cc/matrix_parser.hh +++ b/dynare++/parser/cc/matrix_parser.hh @@ -6,6 +6,7 @@ #define OGP_MATRIX_PARSER #include +#include namespace ogp { @@ -48,7 +49,7 @@ namespace ogp return nc; } /** Parses a given data. This initializes the object data. */ - void parse(int length, const char *stream); + void parse(const std::string &stream); /** Adds newly read item. This should be called from bison * parser. */ void add_item(double v); @@ -56,7 +57,7 @@ namespace ogp * parser. */ void start_row(); /** Process a parse error from the parser. */ - void error(const char *mes) const; + void error(std::string mes) const; /** Return begin iterator. */ MPIterator begin() const; /** Return end iterator. */ diff --git a/dynare++/parser/cc/namelist.cc b/dynare++/parser/cc/namelist.cc deleted file mode 100644 index 3353831af..000000000 --- a/dynare++/parser/cc/namelist.cc +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright © 2006, Ondra Kamenik - -// $Id: namelist.cpp 42 2007-01-22 21:53:24Z ondra $ - -#include "namelist.hh" - -#include -#include - -using namespace ogp; - -/** A global symbol for passing info to NameListParser from its - * parser. */ -NameListParser *name_list_parser; - -void *namelist__scan_buffer(char *, unsigned int); -void namelist__destroy_buffer(void *); -void namelist_parse(); - -void -NameListParser::namelist_parse(int length, const char *stream) -{ - 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.get(), static_cast(length)+2); - name_list_parser = this; - ::namelist_parse(); - namelist__destroy_buffer(p); -} diff --git a/dynare++/parser/cc/namelist.hh b/dynare++/parser/cc/namelist.hh deleted file mode 100644 index db29dd1bc..000000000 --- a/dynare++/parser/cc/namelist.hh +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright © 2007, Ondra Kamenik - -// $Id: namelist.h 107 2007-05-10 22:35:04Z ondra $ - -#ifndef OGP_NAMELIST -#define OGP_NAMELIST - -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. - * - * Parsing a name list is done as follows: implement - * NameListParser interface, create the object, and call - * NameListParser::namelist_parse(int lengt, const char* - * text). When implementing error(), one may consult global - * location_type namelist_lloc. */ - class NameListParser - { - public: - 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); - }; -}; - -#endif diff --git a/dynare++/parser/cc/namelist.ll b/dynare++/parser/cc/namelist.ll deleted file mode 100644 index 057439768..000000000 --- a/dynare++/parser/cc/namelist.ll +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- C++ -*- */ -%{ -#include "location.hh" -#include "namelist_tab.hh" - -#define YY_USER_ACTION SET_LLOC(namelist_); -%} - -%option nounput -%option noyy_top_state -%option stack -%option prefix="namelist_" -%option never-interactive -%x CMT - -%% - - /* comments */ -<*>"/*" {yy_push_state(CMT);} -[^*\n]* -"*"+[^*/\n]* -"*"+"/" {yy_pop_state();} -[\n] -"//".*\n - - /* initial spaces or tabs are ignored */ -[ \t\r\n\0] - - /* names */ -[A-Za-z_][A-Za-z0-9_]* { - namelist_lval.string = namelist_text; - return NAME; -} - -, {return COMMA;} -. { - namelist_lval.character = namelist_text[0]; - return CHARACTER; -} - -%% - -int -namelist_wrap() -{ - return 1; -} - -void -namelist__destroy_buffer(void* p) -{ - namelist__delete_buffer(static_cast(p)); -} diff --git a/dynare++/parser/cc/namelist.yy b/dynare++/parser/cc/namelist.yy deleted file mode 100644 index a50d19822..000000000 --- a/dynare++/parser/cc/namelist.yy +++ /dev/null @@ -1,48 +0,0 @@ -// -*- C++ -*- -// Copyright © 2007-2011, Ondra Kamenik - -%code requires -{ -#include "location.hh" -#define NAMELIST_LTYPE ogp::location_type -} - -%code -{ -#include "namelist.hh" - -void namelist_error(const char*); -int namelist_lex(); -extern ogp::NameListParser* name_list_parser; -} - -%union -{ - int integer; - char *string; - char character; -} - -%token COMMA CHARACTER -%token NAME; - -%define api.prefix {namelist_} - -%locations -%defines -%define parse.error verbose - -%% - -namelist : namelist NAME {name_list_parser->add_name($2);} - | namelist COMMA NAME {name_list_parser->add_name($3);} - | NAME {name_list_parser->add_name($1);} - ; - -%% - -void -namelist_error(const char* mes) -{ - name_list_parser->namelist_error(mes); -} diff --git a/dynare++/parser/cc/static_atoms.cc b/dynare++/parser/cc/static_atoms.cc index baa9d59c9..2e31eeb47 100644 --- a/dynare++/parser/cc/static_atoms.cc +++ b/dynare++/parser/cc/static_atoms.cc @@ -7,32 +7,6 @@ using namespace ogp; -StaticAtoms::StaticAtoms(const StaticAtoms &a) - : Atoms(), Constants(a), varnames(a.varnames), - varorder(), vars(), indices() -{ - // fill varorder - for (auto i : a.varorder) - { - const char *s = varnames.query(i); - varorder.push_back(s); - } - - // fill vars - for (auto var : a.vars) - { - const char *s = varnames.query(var.first); - vars.emplace(s, var.second); - } - - // fill indices - for (auto indice : a.indices) - { - const char *s = varnames.query(indice.second); - indices.emplace(indice.first, s); - } -} - void StaticAtoms::import_atoms(const DynamicAtoms &da, OperationTree &otree, Tintintmap &tmap) { @@ -40,14 +14,14 @@ StaticAtoms::import_atoms(const DynamicAtoms &da, OperationTree &otree, Tintintm for (int i = 0; i < da.get_name_storage().num(); i++) { - const char *name = da.get_name_storage().get_name(i); + const string &name = da.get_name_storage().get_name(i); register_name(name); int tnew = otree.add_nulary(); assign(name, tnew); if (da.is_referenced(name)) { const DynamicAtoms::Tlagmap &lmap = da.lagmap(name); - for (auto it : lmap) + for (const auto &it : lmap) { int told = it.second; tmap.emplace(told, tnew); @@ -57,7 +31,7 @@ StaticAtoms::import_atoms(const DynamicAtoms &da, OperationTree &otree, Tintintm } int -StaticAtoms::check(const char *name) const +StaticAtoms::check(const string &name) const { if (DynamicAtoms::is_string_constant(name)) return Constants::check(name); @@ -66,7 +40,7 @@ StaticAtoms::check(const char *name) const } int -StaticAtoms::index(const char *name) const +StaticAtoms::index(const string &name) const { auto it = vars.find(name); if (it == vars.end()) @@ -75,18 +49,8 @@ StaticAtoms::index(const char *name) const return it->second; } -const char * -StaticAtoms::inv_index(int t) const -{ - auto it = indices.find(t); - if (it == indices.end()) - return nullptr; - else - return it->second; -} - void -StaticAtoms::assign(const char *name, int t) +StaticAtoms::assign(const string &name, int t) { if (DynamicAtoms::is_string_constant(name)) { @@ -95,9 +59,9 @@ StaticAtoms::assign(const char *name, int t) } else { - const char *ss = varnames.insert(name); - vars.emplace(ss, t); - indices.emplace(t, ss); + varnames.insert(name); + vars.emplace(name, t); + indices.emplace(t, name); } } @@ -105,26 +69,26 @@ vector StaticAtoms::variables() const { vector res; - for (auto var : vars) + for (const auto &var : vars) res.push_back(var.second); return res; } void -StaticAtoms::register_name(const char *name) +StaticAtoms::register_name(string name) { - const char *ss = varnames.insert(name); - varorder.push_back(ss); + varnames.insert(name); + varorder.push_back(std::move(name)); } void StaticAtoms::print() const { - printf("constants:\n"); + std::cout << "constants:\n"; Constants::print(); - printf("variable names:\n"); + std::cout << "variable names:\n"; varnames.print(); - printf("map to tree indices:\n"); + std::cout << "map to tree indices:\n"; for (auto var : vars) - printf(u8"%s\t→\t%d\n", var.first, var.second); + std::cout << var.first << u8"\t→\t" << var.second << "\n"; } diff --git a/dynare++/parser/cc/static_atoms.hh b/dynare++/parser/cc/static_atoms.hh index fefc823aa..437ad8775 100644 --- a/dynare++/parser/cc/static_atoms.hh +++ b/dynare++/parser/cc/static_atoms.hh @@ -12,12 +12,12 @@ namespace ogp class StaticAtoms : public Atoms, public Constants { protected: - using Tvarmap = map; - using Tinvmap = map; + using Tvarmap = map; + using Tinvmap = map; /** Storage for names. */ NameStorage varnames; /** Outer order of variables. */ - vector varorder; + vector varorder; /** This is the map mapping a variable name to the tree * index. */ Tvarmap vars; @@ -25,11 +25,7 @@ namespace ogp * variable name. */ Tinvmap indices; public: - StaticAtoms() : Atoms(), Constants(), varnames(), varorder(), vars() - { - } - /* Copy constructor. */ - StaticAtoms(const StaticAtoms &a); + StaticAtoms() = default; /** Conversion from DynamicAtoms. This takes all atoms from * the DynamicAtoms and adds its static version. The new tree * indices are allocated in the passed OperationTree. Whole @@ -51,10 +47,10 @@ namespace ogp * constant is registered in Constants, it returns -1 * otherwise. If the name is not constant, it returns result * from check_variable, which is implemented by a subclass. */ - int check(const char *name) const override; + int check(const string &name) const override; /** This assigns a given tree index to the variable name. The * name should have been checked before the call. */ - void assign(const char *name, int t) override; + void assign(const string &name, int t) override; int nvar() const override { @@ -63,12 +59,9 @@ namespace ogp /** This returns a vector of all variables. */ vector variables() const override; /** This returns a tree index of the given variable. */ - int index(const char *name) const; - /** This returns a name from the given tree index. NULL is - * returned if the tree index doesn't exist. */ - const char *inv_index(int t) const; + int index(const string &name) const; /** This returns a name in a outer ordering. (There is no other ordering.) */ - const char * + const string & name(int i) const { return varorder[i]; @@ -79,7 +72,7 @@ namespace ogp * this, for example, to ensure uniqueness of the * name. However, this method should be always called in * overriding methods to do the registering job. */ - virtual void register_name(const char *name); + virtual void register_name(string name); /** Return the name storage to allow querying to other * classes. */ const NameStorage & @@ -91,7 +84,7 @@ namespace ogp /** This checks the variable. The implementing subclass might * want to throw an exception if the variable has not been * registered. */ - virtual int check_variable(const char *name) const = 0; + virtual int check_variable(const string &name) const = 0; }; }; diff --git a/dynare++/parser/cc/static_fine_atoms.cc b/dynare++/parser/cc/static_fine_atoms.cc index 12e25a6e2..2d49fe457 100644 --- a/dynare++/parser/cc/static_fine_atoms.cc +++ b/dynare++/parser/cc/static_fine_atoms.cc @@ -9,37 +9,6 @@ using namespace ogp; -StaticFineAtoms::StaticFineAtoms(const StaticFineAtoms &sfa) - : StaticAtoms(sfa), - params(), param_outer_map(), - endovars(), endo_outer_map(), - exovars(), exo_outer_map(), - der_atoms(sfa.der_atoms), - endo_atoms_map(sfa.endo_atoms_map), - exo_atoms_map(sfa.exo_atoms_map) -{ - for (unsigned int i = 0; i < sfa.params.size(); i++) - { - const char *name = varnames.query(sfa.params[i]); - params.push_back(name); - 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.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.emplace(name, i); - } -} - void StaticFineAtoms::import_atoms(const FineAtoms &fa, OperationTree &otree, Tintintmap &tmap) { @@ -49,18 +18,18 @@ StaticFineAtoms::import_atoms(const FineAtoms &fa, OperationTree &otree, Tintint // respective vectors, the names are already in the storage // parameters - const vector &fa_params = fa.get_params(); - for (auto fa_param : fa_params) + auto &fa_params = fa.get_params(); + for (const auto &fa_param : fa_params) register_param(fa_param); // endogenous - const vector &fa_endovars = fa.get_endovars(); - for (auto fa_endovar : fa_endovars) + auto &fa_endovars = fa.get_endovars(); + for (const auto &fa_endovar : fa_endovars) register_endo(fa_endovar); // exogenous - const vector &fa_exovars = fa.get_exovars(); - for (auto fa_exovar : fa_exovars) + auto &fa_exovars = fa.get_exovars(); + for (const auto &fa_exovar : fa_exovars) register_exo(fa_exovar); parsing_finished(); @@ -76,17 +45,17 @@ StaticFineAtoms::import_atoms(const FineAtoms &fa, OperationTree &otree, Tintint // respective vectors, the names are already in the storage // parameters - const vector &fa_params = fa.get_params(); - for (auto fa_param : fa_params) + auto &fa_params = fa.get_params(); + for (const auto &fa_param : fa_params) register_param(fa_param); // endogenous - const vector &fa_endovars = fa.get_endovars(); + auto &fa_endovars = fa.get_endovars(); for (unsigned int i = 0; i < fa_endovars.size(); i++) register_endo(fa_endovars[fa.y2outer_endo()[i]]); // exogenous - const vector &fa_exovars = fa.get_exovars(); + auto &fa_exovars = fa.get_exovars(); for (unsigned int i = 0; i < fa_exovars.size(); i++) register_exo(fa_exovars[fa.y2outer_exo()[i]]); @@ -94,10 +63,9 @@ StaticFineAtoms::import_atoms(const FineAtoms &fa, OperationTree &otree, Tintint } int -StaticFineAtoms::check_variable(const char *name) const +StaticFineAtoms::check_variable(const string &name) const { - const char *ss = varnames.query(name); - if (!ss) + if (!varnames.query(name)) throw ParserException(string("Variable <")+name+"> not declared.", 0); return index(name); } @@ -133,7 +101,7 @@ StaticFineAtoms::parsing_finished() } int -StaticFineAtoms::name2outer_param(const char *name) const +StaticFineAtoms::name2outer_param(const string &name) const { auto it = param_outer_map.find(name); if (it == param_outer_map.end()) @@ -143,7 +111,7 @@ StaticFineAtoms::name2outer_param(const char *name) const } int -StaticFineAtoms::name2outer_endo(const char *name) const +StaticFineAtoms::name2outer_endo(const string &name) const { auto it = endo_outer_map.find(name); if (it == endo_outer_map.end()) @@ -153,7 +121,7 @@ StaticFineAtoms::name2outer_endo(const char *name) const } int -StaticFineAtoms::name2outer_exo(const char *name) const +StaticFineAtoms::name2outer_exo(const string &name) const { auto it = exo_outer_map.find(name); if (it == exo_outer_map.end()) @@ -163,75 +131,72 @@ StaticFineAtoms::name2outer_exo(const char *name) const } void -StaticFineAtoms::register_uniq_endo(const char *name) +StaticFineAtoms::register_uniq_endo(string name) { if (varnames.query(name)) throw ogp::ParserException(string("Endogenous variable <")+name+"> is not unique.", 0); - const char *ss = varnames.insert(name); - register_endo(ss); + varnames.insert(name); + register_endo(std::move(name)); } void -StaticFineAtoms::register_uniq_exo(const char *name) +StaticFineAtoms::register_uniq_exo(string name) { if (varnames.query(name)) throw ogp::ParserException(string("Exogenous variable <")+name+"> is not unique.", 0); - const char *ss = varnames.insert(name); - register_exo(ss); + varnames.insert(name); + register_exo(std::move(name)); } void -StaticFineAtoms::register_uniq_param(const char *name) +StaticFineAtoms::register_uniq_param(string name) { if (varnames.query(name)) throw ogp::ParserException(string("Parameter <")+name+"> is not unique.", 0); - const char *ss = varnames.insert(name); - register_param(ss); + varnames.insert(name); + register_param(std::move(name)); } void StaticFineAtoms::print() const { StaticAtoms::print(); - printf("endo atoms map:\n"); + std::cout << "endo atoms map:\n"; for (unsigned int i = 0; i < endo_atoms_map.size(); i++) - printf(u8"%d → %d\n", i, endo_atoms_map[i]); - printf("exo atoms map:\n"); + std::cout << i << u8" → " << endo_atoms_map[i] << "\n"; + std::cout << "exo atoms map:\n"; for (unsigned int i = 0; i < exo_atoms_map.size(); i++) - printf(u8"%d → %d\n", i, exo_atoms_map[i]); - printf("der atoms:\n"); + std::cout << i << u8" → " << exo_atoms_map[i] << "\n"; + std::cout << "der atoms:\n"; for (unsigned int i = 0; i < der_atoms.size(); i++) - printf("%d\t%d\n", i, der_atoms[i]); + std::cout << i << "\t" << der_atoms[i] << "\n"; } void -StaticFineAtoms::register_endo(const char *name) +StaticFineAtoms::register_endo(string name) { - const char *ss = varnames.query(name); - if (!ss) + if (!varnames.query(name)) throw ogp::ParserException(string("Endogenous variable <") +name+"> not found in storage.", 0); - endovars.push_back(ss); - endo_outer_map.emplace(ss, endovars.size()-1); + endovars.push_back(name); + endo_outer_map.emplace(std::move(name), endovars.size()-1); } void -StaticFineAtoms::register_exo(const char *name) +StaticFineAtoms::register_exo(string name) { - const char *ss = varnames.query(name); - if (!ss) + if (!varnames.query(name)) throw ogp::ParserException(string("Exogenous variable <") +name+"> not found in storage.", 0); - exovars.push_back(ss); - exo_outer_map.emplace(ss, exovars.size()-1); + exovars.push_back(name); + exo_outer_map.emplace(std::move(name), exovars.size()-1); } void -StaticFineAtoms::register_param(const char *name) +StaticFineAtoms::register_param(string name) { - const char *ss = varnames.query(name); - if (!ss) + if (!varnames.query(name)) throw ogp::ParserException(string("Parameter <")+name+"> not found in storage.", 0); - params.push_back(ss); - param_outer_map.emplace(ss, params.size()-1); + params.push_back(name); + param_outer_map.emplace(std::move(name), params.size()-1); } diff --git a/dynare++/parser/cc/static_fine_atoms.hh b/dynare++/parser/cc/static_fine_atoms.hh index 2053a78a4..1f09f3c5f 100644 --- a/dynare++/parser/cc/static_fine_atoms.hh +++ b/dynare++/parser/cc/static_fine_atoms.hh @@ -23,22 +23,22 @@ namespace ogp public: using Tintintmap = map; protected: - using Tvarintmap = map; + using Tvarintmap = map; private: /** The vector of parameter names, gives the parameter * ordering. */ - vector params; + vector params; /** A map mappping a parameter name to an index in the ordering. */ Tvarintmap param_outer_map; /** The vector of endogenous variables. This defines the order * like parameters. */ - vector endovars; + vector endovars; /** A map mapping a name of an endogenous variable to an index * in the ordering. */ Tvarintmap endo_outer_map; /** The vector of exogenous variables. Also defines the order * like parameters and endovars. */ - vector exovars; + vector exovars; /** A map mapping a name of an exogenous variable to an index * in the outer ordering. */ Tvarintmap exo_outer_map; @@ -61,8 +61,6 @@ namespace ogp vector exo_atoms_map; public: StaticFineAtoms() = default; - /** Copy constructor making a new storage for atom names. */ - StaticFineAtoms(const StaticFineAtoms &sfa); /** Conversion from dynamic FineAtoms taking its outer * ordering as ordering of parameters, endogenous and * exogenous. A biproduct is an integer to integer map mapping @@ -99,21 +97,21 @@ namespace ogp * variable is declared by inserting it to * StaticAtoms::varnames, which is done with registering * methods. This a responsibility of a subclass. */ - int check_variable(const char *name) const override; + int check_variable(const string &name) const override; /** Return an (external) ordering of parameters. */ - const vector & + const vector & get_params() const { return params; } /** Return an external ordering of endogenous variables. */ - const vector & + const vector & get_endovars() const { return endovars; } /** Return an external ordering of exogenous variables. */ - const vector & + const vector & get_exovars() const { return exovars; @@ -144,15 +142,15 @@ namespace ogp /** Return an index in the outer ordering of a given * parameter. An exception is thrown if the name is not a * parameter. */ - int name2outer_param(const char *name) const; + int name2outer_param(const string &name) const; /** Return an index in the outer ordering of a given * endogenous variable. An exception is thrown if the name is not a * and endogenous variable. */ - int name2outer_endo(const char *name) const; + int name2outer_endo(const string &name) const; /** Return an index in the outer ordering of a given * exogenous variable. An exception is thrown if the name is not a * and exogenous variable. */ - int name2outer_exo(const char *name) const; + int name2outer_exo(const string &name) const; /** Return the number of endogenous variables. */ int ny() const @@ -175,29 +173,29 @@ namespace ogp * calls defines the endo outer ordering. The method is * virtual, since a superclass may want to do some additional * action. */ - virtual void register_uniq_endo(const char *name); + virtual void register_uniq_endo(string name); /** Register unique exogenous variable name. The order of * calls defines the exo outer ordering. The method is * virtual, since a superclass may want to do somem additional * action. */ - virtual void register_uniq_exo(const char *name); + virtual void register_uniq_exo(string name); /** Register unique parameter name. The order of calls defines * the param outer ordering. The method is * virtual, since a superclass may want to do somem additional * action. */ - virtual void register_uniq_param(const char *name); + virtual void register_uniq_param(string name); /** Debug print. */ void print() const override; private: /** Add endogenous variable name, which is already in the name * storage. */ - void register_endo(const char *name); + void register_endo(string name); /** Add exogenous variable name, which is already in the name * storage. */ - void register_exo(const char *name); + void register_exo(string name); /** Add parameter name, which is already in the name * storage. */ - void register_param(const char *name); + void register_param(string name); }; }; diff --git a/dynare++/parser/cc/tree.cc b/dynare++/parser/cc/tree.cc index 6430d0897..e9a1ac677 100644 --- a/dynare++/parser/cc/tree.cc +++ b/dynare++/parser/cc/tree.cc @@ -6,6 +6,8 @@ #include #include +#include +#include using namespace ogp; @@ -539,7 +541,7 @@ EvalTree::EvalTree(const OperationTree &ot, int last) flags[1] = true; values[2] = std::numeric_limits::quiet_NaN(); flags[2] = true; - values[3] = 2.0/sqrt(M_PI); + values[3] = 2.0/std::sqrt(M_PI); flags[3] = true; // this sets from num_constants on reset_all(); @@ -688,32 +690,29 @@ EvalTree::eval(int t) return values[t]; } - // if (! std::isfinite(values[t])) - // printf("Tree value t=%d is not finite = %f\n", t, values[t]); - return values[t]; } void EvalTree::print() const { - printf("last_op=%d\n", last_operation); - printf(" 0 1 2 3 4 5 6 7 8 9\n"); - printf("----------------------------------------------------------------\n"); + std::cout << "last_op=" << last_operation << '\n' + << " 0 1 2 3 4 5 6 7 8 9\n" + << u8"────────────────────────────────────────────────────────────────\n"; for (int i = 0; i <= (last_operation+1)/10; i++) { - printf("%-3d|", i); + std::cout << std::setw(3) << i << u8"│"; int j = 0; while (j < 10 && 10*i+j < last_operation+1) { int k = 10*i+j; if (flags[k]) - printf(" %5.1g", values[k]); + std::cout << " " << std::setw(5) << std::setprecision(1) << values[k]; else - printf(" -----"); + std::cout << u8" ─────"; j++; } - printf("\n"); + std::cout << "\n"; } } @@ -868,21 +867,20 @@ OperationStringConvertor::convert(const Operation &op, int t) const { if (t < OperationTree::num_constants) if (t == OperationTree::zero) - return std::string("0"); + return "0"; else if (t == OperationTree::one) - return std::string("1"); + return "1"; else if (t == OperationTree::nan) - return std::string("NaN"); + return "NaN"; else if (t == OperationTree::two_over_pi) { - char buf[100]; - sprintf(buf, "%20.16g", 2.0/std::sqrt(M_PI)); - return std::string(buf); + std::ostringstream buf; + buf << std::setprecision(std::numeric_limits::max_digits10) + << 2.0/std::sqrt(M_PI); + return buf.str(); } else - { - return std::string("error!error"); - } + return "error!error"; else return nulsc.convert(t); } @@ -890,7 +888,7 @@ OperationStringConvertor::convert(const Operation &op, int t) const { int t1 = op.getOp1(); const Operation &op1 = otree.operation(t1); - const char *opname = "unknown"; + std::string opname = "unknown"; switch (op.getCode()) { case code_t::UMINUS: @@ -924,7 +922,7 @@ OperationStringConvertor::convert(const Operation &op, int t) const break; } std::string s1 = convert(op1, t1); - return std::string(opname) + "(" + s1 + ")"; + return opname + "(" + s1 + ")"; } else { @@ -932,7 +930,7 @@ OperationStringConvertor::convert(const Operation &op, int t) const const Operation &op1 = otree.operation(t1); int t2 = op.getOp2(); const Operation &op2 = otree.operation(t2); - const char *opname = "unknown"; + std::string opname = "unknown"; switch (op.getCode()) { case code_t::PLUS: diff --git a/dynare++/src/dynare3.cc b/dynare++/src/dynare3.cc index 5dbddb7a5..cd04585b9 100644 --- a/dynare++/src/dynare3.cc +++ b/dynare++/src/dynare3.cc @@ -54,7 +54,7 @@ Dynare::Dynare(const std::string &modname, int ord, double sstol, Journal &jr) try { - model = std::make_unique(contents.c_str(), contents.length(), ord); + model = std::make_unique(contents, ord); } catch (const ogp::ParserException &pe) { @@ -86,13 +86,13 @@ Dynare::Dynare(const std::string &modname, int ord, double sstol, Journal &jr) Dynare::Dynare(const std::vector &endo, const std::vector &exo, const std::vector &par, - const char *equations, int len, int ord, + const std::string &equations, int ord, double sstol, Journal &jr) : journal(jr), md(1), ss_tol(sstol) { try { - model = std::make_unique(endo, exo, par, equations, len, ord); + model = std::make_unique(endo, exo, par, equations, ord); } catch (const ogp::ParserException &pe) { @@ -142,9 +142,8 @@ Dynare::writeMat(mat_t *fd, const std::string &prefix) const void Dynare::writeDump(const std::string &basename) const { - std::string fname(basename); - fname += ".dump"; - std::ofstream out(fname.c_str()); + std::string fname(basename + ".dump"); + std::ofstream out(fname); model->dump_model(out); out.close(); } @@ -271,7 +270,7 @@ DynareNameList::DynareNameList(const Dynare &dynare) for (int i = 0; i < dynare.ny(); i++) { int j = dynare.model->getAtoms().y2outer_endo()[i]; - const char *name = dynare.model->getAtoms().get_endovars()[j]; + const std::string &name = dynare.model->getAtoms().get_endovars()[j]; names.push_back(name); } } @@ -290,7 +289,7 @@ DynareExogNameList::DynareExogNameList(const Dynare &dynare) for (int i = 0; i < dynare.nexog(); i++) { int j = dynare.model->getAtoms().y2outer_exo()[i]; - const char *name = dynare.model->getAtoms().get_exovars()[j]; + const std::string &name = dynare.model->getAtoms().get_exovars()[j]; names.push_back(name); } } diff --git a/dynare++/src/dynare3.hh b/dynare++/src/dynare3.hh index 23598924e..4603da10b 100644 --- a/dynare++/src/dynare3.hh +++ b/dynare++/src/dynare3.hh @@ -102,7 +102,7 @@ public: Dynare(const std::vector &endo, const std::vector &exo, const std::vector &par, - const char *equations, int len, int ord, + const std::string &equations, int ord, double sstol, Journal &jr); /** Makes a deep copy of the object. */ Dynare(const Dynare &dyn); diff --git a/dynare++/src/dynare_atoms.cc b/dynare++/src/dynare_atoms.cc index b1c48dd61..e4f3bce3e 100644 --- a/dynare++/src/dynare_atoms.cc +++ b/dynare++/src/dynare_atoms.cc @@ -9,22 +9,25 @@ #include #include +#include +#include +#include using namespace ogdyn; using std::string; void -DynareStaticAtoms::register_name(const char *name) +DynareStaticAtoms::register_name(string name) { if (varnames.query(name)) throw ogp::ParserException(string("The name ")+name+" is not unique.", 0); - StaticAtoms::register_name(name); + StaticAtoms::register_name(std::move(name)); } int -DynareStaticAtoms::check_variable(const char *name) const +DynareStaticAtoms::check_variable(const string &name) const { - if (nullptr == varnames.query(name)) + if (!varnames.query(name)) throw ogp::ParserException(std::string("Unknown name <")+name+">", 0); auto it = vars.find(name); if (it == vars.end()) @@ -33,56 +36,47 @@ DynareStaticAtoms::check_variable(const char *name) const return it->second; } -DynareDynamicAtoms::DynareDynamicAtoms(const DynareDynamicAtoms &dda) - : SAtoms(dda) -{ - // fill atom_type - for (auto it : dda.atom_type) - atom_type.emplace(varnames.query(it.first), it.second); -} - void -DynareDynamicAtoms::parse_variable(const char *in, std::string &out, int &ll) const +DynareDynamicAtoms::parse_variable(const string &in, std::string &out, int &ll) const { ll = 0; - std::string str = in; - auto left = str.find_first_of("({"); + auto left = in.find_first_of("({"); if (left != string::npos) { - out = str.substr(0, left); + out = in.substr(0, left); left++; - auto right = str.find_first_of(")}", left); + auto right = in.find_first_of(")}", left); if (string::npos == right) throw ogp::ParserException(string("Syntax error when parsing Dynare atom <")+in+">.", 0); - ll = std::stoi(str.substr(left, right-left)); + ll = std::stoi(in.substr(left, right-left)); } else out = in; } void -DynareDynamicAtoms::register_uniq_endo(const char *name) +DynareDynamicAtoms::register_uniq_endo(string name) { FineAtoms::register_uniq_endo(name); - atom_type.emplace(varnames.query(name), atype::endovar); + atom_type.emplace(std::move(name), atype::endovar); } void -DynareDynamicAtoms::register_uniq_exo(const char *name) +DynareDynamicAtoms::register_uniq_exo(string name) { FineAtoms::register_uniq_exo(name); - atom_type.emplace(varnames.query(name), atype::exovar); + atom_type.emplace(std::move(name), atype::exovar); } void -DynareDynamicAtoms::register_uniq_param(const char *name) +DynareDynamicAtoms::register_uniq_param(string name) { FineAtoms::register_uniq_param(name); - atom_type.emplace(varnames.query(name), atype::param); + atom_type.emplace(std::move(name), atype::param); } bool -DynareDynamicAtoms::is_type(const char *name, atype tp) const +DynareDynamicAtoms::is_type(const string &name, atype tp) const { auto it = atom_type.find(name); if (it != atom_type.end() && it->second == tp) @@ -95,10 +89,11 @@ void DynareDynamicAtoms::print() const { SAtoms::print(); - printf("Name types:\n"); + std::cout << "Name types:\n"; for (auto it : atom_type) - printf("name=%s type=%s\n", it.first, - it.second == atype::endovar ? "endovar" : it.second == atype::exovar ? "exovar" : "param"); + std::cout << "name=" << it.first << " type=" + << (it.second == atype::endovar ? "endovar" : it.second == atype::exovar ? "exovar" : "param") + << '\n'; } std::string @@ -113,22 +108,18 @@ DynareDynamicAtoms::convert(int t) const if (is_constant(t)) { double v = get_constant_value(t); - char buf[100]; - sprintf(buf, "%20.16g", v); - const char *s = buf; - while (*s == ' ') - ++s; - return s; + std::ostringstream buf; + buf << std::setprecision(std::numeric_limits::max_digits10) + << v; + return buf.str(); } - const char *s = name(t); + const string &s = name(t); if (is_type(s, atype::endovar)) { int ll = lead(t); if (ll) - return std::string{s} + '(' + std::to_string(ll) + ')'; - else - return s; + return s + '(' + std::to_string(ll) + ')'; } return s; @@ -248,7 +239,7 @@ DynareSteadySubstitutions::DynareSteadySubstitutions(const ogp::FineAtoms &a, void DynareSteadySubstitutions::load(int i, double res) { - const char *name = left_hand_sides[i]; + const string &name = left_hand_sides[i]; int iouter = atoms.name2outer_endo(name); int iy = atoms.outer2y_endo()[iouter]; if (!std::isfinite(y[iy])) @@ -263,7 +254,7 @@ DynareStaticSteadySubstitutions(const ogp::FineAtoms &a, const ogp::StaticFineAt : atoms(a), atoms_static(sa), y(yy) { // fill the vector of left and right hand sides - for (auto it : subst) + for (const auto &it : subst) { left_hand_sides.push_back(it.first); right_hand_sides.push_back(it.second); @@ -278,7 +269,7 @@ DynareStaticSteadySubstitutions(const ogp::FineAtoms &a, const ogp::StaticFineAt void DynareStaticSteadySubstitutions::load(int i, double res) { - const char *name = left_hand_sides[i]; + const string &name = left_hand_sides[i]; int iouter = atoms.name2outer_endo(name); int iy = atoms.outer2y_endo()[iouter]; if (!std::isfinite(y[iy])) diff --git a/dynare++/src/dynare_atoms.hh b/dynare++/src/dynare_atoms.hh index 29400744d..91701627e 100644 --- a/dynare++/src/dynare_atoms.hh +++ b/dynare++/src/dynare_atoms.hh @@ -19,11 +19,12 @@ namespace ogdyn { using std::map; using std::vector; + using std::string; /** A definition of a type mapping a string to an integer. Used as * a substitution map, saying what names are substituted for what * expressions represented by tree indices. */ - using Tsubstmap = map; + using Tsubstmap = map; class DynareStaticAtoms : public ogp::StaticAtoms { @@ -37,12 +38,12 @@ namespace ogdyn /** This registers a unique varname identifier. It throws an * exception if the variable name is duplicate. It checks the * uniqueness and then it calls StaticAtoms::register_name. */ - void register_name(const char *name) override; + void register_name(string name) override; protected: /** This returns a tree index of the given variable, and if * the variable has not been registered, it throws an * exception. */ - int check_variable(const char *name) const override; + int check_variable(const string &name) const override; }; class DynareDynamicAtoms : public ogp::SAtoms, public ogp::NularyStringConvertor @@ -50,7 +51,7 @@ namespace ogdyn public: enum class atype {endovar, exovar, param}; protected: - using Tatypemap = map; + using Tatypemap = map; /** The map assigining a type to each name. */ Tatypemap atom_type; public: @@ -58,20 +59,18 @@ namespace ogdyn : ogp::SAtoms() { } - DynareDynamicAtoms(const DynareDynamicAtoms &dda); - ~DynareDynamicAtoms() override = default; /** This parses a variable of the forms: varname(+3), * varname(3), varname, varname(-3), varname(0), varname(+0), * varname(-0). */ - void parse_variable(const char *in, std::string &out, int &ll) const override; + void parse_variable(const string &in, std::string &out, int &ll) const override; /** Registers unique name of endogenous variable. */ - void register_uniq_endo(const char *name) override; + void register_uniq_endo(string name) override; /** Registers unique name of exogenous variable. */ - void register_uniq_exo(const char *name) override; + void register_uniq_exo(string name) override; /** Registers unique name of parameter. */ - void register_uniq_param(const char *name) override; + void register_uniq_param(string name) override; /** Return true if the name is a given type. */ - bool is_type(const char *name, atype tp) const; + bool is_type(const string &name, atype tp) const; /** Debug print. */ void print() const override; /** Implement NularyStringConvertor::convert. */ @@ -194,7 +193,7 @@ namespace ogdyn void load(int i, double res) override; protected: Vector &y; - vector left_hand_sides; + vector left_hand_sides; vector right_hand_sides; }; @@ -217,7 +216,7 @@ namespace ogdyn void load(int i, double res) override; protected: Vector &y; - vector left_hand_sides; + vector left_hand_sides; vector right_hand_sides; }; diff --git a/dynare++/src/dynare_model.cc b/dynare++/src/dynare_model.cc index 83cfa025e..f289fe3ec 100644 --- a/dynare++/src/dynare_model.cc +++ b/dynare++/src/dynare_model.cc @@ -89,14 +89,14 @@ DynareModel::setInitOuter(const Vector &x) void DynareModel::print() const { - printf("all atoms:\n"); + std::cout << "all atoms:\n"; atoms.print(); - printf("formulas:\n"); + std::cout << "formulas:\n"; DebugOperationFormatter dof(*this); for (int i = 0; i < eqs.nformulas(); i++) { int tf = eqs.formula(i); - printf("formula %d:\n", tf); + std::cout << "formula " << tf << "%d:\n"; eqs.getTree().print_operation_tree(tf, std::cout, dof); } } @@ -148,17 +148,17 @@ DynareModel::dump_model(std::ostream &os) const } void -DynareModel::add_name(const std::string &name, int flag) +DynareModel::add_name(std::string name, int flag) { if (flag == 1) // endogenous - atoms.register_uniq_endo(name.c_str()); + atoms.register_uniq_endo(name); else if (flag == 2) // exogenous - atoms.register_uniq_exo(name.c_str()); + atoms.register_uniq_exo(name); else if (flag == 3) // parameter - atoms.register_uniq_param(name.c_str()); + atoms.register_uniq_param(name); else throw DynareException(__FILE__, __LINE__, "Unrecognized flag value."); } @@ -206,7 +206,7 @@ DynareModel::check_model() const int DynareModel::variable_shift(int t, int tshift) { - const char *name = atoms.name(t); + const string &name = atoms.name(t); if (atoms.is_type(name, DynareDynamicAtoms::atype::param) || atoms.is_constant(t)) throw DynareException(__FILE__, __LINE__, @@ -214,10 +214,7 @@ DynareModel::variable_shift(int t, int tshift) int ll = atoms.lead(t) + tshift; int res = atoms.index(name, ll); if (res == -1) - { - std::string str = name + '(' + std::to_string(ll) + ')'; - res = eqs.add_nulary(str.c_str()); - } + res = eqs.add_nulary(name + '(' + std::to_string(ll) + ')'); return res; } @@ -230,7 +227,7 @@ DynareModel::variable_shift_map(const unordered_set &a_set, int tshift, // make shift map only for non-constants and non-parameters if (!atoms.is_constant(t)) { - const char *name = atoms.name(t); + const string &name = atoms.name(t); if (atoms.is_type(name, DynareDynamicAtoms::atype::endovar) || atoms.is_type(name, DynareDynamicAtoms::atype::exovar)) { @@ -278,7 +275,7 @@ DynareModel::get_nonlinear_subterms(int t) const } void -DynareModel::substitute_atom_for_term(const char *name, int ll, int t) +DynareModel::substitute_atom_for_term(const string &name, int ll, int t) { // if the term t is itself a named atom (parameter, exo, endo), // then we have to unassign it first @@ -326,7 +323,7 @@ DynareModel::final_job() extern ogp::location_type dynglob_lloc; -DynareParser::DynareParser(const char *stream, int len, int ord) +DynareParser::DynareParser(const string &stream, int ord) : DynareModel(), pa_atoms(), paramset(pa_atoms), ia_atoms(), initval(ia_atoms), vcov(), @@ -341,7 +338,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord) // global parse try { - parse_glob(len, stream); + parse_glob(stream); } catch (const ogp::ParserException &e) { @@ -351,7 +348,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord) try { if (paramset_end > paramset_beg) - paramset.parse(paramset_end-paramset_beg, stream+paramset_beg); + paramset.parse(stream.substr(paramset_beg, paramset_end-paramset_beg)); } catch (const ogp::ParserException &e) { @@ -361,7 +358,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord) try { if (model_end > model_beg) - eqs.parse(model_end-model_beg, stream+model_beg); + eqs.parse(stream.substr(model_beg, model_end-model_beg)); else throw ogp::ParserException("Model section not found.", 0); } @@ -373,7 +370,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord) try { if (initval_end > initval_beg) - initval.parse(initval_end-initval_beg, stream+initval_beg); + initval.parse(stream.substr(initval_beg, initval_end-initval_beg)); } catch (const ogp::ParserException &e) { @@ -383,7 +380,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord) try { if (vcov_end > vcov_beg) - vcov.parse(vcov_end-vcov_beg, stream+vcov_beg); + vcov.parse(stream.substr(vcov_beg, vcov_end-vcov_beg)); } catch (const ogp::ParserException &e) { @@ -394,7 +391,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord) { if (plobjective_end > plobjective_beg) { - eqs.parse(plobjective_end-plobjective_beg, stream+plobjective_beg); + eqs.parse(stream.substr(plobjective_beg, plobjective_end-plobjective_beg)); t_plobjective = eqs.pop_last_formula(); } } @@ -406,8 +403,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord) try { if (pldiscount_end > pldiscount_beg) - t_pldiscount = parse_pldiscount(pldiscount_end - pldiscount_beg, - stream + pldiscount_beg); + t_pldiscount = parse_pldiscount(stream.substr(pldiscount_beg, pldiscount_end - pldiscount_beg)); } catch (const ogp::ParserException &e) { @@ -417,7 +413,7 @@ DynareParser::DynareParser(const char *stream, int len, int ord) try { if (order_end > order_beg) - order = parse_order(order_end - order_beg, stream + order_beg); + order = parse_order(stream.substr(order_beg, order_end - order_beg)); } catch (const ogp::ParserException &e) { @@ -468,45 +464,45 @@ DynareParser::DynareParser(const DynareParser &dp) } void -DynareParser::add_name(const char *name, int flag) +DynareParser::add_name(string name, int flag) { DynareModel::add_name(name, flag); // register with static atoms used for atom assignements if (flag == 1) // endogenous - ia_atoms.register_name(name); + ia_atoms.register_name(std::move(name)); else if (flag == 2) // exogenous - ia_atoms.register_name(name); + ia_atoms.register_name(std::move(name)); else if (flag == 3) { // parameter pa_atoms.register_name(name); - ia_atoms.register_name(name); + ia_atoms.register_name(std::move(name)); } else throw DynareException(__FILE__, __LINE__, "Unrecognized flag value."); } void -DynareParser::error(const char *mes) +DynareParser::error(string mes) { // throwing zero offset since this exception will be caugth at // constructor - throw ogp::ParserException(mes, 0); + throw ogp::ParserException(std::move(mes), 0); } void DynareParser::print() const { DynareModel::print(); - printf("parameter atoms:\n"); + std::cout << "parameter atoms:\n"; paramset.print(); - printf("initval atoms:\n"); + std::cout << "initval atoms:\n"; initval.print(); - printf("model position: %d %d\n", model_beg, model_end); - printf("paramset position: %d %d\n", paramset_beg, paramset_end); - printf("initval position: %d %d\n", initval_beg, initval_end); + std::cout << "model position: " << model_beg << ' ' << model_end << '\n' + << "paramset position: " << paramset_beg << ' ' << paramset_end << '\n' + << "initval position: " << initval_beg << ' ' << initval_end << '\n'; } /** A global symbol for passing info to the DynareParser from @@ -515,47 +511,35 @@ DynareParser *dynare_parser; /** The declarations of functions defined in dynglob_ll.cc and * dynglob_tab.cc generated from dynglob.lex and dynglob.y */ -void *dynglob__scan_buffer(char *, size_t); +void *dynglob__scan_string(const char *); void dynglob__destroy_buffer(void *); void dynglob_parse(); extern ogp::location_type dynglob_lloc; void -DynareParser::parse_glob(int length, const char *stream) +DynareParser::parse_glob(const string &stream) { - 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.get(), static_cast(length)+2); + void *p = dynglob__scan_string(stream.c_str()); dynare_parser = this; dynglob_parse(); dynglob__destroy_buffer(p); } int -DynareParser::parse_order(int len, const char *str) +DynareParser::parse_order(const string &str) { - auto buf = std::make_unique(len+1); - std::copy_n(str, len, buf.get()); - buf[len] = '\0'; - int res; - sscanf(buf.get(), "%d", &res); - return res; + return std::stoi(str); } int -DynareParser::parse_pldiscount(int len, const char *str) +DynareParser::parse_pldiscount(const string &str) { - auto buf = std::make_unique(len+1); - std::copy_n(str, len, buf.get()); - buf[len] = '\0'; - if (!atoms.is_type(buf.get(), DynareDynamicAtoms::atype::param)) - throw ogp::ParserException(std::string{"Name "} + buf.get() + " is not a parameter", 0); + if (!atoms.is_type(str, DynareDynamicAtoms::atype::param)) + throw ogp::ParserException(std::string{"Name "} + str + " is not a parameter", 0); - int t = atoms.index(buf.get(), 0); + int t = atoms.index(str, 0); if (t == -1) - t = eqs.add_nulary(buf.get()); + t = eqs.add_nulary(str); return t; } @@ -571,8 +555,7 @@ DynareParser::calc_params() for (unsigned int i = 0; i < atoms.get_params().size(); i++) if (!std::isfinite((*param_vals)[i])) - printf("dynare++: warning: value for parameter %s is not finite\n", - atoms.get_params()[i]); + std::cout << "dynare++: warning: value for parameter " << atoms.get_params()[i] << " is not finite\n"; } void @@ -613,8 +596,7 @@ DynareParser::calc_init() for (unsigned int i = 0; i < atoms.get_endovars().size(); i++) if (!std::isfinite((*init_vals)[i])) - printf("dynare++: warning: initval for <%s> is not finite\n", - atoms.get_endovars()[atoms.y2outer_endo()[i]]); + std::cout << "dynare++: warning: initval for <" << atoms.get_endovars()[atoms.y2outer_endo()[i]] << "> is not finite\n"; } // this returns false for linear functions @@ -682,7 +664,7 @@ NLSelector::operator()(int t) const DynareSPModel::DynareSPModel(const std::vector &endo, const std::vector &exo, const std::vector &par, - const char *equations, int len, + const string &equations, int ord) : DynareModel() { @@ -698,7 +680,7 @@ DynareSPModel::DynareSPModel(const std::vector &endo, add_name(it, 3); // parse the equations - eqs.parse(len, equations); + eqs.parse(equations); // parsing finished atoms.parsing_finished(ogp::VarOrdering::bfspbfpb); @@ -843,7 +825,7 @@ MatlabSSWriter::write_atom_assignment(std::ostream &os) const os << "% parameter values\n"; for (unsigned int ip = 0; ip < model.getAtoms().get_params().size(); ip++) { - const char *parname = model.getAtoms().get_params()[ip]; + const string &parname = model.getAtoms().get_params()[ip]; int t = model.getAtoms().index(parname, 0); if (t == -1) os << "% " << parname << " not used in the model\n"; @@ -857,7 +839,7 @@ MatlabSSWriter::write_atom_assignment(std::ostream &os) const 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]; + const string &exoname = model.getAtoms().get_exovars()[ie]; try { const ogp::DynamicAtoms::Tlagmap &lmap = model.getAtoms().lagmap(exoname); @@ -876,7 +858,7 @@ MatlabSSWriter::write_atom_assignment(std::ostream &os) const 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 string &endoname = model.getAtoms().get_endovars()[ie]; const ogp::DynamicAtoms::Tlagmap &lmap = model.getAtoms().lagmap(endoname); for (auto it : lmap) { @@ -920,7 +902,7 @@ MatlabSSWriter::write_der1_assignment(std::ostream &os) const for (int j : eam) { int tvar = variables[j]; - const char *name = model.getAtoms().name(tvar); + const string &name = model.getAtoms().name(tvar); int yi = model.getAtoms().name2outer_endo(name); int t = fder.derivative(ogp::FoldMultiIndex(variables.size(), 1, j)); if (t != ogp::OperationTree::zero) @@ -963,7 +945,7 @@ DebugOperationFormatter::format_nulary(int t, std::ostream &os) const else { int ll = a.lead(t); - std::string name{a.name(t)}; + const std::string &name = a.name(t); if (ll == 0) os << name; else diff --git a/dynare++/src/dynare_model.hh b/dynare++/src/dynare_model.hh index 80546243b..fe9a3b72c 100644 --- a/dynare++/src/dynare_model.hh +++ b/dynare++/src/dynare_model.hh @@ -18,6 +18,7 @@ #include #include #include +#include namespace ogdyn { @@ -40,14 +41,11 @@ namespace ogdyn { } PosInterval &operator=(const PosInterval &pi) = default; - /** This returns the interval beginning and interval length - * within the given string. */ - void translate(const char *beg, int len, const char * &ibeg, int &ilen) const; /** Debug print. */ void print() const { - printf("fl=%d fc=%d ll=%d lc=%d\n", fl, fc, ll, lc); + std::cout << "fl=" << fl << " fc=" << fc << " ll=" << ll << " lc=" << lc << '\n'; } }; @@ -189,7 +187,7 @@ namespace ogdyn * sort is governed by the flag. See dynglob.y for values of * the flag. This is used by a subclass when declaring the * names. */ - void add_name(const std::string &name, int flag); + void add_name(std::string name, int flag); /** This checks the model consistency. Thus includes: number * of endo variables and number of equations, min and max lag * of endogenous variables and occurrrences of exogenous @@ -224,7 +222,7 @@ namespace ogdyn * this way, all occurrences of term t are substituted with * the atom name(ll). The method handles also rewriting * operation tree including derivatives of the term t. */ - void substitute_atom_for_term(const char *name, int ll, int t); + void substitute_atom_for_term(const string &name, int ll, int t); /** This performs a final job after the model is parsed. It * creates the PlannerBuilder object if the planner's FOC are * needed, then it creates ForwSubstBuilder handling multiple @@ -255,7 +253,7 @@ namespace ogdyn * of the given length corresponding to the Dynare++ model * file. If the given ord is not -1, then it overrides setting * in the model file. */ - DynareParser(const char *str, int len, int ord); + DynareParser(const string &str, int ord); DynareParser(const DynareParser &dp); std::unique_ptr clone() const override @@ -265,7 +263,7 @@ namespace ogdyn /** Adds a name of endogenous, exogenous or a parameter. This * addss the name to the parent class DynareModel and also * registers the name to either paramset, or initval. */ - void add_name(const char *name, int flag); + void add_name(string name, int flag); /** Sets position of the model section. Called from * dynglob.y. */ void @@ -323,13 +321,13 @@ namespace ogdyn pldiscount_end = off2; } /** Processes a syntax error from bison. */ - void error(const char *mes); + void error(string mes); /** Debug print. */ void print() const; protected: - void parse_glob(int length, const char *stream); - int parse_order(int length, const char *stream); - int parse_pldiscount(int length, const char *stream); + void parse_glob(const string &stream); + int parse_order(const string &stream); + int parse_pldiscount(const string &stream); /** Evaluate paramset assignings and set param_vals. */ void calc_params(); /** Evaluate initval assignings and set init_vals. */ @@ -364,7 +362,7 @@ namespace ogdyn DynareSPModel(const std::vector &endo, const std::vector &exo, const std::vector &par, - const char *equations, int len, int ord); + const string &equations, int ord); DynareSPModel(const DynareSPModel &dm) = default; ~DynareSPModel() override = default; std::unique_ptr diff --git a/dynare++/src/dynare_params.cc b/dynare++/src/dynare_params.cc index fdd8e4da9..99e97ab82 100644 --- a/dynare++/src/dynare_params.cc +++ b/dynare++/src/dynare_params.cc @@ -160,11 +160,11 @@ DynareParams::DynareParams(int argc, char **argv) break; } } - catch (std::invalid_argument) + catch (std::invalid_argument &) { std::cerr << "Couldn't parse option " << optarg << ", ignored\n"; } - catch (std::out_of_range) + catch (std::out_of_range &) { std::cerr << "Out-of-range value " << optarg << ", ignored\n"; } diff --git a/dynare++/src/dynglob.yy b/dynare++/src/dynglob.yy index 0acdb747e..c92715315 100644 --- a/dynare++/src/dynglob.yy +++ b/dynare++/src/dynglob.yy @@ -9,9 +9,11 @@ %code { +#include + #include "dynare_model.hh" -void dynglob_error(const char*); +void dynglob_error(std::string); int dynglob_lex(); extern ogdyn::DynareParser* dynare_parser; int symblist_flag; @@ -109,7 +111,7 @@ planner_discount : PLANNERDISCOUNT NAME SEMICOLON { %% void -dynglob_error(const char* mes) +dynglob_error(std::string mes) { dynare_parser->error(mes); } diff --git a/dynare++/src/forw_subst_builder.cc b/dynare++/src/forw_subst_builder.cc index c31f9eb39..9abf26693 100644 --- a/dynare++/src/forw_subst_builder.cc +++ b/dynare++/src/forw_subst_builder.cc @@ -59,12 +59,11 @@ ForwSubstBuilder::substitute_for_term(int t, int i, int j) // now maxlead of lagt is +1 // add AUXLD_*_*_1 = f(x(+1)) to the model std::string name = "AUXLD_" + std::to_string(i) + '_' + std::to_string(j) + "_1"; - model.atoms.register_uniq_endo(name.c_str()); + model.atoms.register_uniq_endo(name); info.num_aux_variables++; - const char *ss = model.atoms.get_name_storage().query(name.c_str()); - int auxt = model.eqs.add_nulary(name.c_str()); + int auxt = model.eqs.add_nulary(name); model.eqs.add_formula(model.eqs.add_binary(ogp::code_t::MINUS, auxt, lagt)); - aux_map.emplace(ss, lagt); + aux_map.emplace(name, lagt); // now add variables and equations // AUXLD_*_*_2 = AUXLD_*_*_1(+1) through // AUXLD_*_*_{mlead-1} = AUXLD_*_*_{mlead-2}(+1) @@ -72,13 +71,12 @@ ForwSubstBuilder::substitute_for_term(int t, int i, int j) { // create AUXLD_*_*_{ll}(+1) name = "AUXLD_" + std::to_string(i) + '_' + std::to_string(j) + '_' + std::to_string(ll) + "(+1)"; - int lastauxt_lead = model.eqs.add_nulary(name.c_str()); + int lastauxt_lead = model.eqs.add_nulary(name); // create AUXLD_*_*{ll+1} name = "AUXLD_" + std::to_string(i) + '_' + std::to_string(j) + '_' + std::to_string(ll+1); - model.atoms.register_uniq_endo(name.c_str()); + model.atoms.register_uniq_endo(name); info.num_aux_variables++; - ss = model.atoms.get_name_storage().query(name.c_str()); - auxt = model.eqs.add_nulary(name.c_str()); + auxt = model.eqs.add_nulary(name); // add AUXLD_*_*_{ll+1} = AUXLD_*_*_{ll}(+1) model.eqs.add_formula(model.eqs.add_binary(ogp::code_t::MINUS, auxt, lastauxt_lead)); // add substitution to the map; todo: this @@ -86,38 +84,36 @@ ForwSubstBuilder::substitute_for_term(int t, int i, int j) // aux_map is used the timing doesn't matter, // however, it is misleading, needs to be // changed - aux_map.emplace(ss, lagt); + aux_map.emplace(name, lagt); } // now we have to substitute AUXLD_*_*{mlead-1}(+1) for t name = "AUXLD_" + std::to_string(i) + '_' + std::to_string(j) + '_' + std::to_string(mlead-1); - ss = model.atoms.get_name_storage().query(name.c_str()); - model.substitute_atom_for_term(ss, +1, t); + model.substitute_atom_for_term(name, +1, t); } } void -ForwSubstBuilder::unassign_gt_1_leads(const char *name) +ForwSubstBuilder::unassign_gt_1_leads(const string &name) { - const char *ss = model.atoms.get_name_storage().query(name); int mlead, mlag; model.atoms.varspan(name, mlead, mlag); for (int ll = 2; ll <= mlead; ll++) { - int t = model.atoms.index(ss, ll); + int t = model.atoms.index(name, ll); if (t != -1) - model.atoms.unassign_variable(ss, ll, t); + model.atoms.unassign_variable(name, ll, t); } } void ForwSubstBuilder::unassign_gt_1_leads() { - const vector &endovars = model.atoms.get_endovars(); - for (auto endovar : endovars) + auto &endovars = model.atoms.get_endovars(); + for (const auto &endovar : endovars) unassign_gt_1_leads(endovar); - const vector &exovars = model.atoms.get_exovars(); - for (auto exovar : exovars) + auto &exovars = model.atoms.get_exovars(); + for (const auto &exovar : exovars) unassign_gt_1_leads(exovar); } @@ -125,8 +121,5 @@ ForwSubstBuilder::ForwSubstBuilder(const ForwSubstBuilder &b, DynareModel &m) : model(m) { for (auto it : b.aux_map) - { - const char *ss = m.atoms.get_name_storage().query(it.first); - aux_map.emplace(ss, it.second); - } + aux_map.insert(it); } diff --git a/dynare++/src/forw_subst_builder.hh b/dynare++/src/forw_subst_builder.hh index 1b276e81d..7a83d96d0 100644 --- a/dynare++/src/forw_subst_builder.hh +++ b/dynare++/src/forw_subst_builder.hh @@ -25,7 +25,7 @@ namespace ogdyn class ForwSubstBuilder { - using Ttermauxmap = map; + using Ttermauxmap = map; protected: /** Reference to the model, to which we will add equations and * change some equations. */ @@ -78,7 +78,7 @@ namespace ogdyn * all nulary terms with a lead greater than 1. */ void unassign_gt_1_leads(); /** This unassigns all leads greater than 1 of the given name. */ - void unassign_gt_1_leads(const char *name); + void unassign_gt_1_leads(const string &name); }; }; diff --git a/dynare++/src/main.cc b/dynare++/src/main.cc index b178404f8..53c908db1 100644 --- a/dynare++/src/main.cc +++ b/dynare++/src/main.cc @@ -12,6 +12,8 @@ #include "../kord/approximation.hh" #include +#include +#include int main(int argc, char **argv) @@ -20,27 +22,24 @@ main(int argc, char **argv) if (params.help) { params.printHelp(); - return 0; + return EXIT_SUCCESS; } if (params.version) { - printf(u8"Dynare++ v. %s. Copyright © 2004-2011, Ondra Kamenik\n", - DYNVERSION); - printf("Dynare++ comes with ABSOLUTELY NO WARRANTY and is distributed under\n"); - printf("GPL: modules integ, tl, kord, sylv, src, extern and documentation\n"); - printf("LGPL: modules parser, utils\n"); - printf(" for GPL see http://www.gnu.org/licenses/gpl.html\n"); - printf(" for LGPL see http://www.gnu.org/licenses/lgpl.html\n"); - return 0; + std::cout << u8"Dynare++ v. " << DYNVERSION << ". Copyright © 2004-2011, Ondra Kamenik\n" + << "Dynare++ comes with ABSOLUTELY NO WARRANTY and is distributed under\n" + << "GPL: modules integ, tl, kord, sylv, src, extern and documentation\n" + << "LGPL: modules parser, utils\n" + << " for GPL see https://www.gnu.org/licenses/gpl.html\n" + << " for LGPL see https://www.gnu.org/licenses/lgpl.html\n"; + return EXIT_SUCCESS; } sthread::detach_thread_group::max_parallel_threads = params.num_threads; try { - // make journal name and journal - std::string jname(params.basename); - jname += ".jnl"; - Journal journal(jname.c_str()); + // make journal + Journal journal(params.basename + ".jnl"); // make dynare object Dynare dynare(params.modname, params.order, params.ss_tol, journal); @@ -50,41 +49,38 @@ main(int argc, char **argv) for (int i = 0; i < dynare.nexog(); i++) irf_list_ind.push_back(i); else - irf_list_ind = (static_cast(dynare.getExogNames())).selectIndices(params.irf_list); + irf_list_ind = static_cast(dynare.getExogNames()).selectIndices(params.irf_list); // write matlab files - std::string mfile1(params.basename); - mfile1 += "_f.m"; + std::string mfile1(params.basename + "_f.m"); 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); + std::cerr << "Couldn't open " << mfile1 << " for writing.\n"; + std::exit(EXIT_FAILURE); } - ogdyn::MatlabSSWriter writer0(dynare.getModel(), params.basename.c_str()); + ogdyn::MatlabSSWriter writer0(dynare.getModel(), params.basename); writer0.write_der0(mfd); mfd.close(); - std::string mfile2(params.basename); - mfile2 += "_ff.m"; + std::string mfile2(params.basename + "_ff.m"); 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); + std::cerr << "Couldn't open " << mfile2 << " for writing.\n"; + std::exit(EXIT_FAILURE); } - ogdyn::MatlabSSWriter writer1(dynare.getModel(), params.basename.c_str()); + ogdyn::MatlabSSWriter writer1(dynare.getModel(), params.basename); writer1.write_der1(mfd); mfd.close(); // open mat file - std::string matfile(params.basename); - matfile += ".mat"; + std::string matfile(params.basename + ".mat"); mat_t *matfd = Mat_Create(matfile.c_str(), nullptr); - if (matfd == nullptr) + if (!matfd) { - fprintf(stderr, "Couldn't open %s for writing.\n", matfile.c_str()); - exit(1); + std::cerr << "Couldn't open " << matfile << " for writing.\n"; + std::exit(EXIT_FAILURE); } // write info about the model (dimensions and variables) @@ -106,16 +102,15 @@ main(int argc, char **argv) catch (const KordException &e) { // tell about the exception and continue - printf("Caught (not yet fatal) Kord exception: "); + std::cout << "Caught (not yet fatal) Kord exception: "; e.print(); JournalRecord rec(journal); rec << "Solution routine not finished (" << e.get_message() << "), see what happens" << endrec; } - std::string ss_matrix_name(params.prefix); - ss_matrix_name += "_steady_states"; - ConstTwoDMatrix(app.getSS()).writeMat(matfd, ss_matrix_name.c_str()); + std::string ss_matrix_name(params.prefix + "_steady_states"); + ConstTwoDMatrix(app.getSS()).writeMat(matfd, ss_matrix_name); // check the approximation if (params.check_along_path || params.check_along_shocks @@ -176,42 +171,41 @@ main(int argc, char **argv) } Mat_Close(matfd); - } catch (const KordException &e) { - printf("Caught Kord exception: "); + std::cout << "Caught Kord exception: "; e.print(); return e.code(); } catch (const TLException &e) { - printf("Caught TL exception: "); + std::cout << "Caught TL exception: "; e.print(); return 255; } catch (SylvException &e) { - printf("Caught Sylv exception: "); + std::cout << "Caught Sylv exception: "; e.printMessage(); return 255; } catch (const DynareException &e) { - printf("Caught Dynare exception: %s\n", e.message().c_str()); + std::cout << "Caught Dynare exception: " << e.message() << '\n'; return 255; } catch (const ogu::Exception &e) { - printf("Caught ogu::Exception: "); + std::cout << "Caught ogu::Exception: "; e.print(); return 255; } catch (const ogp::ParserException &e) { - std::cout << "Caught parser exception: " << e.message() << std::endl; + std::cout << "Caught parser exception: " << e.message() << '\n'; return 255; } - return 0; + return EXIT_SUCCESS; } diff --git a/dynare++/src/nlsolve.cc b/dynare++/src/nlsolve.cc index 8aadbb526..1ea24059c 100644 --- a/dynare++/src/nlsolve.cc +++ b/dynare++/src/nlsolve.cc @@ -5,6 +5,9 @@ #include "nlsolve.hh" #include "dynare_exception.hh" +#include +#include + using namespace ogu; double @@ -50,10 +53,8 @@ GoldenSectionSearch::search(OneDFunction &f, double x1, double x2) { // x is on the right from b if (f1 > fb && fb < fx) - { - // pickup bracket [f1,fb,fx] - x2 = x; - } + // pickup bracket [f1,fb,fx] + x2 = x; else { // pickup bracket [fb,fx,f2] @@ -201,7 +202,6 @@ NLSolver::solve(Vector &xx, int &iter) rec << "Iter lambda residual" << endrec; JournalRecord rec1(journal); rec1 << u8"───────────────────────────" << endrec; - char tmpbuf[14]; x = const_cast(xx); iter = 0; @@ -213,8 +213,13 @@ NLSolver::solve(Vector &xx, int &iter) "Initial guess does not yield finite residual in NLSolver::solve"); bool converged = fx.getMax() < tol; JournalRecord rec2(journal); - sprintf(tmpbuf, "%10.6g", fx.getMax()); - rec2 << iter << " N/A " << tmpbuf << endrec; + auto format_double = [](double v) + { + std::ostringstream buf; + buf << std::setw(11) << v; + return buf.str(); + }; + rec2 << iter << " N/A " << format_double(fx.getMax()) << endrec; while (!converged && iter < max_iter) { // setup Jacobian @@ -246,8 +251,7 @@ NLSolver::solve(Vector &xx, int &iter) iter++; JournalRecord rec3(journal); - sprintf(tmpbuf, "%10.6g", fx.getMax()); - rec3 << iter << " " << lambda << " " << tmpbuf << endrec; + rec3 << iter << " " << lambda << " " << format_double(fx.getMax()) << endrec; } xx = const_cast(x); diff --git a/dynare++/src/planner_builder.cc b/dynare++/src/planner_builder.cc index e8d2a954e..4257bf6bc 100644 --- a/dynare++/src/planner_builder.cc +++ b/dynare++/src/planner_builder.cc @@ -159,11 +159,11 @@ PlannerBuilder::shift_derivatives_of_f() // make an auxiliary variable std::string name; name = "AUX_" + std::to_string(yi) + '_' + std::to_string(fset[fi]) + '_' + std::to_string(-ll); - model.atoms.register_uniq_endo(name.c_str()); + model.atoms.register_uniq_endo(name); info.num_aux_variables++; - int taux = model.eqs.add_nulary(name.c_str()); + int taux = model.eqs.add_nulary(name); name = "AUX_" + std::to_string(yi) + '_' + std::to_string(fset[fi]) + '_' + std::to_string(-ll) + '(' + std::to_string(-ll) + ')'; - int taux_leaded = model.eqs.add_nulary(name.c_str()); + int taux_leaded = model.eqs.add_nulary(name); // put aux_leaded to the equation diff_f(yi, fi, ll-minlag) = taux_leaded; // save auxiliary variable and the term @@ -244,8 +244,7 @@ PlannerBuilder::make_static_version() for (const auto &it : aux_map) { int tstatic = static_tree.add_substitution(it.second, tmap, model.eqs.getTree()); - const char *name = static_atoms.get_name_storage().query(it.first); - static_aux_map.emplace(name, tstatic); + static_aux_map.emplace(it.first, tstatic); } } @@ -257,7 +256,7 @@ PlannerBuilder::lagrange_mult_f() for (int fi = 0; fi < diff_f.dim2(); fi++) { mult_name = "MULT" + std::to_string(fset[fi]); - model.atoms.register_uniq_endo(mult_name.c_str()); + model.atoms.register_uniq_endo(mult_name); info.num_lagrange_mults++; } // multiply with the multipliers @@ -267,7 +266,7 @@ PlannerBuilder::lagrange_mult_f() if (diff_f(yi, fi, ll-minlag) != ogp::OperationTree::zero) { mult_name = "MULT" + std::to_string(fset[fi]) + '(' + std::to_string(-ll) + ')'; - int tm = model.eqs.add_nulary(mult_name.c_str()); + int tm = model.eqs.add_nulary(mult_name); diff_f(yi, fi, ll-minlag) = model.eqs.add_binary(ogp::code_t::TIMES, tm, diff_f(yi, fi, ll-minlag)); } @@ -301,7 +300,7 @@ PlannerBuilder::fill_yset(const ogp::NameStorage &ns, const PlannerBuilder::Tvarset &yyset) { for (auto it : yyset) - yset.insert(ns.query(it)); + yset.insert(it); } void @@ -310,11 +309,11 @@ PlannerBuilder::fill_aux_map(const ogp::NameStorage &ns, const Tsubstmap &aaux_m { // fill aux_map for (auto it : aaux_map) - aux_map.emplace(ns.query(it.first), it.second); + aux_map.insert(it); // fill static_aux_map for (auto it : astatic_aux_map) - static_aux_map.emplace(static_atoms.get_name_storage().query(it.first), it.second); + static_aux_map.insert(it); } MultInitSS::MultInitSS(const PlannerBuilder &pb, const Vector &pvals, Vector &yy) @@ -358,7 +357,7 @@ MultInitSS::MultInitSS(const PlannerBuilder &pb, const Vector &pvals, Vector &yy for (int fi = 0; fi < builder.diff_f_static.dim2(); fi++) { std::string mult_name = "MULT" + std::to_string(builder.fset[fi]); - int iouter = builder.model.atoms.name2outer_endo(mult_name.c_str()); + int iouter = builder.model.atoms.name2outer_endo(mult_name); int iy = builder.model.atoms.outer2y_endo()[iouter]; if (!std::isfinite(yy[iy])) yy[iy] = lambda[fi]; @@ -369,13 +368,13 @@ MultInitSS::MultInitSS(const PlannerBuilder &pb, const Vector &pvals, Vector &yy { const ogp::AtomSubstitutions::Toldnamemap &old2new = builder.model.atom_substs->get_old2new(); - auto it = old2new.find(mult_name.c_str()); + auto it = old2new.find(mult_name); if (it != old2new.end()) { const ogp::AtomSubstitutions::Tshiftnameset &sset = it->second; for (const auto & itt : sset) { - const char *newname = itt.first; + const std::string &newname = itt.first; int iouter = builder.model.atoms.name2outer_endo(newname); int iy = builder.model.atoms.outer2y_endo()[iouter]; if (!std::isfinite(yy[iy])) diff --git a/dynare++/src/planner_builder.hh b/dynare++/src/planner_builder.hh index 5e0c53736..df587ac0e 100644 --- a/dynare++/src/planner_builder.hh +++ b/dynare++/src/planner_builder.hh @@ -146,7 +146,7 @@ namespace ogdyn friend class MultInitSS; public: /** Type for a set of variable names. */ - using Tvarset = unordered_set; + using Tvarset = unordered_set; /** Type for a set of equations. An equation is identified by * an index to an equation in the equation vector given by * DynareModel::eqs. The tree index of the i-th formula is diff --git a/dynare++/tl/cc/t_container.hh b/dynare++/tl/cc/t_container.hh index 71bea1f6f..04538e061 100644 --- a/dynare++/tl/cc/t_container.hh +++ b/dynare++/tl/cc/t_container.hh @@ -222,7 +222,7 @@ public: for (int i = 0; i < sym.num(); i++) lname += '_' + std::to_string(sym[i]); ConstTwoDMatrix m(*(it.second)); - m.writeMat(fd, lname.c_str()); + m.writeMat(fd, lname); } } diff --git a/dynare++/tl/cc/twod_matrix.cc b/dynare++/tl/cc/twod_matrix.cc index dfddc8b7b..00969cc2b 100644 --- a/dynare++/tl/cc/twod_matrix.cc +++ b/dynare++/tl/cc/twod_matrix.cc @@ -104,7 +104,7 @@ TwoDMatrix::save(const std::string &fname) const if (fd.fail()) TL_RAISE("Cannot open file for writing in TwoDMatrix::save"); - fd << std::setprecision(std::numeric_limits::digits10 + 1); + fd << std::setprecision(std::numeric_limits::max_digits10); for (int row = 0; row < nrows(); row++) {