From d24a90186cf94e2bc835398d1f902fcac6a0f777 Mon Sep 17 00:00:00 2001 From: Nicolas Cornu Date: Tue, 3 Dec 2024 17:12:10 +0100 Subject: [PATCH] Replace macro ITERATE_REMOVE by functions (#3263) --- src/nrnoc/seclist.cpp | 201 +++++++++++++++++++++--------------------- 1 file changed, 102 insertions(+), 99 deletions(-) diff --git a/src/nrnoc/seclist.cpp b/src/nrnoc/seclist.cpp index d1509e2a00..7ab9e0850c 100644 --- a/src/nrnoc/seclist.cpp +++ b/src/nrnoc/seclist.cpp @@ -1,4 +1,7 @@ #include <../../nrnconf.h> + +#include + #define HOC_L_LIST 1 #include "section.h" #include "neuron.h" @@ -8,14 +11,35 @@ #include "code.h" #include "classreg.h" -/* needs trailing '}' */ -#define ITERATE_REMOVE(q1, q2, lst) \ - for (q1 = (lst)->next; q1 != (lst); q1 = q2) { \ - q2 = q1->next; \ - if (q1->element.sec->prop == NULL) { \ - hoc_l_delete(q1); \ - continue; \ +template +bool seclist_iterate_remove_until(List* sl, F fun, const Section* sec) { + Item* q2 = nullptr; + for (Item* q1 = sl->next; q1 != sl; q1 = q2) { + q2 = q1->next; + if (q1->element.sec->prop == nullptr) { + hoc_l_delete(q1); + continue; + } + if (q1->element.sec == sec) { + fun(q1); + return true; + } + } + return false; +} + +template +void seclist_iterate_remove(List* sl, F fun) { + Item* q2 = nullptr; + for (Item* q1 = sl->next; q1 != sl; q1 = q2) { + q2 = q1->next; + if (q1->element.sec->prop == nullptr) { + hoc_l_delete(q1); + continue; } + fun(q1->element.sec); + } +} extern int hoc_return_type_code; Section* (*nrnpy_o2sec_p_)(Object* o); @@ -143,102 +167,83 @@ static double allroots(void* v) { } static double seclist_remove(void* v) { - Section *sec, *s; - Item *q, *q1; - List* sl; - int i; - - sl = (List*) v; - i = 0; + List* sl = (List*) v; + int i = 0; #if USE_PYTHON if (!ifarg(1) || (*hoc_objgetarg(1))->ctemplate->sym == nrnpy_pyobj_sym_) { #else if (!ifarg(1)) { #endif - sec = nrn_secarg(1); - ITERATE_REMOVE(q, q1, sl) /*{*/ - if (sec == q->element.sec) { - hoc_l_delete(q); - section_unref(sec); + Section* sec = nrn_secarg(1); + if (seclist_iterate_remove_until( + sl, + [](Item* q) { + Section* s = q->element.sec; + hoc_l_delete(q); + section_unref(s); + }, + sec)) { return 1.; } + hoc_warning(secname(sec), "not in this section list"); + } else { + Object* o; + o = *hoc_objgetarg(1); + check_obj_type(o, "SectionList"); + seclist_iterate_remove(sl, [](Section* s) { s->volatile_mark = 0; }); + sl = (List*) o->u.this_pointer; + seclist_iterate_remove(sl, [](Section* s) { s->volatile_mark = 1; }); + sl = (List*) v; + Item* q1; + for (Item* q = sl->next; q != sl; q = q1) { + q1 = q->next; + Section* s = hocSEC(q); + if (s->volatile_mark) { + hoc_l_delete(q); + section_unref(s); + ++i; + } + } } - hoc_warning(secname(sec), "not in this section list"); -} -else { - Object* o; - o = *hoc_objgetarg(1); - check_obj_type(o, "SectionList"); - ITERATE_REMOVE(q, q1, sl) /*{*/ - s = hocSEC(q); - s->volatile_mark = 0; -} -sl = (List*) o->u.this_pointer; -ITERATE_REMOVE(q, q1, sl) /*{*/ -s = hocSEC(q); -s->volatile_mark = 1; -} -sl = (List*) v; -i = 0; -for (q = sl->next; q != sl; q = q1) { - q1 = q->next; - s = hocSEC(q); - if (s->volatile_mark) { - hoc_l_delete(q); - section_unref(s); - ++i; - } -} -} -return (double) i; + return (double) i; } static double unique(void* v) { - int i; /* number deleted */ - Section* s; - Item *q, *q1; + Item* q1; List* sl = (List*) v; hoc_return_type_code = 1; /* integer */ - ITERATE_REMOVE(q, q1, sl) /*{*/ - s = hocSEC(q); - s->volatile_mark = 0; -} -i = 0; -for (q = sl->next; q != sl; q = q1) { - q1 = q->next; - s = hocSEC(q); - if (s->volatile_mark++) { - hoc_l_delete(q); - section_unref(s); - ++i; + seclist_iterate_remove(sl, [](Section* s) { s->volatile_mark = 0; }); + int i = 0; /* number deleted */ + for (Item* q = sl->next; q != sl; q = q1) { + q1 = q->next; + Section* s = hocSEC(q); + if (s->volatile_mark++) { + hoc_l_delete(q); + section_unref(s); + ++i; + } } -} -return (double) i; + return (double) i; } static double contains(void* v) { - Section* s; - Item *q, *q1; List* sl = (List*) v; hoc_return_type_code = 2; /* boolean */ - s = nrn_secarg(1); - ITERATE_REMOVE(q, q1, sl) /*{*/ - if (hocSEC(q) == s) { - return 1.; - } -} -return (0.); + Section* s = nrn_secarg(1); + return seclist_iterate_remove_until( + sl, [](Item*) {}, s) + ? 1. + : 0.; } static double printnames(void* v) { - Item *q, *q1; List* sl = (List*) v; - ITERATE_REMOVE(q, q1, sl) /*{*/ - if (q->element.sec->prop) { - Printf("%s\n", secname(q->element.sec)); - } -} -return 1.; + seclist_iterate_remove(sl, [](Section* s) { + if (s->prop) { + Printf("%s\n", secname(s)); + } + }); + return 1.; } static Member_func members[] = {{"append", append}, @@ -319,33 +324,31 @@ void forall_sectionlist(void) { void hoc_ifseclist(void) { Inst* savepc = pc; - Item *q, *q1; Section* sec = chk_access(); - List* sl; - Object* ob; - Object** obp; /* if arg is a string use forall_section */ if (hoc_stacktype() == STRING) { hoc_ifsec(); return; } - obp = hoc_objpop(); - ob = *obp; + Object** obp = hoc_objpop(); + Object* ob = *obp; check(ob); - sl = (List*) (ob->u.this_pointer); - ITERATE_REMOVE(q, q1, sl) /*{*/ - if (sec == q->element.sec) { - hoc_execute(relative(savepc)); - if (!hoc_returning) { - pc = relative(savepc + 1); - } - hoc_tobj_unref(obp); + List* sl = (List*) (ob->u.this_pointer); + if (seclist_iterate_remove_until( + sl, + [&](Item*) { + hoc_execute(relative(savepc)); + if (!hoc_returning) { + pc = relative(savepc + 1); + } + hoc_tobj_unref(obp); + }, + sec)) { return; } -} -hoc_tobj_unref(obp); -if (!hoc_returning) { - pc = relative(savepc + 1); -} + hoc_tobj_unref(obp); + if (!hoc_returning) { + pc = relative(savepc + 1); + } }