diff --git a/src/ComputingTasks.cc b/src/ComputingTasks.cc
index c58ce315e22cee1dd6e6296a0208a4a66ced3be7..cdf6ff96d92d45e819116901c2c847b9de943c91 100644
--- a/src/ComputingTasks.cc
+++ b/src/ComputingTasks.cc
@@ -544,12 +544,13 @@ void
 RamseyConstraintsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
 {
   output << "M_.ramsey_model_constraints = {" << endl;
-  for (auto it = constraints.begin(); it != constraints.end(); ++it)
+  for (bool printed_something{false};
+       const auto &it : constraints)
     {
-      if (it != constraints.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      output << "{" << it->endo + 1 << ", '";
-      switch (it->code)
+      output << "{" << it.endo + 1 << ", '";
+      switch (it.code)
         {
         case BinaryOpcode::less:
           output << '<';
@@ -568,7 +569,7 @@ RamseyConstraintsStatement::writeOutput(ostream &output, const string &basename,
           exit(EXIT_FAILURE);
         }
       output << "', '";
-      it->expression->writeOutput(output);
+      it.expression->writeOutput(output);
       output << "'}" << endl;
     }
   output << "};" << endl;
@@ -579,12 +580,13 @@ RamseyConstraintsStatement::writeJsonOutput(ostream &output) const
 {
   output << R"({"statementName": "ramsey_constraints")"
          << R"(, "ramsey_model_constraints": [)" << endl;
-  for (auto it = constraints.begin(); it != constraints.end(); ++it)
+  for (bool printed_something{false};
+       const auto &it : constraints)
     {
-      if (it != constraints.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      output << R"({"constraint": ")" << symbol_table.getName(it->endo) << " ";
-      switch (it->code)
+      output << R"({"constraint": ")" << symbol_table.getName(it.endo) << " ";
+      switch (it.code)
         {
         case BinaryOpcode::less:
           output << '<';
@@ -603,7 +605,7 @@ RamseyConstraintsStatement::writeJsonOutput(ostream &output) const
           exit(EXIT_FAILURE);
         }
       output << " ";
-      it->expression->writeJsonOutput(output, {}, {});
+      it.expression->writeJsonOutput(output, {}, {});
       output << R"("})" << endl;
     }
   output << "]" << endl;
@@ -1449,43 +1451,44 @@ EstimatedParamsStatement::writeJsonOutput(ostream &output) const
 {
   output << R"({"statementName": "estimated_params", )"
          << R"("params": [)";
-  for (auto it = estim_params_list.begin(); it != estim_params_list.end(); ++it)
+  for (bool printed_something{false};
+       const auto &it : estim_params_list)
     {
-      if (it != estim_params_list.begin())
+      if (exchange(printed_something, true))
         output << ", ";
       output << "{";
-      switch (it->type)
+      switch (it.type)
         {
         case 1:
-          output << R"("var": ")" << it->name << R"(")";
+          output << R"("var": ")" << it.name << R"(")";
           break;
         case 2:
-          output << R"("param": ")" << it->name << R"(")";
+          output << R"("param": ")" << it.name << R"(")";
           break;
         case 3:
-          output << R"("var1": ")" << it->name << R"(",)"
-                 << R"("var2": ")" << it->name2 << R"(")";
+          output << R"("var1": ")" << it.name << R"(",)"
+                 << R"("var2": ")" << it.name2 << R"(")";
           break;
         }
 
       output << R"(, "init_val": ")";
-      it->init_val->writeJsonOutput(output, {}, {});
+      it.init_val->writeJsonOutput(output, {}, {});
       output << R"(", "lower_bound": ")";
-      it->low_bound->writeJsonOutput(output, {}, {});
+      it.low_bound->writeJsonOutput(output, {}, {});
       output << R"(", "upper_bound": ")";
-      it->up_bound->writeJsonOutput(output, {}, {});
+      it.up_bound->writeJsonOutput(output, {}, {});
       output << R"(", "prior_distribution": )"
-             << static_cast<int>(it->prior)
+             << static_cast<int>(it.prior)
              << R"(, "mean": ")";
-      it->mean->writeJsonOutput(output, {}, {});
+      it.mean->writeJsonOutput(output, {}, {});
       output << R"(", "std": ")";
-      it->std->writeJsonOutput(output, {}, {});
+      it.std->writeJsonOutput(output, {}, {});
       output << R"(", "p3": ")";
-      it->p3->writeJsonOutput(output, {}, {});
+      it.p3->writeJsonOutput(output, {}, {});
       output << R"(", "p4": ")";
-      it->p4->writeJsonOutput(output, {}, {});
+      it.p4->writeJsonOutput(output, {}, {});
       output << R"(", "jscale": ")";
-      it->jscale->writeJsonOutput(output, {}, {});
+      it.jscale->writeJsonOutput(output, {}, {});
       output << R"("})" << endl;
     }
   output << "]"
@@ -1607,26 +1610,27 @@ EstimatedParamsInitStatement::writeJsonOutput(ostream &output) const
     output << R"(, "use_calibration_initialization": 1)";
 
   output << R"(, "params": [)";
-  for (auto it = estim_params_list.begin(); it != estim_params_list.end(); ++it)
+  for (bool printed_something{false};
+       const auto &it : estim_params_list)
     {
-      if (it != estim_params_list.begin())
+      if (exchange(printed_something, true))
         output << ", ";
       output << "{";
-      switch (it->type)
+      switch (it.type)
         {
         case 1:
-          output << R"("var": ")" << it->name << R"(")";
+          output << R"("var": ")" << it.name << R"(")";
           break;
         case 2:
-          output << R"("param": ")" << it->name << R"(")";
+          output << R"("param": ")" << it.name << R"(")";
           break;
         case 3:
-          output << R"("var1": ")" << it->name << R"(",)"
-                 << R"("var2": ")" << it->name2 << R"(")";
+          output << R"("var1": ")" << it.name << R"(",)"
+                 << R"("var2": ")" << it.name2 << R"(")";
           break;
         }
       output << R"(, "init_val": ")";
-      it->init_val->writeJsonOutput(output, {}, {});
+      it.init_val->writeJsonOutput(output, {}, {});
       output << R"("})";
     }
   output << "]"
@@ -1721,28 +1725,29 @@ EstimatedParamsBoundsStatement::writeJsonOutput(ostream &output) const
   output << R"({"statementName": "estimated_params_bounds", )"
          << R"("params": [)";
 
-  for (auto it = estim_params_list.begin(); it != estim_params_list.end(); ++it)
+  for (bool printed_something{false};
+       const auto &it : estim_params_list)
     {
-      if (it != estim_params_list.begin())
+      if (exchange(printed_something, true))
         output << ", ";
       output << "{";
-      switch (it->type)
+      switch (it.type)
         {
         case 1:
-          output << R"("var": ")" << it->name << R"(")";
+          output << R"("var": ")" << it.name << R"(")";
           break;
         case 2:
-          output << R"("param": ")" << it->name << R"(")";
+          output << R"("param": ")" << it.name << R"(")";
           break;
         case 3:
-          output << R"("var1": ")" << it->name << R"(",)"
-                 << R"("var2": ")" << it->name2 << R"(")";
+          output << R"("var1": ")" << it.name << R"(",)"
+                 << R"("var2": ")" << it.name2 << R"(")";
           break;
         }
       output << R"(, "lower_bound": )";
-      it->low_bound->writeJsonOutput(output, {}, {});
+      it.low_bound->writeJsonOutput(output, {}, {});
       output << R"(, "upper_bound": )";
-      it->up_bound->writeJsonOutput(output, {}, {});
+      it.up_bound->writeJsonOutput(output, {}, {});
       output << "}";
     }
   output << "]"
@@ -1819,22 +1824,23 @@ EstimatedParamsRemoveStatement::writeJsonOutput(ostream &output) const
   output << R"({"statementName": "estimated_params_remove", )"
          << R"("params": [)";
 
-  for (auto it = estim_params_list.begin(); it != estim_params_list.end(); ++it)
+  for (bool printed_something{false};
+       const auto &it : estim_params_list)
     {
-      if (it != estim_params_list.begin())
+      if (exchange(printed_something, true))
         output << ", ";
       output << "{";
-      switch (it->type)
+      switch (it.type)
         {
         case 1:
-          output << R"("var": ")" << it->name << R"(")";
+          output << R"("var": ")" << it.name << R"(")";
           break;
         case 2:
-          output << R"("param": ")" << it->name << R"(")";
+          output << R"("param": ")" << it.name << R"(")";
           break;
         case 3:
-          output << R"("var1": ")" << it->name << R"(",)"
-                 << R"("var2": ")" << it->name2 << R"(")";
+          output << R"("var1": ")" << it.name << R"(",)"
+                 << R"("var2": ")" << it.name2 << R"(")";
           break;
         }
       output << "}";
@@ -1874,17 +1880,16 @@ DeterministicTrendsStatement::writeJsonOutput(ostream &output) const
 {
   output << R"({"statementName": "deterministic_trends", )"
          << R"("trends" : {)";
-  bool printed = false;
-  for (const auto &trend_element : trend_elements)
+  for (bool printed_something{false};
+       const auto &trend_element : trend_elements)
     {
       if (symbol_table.getType(trend_element.first) == SymbolType::endogenous)
         {
-          if (printed)
+          if (exchange(printed_something, true))
             output << ", ";
           output << R"(")" << trend_element.first << R"(": ")";
           trend_element.second->writeJsonOutput(output, {}, {});
           output << R"(")" << endl;
-          printed = true;
         }
       else
         cerr << "Warning : Non-variable symbol used in deterministic_trends: " << trend_element.first << endl;
@@ -1924,17 +1929,16 @@ ObservationTrendsStatement::writeJsonOutput(ostream &output) const
 {
   output << R"({"statementName": "observation_trends", )"
          << R"("trends" : {)";
-  bool printed = false;
-  for (const auto &trend_element : trend_elements)
+  for (bool printed_something{false};
+       const auto &trend_element : trend_elements)
     {
       if (symbol_table.getType(trend_element.first) == SymbolType::endogenous)
         {
-          if (printed)
+          if (exchange(printed_something, true))
             output << ", ";
           output << R"(")" << trend_element.first << R"(": ")";
           trend_element.second->writeJsonOutput(output, {}, {});
           output << R"(")" << endl;
-          printed = true;
         }
       else
         cerr << "Warning : Non-variable symbol used in observation_trends: " << trend_element.first << endl;
@@ -1992,12 +1996,11 @@ FilterInitialStateStatement::writeJsonOutput(ostream &output) const
   output << R"({"statementName": "filter_initial_state", )"
          << R"("states": [)";
 
-  for (auto it = filter_initial_state_elements.begin();
-       it != filter_initial_state_elements.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[key, val] : filter_initial_state_elements)
     {
-      if (it != filter_initial_state_elements.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      auto &[key, val] = *it;
       auto &[symb_id, lag] = key;
       output << R"({ "var": ")" << symbol_table.getName(symb_id)
              << R"(", "lag": )" << lag
@@ -2038,8 +2041,8 @@ OsrParamsStatement::writeOutput(ostream &output, const string &basename, bool mi
   symbol_list.writeOutput("M_.osr.param_names", output);
   output << "M_.osr.param_names = cellstr(M_.osr.param_names);" << endl
          << "M_.osr.param_indices = zeros(length(M_.osr.param_names), 1);" << endl;
-  int i = 0;
-  for (auto &symbol : symbol_list.getSymbols())
+  for (int i{0};
+       auto &symbol : symbol_list.getSymbols())
     output << "M_.osr.param_indices(" << ++i <<") = " << symbol_table.getTypeSpecificID(symbol) + 1 << ";" << endl;
 }
 
@@ -2091,15 +2094,16 @@ OsrParamsBoundsStatement::writeJsonOutput(ostream &output) const
 {
   output << R"({"statementName": "osr_params_bounds")"
          << R"(, "bounds": [)";
-  for (auto it = osr_params_list.begin(); it != osr_params_list.end(); ++it)
+  for (bool printed_something{false};
+       const auto &it : osr_params_list)
     {
-      if (it != osr_params_list.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      output << R"({"parameter": ")" << it->name << R"(",)"
+      output << R"({"parameter": ")" << it.name << R"(",)"
              << R"("bounds": [")";
-      it->low_bound->writeJsonOutput(output, {}, {});
+      it.low_bound->writeJsonOutput(output, {}, {});
       output << R"(", ")";
-      it->up_bound->writeJsonOutput(output, {}, {});
+      it.up_bound->writeJsonOutput(output, {}, {});
       output << R"("])"
              << "}";
     }
@@ -2367,12 +2371,13 @@ ModelComparisonStatement::writeJsonOutput(ostream &output) const
   if (!filename_list.empty())
     output << R"(, "filename_list": {)";
 
-  for (auto it = filename_list.begin(); it != filename_list.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[name, prior] : filename_list)
     {
-      if (it != filename_list.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      output << R"("name": ")" << it->first << R"(")"
-             << R"("prior": ")" << it->second << R"(")";
+      output << R"("name": ")" << name << R"(")"
+             << R"("prior": ")" << prior << R"(")";
     }
 
   if (!filename_list.empty())
@@ -3436,16 +3441,17 @@ SvarIdentificationStatement::writeJsonOutput(ostream &output) const
       output << R"(, "nlags": )" << getMaxLag()
              << R"(, "restrictions": [)";
 
-      for (auto it = restrictions.begin(); it != restrictions.end(); ++it)
+      for (bool printed_something{false};
+           const auto &it : restrictions)
         {
-          if (it != restrictions.begin())
+          if (exchange(printed_something, true))
             output << ", ";
           output << "{"
-                 << R"("equation_number": )" << it->equation << ", "
-                 << R"("restriction_number": )" << it->restriction_nbr << ", "
-                 << R"("variable": ")" << symbol_table.getName(it->variable) << R"(", )"
+                 << R"("equation_number": )" << it.equation << ", "
+                 << R"("restriction_number": )" << it.restriction_nbr << ", "
+                 << R"("variable": ")" << symbol_table.getName(it.variable) << R"(", )"
                  << R"("expression": ")";
-          it->value->writeOutput(output);
+          it.value->writeOutput(output);
           output << R"("})";
         }
       output << "]";
