From a039b04716dc0ea4185d612d2b92f656278d724b Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Wed, 14 Aug 2024 17:30:57 +0200 Subject: [PATCH 1/4] Simplify if statement with `unordered_map` --- src/nmodl/solve.cpp | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/nmodl/solve.cpp b/src/nmodl/solve.cpp index 9406a74a00..83d29628ab 100644 --- a/src/nmodl/solve.cpp +++ b/src/nmodl/solve.cpp @@ -6,6 +6,8 @@ #include "symbol.h" #include +#include +#include /* make it an error if 2 solve statements are called on a single call to model() */ @@ -126,20 +128,13 @@ void solvhandler() { lq = lq->next; method = SYM(lq); cvodemethod_ = 0; - if (method && strcmp(method->name, "after_cvode") == 0) { - method = (Symbol*) 0; - lq->element.sym = (Symbol*) 0; - cvodemethod_ = 1; - } - if (method && strcmp(method->name, "cvode_t") == 0) { - method = (Symbol*) 0; - lq->element.sym = (Symbol*) 0; - cvodemethod_ = 2; - } - if (method && strcmp(method->name, "cvode_v") == 0) { - method = (Symbol*) 0; - lq->element.sym = (Symbol*) 0; - cvodemethod_ = 3; + const std::unordered_map methods = {{"after_cvode", 1}, + {"cvode_t", 2}, + {"cvode_v", 3}}; + if (method && methods.count(method->name)) { + cvodemethod_ = methods.at(method->name); + method = nullptr; + lq->element.sym = nullptr; } lq = lq->next; errstmt = LST(lq); From ab86a18b9d0586266aec774c8b1b530f1fa69281 Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Thu, 15 Aug 2024 11:41:23 +0200 Subject: [PATCH 2/4] Use `vector` instead of `unordered_map` - fix a bug: `cvode_v` should have been `cvode_t_v` - use an internal `enum class` to avoid the above happening again --- src/nmodl/solve.cpp | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/nmodl/solve.cpp b/src/nmodl/solve.cpp index 83d29628ab..2db75e44eb 100644 --- a/src/nmodl/solve.cpp +++ b/src/nmodl/solve.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include /* make it an error if 2 solve statements are called on a single call to model() */ @@ -27,6 +27,10 @@ Symbol* cvode_nrn_current_solve_; void whileloop(Item*, long, int); void check_ss_consist(Item*); +namespace { +enum class CVodeMethod { nomethod = 0, after_cvode = 1, cvode_t = 2, cvode_t_v = 3 }; +} + /* Need list of solve statements. We impress the general list structure to handle it. The element is a pointer to an item which is the first item in the statement sequence in another list. @@ -111,7 +115,7 @@ void solvhandler() { List* errstmt; Symbol *fun, *method; int numeqn, listnum, btype, steadystate; - int cvodemethod_; + CVodeMethod cvodemethod_; if (!solvq) solvq = newlist(); @@ -127,12 +131,18 @@ void solvhandler() { qsol = ITM(lq); lq = lq->next; method = SYM(lq); - cvodemethod_ = 0; - const std::unordered_map methods = {{"after_cvode", 1}, - {"cvode_t", 2}, - {"cvode_v", 3}}; - if (method && methods.count(method->name)) { - cvodemethod_ = methods.at(method->name); + cvodemethod_ = CVodeMethod::nomethod; + const std::vector> cvode_methods = { + {"after_cvode", CVodeMethod::after_cvode}, + {"cvode_t", CVodeMethod::cvode_t}, + {"cvode_t_v", CVodeMethod::cvode_t_v}}; + + const auto& method_match = + std::find_if(cvode_methods.begin(), cvode_methods.end(), [&method](const auto& item) { + return method && method->name == item.first; + }); + if (method && method_match != cvode_methods.end()) { + cvodemethod_ = method_match->second; method = nullptr; lq->element.sym = nullptr; } @@ -226,16 +236,16 @@ void solvhandler() { case PROCED: if (btype == BREAKPOINT) { whileloop(qsol, (long) DERF, 0); - if (cvodemethod_ == 1) { /*after_cvode*/ + if (cvodemethod_ == CVodeMethod::after_cvode) { cvode_interface(fun, listnum, 0); } - if (cvodemethod_ == 2) { /*cvode_t*/ + if (cvodemethod_ == CVodeMethod::cvode_t) { cvode_interface(fun, listnum, 0); insertstr(qsol, "if (!cvode_active_)"); cvode_nrn_cur_solve_ = fun; linsertstr(procfunc, "extern int cvode_active_;\n"); } - if (cvodemethod_ == 3) { /*cvode_t_v*/ + if (cvodemethod_ == CVodeMethod::cvode_t_v) { cvode_interface(fun, listnum, 0); insertstr(qsol, "if (!cvode_active_)"); cvode_nrn_current_solve_ = fun; From 5f91500b8ebcd3413564f51288232f1af6ceb39d Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Thu, 15 Aug 2024 11:43:48 +0200 Subject: [PATCH 3/4] Include `algorithm` header for `std::find_if` --- src/nmodl/solve.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nmodl/solve.cpp b/src/nmodl/solve.cpp index 2db75e44eb..b978bbcf00 100644 --- a/src/nmodl/solve.cpp +++ b/src/nmodl/solve.cpp @@ -5,6 +5,7 @@ #include "parse1.hpp" #include "symbol.h" +#include #include #include #include From 53fb177268c13c723748c93f11adb561aa0eb0eb Mon Sep 17 00:00:00 2001 From: Goran Jelic-Cizmek Date: Thu, 15 Aug 2024 16:43:25 +0200 Subject: [PATCH 4/4] Use a global `unordered_map` --- src/nmodl/solve.cpp | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/nmodl/solve.cpp b/src/nmodl/solve.cpp index b978bbcf00..667a9f195c 100644 --- a/src/nmodl/solve.cpp +++ b/src/nmodl/solve.cpp @@ -5,10 +5,9 @@ #include "parse1.hpp" #include "symbol.h" -#include #include #include -#include +#include /* make it an error if 2 solve statements are called on a single call to model() */ @@ -31,6 +30,11 @@ void check_ss_consist(Item*); namespace { enum class CVodeMethod { nomethod = 0, after_cvode = 1, cvode_t = 2, cvode_t_v = 3 }; } +static const std::unordered_map cvode_method_map = { + {"after_cvode", CVodeMethod::after_cvode}, + {"cvode_t", CVodeMethod::cvode_t}, + {"cvode_t_v", CVodeMethod::cvode_t_v}}; + /* Need list of solve statements. We impress the general list structure to handle it. The element is a pointer to an @@ -133,17 +137,8 @@ void solvhandler() { lq = lq->next; method = SYM(lq); cvodemethod_ = CVodeMethod::nomethod; - const std::vector> cvode_methods = { - {"after_cvode", CVodeMethod::after_cvode}, - {"cvode_t", CVodeMethod::cvode_t}, - {"cvode_t_v", CVodeMethod::cvode_t_v}}; - - const auto& method_match = - std::find_if(cvode_methods.begin(), cvode_methods.end(), [&method](const auto& item) { - return method && method->name == item.first; - }); - if (method && method_match != cvode_methods.end()) { - cvodemethod_ = method_match->second; + if (method && cvode_method_map.count(method->name)) { + cvodemethod_ = cvode_method_map.at(method->name); method = nullptr; lq->element.sym = nullptr; }