@@ -3601,11 +3607,12 @@ MarkovSwitchingStatement::writeOutput(ostream &output, const string &basename, b
     {
       output << "[";
       auto &v = options_list.vector_value_options.at("ms.duration");
-      for (auto it = v.begin(); it != v.end(); ++it)
+      for (bool printed_something{false};
+           const auto &it : v)
         {
-          if (it != v.begin())
+          if (exchange(printed_something, true))
             output << ", ";
-          output << *it;
+          output << it;
         }
       output << "]";
     }
@@ -3624,8 +3631,8 @@ MarkovSwitchingStatement::writeOutput(ostream &output, const string &basename, b
       output << ";" << endl;
     }
 
-  int restrictions_index = 0;
-  for (const auto &[regimes, prob] : restriction_map)
+  for (int restrictions_index{0};
+       const auto &[regimes, prob] : restriction_map)
     output << "options_.ms.ms_chain(" << itChain->second << ").restrictions("
            << ++restrictions_index << ") = {[" << regimes.first << ", "
            << regimes.second << ", " << prob << "]};" << endl;
@@ -3643,13 +3650,14 @@ MarkovSwitchingStatement::writeJsonOutput(ostream &output) const
 
   if (!restriction_map.empty())
     output << ", {";
-  for (auto it = restriction_map.begin(); it != restriction_map.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[regimes, prob] : restriction_map)
     {
-      if (it != restriction_map.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      output << R"({"current_period_regime": )" << it->first.first
-             << R"(, "next_period_regime": )" << it->first.second
-             << R"(, "transition_probability": )"<< it->second
+      output << R"({"current_period_regime": )" << regimes.first
+             << R"(, "next_period_regime": )" << regimes.second
+             << R"(, "transition_probability": )"<< prob
              << "}";
     }
   if (!restriction_map.empty())
@@ -3833,15 +3841,17 @@ SubsamplesStatement::writeOutput(ostream &output, const string &basename, bool m
          << "estimation_info.subsamples(subsamples_indx).range = {};" << endl
          << "estimation_info.subsamples(subsamples_indx).range_index = {};" << endl;
 
-  int map_indx = 1;
-  for (auto it = subsample_declaration_map.begin();
-       it != subsample_declaration_map.end(); ++it, map_indx++)
-    output << "estimation_info.subsamples(subsamples_indx).range_index(" << map_indx << ") = {'"
-           << it->first << "'};" << endl
-           << "estimation_info.subsamples(subsamples_indx).range(" << map_indx << ").date1 = "
-           << it->second.first << ";" << endl
-           << "estimation_info.subsamples(subsamples_indx).range(" << map_indx << ").date2 = "
-           << it->second.second << ";" << endl;
+  for (int map_indx{1};
+       const auto &[range, dates] : subsample_declaration_map)
+    {
+      output << "estimation_info.subsamples(subsamples_indx).range_index(" << map_indx << ") = {'"
+             << range << "'};" << endl
+             << "estimation_info.subsamples(subsamples_indx).range(" << map_indx << ").date1 = "
+             << dates.first << ";" << endl
+             << "estimation_info.subsamples(subsamples_indx).range(" << map_indx << ").date2 = "
+             << dates.second << ";" << endl;
+      map_indx++;
+    }
 
   // Initialize associated subsample substructures in estimation_info
   const SymbolType symb_type = symbol_table.getType(name1);
@@ -3896,15 +3906,15 @@ SubsamplesStatement::writeJsonOutput(ostream &output) const
     output << R"(, "name2": ")" << name2 << R"(")";
 
   output << R"(, "declarations": {)";
-  for (auto it = subsample_declaration_map.begin();
-       it != subsample_declaration_map.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[range, dates] : subsample_declaration_map)
     {
-      if (it != subsample_declaration_map.begin())
+      if (exchange(printed_something, true))
         output << ",";
       output << "{"
-             << R"("range_index": ")" << it->first << R"(")"
-             << R"(, "date1": ")" << it->second.first << R"(")"
-             << R"(, "date2": ")" << it->second.second << R"(")"
+             << R"("range_index": ")" << range << R"(")"
+             << R"(, "date1": ")" << dates.first << R"(")"
+             << R"(, "date2": ")" << dates.second << R"(")"
              << "}";
     }
   output << "}"
@@ -4094,11 +4104,12 @@ JointPriorStatement::writeOutputHelper(ostream &output, const string &field, con
            it != options_list.vector_value_options.end())
     {
       output << "[";
-      for (auto it2 = it->second.begin(); it2 != it->second.end(); ++it2)
+      for (bool printed_something{false};
+           const auto &it2 : it->second)
         {
-          if (it2 != it->second.begin())
+          if (exchange(printed_something, true))
             output << ", ";
-          output << *it2;
+          output << it2;
         }
       output << "]";
     }
@@ -4106,16 +4117,18 @@ JointPriorStatement::writeOutputHelper(ostream &output, const string &field, con
            it != options_list.vector_of_vector_value_options.end())
     {
       output << "{";
-      for (auto it2 = it->second.begin(); it2 != it->second.end(); ++it2)
+      for (bool printed_something{false};
+           const auto &it2 : it->second)
         {
-          if (it2 != it->second.begin())
+          if (exchange(printed_something, true))
             output << ", ";
           output << "[";
-          for (auto it3 = it2->begin(); it3 != it2->end(); ++it3)
+          for (bool printed_something2{false};
+               const auto &it3 : it2)
             {
-              if (it3 != it2->begin())
+              if (exchange(printed_something2, true))
                 output << ", ";
-              output << *it3;
+              output << it3;
             }
           output << "]";
         }
@@ -4131,11 +4144,12 @@ JointPriorStatement::writeJsonOutput(ostream &output) const
 {
   output << R"({"statementName": "joint_prior")"
          << R"(, "key": [)";
-  for (auto it = joint_parameters.begin(); it != joint_parameters.end(); ++it)
+  for (bool printed_something{false};
+       const auto &it : joint_parameters)
     {
-      if (it != joint_parameters.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      output << R"(")" << *it << R"(")";
+      output << R"(")" << it << R"(")";
     }
   output << "]";
 
@@ -5126,14 +5140,13 @@ GenerateIRFsStatement::writeJsonOutput(ostream &output) const
       for (size_t i = 0; i < generate_irf_names.size(); i++)
         {
           output << R"({"name": ")" << generate_irf_names[i] << R"(", "shocks": [)";
-          map<string, double> m = generate_irf_elements[i];
-          size_t idx = 0;
-          for (auto it = m.begin(); it != m.end(); ++it, idx++)
+          for (bool printed_something{false};
+               auto &[exo_name, exo_value] : generate_irf_elements[i])
             {
-              output << R"({"exogenous_variable": ")" << it->first << R"(", )"
-                     << R"("exogenous_variable_value": ")" << it->second << R"("})";
-              if (idx + 1 < m.size())
+              if (exchange(printed_something, true))
                 output << ", ";
+              output << R"({"exogenous_variable": ")" << exo_name << R"(", )"
+                     << R"("exogenous_variable_value": ")" << exo_value << R"("})";
             }
           output << "]}";
           if (i + 1 < generate_irf_names.size())
@@ -5174,34 +5187,36 @@ void
 MatchedMomentsStatement::writeJsonOutput(ostream &output) const
 {
   output << R"({"statementName": "matched_moments", "moments": [)" << endl;
-  for (auto it = moments.begin(); it != moments.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[symb_ids, lags, powers] : moments)
     {
-      const auto &[symb_ids, lags, powers] = *it;
+      if (exchange(printed_something, true))
+        output << ',';
       output << R"(  { "endos": [)";
-      for (auto it2 = symb_ids.begin(); it2 != symb_ids.end(); ++it2)
+      for (bool printed_something2{false};
+           int s : symb_ids)
         {
-          if (it2 != symb_ids.begin())
+          if (exchange(printed_something2, true))
             output << ',';
-          output << symbol_table.getTypeSpecificID(*it2)+1;
+          output << symbol_table.getTypeSpecificID(s)+1;
         }
       output << R"(], "lags": [)";
-      for (auto it2 = lags.begin(); it2 != lags.end(); ++it2)
+      for (bool printed_something2{false};
+           int l : lags)
         {
-          if (it2 != lags.begin())
+          if (exchange(printed_something2, true))
             output << ',';
-          output << *it2;
+          output << l;
         }
       output << R"(], "powers": [)";
-      for (auto it2 = powers.begin(); it2 != powers.end(); ++it2)
+      for (bool printed_something2{false};
+           int p : powers)
         {
-          if (it2 != powers.begin())
+          if (exchange(printed_something2, true))
             output << ',';
-          output << *it2;
+          output << p;
         }
-      output << "]}";
-      if (next(it) != moments.end())
-        output << ',';
-      output << endl;
+      output << "]}" << endl;
     }
   output << "]}" << endl;
 }
@@ -5249,8 +5264,8 @@ OccbinConstraintsStatement::writeOutput(ostream &output, const string &basename,
       exit(EXIT_FAILURE);
     }
   diff_output << "function [binding, relax, err] = occbin_difference(zdatalinear, params, steady_state)" << endl;
-  int idx = 1;
-  for (const auto &[name, bind, relax, error_bind, error_relax] : constraints)
+  for (int idx{1};
+       const auto &[name, bind, relax, error_bind, error_relax] : constraints)
     {
       diff_output << "binding.constraint_" << idx << " = ";
       dynamic_cast<ExprNode *>(bind)->writeOutput(diff_output, ExprNodeOutputType::occbinDifferenceFile);
@@ -5310,10 +5325,11 @@ void
 OccbinConstraintsStatement::writeJsonOutput(ostream &output) const
 {
   output << R"({"statementName": "occbin_constraints", "constraints": [)" << endl;
-  for (auto it = constraints.begin(); it != constraints.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[name, bind, relax, error_bind, error_relax] : constraints)
     {
-      auto [name, bind, relax, error_bind, error_relax] = *it;
-
+      if (exchange(printed_something, true))
+        output << ',';
       output << R"({ "name": ")" << name << R"(", "bind": ")";
       dynamic_cast<ExprNode *>(bind)->writeJsonOutput(output, {}, {});
       output << R"(", "relax": ")";
@@ -5325,10 +5341,7 @@ OccbinConstraintsStatement::writeJsonOutput(ostream &output) const
       output << R"(", "error_relax": ")";
       if (error_relax)
         error_relax->writeJsonOutput(output, {}, {});
-      output << R"(" })";
-      if (next(it) != constraints.end())
-        output << ',';
-      output << endl;
+      output << R"(" })" << endl;
     }
   output << "]}" << endl;
 }
diff --git a/src/ConfigFile.cc b/src/ConfigFile.cc
index ff2818cb6585f733c03ce5ab84c2d27d88762e34..2d5a0807e3e10941d4c91e5a0d9c5fbb877e02de 100644
--- a/src/ConfigFile.cc
+++ b/src/ConfigFile.cc
@@ -382,9 +382,9 @@ ConfigFile::getConfigFileInfo(const string &config_file)
               {
                 char_separator sep(" ,;", "()", drop_empty_tokens);
                 tokenizer tokens(tokenizedLine.back(), sep);
-                bool begin_weight = false;
                 string node_name;
-                for (const auto &token : tokens)
+                for (bool begin_weight{false};
+                     const auto &token : tokens)
                   {
                     if (token.compare("(") == 0)
                       {
@@ -535,19 +535,15 @@ ConfigFile::addParallelConfFileElement(bool inNode, bool inCluster, const member
 void
 ConfigFile::checkPass(WarningConsolidation &warnings) const
 {
-  bool global_init_file_declared = false;
-  for (const auto &hook : hooks)
-    {
-      for (const auto &mapit : hook.get_hooks())
-        if (mapit.first.compare("global_init_file") == 0)
-          if (global_init_file_declared == true)
-            {
-              cerr << "ERROR: Only one global initialization file may be provided." << endl;
-              exit(EXIT_FAILURE);
-            }
-          else
-            global_init_file_declared = true;
-    }
+  for (bool global_init_file_declared{false};
+       const auto &hook : hooks)
+    for (const auto &mapit : hook.get_hooks())
+      if (mapit.first.compare("global_init_file") == 0)
+        if (exchange(global_init_file_declared, true))
+          {
+            cerr << "ERROR: Only one global initialization file may be provided." << endl;
+            exit(EXIT_FAILURE);
+          }
 
   if (!parallel && !parallel_test)
     return;
@@ -709,8 +705,8 @@ ConfigFile::writeCluster(ostream &output) const
 
   auto cluster_it = cluster_name.empty() ? clusters.find(firstClusterName) : clusters.find(cluster_name);
 
-  int i{1};
-  for (const auto &slave_node : slave_nodes)
+  for (int i{1};
+       const auto &slave_node : slave_nodes)
     {
       bool slave_node_in_member_nodes = false;
       for (const auto &itmn : cluster_it->second.member_nodes)
diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc
index c3eb92afea3dbb64c7e63d1eb4e867d946e7e201..c5e3b475b624aaca9a7f7be01f88b13229d8aa01 100644
--- a/src/DynamicModel.cc
+++ b/src/DynamicModel.cc
@@ -1535,12 +1535,12 @@ DynamicModel::printNonZeroHessianEquations(ostream &output) const
 {
   if (nonzero_hessian_eqs.size() != 1)
     output << "[";
-  for (auto it = nonzero_hessian_eqs.begin();
-       it != nonzero_hessian_eqs.end(); ++it)
+  for (bool printed_something{false};
+       int it : nonzero_hessian_eqs)
     {
-      if (it != nonzero_hessian_eqs.begin())
+      if (exchange(printed_something, true))
         output << " ";
-      output << *it + 1;
+      output << it + 1;
     }
   if (nonzero_hessian_eqs.size() != 1)
     output << "]";
@@ -1964,8 +1964,8 @@ DynamicModel::writeDynamicModel(const string &basename, ostream &DynamicOutput,
            accesses and expression reusage. */
         ostringstream i_output, j_output, v_output;
 
-        int k = 0; // Current line index in the 3-column matrix
-        for (const auto &[vidx, d] : derivatives[i])
+        for (int k{0}; // Current line index in the 3-column matrix
+             const auto &[vidx, d] : derivatives[i])
           {
             int eq = vidx[0];
 
@@ -2356,8 +2356,8 @@ DynamicModel::writeDynamicJacobianNonZeroElts(const string &basename) const
          << "% Returns the coordinates of non-zero elements in the Jacobian, in column-major order, for each lead/lag (only for endogenous)" << endl;
   auto print_nzij = [&output](const vector<pair<int, int>> &nzij, const string &name) {
                       output << "  " << name << " = zeros(" << nzij.size() << ", 2, 'int32');" << endl;
-                      int idx = 1;
-                      for (const auto &it : nzij)
+                      for (int idx{1};
+                           const auto &it : nzij)
                         {
                           output << "  " << name << "(" << idx << ",1)=" << it.second+1 << ';'
                                  << " " << name << "(" << idx << ",2)=" << it.first+1 << ';' << endl;
@@ -2677,8 +2677,8 @@ DynamicModel::writeBlockDriverOutput(ostream &output, const string &basename,
       output << "];" << endl;
 
       output << "M_.block_structure.block(" << blk+1 << ").tm1 = zeros(" << blocks_other_endo[blk].size() << ", " << state_var.size() << ");" << endl;
-      int line = 1;
-      for (auto other_endo : blocks_other_endo[blk])
+      for (int line{1};
+           auto other_endo : blocks_other_endo[blk])
         {
           if (auto it = find(state_var.begin(), state_var.end(), other_endo);
               it != state_var.end())
@@ -3481,10 +3481,10 @@ DynamicModel::computeAutoregressiveMatrices() const
   map<string, map<tuple<int, int, int>, expr_t>> ARr;
   for (const auto &[model_name, eqns] : trend_component_model_table.getNonTargetEqNums())
     {
-      int i = 0;
       map<tuple<int, int, int>, expr_t> AR;
       const vector<int> &lhs = trend_component_model_table.getNonTargetLhs(model_name);
-      for (auto eqn : eqns)
+      for (int i{0};
+           auto eqn : eqns)
         {
           auto bopn = dynamic_cast<BinaryOpNode *>(equations[eqn]->arg2);
           bopn->fillAutoregressiveRow(i++, lhs, AR);
@@ -3586,22 +3586,22 @@ DynamicModel::computeErrorComponentMatrices(const ExprNode::subst_table_t &diff_
 
   for (const auto &[model_name, eqns] : trend_component_model_table.getEqNums())
     {
-      int i = 0;
       map<tuple<int, int>, expr_t> A0, A0star;
       vector<int> target_lhs = trend_component_model_table.getTargetLhs(model_name);
       vector<int> nontarget_eqnums = trend_component_model_table.getNonTargetEqNums(model_name);
       vector<int> undiff_nontarget_lhs = getUndiffLHSForPac(model_name, diff_subst_table);
       vector<int> parsed_undiff_nontarget_lhs;
 
-      for (auto eqn : eqns)
+      for (int i{0};
+           auto eqn : eqns)
         {
           if (find(nontarget_eqnums.begin(), nontarget_eqnums.end(), eqn) != nontarget_eqnums.end())
             parsed_undiff_nontarget_lhs.push_back(undiff_nontarget_lhs.at(i));
           i++;
         }
 
-      i = 0;
-      for (auto eqn : eqns)
+      for (int i{0};
+           auto eqn : eqns)
         if (find(nontarget_eqnums.begin(), nontarget_eqnums.end(), eqn) != nontarget_eqnums.end())
           equations[eqn]->arg2->fillErrorCorrectionRow(i++, parsed_undiff_nontarget_lhs, target_lhs, A0, A0star);
       A0r[model_name] = A0;
@@ -4109,9 +4109,9 @@ DynamicModel::computePacBackwardExpectationSubstitutionWithComponents(const stri
   };
 
   expr_t substexpr = Zero;
-  int component_idx = 1;
 
-  for (auto &[component, growth, auxname, kind, coeff, growth_neutrality_param, h_indices, original_growth, growth_info] : pac_target_components)
+  for (int component_idx{1};
+       auto &[component, growth, auxname, kind, coeff, growth_neutrality_param, h_indices, original_growth, growth_info] : pac_target_components)
     {
       string name_component = name + "_component" + to_string(component_idx);
 
@@ -4276,21 +4276,22 @@ DynamicModel::computingPass(bool jacobianExo, int derivsOrder, int paramsDerivsO
 void
 DynamicModel::computeXrefs()
 {
-  int i = 0;
-  for (auto &equation : equations)
+  for (int i{0};
+       auto &equation : equations)
     {
       ExprNode::EquationInfo ei;
       equation->computeXrefs(ei);
       xrefs[i++] = ei;
     }
 
-  i = 0;
-  for (auto it = xrefs.begin(); it != xrefs.end(); ++it, i++)
+  for (int i{0};
+       const auto &[eq, eqinfo] : xrefs)
     {
-      computeRevXref(xref_param, it->second.param, i);
-      computeRevXref(xref_endo, it->second.endo, i);
-      computeRevXref(xref_exo, it->second.exo, i);
-      computeRevXref(xref_exo_det, it->second.exo_det, i);
+      computeRevXref(xref_param, eqinfo.param, i);
+      computeRevXref(xref_endo, eqinfo.endo, i);
+      computeRevXref(xref_exo, eqinfo.exo, i);
+      computeRevXref(xref_exo_det, eqinfo.exo_det, i);
+      i++;
     }
 }
 
@@ -4314,28 +4315,30 @@ DynamicModel::writeXrefs(ostream &output) const
          << "M_.xref1.endo = cell(1, M_.eq_nbr);" << endl
          << "M_.xref1.exo = cell(1, M_.eq_nbr);" << endl
          << "M_.xref1.exo_det = cell(1, M_.eq_nbr);" << endl;
-  int i = 1;
-  for (auto it = xrefs.begin(); it != xrefs.end(); ++it, i++)
+  for (int i{1};
+       const auto &[eq, eqinfo] : xrefs)
     {
       output << "M_.xref1.param{" << i << "} = [ ";
-      for (const auto &it1 : it->second.param)
-        output << symbol_table.getTypeSpecificID(it1.first) + 1 << " ";
+      for (const auto &[id, lag] : eqinfo.param)
+        output << symbol_table.getTypeSpecificID(id) + 1 << " ";
       output << "];" << endl;
 
       output << "M_.xref1.endo{" << i << "} = [ ";
-      for (const auto &it1 : it->second.endo)
-        output << "struct('id', " << symbol_table.getTypeSpecificID(it1.first) + 1 << ", 'shift', " << it1.second << ");";
+      for (const auto &[id, lag] : eqinfo.endo)
+        output << "struct('id', " << symbol_table.getTypeSpecificID(id) + 1 << ", 'shift', " << lag << ");";
       output << "];" << endl;
 
       output << "M_.xref1.exo{" << i << "} = [ ";
-      for (const auto &it1 : it->second.exo)
-        output << "struct('id', " << symbol_table.getTypeSpecificID(it1.first) + 1 << ", 'shift', " << it1.second << ");";
+      for (const auto &[id, lag] : eqinfo.exo)
+        output << "struct('id', " << symbol_table.getTypeSpecificID(id) + 1 << ", 'shift', " << lag << ");";
       output << "];" << endl;
 
       output << "M_.xref1.exo_det{" << i << "} = [ ";
-      for (const auto &it1 : it->second.exo_det)
-        output << "struct('id', " << symbol_table.getTypeSpecificID(it1.first) + 1 << ", 'shift', " << it1.second << ");";
+      for (const auto &[id, lag] : eqinfo.exo_det)
+        output << "struct('id', " << symbol_table.getTypeSpecificID(id) + 1 << ", 'shift', " << lag << ");";
       output << "];" << endl;
+
+      i++;
     }
 
   output << "M_.xref2.param = cell(1, M_.param_nbr);" << endl
@@ -4351,21 +4354,22 @@ DynamicModel::writeXrefs(ostream &output) const
 void
 DynamicModel::writeRevXrefs(ostream &output, const map<pair<int, int>, set<int>> &xrefmap, const string &type) const
 {
-  int last_tsid = -1;
-  for (const auto &it : xrefmap)
+  for (int last_tsid{-1};
+       const auto &[key, eqs] : xrefmap)
     {
-      int tsid = symbol_table.getTypeSpecificID(it.first.first) + 1;
+      auto &[id, lag] = key;
+      int tsid = symbol_table.getTypeSpecificID(id) + 1;
       output << "M_.xref2." << type << "{" << tsid << "} = [ ";
       if (last_tsid == tsid)
         output << "M_.xref2." << type << "{" << tsid << "}; ";
       else
         last_tsid = tsid;
 
-      for (const auto &it1 : it.second)
+      for (int eq : eqs)
         if (type == "param")
-          output << it1 + 1 << " ";
+          output << eq + 1 << " ";
         else
-          output << "struct('shift', " << it.first.second << ", 'eq', " << it1+1 << ");";
+          output << "struct('shift', " << lag << ", 'eq', " << eq+1 << ");";
       output << "];" << endl;
     }
 }
@@ -4511,20 +4515,20 @@ DynamicModel::computeBlockDynJacobianCols()
   blocks_jacob_cols_exo_det.resize(nb_blocks);
   for (int blk = 0; blk < nb_blocks; blk++)
     {
-      int index = 0;
-      for (auto [lag, var] : dynamic_endo[blk])
+      for (int index{0};
+           auto [lag, var] : dynamic_endo[blk])
         blocks_jacob_cols_endo[blk][{ var, lag }] = index++;
 
-      index = 0;
-      for (auto [lag, var] : dynamic_other_endo[blk])
+      for (int index{0};
+           auto [lag, var] : dynamic_other_endo[blk])
         blocks_jacob_cols_other_endo[blk][{ var, lag }] = index++;
 
-      index = 0;
-      for (auto [lag, var] : dynamic_exo[blk])
+      for (int index{0};
+           auto [lag, var] : dynamic_exo[blk])
         blocks_jacob_cols_exo[blk][{ var, lag }] = index++;
 
-      index = 0;
-      for (auto [lag, var] : dynamic_exo_det[blk])
+      for (int index{0};
+           auto [lag, var] : dynamic_exo_det[blk])
         blocks_jacob_cols_exo_det[blk][{ var, lag }] = index++;
     }
 }
@@ -5001,8 +5005,8 @@ DynamicModel::computeDynJacobianCols(bool jacobianExo)
     }
 
   // Fill in dynamic jacobian columns for endogenous
-  int sorted_id = 0;
-  for (auto &it : ordered_dyn_endo)
+  for (int sorted_id{0};
+       auto &it : ordered_dyn_endo)
     dyn_jacobian_cols_table[it.second] = sorted_id++;
 
   // Set final value for dynJacobianColsNbr
@@ -5105,8 +5109,8 @@ DynamicModel::writeParamsDerivativesFile(const string &basename, bool julia) con
       gp_output << ";" << endl;
     }
 
-  int i = 1;
-  for (const auto &[indices, d2] : params_derivatives.find({ 0, 2 })->second)
+  for (int i{1};
+       const auto &[indices, d2] : params_derivatives.find({ 0, 2 })->second)
     {
       auto [eq, param1, param2] = vectorToTuple<3>(indices);
 
@@ -5143,8 +5147,8 @@ DynamicModel::writeParamsDerivativesFile(const string &basename, bool julia) con
         }
     }
 
-  i = 1;
-  for (const auto &[indices, d2] : params_derivatives.find({ 1, 2 })->second)
+  for (int i{1};
+       const auto &[indices, d2] : params_derivatives.find({ 1, 2 })->second)
     {
       auto [eq, var, param1, param2] = vectorToTuple<4>(indices);
 
@@ -5186,8 +5190,8 @@ DynamicModel::writeParamsDerivativesFile(const string &basename, bool julia) con
         }
     }
 
-  i = 1;
-  for (const auto &[indices, d2] : params_derivatives.find({ 2, 1 })->second)
+  for (int i{1};
+       const auto &[indices, d2] : params_derivatives.find({ 2, 1 })->second)
     {
       auto [eq, var1, var2, param] = vectorToTuple<4>(indices);
 
@@ -5229,8 +5233,8 @@ DynamicModel::writeParamsDerivativesFile(const string &basename, bool julia) con
         }
     }
 
-  i = 1;
-  for (const auto &[indices, d2] : params_derivatives.find({ 3, 1 })->second)
+  for (int i{1};
+       const auto &[indices, d2] : params_derivatives.find({ 3, 1 })->second)
     {
       auto [eq, var1, var2, var3, param] = vectorToTuple<5>(indices);
 
@@ -5581,8 +5585,8 @@ set<int>
 DynamicModel::findPacExpectationEquationNumbers() const
 {
   set<int> eqnumbers;
-  int i = 0;
-  for (auto &equation : equations)
+  for (int i{0};
+       auto &equation : equations)
     {
       if (equation->containsPacExpectation())
         eqnumbers.insert(i);
@@ -6082,20 +6086,18 @@ void
 DynamicModel::writeJsonVariableMapping(ostream &output) const
 {
   output << R"("variable_mapping":[)" << endl;
-  for (auto it = variableMapping.begin(); it != variableMapping.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[var, eqs] : variableMapping)
     {
-      if (it != variableMapping.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      auto [var, eqs] = *it;
       output << R"({"name": ")" << symbol_table.getName(var) << R"(", "equations":[)";
-      bool first_eq = true;
-      for (int it2 : eqs)
+      for (bool printed_something2{false};
+           int it2 : eqs)
         if (auto tmp = equation_tags.getTagValueByEqnAndKey(it2, "name");
             !tmp.empty())
           {
-            if (first_eq)
-              first_eq = false;
-            else
+            if (exchange(printed_something2, true))
               output << ", ";
             output << '"' << tmp << '"';
           }
@@ -6107,18 +6109,20 @@ DynamicModel::writeJsonVariableMapping(ostream &output) const
 void
 DynamicModel::writeJsonXrefsHelper(ostream &output, const map<pair<int, int>, set<int>> &xrefmap) const
 {
-  for (auto it = xrefmap.begin(); it != xrefmap.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[symb_lag, eqs] : xrefmap)
     {
-      if (it != xrefmap.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      output << R"({"name": ")" << symbol_table.getName(it->first.first) << R"(")"
-             << R"(, "shift": )" << it->first.second
+      output << R"({"name": ")" << symbol_table.getName(symb_lag.first) << R"(")"
+             << R"(, "shift": )" << symb_lag.second
              << R"(, "equations": [)";
-      for (auto it1 = it->second.begin(); it1 != it->second.end(); ++it1)
+      for (bool printed_something2{false};
+           int eq : eqs)
         {
-          if (it1 != it->second.begin())
+          if (exchange(printed_something2, true))
             output << ", ";
-          output << *it1 + 1;
+          output << eq + 1;
         }
       output << "]}";
     }
@@ -6272,13 +6276,12 @@ DynamicModel::writeJsonComputingPassOutput(ostream &output, bool writeDetails) c
                   << R"(, "ncols": )" << ncols
                   << R"(, "entries": [)";
 
-      for (auto it = derivatives[i].begin(); it != derivatives[i].end(); ++it)
+      for (bool printed_something{false};
+           const auto &[vidx, d] : derivatives[i])
         {
-          if (it != derivatives[i].begin())
+          if (exchange(printed_something, true))
             d_output[i] << ", ";
 
-          const vector<int> &vidx = it->first;
-          expr_t d = it->second;
           int eq = vidx[0];
 
           int col_idx = 0;
@@ -6353,14 +6356,13 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
             << R"(  "neqs": )" << equations.size()
             << R"(, "nparamcols": )" << symbol_table.param_nbr()
             << R"(, "entries": [)";
-  auto &rp = params_derivatives.find({ 0, 1 })->second;
-  for (auto it = rp.begin(); it != rp.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[vidx, d] : params_derivatives.find({ 0, 1 })->second)
     {
-      if (it != rp.begin())
+      if (exchange(printed_something, true))
         rp_output << ", ";
 
-      auto [eq, param] = vectorToTuple<2>(it->first);
-      expr_t d1 = it->second;
+      auto [eq, param] = vectorToTuple<2>(vidx);
 
       int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1;
 
@@ -6375,7 +6377,7 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
         rp_output << R"(, "param": ")" << symbol_table.getName(getSymbIDByDerivID(param)) << R"(")";
 
       rp_output << R"(, "val": ")";
-      d1->writeJsonOutput(rp_output, temp_term_union, tef_terms);
+      d->writeJsonOutput(rp_output, temp_term_union, tef_terms);
       rp_output << R"("})" << endl;
     }
   rp_output << "]}";
@@ -6385,14 +6387,13 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
             << R"(, "nvarcols": )" << dynJacobianColsNbr
             << R"(, "nparamcols": )" << symbol_table.param_nbr()
             << R"(, "entries": [)";
-  auto &gp = params_derivatives.find({ 1, 1 })->second;
-  for (auto it = gp.begin(); it != gp.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[vidx, d] : params_derivatives.find({ 1, 1 })->second)
     {
-      if (it != gp.begin())
+      if (exchange(printed_something, true))
         gp_output << ", ";
 
-      auto [eq, var, param] = vectorToTuple<3>(it->first);
-      expr_t d2 = it->second;
+      auto [eq, var, param] = vectorToTuple<3>(vidx);
 
       int var_col = getDynJacobianCol(var) + 1;
       int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1;
@@ -6411,7 +6412,7 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
                   << R"(, "param": ")" << symbol_table.getName(getSymbIDByDerivID(param)) << R"(")";
 
       gp_output << R"(, "val": ")";
-      d2->writeJsonOutput(gp_output, temp_term_union, tef_terms);
+      d->writeJsonOutput(gp_output, temp_term_union, tef_terms);
       gp_output << R"("})" << endl;
     }
   gp_output << "]}";
@@ -6421,14 +6422,13 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
              << R"(, "nparam1cols": )" << symbol_table.param_nbr()
              << R"(, "nparam2cols": )" << symbol_table.param_nbr()
              << R"(, "entries": [)";
-  auto &rpp = params_derivatives.find({ 0, 2 })->second;
-  for (auto it = rpp.begin(); it != rpp.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[vidx, d] : params_derivatives.find({ 0, 2 })->second)
     {
-      if (it != rpp.begin())
+      if (exchange(printed_something, true))
         rpp_output << ", ";
 
-      auto [eq, param1, param2] = vectorToTuple<3>(it->first);
-      expr_t d2 = it->second;
+      auto [eq, param1, param2] = vectorToTuple<3>(vidx);
 
       int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1;
       int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1;
@@ -6445,7 +6445,7 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
                    << R"(, "param2": ")" << symbol_table.getName(getSymbIDByDerivID(param2)) << R"(")";
 
       rpp_output << R"(, "val": ")";
-      d2->writeJsonOutput(rpp_output, temp_term_union, tef_terms);
+      d->writeJsonOutput(rpp_output, temp_term_union, tef_terms);
       rpp_output << R"("})" << endl;
     }
   rpp_output << "]}";
@@ -6456,14 +6456,13 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
              << R"(, "nparam1cols": )" << symbol_table.param_nbr()
              << R"(, "nparam2cols": )" << symbol_table.param_nbr()
              << R"(, "entries": [)";
-  auto &gpp = params_derivatives.find({ 1, 2 })->second;
-  for (auto it = gpp.begin(); it != gpp.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[vidx, d] : params_derivatives.find({ 1, 2 })->second)
     {
-      if (it != gpp.begin())
+      if (exchange(printed_something, true))
         gpp_output << ", ";
 
-      auto [eq, var, param1, param2] = vectorToTuple<4>(it->first);
-      expr_t d2 = it->second;
+      auto [eq, var, param1, param2] = vectorToTuple<4>(vidx);
 
       int var_col = getDynJacobianCol(var) + 1;
       int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1;
@@ -6485,7 +6484,7 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
                    << R"(, "param2": ")" << symbol_table.getName(getSymbIDByDerivID(param2)) << R"(")";
 
       gpp_output << R"(, "val": ")";
-      d2->writeJsonOutput(gpp_output, temp_term_union, tef_terms);
+      d->writeJsonOutput(gpp_output, temp_term_union, tef_terms);
       gpp_output << R"("})" << endl;
     }
   gpp_output << "]}" << endl;
@@ -6496,14 +6495,13 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
             << R"(, "nvar2cols": )" << dynJacobianColsNbr
             << R"(, "nparamcols": )" << symbol_table.param_nbr()
             << R"(, "entries": [)";
-  auto &hp = params_derivatives.find({ 2, 1 })->second;
-  for (auto it = hp.begin(); it != hp.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[vidx, d] : params_derivatives.find({ 2, 1 })->second)
     {
-      if (it != hp.begin())
+      if (exchange(printed_something, true))
         hp_output << ", ";
 
-      auto [eq, var1, var2, param] = vectorToTuple<4>(it->first);
-      expr_t d2 = it->second;
+      auto [eq, var1, var2, param] = vectorToTuple<4>(vidx);
 
       int var1_col = getDynJacobianCol(var1) + 1;
       int var2_col = getDynJacobianCol(var2) + 1;
@@ -6526,7 +6524,7 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
                   << R"(, "param": ")" << symbol_table.getName(getSymbIDByDerivID(param)) << R"(")";
 
       hp_output << R"(, "val": ")";
-      d2->writeJsonOutput(hp_output, temp_term_union, tef_terms);
+      d->writeJsonOutput(hp_output, temp_term_union, tef_terms);
       hp_output << R"("})" << endl;
     }
   hp_output << "]}" << endl;
@@ -6538,14 +6536,13 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
              << R"(, "nvar3cols": )" << dynJacobianColsNbr
              << R"(, "nparamcols": )" << symbol_table.param_nbr()
              << R"(, "entries": [)";
-  auto &g3p = params_derivatives.find({ 3, 1 })->second;
-  for (auto it = g3p.begin(); it != g3p.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[vidx, d] : params_derivatives.find({ 3, 1 })->second)
     {
-      if (it != g3p.begin())
+      if (exchange(printed_something, true))
         g3p_output << ", ";
 
-      auto [eq, var1, var2, var3, param] = vectorToTuple<5>(it->first);
-      expr_t d2 = it->second;
+      auto [eq, var1, var2, var3, param] = vectorToTuple<5>(vidx);
 
       int var1_col = getDynJacobianCol(var1) + 1;
       int var2_col = getDynJacobianCol(var2) + 1;
@@ -6572,7 +6569,7 @@ DynamicModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
                    << R"(, "param": ")" << symbol_table.getName(getSymbIDByDerivID(param)) << R"(")";
 
       g3p_output << R"(, "val": ")";
-      d2->writeJsonOutput(g3p_output, temp_term_union, tef_terms);
+      d->writeJsonOutput(g3p_output, temp_term_union, tef_terms);
       g3p_output << R"("})" << endl;
     }
   g3p_output << "]}" << endl;
diff --git a/src/ExprNode.cc b/src/ExprNode.cc
index 1e0ea96e2d30016ddef2f153778707e8884e8fe9..09c4b12a80d444a4c55a5dab2b724ab652ccae2d 100644
--- a/src/ExprNode.cc
+++ b/src/ExprNode.cc
@@ -2487,11 +2487,12 @@ UnaryOpNode::writeJsonAST(ostream &output) const
     case UnaryOpcode::adl:
       output << R"(, "adl_param_name" : ")" << adl_param_name << R"(")"
              << R"(, "lags" : [)";
-      for (auto it = adl_lags.begin(); it != adl_lags.end(); ++it)
+      for (bool printed_something{false};
+           int lag : adl_lags)
         {
-          if (it != adl_lags.begin())
+          if (exchange(printed_something, true))
             output << ", ";
-          output << *it;
+          output << lag;
         }
       output << "]";
       break;
@@ -2586,11 +2587,12 @@ UnaryOpNode::writeJsonOutput(ostream &output,
       output << "adl(";
       arg->writeJsonOutput(output, temporary_terms, tef_terms);
       output << ", '" << adl_param_name << "', [";
-      for (auto it = adl_lags.begin(); it != adl_lags.end(); ++it)
+      for (bool printed_something{false};
+           int lag : adl_lags)
         {
-          if (it != adl_lags.begin())
+          if (exchange(printed_something, true))
             output << ", ";
-          output << *it;
+          output << lag;
         }
       output << "])";
       return;
@@ -3287,11 +3289,12 @@ UnaryOpNode::substituteAdl() const
   expr_t arg1subst = arg->substituteAdl();
   expr_t retval = nullptr;
 
-  for (auto it = adl_lags.begin(); it != adl_lags.end(); ++it)
+  for (bool first_term{true};
+       int lag : adl_lags)
     {
-      expr_t e = datatree.AddTimes(datatree.AddVariable(datatree.symbol_table.getID(adl_param_name + "_lag_" + to_string(*it)), 0),
-                                   arg1subst->decreaseLeadsLags(*it));
-      if (it == adl_lags.begin())
+      expr_t e = datatree.AddTimes(datatree.AddVariable(datatree.symbol_table.getID(adl_param_name + "_lag_" + to_string(lag)), 0),
+                                   arg1subst->decreaseLeadsLags(lag));
+      if (exchange(first_term, false))
         retval = e;
       else
         retval = datatree.AddPlus(retval, e);
@@ -7078,27 +7081,28 @@ AbstractExternalFunctionNode::writeExternalFunctionArguments(ostream &output, Ex
                                                              const temporary_terms_idxs_t &temporary_terms_idxs,
                                                              const deriv_node_temp_terms_t &tef_terms) const
 {
-  for (auto it = arguments.begin(); it != arguments.end(); ++it)
+  for (bool printed_something{false};
+       auto arg : arguments)
     {
-      if (it != arguments.begin())
+      if (exchange(printed_something, true))
         output << ",";
 
-      (*it)->writeOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms);
+      arg->writeOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms);
     }
 }
 
 void
 AbstractExternalFunctionNode::writeJsonASTExternalFunctionArguments(ostream &output) const
 {
-  int i = 0;
   output << "{";
-  for (auto it = arguments.begin(); it != arguments.end(); ++it, i++)
+  for (int i{0};
+       auto arg : arguments)
     {
-      if (it != arguments.begin())
+      if (i != 0)
         output << ",";
 
-      output << R"("arg)" << i << R"(" : )";
-      (*it)->writeJsonAST(output);
+      output << R"("arg)" << i++ << R"(" : )";
+      arg->writeJsonAST(output);
     }
   output << "}";
 }
@@ -7109,12 +7113,13 @@ AbstractExternalFunctionNode::writeJsonExternalFunctionArguments(ostream &output
                                                                  const deriv_node_temp_terms_t &tef_terms,
                                                                  bool isdynamic) const
 {
-  for (auto it = arguments.begin(); it != arguments.end(); ++it)
+  for (bool printed_something{false};
+       auto arg : arguments)
     {
-      if (it != arguments.begin())
+      if (exchange(printed_something, true))
         output << ",";
 
-      (*it)->writeJsonOutput(output, temporary_terms, tef_terms, isdynamic);
+      arg->writeJsonOutput(output, temporary_terms, tef_terms, isdynamic);
     }
 }
 
@@ -7124,8 +7129,8 @@ AbstractExternalFunctionNode::writePrhs(ostream &output, ExprNodeOutputType outp
                                         const temporary_terms_idxs_t &temporary_terms_idxs,
                                         const deriv_node_temp_terms_t &tef_terms) const
 {
-  int i = 0;
-  for (auto argument : arguments)
+  for (int i{0};
+       auto argument : arguments)
     {
       output << "  prhs[" << i++ << "] = mxCreateDoubleScalar("; // All external_function arguments are scalars
       argument->writeOutput(output, output_type, temporary_terms, temporary_terms_idxs, tef_terms);
diff --git a/src/ModFile.cc b/src/ModFile.cc
index d8130dbd8500ec4b24c0ca39346de7f70d7a7b4c..6489e41d112c06697a42c1eef4143b08e36ce28d 100644
--- a/src/ModFile.cc
+++ b/src/ModFile.cc
@@ -339,12 +339,12 @@ ModFile::checkPass(bool nostrict, bool stochastic)
   if (parameters_intersect.size() > 0)
     {
       cerr << "ERROR: some estimated parameters (";
-      for (auto it = parameters_intersect.begin();
-           it != parameters_intersect.end();)
+      for (bool printed_something{false};
+           int symb_id : parameters_intersect)
         {
-          cerr << symbol_table.getName(*it);
-          if (++it != parameters_intersect.end())
+          if (exchange(printed_something, true))
             cerr << ", ";
+          cerr << symbol_table.getName(symb_id);
         }
       cerr << ") also appear in the expressions defining the variance/covariance matrix of shocks; this is not allowed." << endl;
       exit(EXIT_FAILURE);
@@ -1201,11 +1201,12 @@ ModFile::writeJsonOutputParsingCheck(const string &basename, JsonFileOutputType
           output << ", ";
         }
 
-      for (auto it = statements.begin(); it != statements.end(); ++it)
+      for (bool printed_something{false};
+           auto &it : statements)
         {
-          if (it != statements.begin())
+          if (exchange(printed_something, true))
             output << ", " << endl;
-          (*it)->writeJsonOutput(output);
+          it->writeJsonOutput(output);
         }
       output << "]" << endl;
     }
@@ -1241,10 +1242,10 @@ ModFile::writeJsonOutputParsingCheck(const string &basename, JsonFileOutputType
               pac_model_table.writeJsonOutput(original_model_output);
               original_model_output << ", ";
             }
-          int i = 0;
-          for (const auto &it : statements)
+          for (bool printed_something{false};
+               const auto &it : statements)
             {
-              original_model_output << (i++ > 0 ? "," : "") << endl;
+              original_model_output << (exchange(printed_something, true) ? "," : "") << endl;
               it->writeJsonOutput(original_model_output);
             }
           original_model_output << "]" << endl;
diff --git a/src/ModelEquationBlock.cc b/src/ModelEquationBlock.cc
index 2b7d35e98c0ca5e14ed2a82b02beaf8b271f2814..002a4af0b6e42d71ece6d3520838b469f4bc7444 100644
--- a/src/ModelEquationBlock.cc
+++ b/src/ModelEquationBlock.cc
@@ -241,26 +241,27 @@ SteadyStateModel::writeJsonSteadyStateFile(ostream &output, bool transformComput
 
   output << "{\"steady_state_model\": [";
 
-  for (size_t i = 0; i < def_table.size(); i++)
+  for (bool printed_something{false};
+       const auto &[symb_ids, value] : def_table)
     {
-      const vector<int> &symb_ids = def_table[i].first;
-      if (i != 0)
+      if (exchange(printed_something, true))
         output << ",";
       output << "{\"lhs\": ";
       if (symb_ids.size() > 1)
         output << "[";
-      for (size_t j = 0; j < symb_ids.size(); j++)
+      for (bool printed_something2{false};
+           int symb_id : symb_ids)
         {
-          if (j != 0)
+          if (exchange(printed_something2, true))
             output << ",";
           output << "\"";
-          getVariable(symb_ids[j])->writeJsonOutput(output, {}, {}, false);
+          getVariable(symb_id)->writeJsonOutput(output, {}, {}, false);
           output << "\"";
         }
       if (symb_ids.size() > 1)
         output << "]";
       output << R"(, "rhs":")";
-      def_table[i].second->writeJsonOutput(output, {}, {}, false);
+      value->writeJsonOutput(output, {}, {}, false);
       output << "\"}" << endl;
     }
 
@@ -445,11 +446,12 @@ Epilogue::writeDynamicEpilogueFile(const string &basename) const
              << "end" << endl
              << "try" << endl
              << "    simul_begin_date = firstobservedperiod(ds{";
-      for (auto it1 = used_symbols.begin(); it1 != used_symbols.end(); ++it1)
+      for (bool printed_something{false};
+           int symb_id : used_symbols)
         {
-          if (it1 != used_symbols.begin())
+          if (exchange(printed_something, true))
             output << ", ";
-          output << "'" << symbol_table.getName(*it1) << "'";
+          output << "'" << symbol_table.getName(symb_id) << "'";
         }
       output << "}) + " << max_lag << ";" << endl
              << "    from simul_begin_date to simul_end_date do "
@@ -473,9 +475,9 @@ Epilogue::writeOutput(ostream &output) const
       return;
     }
 
-  int idx = 1;
   output << "M_.epilogue_names = cell(" << dynamic_def_table.size() << ",1);" << endl;
-  for (const auto & [symb_id, expr] : dynamic_def_table)
+  for (int idx{1};
+       const auto &[symb_id, expr] : dynamic_def_table)
     output << "M_.epilogue_names{" << idx++ << "} = '"
            << symbol_table.getName(symb_id) << "';" << endl;
 
diff --git a/src/ModelTree.cc b/src/ModelTree.cc
index f7cfe01f4ac205ffff16fb7daa0ea9aa8f42a66e..80b23c0b3bffafd7653d7b2d54b4d099f2419398 100644
--- a/src/ModelTree.cc
+++ b/src/ModelTree.cc
@@ -1015,9 +1015,9 @@ ModelTree::computeBlockTemporaryTerms()
     }
 
   // Compute indices in the temporary terms vector
-  int idx = 0;
   blocks_temporary_terms_idxs.clear();
-  for (auto &blk_tt : blocks_temporary_terms)
+  for (int idx{0};
+       auto &blk_tt : blocks_temporary_terms)
     for (auto &eq_tt : blk_tt)
       for (auto tt : eq_tt)
         blocks_temporary_terms_idxs[tt] = idx++;
@@ -1095,35 +1095,35 @@ ModelTree::writeJsonTemporaryTerms(const temporary_terms_t &tt,
                                    deriv_node_temp_terms_t &tef_terms, const string &concat) const
 {
   // Local var used to keep track of temp nodes already written
-  bool wrote_term = false;
   temporary_terms_t tt2 = temp_term_union;
 
   output << R"("external_functions_temporary_terms_)" << concat << R"(": [)";
-  for (auto it : tt)
+  for (bool printed_term{false};
+       auto it : tt)
     {
       if (dynamic_cast<AbstractExternalFunctionNode *>(it))
         {
-          if (wrote_term)
+          if (exchange(printed_term, true))
             output << ", ";
           vector<string> efout;
           it->writeJsonExternalFunctionOutput(efout, tt2, tef_terms);
-          for (auto it1 = efout.begin(); it1 != efout.end(); ++it1)
+          for (bool printed_efout{false};
+               auto &it : efout)
             {
-              if (it1 != efout.begin())
+              if (exchange(printed_efout, true))
                 output << ", ";
-              output << *it1;
+              output << it;
             }
-          wrote_term = true;
         }
       tt2.insert(it);
     }
 
-  wrote_term = false;
   output << "]"
          << R"(, "temporary_terms_)" << concat << R"(": [)";
-  for (const auto &it : tt)
+  for (bool printed_term{false};
+       const auto &it : tt)
     {
-      if (wrote_term)
+      if (exchange(printed_term, true))
         output << ", ";
       output << R"({"temporary_term": ")";
       it->writeJsonOutput(output, tt, tef_terms);
@@ -1131,7 +1131,6 @@ ModelTree::writeJsonTemporaryTerms(const temporary_terms_t &tt,
              << R"(, "value": ")";
       it->writeJsonOutput(output, temp_term_union, tef_terms);
       output << R"("})" << endl;
-      wrote_term = true;
 
       temp_term_union.insert(it);
     }
@@ -1241,8 +1240,8 @@ ModelTree::fixNestedParenthesis(ostringstream &output, map<string, string> &tmp_
 bool
 ModelTree::testNestedParenthesis(const string &str) const
 {
-  int open = 0;
-  for (char i : str)
+  for (int open{0};
+       char i : str)
     {
       if (i == '(')
         open++;
@@ -1291,25 +1290,24 @@ ModelTree::writeJsonModelLocalVariables(ostream &output, bool write_tef_terms, d
     equation->collectVariables(SymbolType::modelLocalVariable, used_local_vars);
 
   output << R"("model_local_variables": [)";
-  bool printed = false;
-  for (int id : local_variables_vector)
+  for (bool printed_something{false};
+       int id : local_variables_vector)
     if (used_local_vars.contains(id))
       {
-        if (printed)
+        if (exchange(printed_something, true))
           output << ", ";
-        else
-          printed = true;
 
         expr_t value = local_variables_table.find(id)->second;
         if (write_tef_terms)
           {
             vector<string> efout;
             value->writeJsonExternalFunctionOutput(efout, {}, tef_terms);
-            for (auto it1 = efout.begin(); it1 != efout.end(); ++it1)
+            for (bool printed_efout{false};
+                 auto &it : efout)
               {
-                if (it1 != efout.begin())
+                if (exchange(printed_efout, true))
                   output << ", ";
-                output << *it1;
+                output << it;
               }
 
             if (!efout.empty())
@@ -1751,13 +1749,12 @@ ModelTree::writeJsonModelEquations(ostream &output, bool residuals) const
               !eqtags.empty())
             {
               output << R"(, "tags": {)";
-              int i = 0;
-              for (const auto &[name, value] : eqtags)
+              for (bool printed_something{false};
+                   const auto &[name, value] : eqtags)
                 {
-                  if (i != 0)
+                  if (exchange(printed_something, true))
                     output << ", ";
                   output << R"(")" << name << R"(": ")" << value << R"(")";
-                  i++;
                 }
               output << "}";
               eqtags.clear();
diff --git a/src/NumericalInitialization.cc b/src/NumericalInitialization.cc
index b9f07f338e81ac440fee0bb2c8896985737197f8..bd738aa7639857713b986b07d33ebb7182e1334c 100644
--- a/src/NumericalInitialization.cc
+++ b/src/NumericalInitialization.cc
@@ -163,13 +163,12 @@ InitOrEndValStatement::writeInitValues(ostream &output) const
 void
 InitOrEndValStatement::writeJsonInitValues(ostream &output) const
 {
-  for (auto it = init_values.begin();
-       it != init_values.end(); ++it)
+  for (bool printed_something{false};
+       auto &[symb_id, value] : init_values)
     {
-      auto [symb_id, value] = *it;
       if (symbol_table.getType(symb_id) == SymbolType::unusedEndogenous) // See #82
         continue;
-      if (it != init_values.begin())
+      if (exchange(printed_something, true))
         output << ", ";
       output << R"({"name": ")" << symbol_table.getName(symb_id) << R"(", )" << R"("value": ")";
       value->writeJsonOutput(output, {}, {});
@@ -348,13 +347,12 @@ EndValLearntInStatement::writeJsonOutput(ostream &output) const
 {
   output << R"({"statementName": "endval", "learnt_in": )"
          << learnt_in_period <<  R"(, "vals": [)";
-  for (auto it = learnt_end_values.begin();
-       it != learnt_end_values.end(); ++it)
+  for (bool printed_something{false};
+       auto &[type, symb_id, value] : learnt_end_values)
     {
-      auto [type, symb_id, value] = *it;
       if (symbol_table.getType(symb_id) == SymbolType::unusedEndogenous) // See #82
         continue;
-      if (it != learnt_end_values.begin())
+      if (exchange(printed_something, true))
         output << ", ";
       output << R"({"name": ")" << symbol_table.getName(symb_id) << R"(", )"
              << R"("type": ")" << typeToString(type) << R"(", )"
@@ -453,18 +451,18 @@ void
 HistValStatement::writeJsonOutput(ostream &output) const
 {
   output << R"({"statementName": "histval", "vals": [)";
-  for (auto it = hist_values.begin();
-       it != hist_values.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[key, value] : hist_values)
     {
-      auto [symb_id, lag] = it->first;
+      auto &[symb_id, lag] = key;
       if (symbol_table.getType(symb_id) == SymbolType::unusedEndogenous) // See #82
         continue;
-      if (it != hist_values.begin())
+      if (exchange(printed_something, true))
         output << ", ";
       output << R"({ "name": ")" << symbol_table.getName(symb_id) << R"(")"
              << R"(, "lag": )" << lag
              << R"(, "value": ")";
-      it->second->writeJsonOutput(output, {}, {});
+      value->writeJsonOutput(output, {}, {});
       output << R"("})";
     }
   output << "]}";
@@ -562,14 +560,12 @@ HomotopyStatement::writeJsonOutput(ostream &output) const
 {
   output << R"({"statementName": "homotopy", )"
          << R"("values": [)";
-  for (auto it = homotopy_values.begin();
-       it != homotopy_values.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[symb_id, expression1, expression2] : homotopy_values)
     {
-      if (it != homotopy_values.begin())
+      if (exchange(printed_something, true))
         output << ", ";
 
-      auto [symb_id, expression1, expression2] = *it;
-
       output << R"({"name": ")" << symbol_table.getName(symb_id) << R"(")"
              << R"(, "initial_value": ")";
       if (expression1)
@@ -672,12 +668,13 @@ LoadParamsAndSteadyStateStatement::writeJsonOutput(ostream &output) const
 {
   output << R"({"statementName": "load_params_and_steady_state",)"
          << R"("values": [)";
-  for (auto it = content.begin(); it != content.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[id, value] : content)
     {
-      if (it != content.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      output << R"({"name": ")" << symbol_table.getName(it->first) << R"(")"
-             << R"(, "value": ")" << it->second << R"("})";
+      output << R"({"name": ")" << symbol_table.getName(id) << R"(")"
+             << R"(, "value": ")" << value << R"("})";
     }
   output << "]"
          << "}";
diff --git a/src/Shocks.cc b/src/Shocks.cc
index de5f78dfb54e383a475ec751e8d0170dc8ae01e7..97d952df4990783edcd2977aa4efd431e22b1622 100644
--- a/src/Shocks.cc
+++ b/src/Shocks.cc
@@ -41,25 +41,22 @@ AbstractShocksStatement::writeDetShocks(ostream &output) const
   int exo_det_length = 0;
 
   for (const auto & [id, shock_vec] : det_shocks)
-    {
-      bool exo_det = (symbol_table.getType(id) == SymbolType::exogenousDet);
+    for (bool exo_det = (symbol_table.getType(id) == SymbolType::exogenousDet);
+         const auto &[period1, period2, value] : shock_vec)
+      {
+        output << "M_.det_shocks = [ M_.det_shocks;" << endl
+               << boolalpha
+               << "struct('exo_det'," << exo_det
+               << ",'exo_id'," << symbol_table.getTypeSpecificID(id)+1
+               << ",'multiplicative'," << mshocks
+               << ",'periods'," << period1 << ":" << period2
+               << ",'value',";
+        value->writeOutput(output);
+        output << ") ];" << endl;
 
-      for (const auto &[period1, period2, value] : shock_vec)
-        {
-          output << "M_.det_shocks = [ M_.det_shocks;" << endl
-                 << boolalpha
-                 << "struct('exo_det'," << exo_det
-                 << ",'exo_id'," << symbol_table.getTypeSpecificID(id)+1
-                 << ",'multiplicative'," << mshocks
-                 << ",'periods'," << period1 << ":" << period2
-                 << ",'value',";
-          value->writeOutput(output);
-          output << ") ];" << endl;
-
-          if (exo_det && period2 > exo_det_length)
-            exo_det_length = period2;
-        }
-    }
+        if (exo_det && period2 > exo_det_length)
+          exo_det_length = period2;
+      }
   output << "M_.exo_det_length = " << exo_det_length << ";\n";
 }
 
@@ -67,16 +64,17 @@ void
 AbstractShocksStatement::writeJsonDetShocks(ostream &output) const
 {
   output << R"("deterministic_shocks": [)";
-  for (auto it = det_shocks.begin(); it != det_shocks.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[id, shock_vec] : det_shocks)
     {
-      if (it != det_shocks.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      output << R"({"var": ")" << symbol_table.getName(it->first) << R"(", )"
+      output << R"({"var": ")" << symbol_table.getName(id) << R"(", )"
              << R"("values": [)";
-      for (auto it1 = it->second.begin(); it1 != it->second.end(); ++it1)
+      for (bool printed_something2{false};
+           const auto &[period1, period2, value] : shock_vec)
         {
-          auto [period1, period2, value] = *it1;
-          if (it1 != it->second.begin())
+          if (exchange(printed_something2, true))
             output << ", ";
           output << R"({"period1": )" << period1 << ", "
                  << R"("period2": )" << period2 << ", "
@@ -156,50 +154,54 @@ ShocksStatement::writeJsonOutput(ostream &output) const
       writeJsonDetShocks(output);
     }
   output<< R"(, "variance": [)";
-  for (auto it = var_shocks.begin(); it != var_shocks.end(); ++it)
+  for (bool printed_something{false};
+       auto &[id, value] : var_shocks)
     {
-      if (it != var_shocks.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      output << R"({"name": ")" << symbol_table.getName(it->first) << R"(", )"
+      output << R"({"name": ")" << symbol_table.getName(id) << R"(", )"
              << R"("variance": ")";
-      it->second->writeJsonOutput(output, {}, {});
+      value->writeJsonOutput(output, {}, {});
       output << R"("})";
     }
   output << "]"
          << R"(, "stderr": [)";
-  for (auto it = std_shocks.begin(); it != std_shocks.end(); it++)
+  for (bool printed_something{false};
+       auto &[id, value] : std_shocks)
     {
-      if (it != std_shocks.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      output << R"({"name": ")" << symbol_table.getName(it->first) << R"(", )"
+      output << R"({"name": ")" << symbol_table.getName(id) << R"(", )"
              << R"("stderr": ")";
-      it->second->writeJsonOutput(output, {}, {});
+      value->writeJsonOutput(output, {}, {});
       output << R"("})";
     }
   output << "]"
          << R"(, "covariance": [)";
-  for (auto it = covar_shocks.begin(); it != covar_shocks.end(); ++it)
+  for (bool printed_something{false};
+       auto &[ids, value] : covar_shocks)
     {
-      if (it != covar_shocks.begin())
+      if (exchange(printed_something, true))
         output << ", ";
       output << "{"
-             << R"("name": ")" << symbol_table.getName(it->first.first) << R"(", )"
-             << R"("name2": ")" << symbol_table.getName(it->first.second) << R"(", )"
+             << R"("name": ")" << symbol_table.getName(ids.first) << R"(", )"
+             << R"("name2": ")" << symbol_table.getName(ids.second) << R"(", )"
              << R"("covariance": ")";
-      it->second->writeJsonOutput(output, {}, {});
+      value->writeJsonOutput(output, {}, {});
       output << R"("})";
     }
   output << "]"
          << R"(, "correlation": [)";
-  for (auto it = corr_shocks.begin(); it != corr_shocks.end(); ++it)
+  for (bool printed_something{false};
+       auto &[ids, value] : corr_shocks)
     {
-      if (it != corr_shocks.begin())
+      if (exchange(printed_something, true))
         output << ", ";
       output << "{"
-             << R"("name": ")" << symbol_table.getName(it->first.first) << R"(", )"
-             << R"("name2": ")" << symbol_table.getName(it->first.second) << R"(", )"
+             << R"("name": ")" << symbol_table.getName(ids.first) << R"(", )"
+             << R"("name2": ")" << symbol_table.getName(ids.second) << R"(", )"
              << R"("correlation": ")";
-      it->second->writeJsonOutput(output, {}, {});
+      value->writeJsonOutput(output, {}, {});
       output << R"("})";
     }
   output << "]"
@@ -468,16 +470,17 @@ ShocksSurpriseStatement::writeJsonOutput(ostream &output) const
   output << R"({"statementName": "shocks")"
          << R"(, "surprise": true)"
          << R"(, "surprise_shocks": [)";
-  for (auto it = surprise_shocks.begin(); it != surprise_shocks.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[id, shock_vec] : surprise_shocks)
     {
-      if (it != surprise_shocks.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      output << R"({"var": ")" << symbol_table.getName(it->first) << R"(", )"
+      output << R"({"var": ")" << symbol_table.getName(id) << R"(", )"
              << R"("values": [)";
-      for (auto it1 = it->second.begin(); it1 != it->second.end(); ++it1)
+      for (bool printed_something2{false};
+           const auto &[period1, period2, value] : shock_vec)
         {
-          auto [period1, period2, value] = *it1;
-          if (it1 != it->second.begin())
+          if (exchange(printed_something2, true))
             output << ", ";
           output << R"({"period1": )" << period1 << ", "
                  << R"("period2": )" << period2 << ", "
@@ -549,16 +552,17 @@ ShocksLearntInStatement::writeJsonOutput(ostream &output) const
          << R"(, "learnt_in": )" << learnt_in_period
          << R"(, "overwrite": )" << boolalpha << overwrite
          << R"(, "learnt_shocks": [)";
-  for (auto it = learnt_shocks.begin(); it != learnt_shocks.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[id, shock_vec] : learnt_shocks)
     {
-      if (it != learnt_shocks.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      output << R"({"var": ")" << symbol_table.getName(it->first) << R"(", )"
+      output << R"({"var": ")" << symbol_table.getName(id) << R"(", )"
              << R"("values": [)";
-      for (auto it1 = it->second.begin(); it1 != it->second.end(); ++it1)
+      for (bool printed_something2{false};
+           const auto &[type, period1, period2, value] : shock_vec)
         {
-          auto [type, period1, period2, value] = *it1;
-          if (it1 != it->second.begin())
+          if (exchange(printed_something2, true))
             output << ", ";
           output << R"({"period1": )" << period1 << ", "
                  << R"("period2": )" << period2 << ", "
@@ -598,20 +602,21 @@ ConditionalForecastPathsStatement::writeOutput(ostream &output, const string &ba
   output << "constrained_vars_ = [];" << endl
          << "constrained_paths_ = NaN(" << paths.size() << ", " << path_length << ");" << endl;
 
-  int k = 1;
-  for (auto it = paths.begin(); it != paths.end(); ++it, k++)
+  for (int k{1};
+       const auto &[id, elems] : paths)
     {
-      if (it == paths.begin())
-        output << "constrained_vars_ = " << symbol_table.getTypeSpecificID(it->first) + 1 << ";" << endl;
+      if (k == 1)
+        output << "constrained_vars_ = " << symbol_table.getTypeSpecificID(id) + 1 << ";" << endl;
       else
-        output << "constrained_vars_ = [constrained_vars_; " << symbol_table.getTypeSpecificID(it->first) + 1 << "];" << endl;
-      for (const auto &[period1, period2, value] : it->second)
+        output << "constrained_vars_ = [constrained_vars_; " << symbol_table.getTypeSpecificID(id) + 1 << "];" << endl;
+      for (const auto &[period1, period2, value] : elems)
         for (int j = period1; j <= period2; j++)
           {
             output << "constrained_paths_(" << k << "," << j << ")=";
             value->writeOutput(output);
             output << ";" << endl;
           }
+      k++;
     }
 }
 
@@ -620,16 +625,17 @@ ConditionalForecastPathsStatement::writeJsonOutput(ostream &output) const
 {
   output << R"({"statementName": "conditional_forecast_paths")"
          << R"(, "paths": [)";
-  for (auto it = paths.begin(); it != paths.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[id, elems] : paths)
     {
-      if (it != paths.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      output << R"({"var": ")" << symbol_table.getName(it->first) << R"(", )"
+      output << R"({"var": ")" << symbol_table.getName(id) << R"(", )"
              << R"("values": [)";
-      for (auto it1 = it->second.begin(); it1 != it->second.end(); ++it1)
+      for (bool printed_something2{false};
+           const auto &[period1, period2, value] : elems)
         {
-          auto [period1, period2, value] = *it1;
-          if (it1 != it->second.begin())
+          if (exchange(printed_something2, true))
             output << ", ";
           output << R"({"period1": )" << period1 << ", "
                  << R"("period2": )" << period2 << ", "
@@ -672,18 +678,19 @@ MomentCalibration::writeJsonOutput(ostream &output) const
 {
   output << R"({"statementName": "moment_calibration")"
          << R"(, "moment_calibration_criteria": [)";
-  for (auto it = constraints.begin(); it != constraints.end(); ++it)
+  for (bool printed_something{false};
+       const auto &c : constraints)
     {
-      if (it != constraints.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      output << R"({"endogenous1": ")" << symbol_table.getName(it->endo1) << R"(")"
-             << R"(, "endogenous2": ")" << symbol_table.getName(it->endo2) << R"(")"
-             << R"(, "lags": ")" << it->lags << R"(")"
+      output << R"({"endogenous1": ")" << symbol_table.getName(c.endo1) << R"(")"
+             << R"(, "endogenous2": ")" << symbol_table.getName(c.endo2) << R"(")"
+             << R"(, "lags": ")" << c.lags << R"(")"
              << R"(, "lower_bound": ")";
-      it->lower_bound->writeJsonOutput(output, {}, {});
+      c.lower_bound->writeJsonOutput(output, {}, {});
       output << R"(")"
              << R"(, "upper_bound": ")";
-      it->upper_bound->writeJsonOutput(output, {}, {});
+      c.upper_bound->writeJsonOutput(output, {}, {});
       output << R"(")"
              << "}";
     }
@@ -730,18 +737,19 @@ IrfCalibration::writeJsonOutput(ostream &output) const
     }
 
   output << R"(, "irf_restrictions": [)";
-  for (auto it = constraints.begin(); it != constraints.end(); ++it)
+  for (bool printed_something{false};
+       const auto &c : constraints)
     {
-      if (it != constraints.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      output << R"({"endogenous": ")" << symbol_table.getName(it->endo) << R"(")"
-             << R"(, "exogenous": ")" << symbol_table.getName(it->exo) << R"(")"
-             << R"(, "periods": ")" << it->periods << R"(")"
+      output << R"({"endogenous": ")" << symbol_table.getName(c.endo) << R"(")"
+             << R"(, "exogenous": ")" << symbol_table.getName(c.exo) << R"(")"
+             << R"(, "periods": ")" << c.periods << R"(")"
              << R"(, "lower_bound": ")";
-      it->lower_bound->writeJsonOutput(output, {}, {});
+      c.lower_bound->writeJsonOutput(output, {}, {});
       output << R"(")";
       output << R"(, "upper_bound": ")";
-      it->upper_bound->writeJsonOutput(output, {}, {});
+      c.upper_bound->writeJsonOutput(output, {}, {});
       output << R"(")"
              << "}";
     }
@@ -805,11 +813,12 @@ ShockGroupsStatement::writeJsonOutput(ostream &output) const
             output << ", ";
           output << R"({"group_name": ")" << it->name << R"(",)"
                  << R"("shocks": [)";
-          for (auto it1 = it->list.begin(); it1 != it->list.end(); ++it1)
+          for (bool printed_something2{false};
+               const auto &it1 : it->list)
             {
-              if (it1 != it->list.begin())
+              if (exchange(printed_something2, true))
                 output << ", ";
-              output << R"(")" << *it1 << R"(")";
+              output << R"(")" << it1 << R"(")";
             }
           output << "]}";
         }
@@ -850,12 +859,13 @@ void
 Init2shocksStatement::writeJsonOutput(ostream &output) const
 {
   output << R"({"statementName": "init2shocks", "name": ")" << name << R"(", "groups": [)";
-  for (auto &it : init2shocks)
+  for (bool printed_something{false};
+       const auto &[id1, id2] : init2shocks)
     {
-      if (it != *(init2shocks.begin()))
+      if (exchange(printed_something, true))
         output << ",";
-      output << R"({"endogenous": ")" << symbol_table.getName(it.first) << R"(", )"
-             << R"( "exogenous": ")" << symbol_table.getName(it.second) << R"("})";
+      output << R"({"endogenous": ")" << symbol_table.getName(id1) << R"(", )"
+             << R"( "exogenous": ")" << symbol_table.getName(id2) << R"("})";
     }
   output << "]}";
 }
@@ -877,29 +887,25 @@ HeteroskedasticShocksStatement::writeOutput(ostream &output, const string &basen
            << "M_.heteroskedastic_shocks.Qscale_orig = [];" << endl;
 
   for (const auto &[symb_id, vec] : values)
-    {
-      int tsid = symbol_table.getTypeSpecificID(symb_id);
-      for (const auto &[period1, period2, value] : vec)
-        {
-          output << "M_.heteroskedastic_shocks.Qvalue_orig = [M_.heteroskedastic_shocks.Qvalue_orig; struct('exo_id', "
-                 << tsid+1 << ",'periods',"
-                 << period1 << ":" << period2 << ",'value',";
-          value->writeOutput(output);
-          output << ")];" << endl;
-        }
-    }
+    for (int tsid = symbol_table.getTypeSpecificID(symb_id);
+         const auto &[period1, period2, value] : vec)
+      {
+        output << "M_.heteroskedastic_shocks.Qvalue_orig = [M_.heteroskedastic_shocks.Qvalue_orig; struct('exo_id', "
+               << tsid+1 << ",'periods',"
+               << period1 << ":" << period2 << ",'value',";
+        value->writeOutput(output);
+        output << ")];" << endl;
+      }
   for (const auto &[symb_id, vec] : scales)
-    {
-      int tsid = symbol_table.getTypeSpecificID(symb_id);
-      for (const auto &[period1, period2, scale] : vec)
-        {
-          output << "M_.heteroskedastic_shocks.Qscale_orig = [M_.heteroskedastic_shocks.Qscale_orig; struct('exo_id', "
-                 << tsid+1 << ",'periods',"
-                 << period1 << ":" << period2 << ",'scale',";
-          scale->writeOutput(output);
-          output << ")];" << endl;
-        }
-    }
+    for (int tsid = symbol_table.getTypeSpecificID(symb_id);
+         const auto &[period1, period2, scale] : vec)
+      {
+        output << "M_.heteroskedastic_shocks.Qscale_orig = [M_.heteroskedastic_shocks.Qscale_orig; struct('exo_id', "
+               << tsid+1 << ",'periods',"
+               << period1 << ":" << period2 << ",'scale',";
+        scale->writeOutput(output);
+        output << ")];" << endl;
+      }
 }
 
 void
@@ -908,17 +914,18 @@ HeteroskedasticShocksStatement::writeJsonOutput(ostream &output) const
   output << R"({"statementName": "heteroskedastic_shocks")"
          << R"(, "overwrite": )" << boolalpha << overwrite
          << R"(, "shocks_values": [)";
-  for (auto it = values.begin(); it != values.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[symb_id, vec] : values)
     {
-      if (it != values.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      output << R"({"var": ")" << symbol_table.getName(it->first) << R"(", )"
+      output << R"({"var": ")" << symbol_table.getName(symb_id) << R"(", )"
              << R"("values": [)";
-      for (auto it1 = it->second.begin(); it1 != it->second.end(); ++it1)
+      for (bool printed_something2{false};
+           const auto &[period1, period2, value] : vec)
         {
-          if (it1 != it->second.begin())
+          if (exchange(printed_something2, true))
             output << ", ";
-          auto [period1, period2, value] = *it1;
           output << R"({"period1": )" << period1 << ", "
                  << R"("period2": )" << period2 << ", "
                  << R"("value": ")";
@@ -928,17 +935,18 @@ HeteroskedasticShocksStatement::writeJsonOutput(ostream &output) const
       output << "]}";
     }
   output << R"(], "shocks_scales": [)";
-  for (auto it = scales.begin(); it != scales.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[symb_id, vec] : scales)
     {
-      if (it != scales.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      output << R"({"var": ")" << symbol_table.getName(it->first) << R"(", )"
+      output << R"({"var": ")" << symbol_table.getName(symb_id) << R"(", )"
              << R"("scales": [)";
-      for (auto it1 = it->second.begin(); it1 != it->second.end(); ++it1)
+      for (bool printed_something2{false};
+           const auto &[period1, period2, value] : vec)
         {
-          if (it1 != it->second.begin())
+          if (exchange(printed_something2, true))
             output << ", ";
-          auto [period1, period2, value] = *it1;
           output << R"({"period1": )" << period1 << ", "
                  << R"("period2": )" << period2 << ", "
                  << R"("value": ")";
diff --git a/src/SigmaeInitialization.cc b/src/SigmaeInitialization.cc
index c8ef117643be3d8a2a758a3e637fa02280034686..6b239968ea3e165ea8fec8a644b8a661cb441ada 100644
--- a/src/SigmaeInitialization.cc
+++ b/src/SigmaeInitialization.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2003-2020 Dynare Team
+ * Copyright © 2003-2022 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -101,17 +101,19 @@ void
 SigmaeStatement::writeJsonOutput(ostream &output) const
 {
   output << R"({"statementName": "Sigma_e", "value": [)";
-  for (auto it = matrix.begin(); it != matrix.end(); ++it)
+  for (bool printed_something{false};
+       const auto &row : matrix)
     {
-      if (it != matrix.begin())
+      if (exchange(printed_something, true))
         output << ", ";
       output << "[";
-      for (auto it2 = it->begin(); it2 != it->end(); ++it2)
+      for (bool printed_something2{false};
+           auto elem : row)
         {
-          if (it2 != it->begin())
+          if (exchange(printed_something2, true))
             output << ", ";
           output << '"';
-          (*it2)->writeJsonOutput(output, {}, {});
+          elem->writeJsonOutput(output, {}, {});
           output << '"';
         }
       output << "]";
diff --git a/src/Statement.cc b/src/Statement.cc
index ba574eb8213de816c955712b96503b775f6cc7fa..77d532a6a12ac933dad2f7f41921d4fd3397355c 100644
--- a/src/Statement.cc
+++ b/src/Statement.cc
@@ -320,11 +320,12 @@ OptionsList::writeJsonOutput(ostream &output) const
       if (opt_written)
         output << ", ";
       output << R"(")" << name << R"(": [)";
-      for (auto it = vals.begin(); it != vals.end(); ++it)
+      for (bool printed_something{false};
+           int val : vals)
         {
-          if (it != vals.begin())
+          if (exchange(printed_something, true))
             output << ", ";
-          output << *it;
+          output << val;
         }
       output << "]";
       opt_written = true;
@@ -335,11 +336,12 @@ OptionsList::writeJsonOutput(ostream &output) const
       if (opt_written)
         output << ", ";
       output << R"(")" << name << R"(": [)";
-      for (auto it = vals.begin(); it != vals.end(); ++it)
+      for (bool printed_something{false};
+           const auto &val : vals)
         {
-          if (it != vals.begin())
+          if (exchange(printed_something, true))
             output << ", ";
-          output << R"(")" << *it << R"(")";
+          output << R"(")" << val << R"(")";
         }
       output << "]";
       opt_written = true;
@@ -350,11 +352,12 @@ OptionsList::writeJsonOutput(ostream &output) const
       if (opt_written)
         output << ", ";
       output << R"(")" << name << R"(": [)";
-      for (auto it = vals.begin(); it != vals.end(); ++it)
+      for (bool printed_something{false};
+           const auto &val : vals)
         {
-          if (it != vals.begin())
+          if (exchange(printed_something, true))
             output << ", ";
-          output << R"(")" << *it << R"(")";
+          output << R"(")" << val << R"(")";
         }
       output << "]";
       opt_written = true;
@@ -365,11 +368,12 @@ OptionsList::writeJsonOutput(ostream &output) const
       if (opt_written)
         output << ", ";
       output << R"(")" << name << R"(": [)";
-      for (auto it = vals.begin(); it != vals.end(); ++it)
+      for (bool printed_something{false};
+           const auto &val : vals)
         {
-          if (it != vals.begin())
+          if (exchange(printed_something, true))
             output << ", ";
-          output << *it;
+          output << val;
         }
       output << "]";
       opt_written = true;
@@ -380,16 +384,18 @@ OptionsList::writeJsonOutput(ostream &output) const
       if (opt_written)
         output << ", ";
       output << R"(")" << name << R"(": [)";
-      for (auto it = vec_vals.begin(); it != vec_vals.end(); ++it)
+      for (bool printed_something{false};
+           const auto &vals : vec_vals)
         {
-          if (it != vec_vals.begin())
+          if (exchange(printed_something, true))
             output << ", ";
           output << "[";
-          for (auto it2 = it->begin(); it2 != it->end(); ++it2)
+          for (bool printed_something2{false};
+               const auto &val : vals)
             {
-              if (it2 != it->begin())
+              if (exchange(printed_something2, true))
                 output << ", ";
-              output << *it2;
+              output << val;
             }
           output << "]";
         }
diff --git a/src/StaticModel.cc b/src/StaticModel.cc
index b8ca7155b90fbf7cedd5d71989f1fdf920be3d3d..58590cc36c29c2479fa99afda165c625304e69d6 100644
--- a/src/StaticModel.cc
+++ b/src/StaticModel.cc
@@ -209,8 +209,8 @@ StaticModel::writeStaticPerBlockHelper(int blk, ostream &output, ExprNodeOutputT
       write_eq_tt(blocks[blk].size);
 
       ostringstream i_output, j_output, v_output;
-      int line_counter = ARRAY_SUBSCRIPT_OFFSET(output_type);
-      for (const auto &[indices, d] : blocks_derivatives[blk])
+      for (int line_counter{ARRAY_SUBSCRIPT_OFFSET(output_type)};
+           const auto &[indices, d] : blocks_derivatives[blk])
         {
           auto [eq, var, ignore] = indices;
           i_output << "  g1_i" << LEFT_ARRAY_SUBSCRIPT(output_type) << line_counter
@@ -464,15 +464,16 @@ StaticModel::writeStaticBytecode(const string &basename) const
       fldr.write(code_file, instruction_number);
       if (my_derivatives[i].size())
         {
-          for (auto it = my_derivatives[i].begin(); it != my_derivatives[i].end(); ++it)
+          for (bool printed_something{false};
+               const auto &it : my_derivatives[i])
             {
-              FLDSU_ fldsu(it->second);
+              FLDSU_ fldsu(it.second);
               fldsu.write(code_file, instruction_number);
-              FLDSV_ fldsv{static_cast<int>(SymbolType::endogenous), static_cast<unsigned int>(it->first)};
+              FLDSV_ fldsv{static_cast<int>(SymbolType::endogenous), static_cast<unsigned int>(it.first)};
               fldsv.write(code_file, instruction_number);
               FBINARY_ fbinary{static_cast<int>(BinaryOpcode::times)};
               fbinary.write(code_file, instruction_number);
-              if (it != my_derivatives[i].begin())
+              if (exchange(printed_something, true))
                 {
                   FBINARY_ fbinary{static_cast<int>(BinaryOpcode::plus)};
                   fbinary.write(code_file, instruction_number);
@@ -1316,8 +1317,8 @@ StaticModel::writeStaticModel(const string &basename,
            accesses and expression reusage. */
         ostringstream i_output, j_output, v_output;
 
-        int k = 0; // Current line index in the 3-column matrix
-        for (const auto &[vidx, d] : derivatives[i])
+        for (int k{0}; // Current line index in the 3-column matrix
+             const auto &[vidx, d] : derivatives[i])
           {
             int eq = vidx[0];
 
@@ -2195,11 +2196,12 @@ StaticModel::writeJsonAuxVarRecursiveDefinitions(ostream &output) const
                                                                                 temporary_terms,
                                                                                 tef_terms,
                                                                                 false);
-        for (auto it = efout.begin(); it != efout.end(); ++it)
+        for (bool printed_something{false};
+             const auto &it : efout)
           {
-            if (it != efout.begin())
+            if (exchange(printed_something, true))
               output << ", ";
-            output << *it;
+            output << it;
           }
       }
 
@@ -2262,8 +2264,8 @@ StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) cons
       hessian_output << ";" << endl;
     }
 
-  int i = 1;
-  for (const auto &[indices, d2] : params_derivatives.find({ 0, 2 })->second)
+  for (int i{1};
+       const auto &[indices, d2] : params_derivatives.find({ 0, 2 })->second)
     {
       auto [eq, param1, param2] = vectorToTuple<3>(indices);
 
@@ -2300,8 +2302,8 @@ StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) cons
         }
     }
 
-  i = 1;
-  for (const auto &[indices, d2] : params_derivatives.find({ 1, 2 })->second)
+  for (int i{1};
+       const auto &[indices, d2] : params_derivatives.find({ 1, 2 })->second)
     {
       auto [eq, var, param1, param2] = vectorToTuple<4>(indices);
 
@@ -2343,8 +2345,8 @@ StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) cons
         }
     }
 
-  i = 1;
-  for (const auto &[indices, d2] : params_derivatives.find({ 2, 1 })->second)
+  for (int i{1};
+       const auto &[indices, d2] : params_derivatives.find({ 2, 1 })->second)
     {
       auto [eq, var1, var2, param] = vectorToTuple<4>(indices);
 
@@ -2523,13 +2525,12 @@ StaticModel::writeJsonComputingPassOutput(ostream &output, bool writeDetails) co
                   << R"(, "ncols": )" << ncols
                   << R"(, "entries": [)";
 
-      for (auto it = derivatives[i].begin(); it != derivatives[i].end(); ++it)
+      for (bool printed_something{false};
+           const auto &[vidx, d] : derivatives[i])
         {
-          if (it != derivatives[i].begin())
+          if (exchange(printed_something, true))
             d_output[i] << ", ";
 
-          const vector<int> &vidx = it->first;
-          expr_t d = it->second;
           int eq = vidx[0];
 
           int col_idx = 0;
@@ -2602,14 +2603,13 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
                   << R"(  "neqs": )" << equations.size()
                   << R"(, "nparamcols": )" << symbol_table.param_nbr()
                   << R"(, "entries": [)";
-  auto &rp = params_derivatives.find({ 0, 1 })->second;
-  for (auto it = rp.begin(); it != rp.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[vidx, d] : params_derivatives.find({ 0, 1 })->second)
     {
-      if (it != rp.begin())
+      if (exchange(printed_something, true))
         jacobian_output << ", ";
 
-      auto [eq, param] = vectorToTuple<2>(it->first);
-      expr_t d1 = it->second;
+      auto [eq, param] = vectorToTuple<2>(vidx);
 
       int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1;
 
@@ -2624,7 +2624,7 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
       jacobian_output << R"(, "param": ")" << symbol_table.getName(getSymbIDByDerivID(param)) << R"(")";
 
       jacobian_output << R"(, "val": ")";
-      d1->writeJsonOutput(jacobian_output, temp_term_union, tef_terms);
+      d->writeJsonOutput(jacobian_output, temp_term_union, tef_terms);
       jacobian_output << R"("})" << endl;
     }
   jacobian_output << "]}";
@@ -2634,14 +2634,13 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
                  << R"(, "nvarcols": )" << symbol_table.endo_nbr()
                  << R"(, "nparamcols": )" << symbol_table.param_nbr()
                  << R"(, "entries": [)";
-  auto &gp = params_derivatives.find({ 1, 1 })->second;
-  for (auto it = gp.begin(); it != gp.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[vidx, d] : params_derivatives.find({ 1, 1 })->second)
     {
-      if (it != gp.begin())
+      if (exchange(printed_something, true))
         hessian_output << ", ";
 
-      auto [eq, var, param] = vectorToTuple<3>(it->first);
-      expr_t d2 = it->second;
+      auto [eq, var, param] = vectorToTuple<3>(vidx);
 
       int var_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var)) + 1;
       int param_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param)) + 1;
@@ -2658,7 +2657,7 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
       hessian_output << R"(, "var_col": )" << var_col
                      << R"(, "param_col": )" << param_col
                      << R"(, "val": ")";
-      d2->writeJsonOutput(hessian_output, temp_term_union, tef_terms);
+      d->writeJsonOutput(hessian_output, temp_term_union, tef_terms);
       hessian_output << R"("})" << endl;
     }
   hessian_output << "]}";
@@ -2668,14 +2667,13 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
                   << R"(, "nparam1cols": )" << symbol_table.param_nbr()
                   << R"(, "nparam2cols": )" << symbol_table.param_nbr()
                   << R"(, "entries": [)";
-  auto &rpp = params_derivatives.find({ 0, 2 })->second;
-  for (auto it = rpp.begin(); it != rpp.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[vidx, d] : params_derivatives.find({ 0, 2 })->second)
     {
-      if (it != rpp.begin())
+      if (exchange(printed_something, true))
         hessian1_output << ", ";
 
-      auto [eq, param1, param2] = vectorToTuple<3>(it->first);
-      expr_t d2 = it->second;
+      auto [eq, param1, param2] = vectorToTuple<3>(vidx);
 
       int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1;
       int param2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param2)) + 1;
@@ -2693,7 +2691,7 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
                         << R"(, "param2": ")" << symbol_table.getName(getSymbIDByDerivID(param2)) << R"(")";
 
       hessian1_output << R"(, "val": ")";
-      d2->writeJsonOutput(hessian1_output, temp_term_union, tef_terms);
+      d->writeJsonOutput(hessian1_output, temp_term_union, tef_terms);
       hessian1_output << R"("})" << endl;
     }
   hessian1_output << "]}";
@@ -2704,14 +2702,13 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
                       << R"(, "nparam1cols": )" << symbol_table.param_nbr()
                       << R"(, "nparam2cols": )" << symbol_table.param_nbr()
                       << R"(, "entries": [)";
-  auto &gpp = params_derivatives.find({ 1, 2 })->second;
-  for (auto it = gpp.begin(); it != gpp.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[vidx, d] : params_derivatives.find({ 1, 2 })->second)
     {
-      if (it != gpp.begin())
+      if (exchange(printed_something, true))
         third_derivs_output << ", ";
 
-      auto [eq, var, param1, param2] = vectorToTuple<4>(it->first);
-      expr_t d2 = it->second;
+      auto [eq, var, param1, param2] = vectorToTuple<4>(vidx);
 
       int var_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var)) + 1;
       int param1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(param1)) + 1;
@@ -2731,7 +2728,7 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
                             << R"(, "param2": ")" << symbol_table.getName(getSymbIDByDerivID(param2)) << R"(")";
 
       third_derivs_output << R"(, "val": ")";
-      d2->writeJsonOutput(third_derivs_output, temp_term_union, tef_terms);
+      d->writeJsonOutput(third_derivs_output, temp_term_union, tef_terms);
       third_derivs_output << R"("})" << endl;
     }
   third_derivs_output << "]}" << endl;
@@ -2742,14 +2739,13 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
                        << R"(, "nvar2cols": )" << symbol_table.endo_nbr()
                        << R"(, "nparamcols": )" << symbol_table.param_nbr()
                        << R"(, "entries": [)";
-  auto &hp = params_derivatives.find({ 2, 1 })->second;
-  for (auto it = hp.begin(); it != hp.end(); ++it)
+  for (bool printed_something{false};
+       const auto &[vidx, d] : params_derivatives.find({ 2, 1 })->second)
     {
-      if (it != hp.begin())
+      if (exchange(printed_something, true))
         third_derivs1_output << ", ";
 
-      auto [eq, var1, var2, param] = vectorToTuple<4>(it->first);
-      expr_t d2 = it->second;
+      auto [eq, var1, var2, param] = vectorToTuple<4>(vidx);
 
       int var1_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var1)) + 1;
       int var2_col = symbol_table.getTypeSpecificID(getSymbIDByDerivID(var2)) + 1;
@@ -2770,7 +2766,7 @@ StaticModel::writeJsonParamsDerivativesFile(ostream &output, bool writeDetails)
                              << R"(, "param1": ")" << symbol_table.getName(getSymbIDByDerivID(param)) << R"(")";
 
       third_derivs1_output << R"(, "val": ")";
-      d2->writeJsonOutput(third_derivs1_output, temp_term_union, tef_terms);
+      d->writeJsonOutput(third_derivs1_output, temp_term_union, tef_terms);
       third_derivs1_output << R"("})" << endl;
     }
   third_derivs1_output << "]}" << endl;
diff --git a/src/SubModel.cc b/src/SubModel.cc
index 118d39b10097f8db1b42b08de84aff4efd7e4ad3..1974e022559c5ac39272c4cf435dae33bc6c0bc9 100644
--- a/src/SubModel.cc
+++ b/src/SubModel.cc
@@ -297,8 +297,8 @@ TrendComponentModelTable::writeOutput(const string &basename, ostream &output) c
       for (size_t i = 0; i < diff.at(name).size(); i++)
         output << "true ";
       output << "];" << endl;
-      int i = 1;
-      for (const auto &it : rhs.at(name))
+      for (int i{1};
+           const auto &it : rhs.at(name))
         {
           output << "M_.trend_component." << name << ".rhs.vars_at_eq{" << i << "}.var = [";
           for (auto [var, lag] : it)
@@ -376,25 +376,28 @@ TrendComponentModelTable::writeOutput(const string &basename, ostream &output) c
 void
 TrendComponentModelTable::writeJsonOutput(ostream &output) const
 {
-  for (const auto &name : names)
+  for (bool printed_something{false};
+       const auto &name : names)
     {
-      if (name != *names.begin())
+      if (exchange(printed_something, true))
         output << ", ";
       output << R"({"statementName": "trend_component_model",)"
              << R"("model_name": ")" << name << R"(",)"
              << R"("eqtags": [)";
-      for (const auto &it : eqtags.at(name))
+      for (bool printed_something2{false};
+           const auto &it : eqtags.at(name))
         {
-          output << R"(")" << it << R"(")";
-          if (&it != &eqtags.at(name).back())
+          if (exchange(printed_something2, true))
             output << ", ";
+          output << R"(")" << it << R"(")";
         }
       output << R"(], "target_eqtags": [)";
-      for (const auto &it : target_eqtags.at(name))
+      for (bool printed_something2{false};
+           const auto &it : target_eqtags.at(name))
         {
-          output << R"(")" << it << R"(")";
-          if (&it != &target_eqtags.at(name).back())
+          if (exchange(printed_something2, true))
             output << ", ";
+          output << R"(")" << it << R"(")";
         }
       output << "]}";
     }
@@ -468,8 +471,8 @@ VarModelTable::writeOutput(const string &basename, ostream &output) const
       for (const auto &it : orig_diff_var.at(name))
         output << (it ? symbol_table.getTypeSpecificID(*it) + 1 : -1) << " ";
       output << "];" << endl;
-      int i = 1;
-      for (const auto &it : rhs.at(name))
+      for (int i{1};
+           const auto &it : rhs.at(name))
         {
           output << "M_.var." << name << ".rhs.vars_at_eq{" << i << "}.var = [";
           for (auto [var, lag] : it)
@@ -539,18 +542,20 @@ VarModelTable::writeOutput(const string &basename, ostream &output) const
 void
 VarModelTable::writeJsonOutput(ostream &output) const
 {
-  for (const auto &name : names)
+  for (bool printed_something{false};
+       const auto &name : names)
     {
-      if (name != *names.begin())
+      if (exchange(printed_something, true))
         output << ", ";
       output << R"({"statementName": "var_model",)"
              << R"("model_name": ")" << name << R"(",)"
              << R"("eqtags": [)";
-      for (const auto &it : eqtags.at(name))
+      for (bool printed_something2{false};
+           const auto &it : eqtags.at(name))
         {
-          output << R"(")" << it << R"(")";
-          if (&it != &eqtags.at(name).back())
+          if (exchange(printed_something2, true))
             output << ", ";
+          output << R"(")" << it << R"(")";
         }
       output << "]}";
     }
@@ -783,20 +788,21 @@ VarExpectationModelTable::writeOutput(const string &basename, ostream &output) c
         }
 
       ostringstream vars_list, params_list, constants_list;
-      for (auto it = vpc.begin(); it != vpc.end(); ++it)
+      for (bool printed_something{false};
+           const auto &[variable_id, param_id, constant] : vpc)
         {
-          if (it != vpc.begin())
+          if (exchange(printed_something, true))
             {
               vars_list << ", ";
               params_list << ", ";
               constants_list << ", ";
             }
-          vars_list << symbol_table.getTypeSpecificID(get<0>(*it))+1;
-          if (get<1>(*it))
-            params_list << symbol_table.getTypeSpecificID(*get<1>(*it))+1;
+          vars_list << symbol_table.getTypeSpecificID(variable_id)+1;
+          if (param_id)
+            params_list << symbol_table.getTypeSpecificID(*param_id)+1;
           else
             params_list << "NaN";
-          constants_list << get<2>(*it);
+          constants_list << constant;
         }
       output << mstruct << ".expr.vars = [ " << vars_list.str() << " ];" << endl
              << mstruct << ".expr.params = [ " << params_list.str() << " ];" << endl
@@ -923,9 +929,10 @@ VarExpectationModelTable::transformPass(ExprNode::subst_table_t &diff_subst_tabl
 void
 VarExpectationModelTable::writeJsonOutput(ostream &output) const
 {
-  for (const auto &name : names)
+  for (bool printed_something{false};
+       const auto &name : names)
     {
-      if (name != *names.begin())
+      if (exchange(printed_something, true))
         output << ", ";
       output << R"({"statementName": "var_expectation_model",)"
              << R"("model_name": ")" << name << R"(", )"
@@ -1362,8 +1369,8 @@ PacModelTable::writeOutput(const string &basename, ostream &output) const
   // Helper to print the “growth_info” structure (linear decomposition of growth)
   auto growth_info_helper = [&](const string &fieldname, const growth_info_t &gi)
   {
-    int i = 1;
-    for (auto [growth_symb_id, growth_lag, param_id, constant] : gi)
+    for (int i{1};
+         auto [growth_symb_id, growth_lag, param_id, constant] : gi)
       {
         string structname = fieldname + "(" + to_string(i++) + ").";
         if (growth_symb_id)
@@ -1621,42 +1628,41 @@ PacModelTable::writeOutput(const string &basename, ostream &output) const
     }
 
   for (auto &[name, val] : target_info)
-    {
-      int component_idx = 1;
-      for (auto &[component, growth_component, auxname, kind, coeff, growth_neutrality_param, h_indices, original_growth_component, growth_component_info] : get<2>(val))
-        {
-          string fieldname = "M_.pac." + name + ".components(" + to_string(component_idx) + ")";
-          output << fieldname << ".aux_id = " << symbol_table.getTypeSpecificID(auxname) + 1 << ";" << endl
-                 << fieldname << ".endo_var = " << symbol_table.getTypeSpecificID(dynamic_cast<VariableNode *>(component)->symb_id) + 1 << ";" << endl
-                 << fieldname << ".kind = '" << kindToString(kind) << "';" << endl
-                 << fieldname << ".h_param_indices = [";
-          for (int id : h_indices)
-            output << symbol_table.getTypeSpecificID(id) + 1 << " ";
-          output << "];" << endl
-                 << fieldname << ".coeff_str = '";
-          coeff->writeJsonOutput(output, {}, {}, true);
-          output << "';" << endl;
-          if (growth_component)
-            {
-              output << fieldname << ".growth_neutrality_param_index = " << symbol_table.getTypeSpecificID(growth_neutrality_param) + 1 << ";" << endl
-                     << fieldname << ".growth_str = '";
-              original_growth_component->writeJsonOutput(output, {}, {}, true);
-              output << "';" << endl;
-              growth_info_helper(fieldname + ".growth_linear_comb", growth_component_info);
-            }
-          component_idx++;
-        }
-    }
+    for (int component_idx{1};
+         auto &[component, growth_component, auxname, kind, coeff, growth_neutrality_param, h_indices, original_growth_component, growth_component_info] : get<2>(val))
+      {
+        string fieldname = "M_.pac." + name + ".components(" + to_string(component_idx) + ")";
+        output << fieldname << ".aux_id = " << symbol_table.getTypeSpecificID(auxname) + 1 << ";" << endl
+               << fieldname << ".endo_var = " << symbol_table.getTypeSpecificID(dynamic_cast<VariableNode *>(component)->symb_id) + 1 << ";" << endl
+               << fieldname << ".kind = '" << kindToString(kind) << "';" << endl
+               << fieldname << ".h_param_indices = [";
+        for (int id : h_indices)
+          output << symbol_table.getTypeSpecificID(id) + 1 << " ";
+        output << "];" << endl
+               << fieldname << ".coeff_str = '";
+        coeff->writeJsonOutput(output, {}, {}, true);
+        output << "';" << endl;
+        if (growth_component)
+          {
+            output << fieldname << ".growth_neutrality_param_index = " << symbol_table.getTypeSpecificID(growth_neutrality_param) + 1 << ";" << endl
+                   << fieldname << ".growth_str = '";
+            original_growth_component->writeJsonOutput(output, {}, {}, true);
+            output << "';" << endl;
+            growth_info_helper(fieldname + ".growth_linear_comb", growth_component_info);
+          }
+        component_idx++;
+      }
 }
 
 void
 PacModelTable::writeJsonOutput(ostream &output) const
 {
-  for (const auto &name : names)
+  for (bool printed_something{false};
+       const auto &name : names)
     {
       /* The calling method has already added a comma, so don’t output one for
          the first statement */
-      if (name != *names.begin())
+      if (exchange(printed_something, true))
         output << ", ";
       output << R"({"statementName": "pac_model",)"
              << R"("model_name": ")" << name << R"(",)"
@@ -1760,8 +1766,8 @@ PacModelTable::writeTargetCoefficientsFile(const string &basename) const
     {
       output << "  if strcmp(model_name, '" << model_name << "')" << endl
              << "    coeffs = NaN(" << get<2>(val).size() << ",1);" << endl;
-      int i = 1;
-      for (auto &[component, growth_component, auxname, kind, coeff, growth_neutrality_param, h_indices, original_growth_component, growth_component_info] : get<2>(val))
+      for (int i{1};
+           auto &[component, growth_component, auxname, kind, coeff, growth_neutrality_param, h_indices, original_growth_component, growth_component_info] : get<2>(val))
         {
           output << "    coeffs(" << i++ << ") = ";
           coeff->writeOutput(output, ExprNodeOutputType::matlabDynamicModel);
diff --git a/src/SymbolList.cc b/src/SymbolList.cc
index 475b3a8e48908354f4ed28e90f8c46b6f7782e57..2bb52d77efae35c786917ddd7dbf52c7a67fb25d 100644
--- a/src/SymbolList.cc
+++ b/src/SymbolList.cc
@@ -113,11 +113,12 @@ void
 SymbolList::writeOutput(const string &varname, ostream &output) const
 {
   output << varname << " = {";
-  for (auto it = symbols.begin(); it != symbols.end(); ++it)
+  for (bool printed_something{false};
+       const auto &name : symbols)
     {
-      if (it != symbols.begin())
+      if (exchange(printed_something, true))
         output << ";";
-      output << "'" << *it << "'";
+      output << "'" << name << "'";
     }
   output << "};" << endl;
 }
@@ -126,11 +127,12 @@ void
 SymbolList::writeJsonOutput(ostream &output) const
 {
   output << R"("symbol_list": [)";
-  for (auto it = symbols.begin(); it != symbols.end(); ++it)
+  for (bool printed_something{false};
+       const auto &name : symbols)
     {
-      if (it != symbols.begin())
+      if (exchange(printed_something, true))
         output << ",";
-      output << R"(")" << *it << R"(")";
+      output << R"(")" << name << R"(")";
     }
   output << "]";
 }
diff --git a/src/SymbolTable.cc b/src/SymbolTable.cc
index 11b097149758e77d1a5dab36739cd8e7bdb32383..fa6dc2340c03672867516698bdfa0e9741ab8c54 100644
--- a/src/SymbolTable.cc
+++ b/src/SymbolTable.cc
@@ -394,10 +394,10 @@ SymbolTable::writeOutput(ostream &output) const noexcept(false)
 
   if (observedVariablesNbr() > 0)
     {
-      int ic = 1;
       output << "options_.varobs = cell(" << observedVariablesNbr() << ", 1);" << endl;
-      for (auto it = varobs.begin(); it != varobs.end(); ++it, ic++)
-        output << "options_.varobs(" << ic << ")  = {'" << getName(*it) << "'};" << endl;
+      for (int ic{1};
+           int it : varobs)
+        output << "options_.varobs(" << ic++ << ")  = {'" << getName(it) << "'};" << endl;
 
       output << "options_.varobs_id = [ ";
       for (int varob : varobs)
@@ -407,10 +407,10 @@ SymbolTable::writeOutput(ostream &output) const noexcept(false)
 
   if (observedExogenousVariablesNbr() > 0)
     {
-      int ic = 1;
       output << "options_.varexobs = cell(1);" << endl;
-      for (auto it = varexobs.begin(); it != varexobs.end(); ++it, ic++)
-        output << "options_.varexobs(" << ic << ")  = {'" << getName(*it) << "'};" << endl;
+      for (int ic{1};
+           int it : varexobs)
+        output << "options_.varexobs(" << ic++ << ")  = {'" << getName(it) << "'};" << endl;
 
       output << "options_.varexobs_id = [ ";
       for (int varexob : varexobs)
diff --git a/src/macro/Directives.cc b/src/macro/Directives.cc
index c84f2294be340e5b1e7fcf49cea35ff937c9fcd1..d97c64c597b5dd3f2611f3d9563dd0b134cd5916 100644
--- a/src/macro/Directives.cc
+++ b/src/macro/Directives.cc
@@ -259,13 +259,12 @@ For::interpret(ostream &output, Environment &env, vector<filesystem::path> &path
 void
 If::interpret(ostream &output, Environment &env, vector<filesystem::path> &paths)
 {
-  bool first_clause = true;
-  for (const auto & [expr, body] : expr_and_body)
+  for (bool first_clause{true};
+       const auto &[expr, body] : expr_and_body)
     try
       {
-        if ((ifdef || ifndef) && first_clause)
+        if ((ifdef || ifndef) && exchange(first_clause, false))
           {
-            first_clause = false;
             VariablePtr vp = dynamic_pointer_cast<Variable>(expr);
             if (!vp)
               error(StackTrace(ifdef ? "@#ifdef" : "@#ifndef",
@@ -307,14 +306,11 @@ If::interpret(ostream &output, Environment &env, vector<filesystem::path> &paths
 void
 If::interpretBody(const vector<DirectivePtr> &body, ostream &output, Environment &env, vector<filesystem::path> &paths)
 {
-  bool printLine = true;
-  for (const auto &statement : body)
+  for (bool printLine{true};
+       const auto &statement : body)
     {
-      if (printLine)
-        {
-          statement->printLineInfo(output);
-          printLine = false;
-        }
+      if (exchange(printLine, false))
+        statement->printLineInfo(output);
       statement->interpret(output, env, paths);
     }
 }
diff --git a/src/macro/Driver.cc b/src/macro/Driver.cc
index 9fb99b2644558ce56db59316c28c21e984bf7279..f4a7351cfe4a81f1555081e61de0f5a8a8dea797 100644
--- a/src/macro/Driver.cc
+++ b/src/macro/Driver.cc
@@ -53,14 +53,11 @@ Driver::parse(const string &file_arg, const string &basename_arg, const istream
   parser.parse();
 
   // Interpret parsed statements
-  bool printLine = true;
-  for (const auto &statement : statements)
+  for (bool printLine{true};
+       const auto &statement : statements)
     {
-      if (printLine)
-        {
-          statement->printLineInfo(output);
-          printLine = false;
-        }
+      if (exchange(printLine, false))
+        statement->printLineInfo(output);
       statement->interpret(output, env, paths);
     }
 }
diff --git a/src/macro/Expressions.cc b/src/macro/Expressions.cc
index d2cce597705227fb78134466c145710496ea0b17..13059bfee1c9ad60be59e51fc08082063d0a729a 100644
--- a/src/macro/Expressions.cc
+++ b/src/macro/Expressions.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2019-2020 Dynare Team
+ * Copyright © 2019-2022 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -1292,11 +1292,12 @@ void
 Array::print(ostream &output, bool matlab_output) const noexcept
 {
   output << (matlab_output ? "{" : "[");
-  for (auto it = arr.begin(); it != arr.end(); it++)
+  for (bool printed_something{false};
+       auto e : arr)
     {
-      if (it != arr.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      (*it)->print(output, matlab_output);
+      e->print(output, matlab_output);
     }
   output << (matlab_output ? "}" : "]");
 }
@@ -1305,11 +1306,12 @@ void
 Tuple::print(ostream &output, bool matlab_output) const noexcept
 {
   output << (matlab_output ? "{" : "(");
-  for (auto it = tup.begin(); it != tup.end(); it++)
+  for (bool printed_something{false};
+       auto e : tup)
     {
-      if (it != tup.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      (*it)->print(output, matlab_output);
+      e->print(output, matlab_output);
     }
   output << (matlab_output ? "}" : ")");
 }
@@ -1318,11 +1320,12 @@ void
 Function::printArgs(ostream &output) const noexcept
 {
   output << "(";
-  for (auto it = args.begin(); it != args.end(); it++)
+  for (bool printed_something{false};
+       auto e : args)
     {
-      if (it != args.begin())
+      if (exchange(printed_something, true))
         output << ", ";
-      (*it)->print(output);
+      e->print(output);
     }
   output << ")";
 }