From 80357bc7e0c19e47f378cb0c679beb9109bf4a2c Mon Sep 17 00:00:00 2001 From: Nicolas Cornu Date: Tue, 31 May 2022 17:30:12 +0200 Subject: [PATCH] Remove some PtrList and List use outside context of IV (#1815) * Tests added to cover some of the PtrList transformations. Co-authored-by: Michael Hines --- src/gnu/RndInt.h | 18 +-- src/ivoc/datapath.cpp | 42 +++---- src/ivoc/ivoc.cpp | 22 ++-- src/ivoc/ivocrand.cpp | 85 +++++-------- src/ivoc/oclist.cpp | 86 +++++-------- src/ivoc/oclist.h | 7 +- src/ivoc/ocobserv.h | 2 +- src/nrncvode/cvodeobj.cpp | 185 ++++++++++------------------ src/nrncvode/netcon.h | 2 +- src/nrncvode/netcvode.h | 2 +- src/nrniv/finithnd.cpp | 48 +++----- src/nrniv/kschan.cpp | 238 +++++++++++++++--------------------- src/nrniv/kschan.h | 1 + src/nrniv/multisplit.cpp | 96 ++++++--------- src/nrniv/singlech.cpp | 55 +++------ src/nrniv/spaceplt.cpp | 91 +++++++------- src/nrniv/splitcell.cpp | 55 ++------- test/pynrn/test_zptrlist.py | 76 ++++++++++++ 18 files changed, 473 insertions(+), 638 deletions(-) create mode 100644 test/pynrn/test_zptrlist.py diff --git a/src/gnu/RndInt.h b/src/gnu/RndInt.h index 9874d6fe15..97251ff666 100755 --- a/src/gnu/RndInt.h +++ b/src/gnu/RndInt.h @@ -91,22 +91,22 @@ class RandomInteger inline RandomInteger::RandomInteger(long low, long high, RNG *gen) - : pLow((low < high) ? low : high), - pHigh((low < high) ? high : low), - pGenerator(gen) + : pGenerator(gen), + pLow((low < high) ? low : high), + pHigh((low < high) ? high : low) {} inline RandomInteger::RandomInteger(long high, RNG *gen) - : pLow((0 < high) ? 0 : high), - pHigh((0 < high) ? high : 0), - pGenerator(gen) + : pGenerator(gen), + pLow((0 < high) ? 0 : high), + pHigh((0 < high) ? high : 0) {} inline RandomInteger::RandomInteger(RNG *gen) - : pLow(0), - pHigh(1), - pGenerator(gen) + : pGenerator(gen), + pLow(0), + pHigh(1) {} inline RNG* RandomInteger::generator() const { return pGenerator;} diff --git a/src/ivoc/datapath.cpp b/src/ivoc/datapath.cpp index e2ccd4b5a9..a8d992a78f 100644 --- a/src/ivoc/datapath.cpp +++ b/src/ivoc/datapath.cpp @@ -75,9 +75,7 @@ PathValue::~PathValue() { } } -declarePtrList(StringList, char); -implementPtrList(StringList, char); - +using StringList = std::vector; class HocDataPathImpl { private: @@ -172,7 +170,6 @@ Symbol* HocDataPaths::retrieve_sym(double* pd) { void HocDataPaths::append(char** pd) { // printf("HocDataPaths::append\n"); - PathValue* pv; if (*pd && impl_->table_.find((void*) pd) == impl_->table_.end()) { PathValue* pv = new PathValue; pv->str = *pd; @@ -250,11 +247,8 @@ PathValue* HocDataPathImpl::found_v(void* v, const char* buf, Symbol* sym) { if (pathstyle_ != 2) { char path[500]; CopyString cs(""); - long i, cnt; - int len = 0; - cnt = strlist_.count(); - for (i = 0; i < cnt; ++i) { - sprintf(path, "%s%s.", cs.string(), strlist_.item(i)); + for (const auto& str: strlist_) { + sprintf(path, "%s%s.", cs.string(), str); cs = path; } sprintf(path, "%s%s", cs.string(), buf); @@ -351,11 +345,11 @@ void HocDataPathImpl::search(Objectdata* od, Symlist* sl) { if (obp[i]->u.dataspace != od) { sprintf(buf, "%s%s", sym->name, hoc_araystr(sym, i, od)); cs = buf; - strlist_.append((char*) cs.string()); + strlist_.push_back((char*) cs.string()); obp[i]->recurse = 1; search(obp[i]->u.dataspace, obp[i]->ctemplate->symtable); obp[i]->recurse = 0; - strlist_.remove(strlist_.count() - 1); + strlist_.pop_back(); } } else { /* point processes */ @@ -363,9 +357,9 @@ void HocDataPathImpl::search(Objectdata* od, Symlist* sl) { if (t->is_point_) { sprintf(buf, "%s%s", sym->name, hoc_araystr(sym, i, od)); cs = buf; - strlist_.append((char*) cs.string()); + strlist_.push_back((char*) cs.string()); search((Point_process*) obp[i]->u.this_pointer, sym); - strlist_.remove(strlist_.count() - 1); + strlist_.pop_back(); } #endif /* seclists, object lists */ @@ -380,9 +374,9 @@ void HocDataPathImpl::search(Objectdata* od, Symlist* sl) { if (pitm[i]) { sprintf(buf, "%s%s", sym->name, hoc_araystr(sym, i, od)); cs = buf; - strlist_.append((char*) cs.string()); + strlist_.push_back((char*) cs.string()); search(hocSEC(pitm[i])); - strlist_.remove(strlist_.count() - 1); + strlist_.pop_back(); } } } break; @@ -394,7 +388,7 @@ void HocDataPathImpl::search(Objectdata* od, Symlist* sl) { Object* obj = OBJ(q); sprintf(buf, "%s[%d]", sym->name, obj->index); cs = buf; - strlist_.append((char*) cs.string()); + strlist_.push_back((char*) cs.string()); if (!t->constructor) { search(obj->u.dataspace, t->symtable); } else { @@ -404,7 +398,7 @@ void HocDataPathImpl::search(Objectdata* od, Symlist* sl) { } #endif } - strlist_.remove(strlist_.count() - 1); + strlist_.pop_back(); } } break; } @@ -413,7 +407,6 @@ void HocDataPathImpl::search(Objectdata* od, Symlist* sl) { } void HocDataPathImpl::search_vectors() { - int i, cnt; char buf[200]; CopyString cs(""); cTemplate* t = sym_vec->u.ctemplate; @@ -422,17 +415,17 @@ void HocDataPathImpl::search_vectors() { Object* obj = OBJ(q); sprintf(buf, "%s[%d]", sym_vec->name, obj->index); cs = buf; - strlist_.append((char*) cs.string()); + strlist_.push_back((char*) cs.string()); Vect* vec = (Vect*) obj->u.this_pointer; int size = vec->size(); double* pd = vector_vec(vec); - for (i = 0; i < size; ++i) { + for (size_t i = 0; i < size; ++i) { if (pd[i] == sentinal) { - sprintf(buf, "x[%d]", i); + sprintf(buf, "x[%zu]", i); found(pd + i, buf, sym_vec); } } - strlist_.remove(strlist_.count() - 1); + strlist_.pop_back(); } } @@ -447,9 +440,9 @@ void HocDataPathImpl::search_pysec() { Section* sec = hocSEC(qsec); if (sec->prop && sec->prop->dparam[PROP_PY_INDEX]._pvoid) { cs = secname(sec); - strlist_.append((char*) cs.string()); + strlist_.push_back((char*) cs.string()); search(sec); - strlist_.remove(strlist_.count() - 1); + strlist_.pop_back(); } } #endif @@ -474,7 +467,6 @@ void HocDataPathImpl::search(Section* sec) { } void HocDataPathImpl::search(Node* nd, double x) { char buf[100]; - int i, cnt; CopyString cs(""); if (NODEV(nd) == sentinal) { sprintf(buf, "v(%g)", x); diff --git a/src/ivoc/ivoc.cpp b/src/ivoc/ivoc.cpp index cca7561928..d74fc80917 100644 --- a/src/ivoc/ivoc.cpp +++ b/src/ivoc/ivoc.cpp @@ -1,6 +1,6 @@ #include <../../nrnconf.h> -#include +#include #include #include #include @@ -19,12 +19,11 @@ extern double (*nrnpy_object_to_double_)(Object*); #include "bimap.hpp" #if USE_PTHREAD -static MUTDEC +static MUTDEC; #endif - typedef void (*PF)(void*, int); -declareList(FList, PF); -implementList(FList, PF); +using PF = void (*)(void*, int); +using FList = std::vector; static FList* f_list; @@ -47,8 +46,7 @@ void nrn_notify_freed(PF pf) { if (!f_list) { f_list = new FList; } - f_list->append(pf); - // printf("appended to f_list in ivoc.cpp\n"); + f_list->push_back(pf); } void nrn_notify_when_void_freed(void* p, Observer* ob) { @@ -94,18 +92,16 @@ void notify_pointer_freed(void* pt) { } void notify_freed(void* p) { if (f_list) { - long i, n = f_list->count(); - for (i = 0; i < n; ++i) { - (*f_list->item(i))(p, 1); + for (PF f: *f_list) { + f(p, 1); } } notify_pointer_freed(p); } void notify_freed_val_array(double* p, size_t size) { if (f_list) { - long i, n = f_list->count(); - for (i = 0; i < n; ++i) { - (*f_list->item(i))((void*) p, size); + for (PF f: *f_list) { + f((void*) p, size); } } if (pdob) { diff --git a/src/ivoc/ivocrand.cpp b/src/ivoc/ivocrand.cpp index aeaac90db9..bc5cdc3743 100644 --- a/src/ivoc/ivocrand.cpp +++ b/src/ivoc/ivocrand.cpp @@ -11,7 +11,7 @@ #include "oc2iv.h" #include "nrnisaac.h" -#include +#include #include #include "ocobserv.h" #include @@ -55,8 +55,8 @@ class RandomPlay: public Observer, public Resource { double* px_; }; -declarePtrList(RandomPlayList, RandomPlay) - implementPtrList(RandomPlayList, RandomPlay) static RandomPlayList* random_play_list_; +using RandomPlayList = std::vector; +static RandomPlayList* random_play_list_; extern "C" { double nrn_random_pick(Rand* r); @@ -185,7 +185,7 @@ RandomPlay::RandomPlay(Rand* r, double* px) { // printf("RandomPlay\n"); r_ = r; px_ = px; - random_play_list_->append(this); + random_play_list_->push_back(this); ref(); nrn_notify_when_double_freed(px_, this); nrn_notify_when_void_freed((void*) r->obj_, this); @@ -198,11 +198,10 @@ void RandomPlay::play() { *px_ = (*(r_->rand))(); } void RandomPlay::list_remove() { - long i, cnt = random_play_list_->count(); - for (i = 0; i < cnt; ++i) { - if (random_play_list_->item(i) == (RandomPlay*) this) { + for (auto it = random_play_list_->begin(); it != random_play_list_->end(); ++it) { + if (*it == (RandomPlay*) this) { // printf("RandomPlay %p removed from list cnt=%d i=%d %p\n", this, cnt, i); - random_play_list_->remove(i); + random_play_list_->erase(it); unref_deferred(); break; } @@ -618,57 +617,35 @@ static double r_play(void* r) { } extern "C" void nrn_random_play() { - long i, cnt = random_play_list_->count(); - for (i = 0; i < cnt; ++i) { - random_play_list_->item(i)->play(); + for (const auto& rp: *random_play_list_) { + rp->play(); } } -static Member_func r_members[] = {"ACG", - r_ACG, - "MLCG", - r_MLCG, - "Isaac64", - r_Isaac64, - "MCellRan4", - r_MCellRan4, - "Random123", - r_nrnran123, - "Random123_globalindex", - r_ran123_globalindex, - "seq", - r_sequence, - "repick", - r_repick, - "uniform", - r_uniform, - "discunif", - r_discunif, - "normal", - r_normal, - "lognormal", - r_lognormal, - "binomial", - r_binomial, - "poisson", - r_poisson, - "geometric", - r_geometric, - "hypergeo", - r_hypergeo, - "negexp", - r_negexp, - "erlang", - r_erlang, - "weibull", - r_weibull, - "play", - r_play, - 0, - 0}; +static Member_func r_members[] = {{"ACG", r_ACG}, + {"MLCG", r_MLCG}, + {"Isaac64", r_Isaac64}, + {"MCellRan4", r_MCellRan4}, + {"Random123", r_nrnran123}, + {"Random123_globalindex", r_ran123_globalindex}, + {"seq", r_sequence}, + {"repick", r_repick}, + {"uniform", r_uniform}, + {"discunif", r_discunif}, + {"normal", r_normal}, + {"lognormal", r_lognormal}, + {"binomial", r_binomial}, + {"poisson", r_poisson}, + {"geometric", r_geometric}, + {"hypergeo", r_hypergeo}, + {"negexp", r_negexp}, + {"erlang", r_erlang}, + {"weibull", r_weibull}, + {"play", r_play}, + {nullptr, nullptr}}; void Random_reg() { class2oc("Random", r_cons, r_destruct, r_members, NULL, NULL, NULL); - random_play_list_ = new RandomPlayList(); + random_play_list_ = new RandomPlayList; } diff --git a/src/ivoc/oclist.cpp b/src/ivoc/oclist.cpp index 927592ec58..22a44930f3 100644 --- a/src/ivoc/oclist.cpp +++ b/src/ivoc/oclist.cpp @@ -4,7 +4,6 @@ #endif #include -#include #include #include "classreg.h" #include "oclist.h" @@ -78,9 +77,6 @@ void handle_old_focus(); class OcListBrowser {}; #endif -declarePtrList(OcListImpl, Object); -implementPtrList(OcListImpl, Object); - static Symbol* list_class_sym_; static void chk_list(Object* o) { if (!o || o->ctemplate != list_class_sym_->u.ctemplate) { @@ -98,7 +94,7 @@ void OcList::append(Object* ob) { if (!ob) return; oref(ob); - oli_->append(ob); + oli_.push_back(ob); #if HAVE_IV if (b_) { b_->load_item(count() - 1); @@ -156,7 +152,7 @@ void OcList::prepend(Object* ob) { if (!ob) return; oref(ob); - oli_->prepend(ob); + oli_.insert(oli_.begin(), ob); #if HAVE_IV if (b_) { b_->reload(); @@ -175,7 +171,7 @@ void OcList::insert(long i, Object* ob) { if (!ob) return; oref(ob); - oli_->insert(i, ob); + oli_.insert(oli_.begin() + i, ob); #if HAVE_IV if (b_) { b_->reload(); @@ -189,7 +185,7 @@ static double l_count(void* v) { return o->count(); } long OcList::count() { - return oli_->count(); + return oli_.size(); } static double l_remove(void* v) { @@ -199,8 +195,8 @@ static double l_remove(void* v) { return o->count(); } void OcList::remove(long i) { - Object* ob = oli_->item(i); - oli_->remove(i); + Object* ob = oli_[i]; + oli_.erase(oli_.begin() + i); #if HAVE_IV if (b_) { b_->select(-1); @@ -219,9 +215,8 @@ static double l_index(void* v) { return o->index(ob); } long OcList::index(Object* ob) { - long i, cnt = oli_->count(); - for (i = 0; i < cnt; ++i) { - if (oli_->item(i) == ob) { + for (long i = 0; i < oli_.size(); ++i) { + if (oli_[i] == ob) { return i; } } @@ -234,7 +229,7 @@ static Object** l_object(void* v) { return hoc_temp_objptr(o->object(i)); } Object* OcList::object(long i) { - return oli_->item(i); + return oli_[i]; } static double l_remove_all(void* v) { @@ -243,12 +238,10 @@ static double l_remove_all(void* v) { return o->count(); } void OcList::remove_all() { - long i, cnt = oli_->count(); - for (i = 0; i < cnt; ++i) { - Object* ob = oli_->item(i); + for (auto& ob: oli_) { ounref(ob); } - oli_->remove_all(); + oli_.clear(); #if HAVE_IV if (b_) { b_->select(-1); @@ -378,36 +371,24 @@ static double l_scroll_pos(void* v) { } -static Member_func l_members[] = {"append", - l_append, - "prepend", - l_prepend, - "insrt", - l_insert, - "remove", - l_remove, - "remove_all", - l_remove_all, - "index", - l_index, - "count", - l_count, - "browser", - l_browser, - "selected", - l_selected, - "select", - l_select, - "select_action", - l_select_action, - "accept_action", - l_accept_action, - "scroll_pos", - l_scroll_pos, - 0, - 0}; - -static Member_ret_obj_func l_retobj_members[] = {"object", l_object, "o", l_object, 0, 0}; +static Member_func l_members[] = {{"append", l_append}, + {"prepend", l_prepend}, + {"insrt", l_insert}, + {"remove", l_remove}, + {"remove_all", l_remove_all}, + {"index", l_index}, + {"count", l_count}, + {"browser", l_browser}, + {"selected", l_selected}, + {"select", l_select}, + {"select_action", l_select_action}, + {"accept_action", l_accept_action}, + {"scroll_pos", l_scroll_pos}, + {nullptr, nullptr}}; + +static Member_ret_obj_func l_retobj_members[] = {{"object", l_object}, + {"o", l_object}, + {nullptr, nullptr}}; static void* l_cons(Object*) { OcList* o; @@ -441,9 +422,8 @@ Object* ivoc_list_item(Object* olist, int i) { } OcList::OcList(long n) { - oli_ = new OcListImpl(n); - b_ = NULL; - ct_ = NULL; + b_ = nullptr; + ct_ = nullptr; } OcList::OcList(const char* name) { @@ -457,8 +437,7 @@ OcList::OcList(const char* name) { ct_ = s->u.ctemplate; int cnt = ct_->count; cnt = (cnt) ? cnt : 5; - oli_ = new OcListImpl(cnt); - b_ = NULL; + b_ = nullptr; hoc_Item* q; ITERATE(q, ct_->olist) { append(OBJ(q)); @@ -482,7 +461,6 @@ OcList::~OcList() { #endif b_ = NULL; remove_all(); - delete oli_; } static int l_chkpt(void** vp) { diff --git a/src/ivoc/oclist.h b/src/ivoc/oclist.h index 9526f987cd..9fd7a1b06c 100644 --- a/src/ivoc/oclist.h +++ b/src/ivoc/oclist.h @@ -1,12 +1,13 @@ #ifndef oclist_h #define oclist_h +#include + #include #include -class OcListImpl; struct Object; class OcListBrowser; -class cTemplate; +struct cTemplate; class OcList: public Resource, public Observer { public: @@ -36,7 +37,7 @@ class OcList: public Resource, public Observer { void ounref(Object*); private: - OcListImpl* oli_; + std::vector oli_; OcListBrowser* b_; cTemplate* ct_; }; diff --git a/src/ivoc/ocobserv.h b/src/ivoc/ocobserv.h index 88a633205f..f92de72cbf 100644 --- a/src/ivoc/ocobserv.h +++ b/src/ivoc/ocobserv.h @@ -4,7 +4,7 @@ #include struct Object; -class cTemplate; +struct cTemplate; // For an Observer watching a hoc Object // when the last ref disappears, disconnect is called on the Observer diff --git a/src/nrncvode/cvodeobj.cpp b/src/nrncvode/cvodeobj.cpp index a2fbc632d2..4865d39b89 100644 --- a/src/nrncvode/cvodeobj.cpp +++ b/src/nrncvode/cvodeobj.cpp @@ -345,7 +345,6 @@ static double dae_init_dteps(void* v) { } static double use_mxb(void* v) { - NetCvode* d = (NetCvode*) v; hoc_return_type_code = 2; // boolean if (ifarg(1)) { int i = (int) chkarg(1, 0, 1); @@ -358,7 +357,6 @@ static double use_mxb(void* v) { } static double cache_efficient(void* v) { - NetCvode* d = (NetCvode*) v; if (ifarg(1)) { int i = (int) chkarg(1, 0, 1); nrn_cachevec(i); @@ -528,16 +526,14 @@ static double nrn_diam_change_count(void* v) { int (*nrnpy_pysame)(Object*, Object*); extern int (*nrnpy_hoccommand_exec)(Object*); -declarePtrList(ExtraScatterList, Object) - implementPtrList(ExtraScatterList, - Object) static ExtraScatterList* extra_scatterlist[2]; // 0 scatter, 1 gather +using ExtraScatterList = std::vector; +static ExtraScatterList* extra_scatterlist[2]; // 0 scatter, 1 gather void nrn_extra_scatter_gather(int direction, int tid) { ExtraScatterList* esl = extra_scatterlist[direction]; if (esl) { nrn_thread_error("extra_scatter_gather not allowed with multiple threads"); - for (int i = 0; i < esl->count(); ++i) { - Object* callable = esl->item(i); + for (Object* callable: *esl) { if (!(*nrnpy_hoccommand_exec)(callable)) { hoc_execerror("extra_scatter_gather runtime error", 0); } @@ -551,10 +547,10 @@ static double extra_scatter_gather(void* v) { check_obj_type(o, "PythonObject"); ExtraScatterList* esl = extra_scatterlist[direction]; if (!esl) { - esl = new ExtraScatterList(2); + esl = new ExtraScatterList; extra_scatterlist[direction] = esl; } - esl->append(o); + esl->push_back(o); hoc_obj_ref(o); return 0.; } @@ -563,15 +559,18 @@ static double extra_scatter_gather_remove(void* v) { Object* o = *hoc_objgetarg(1); for (int direction = 0; direction < 2; ++direction) { ExtraScatterList* esl = extra_scatterlist[direction]; - if (esl) - for (int i = esl->count() - 1; i >= 0; --i) { - Object* o1 = esl->item(i); + if (esl) { + for (auto it = esl->begin(); it != esl->end();) { + Object* o1 = *it; // if esl exists then python exists if ((*nrnpy_pysame)(o, o1)) { - esl->remove(i); + it = esl->erase(it); hoc_obj_unref(o1); + } else { + ++it; } } + } } return 0.; } @@ -586,106 +585,57 @@ static double use_fast_imem(void* v) { return double(i); } -static Member_func members[] = {"solve", - solve, - "atol", - nrn_atol, - "rtol", - rtol, - "re_init", - re_init, - "stiff", - stiff, - "active", - active, - "maxorder", - maxorder, - "minstep", - minstep, - "maxstep", - maxstep, - "jacobian", - jacobian, - "states", - states, - "dstates", - dstates, - "error_weights", - error_weights, - "acor", - acor, - "statename", - statename, - "atolscale", - abstol, - "use_local_dt", - use_local_dt, - "record", - n_record, - "record_remove", - n_remove, - "debug_event", - debug_event, - "order", - order, - "use_daspk", - use_daspk, - "event", - tstop_event, - "current_method", - current_method, - "use_mxb", - use_mxb, - "print_event_queue", - peq, - "event_queue_info", - event_queue_info, - "store_events", - store_events, - "condition_order", - condition_order, - "dae_init_dteps", - dae_init_dteps, - "simgraph_remove", - simgraph_remove, - "state_magnitudes", - state_magnitudes, - "ncs_netcons", - ncs_netcons, - "statistics", - statistics, - "spike_stat", - spikestat, - "queue_mode", - queue_mode, - "cache_efficient", - cache_efficient, - "use_long_double", - use_long_double, - "use_parallel", - use_parallel, - "f", - nrn_hoc2fun, - "yscatter", - nrn_hoc2scatter_y, - "ygather", - nrn_hoc2gather_y, - "fixed_step", - nrn_hoc2fixed_step, - "structure_change_count", - nrn_structure_change_count, - "diam_change_count", - nrn_diam_change_count, - "extra_scatter_gather", - extra_scatter_gather, - "extra_scatter_gather_remove", - extra_scatter_gather_remove, - "use_fast_imem", - use_fast_imem, - 0, - 0}; - -static Member_ret_obj_func omembers[] = {"netconlist", netconlist, 0, 0}; +static Member_func members[] = {{"solve", solve}, + {"atol", nrn_atol}, + {"rtol", rtol}, + {"re_init", re_init}, + {"stiff", stiff}, + {"active", active}, + {"maxorder", maxorder}, + {"minstep", minstep}, + {"maxstep", maxstep}, + {"jacobian", jacobian}, + {"states", states}, + {"dstates", dstates}, + {"error_weights", error_weights}, + {"acor", acor}, + {"statename", statename}, + {"atolscale", abstol}, + {"use_local_dt", use_local_dt}, + {"record", n_record}, + {"record_remove", n_remove}, + {"debug_event", debug_event}, + {"order", order}, + {"use_daspk", use_daspk}, + {"event", tstop_event}, + {"current_method", current_method}, + {"use_mxb", use_mxb}, + {"print_event_queue", peq}, + {"event_queue_info", event_queue_info}, + {"store_events", store_events}, + {"condition_order", condition_order}, + {"dae_init_dteps", dae_init_dteps}, + {"simgraph_remove", simgraph_remove}, + {"state_magnitudes", state_magnitudes}, + {"ncs_netcons", ncs_netcons}, + {"statistics", statistics}, + {"spike_stat", spikestat}, + {"queue_mode", queue_mode}, + {"cache_efficient", cache_efficient}, + {"use_long_double", use_long_double}, + {"use_parallel", use_parallel}, + {"f", nrn_hoc2fun}, + {"yscatter", nrn_hoc2scatter_y}, + {"ygather", nrn_hoc2gather_y}, + {"fixed_step", nrn_hoc2fixed_step}, + {"structure_change_count", nrn_structure_change_count}, + {"diam_change_count", nrn_diam_change_count}, + {"extra_scatter_gather", extra_scatter_gather}, + {"extra_scatter_gather_remove", extra_scatter_gather_remove}, + {"use_fast_imem", use_fast_imem}, + {nullptr, nullptr}}; + +static Member_ret_obj_func omembers[] = {{"netconlist", netconlist}, {nullptr, nullptr}}; static void* cons(Object*) { #if 0 @@ -737,7 +687,6 @@ static void f_gvardt(realtype t, N_Vector y, N_Vector ydot, void* f_data); static void f_lvardt(realtype t, N_Vector y, N_Vector ydot, void* f_data); static CVRhsFn pf_; -static void* msetup_thread(NrnThread*); static void* msolve_thread(NrnThread*); static void* msolve_thread_part1(NrnThread*); static void* msolve_thread_part2(NrnThread*); @@ -972,7 +921,6 @@ void Cvode::activate_maxstate(bool on) { maxacor_ = nil; } if (on && neq_ > 0) { - int i; maxstate_ = nvnew(neq_); maxacor_ = nvnew(neq_); N_VConst(0.0, maxstate_); @@ -1123,7 +1071,6 @@ void NetCvode::set_CVRhsFn() { } int Cvode::cvode_init(double) { - int iter; int err = SUCCESS; // note, a change in stiff_ due to call of stiff() destroys mem_ gather_y(y_); @@ -1443,8 +1390,7 @@ int Cvode::cvode_interpolate(double tout) { } int Cvode::daspk_advance_tn() { - int flag, err; - double tin; + int err; // printf("Cvode::solve test stop time t=%.20g tstop-t=%g\n", t, tstop_-t); // printf("in Cvode::solve t_=%g tstop=%g calling daspk_->solve(%g)\n", t_, tstop_, // daspk_->tout_); @@ -1612,7 +1558,6 @@ static void* msolve_thread_part1(NrnThread* nt) { return 0; } static void* msolve_thread_part2(NrnThread* nt) { - int i = nt->id; Cvode* cv = msolve_cv_; cv->solvex_thread_part2(nt); return 0; @@ -1706,13 +1651,11 @@ static void* f_thread_ms_part1(NrnThread* nt) { return 0; } static void* f_thread_ms_part2(NrnThread* nt) { - int i = nt->id; Cvode* cv = f_cv_; cv->fun_thread_ms_part2(nt); return 0; } static void* f_thread_ms_part3(NrnThread* nt) { - int i = nt->id; Cvode* cv = f_cv_; cv->fun_thread_ms_part3(nt); return 0; diff --git a/src/nrncvode/netcon.h b/src/nrncvode/netcon.h index 90d96cbcb5..1dfc58fe15 100644 --- a/src/nrncvode/netcon.h +++ b/src/nrncvode/netcon.h @@ -33,7 +33,7 @@ class STETransition; class IvocVect; class BGP_DMASend; class BGP_DMASend_Phase2; -class Point_process; +struct Point_process; using SelfEventPPTable = std::unordered_map; #define DiscreteEventType 0 diff --git a/src/nrncvode/netcvode.h b/src/nrncvode/netcvode.h index 72f9594344..1076469cf9 100644 --- a/src/nrncvode/netcvode.h +++ b/src/nrncvode/netcvode.h @@ -17,7 +17,7 @@ class DiscreteEvent; class TQItemPool; class SelfEventPool; class SelfEvent; -class hoc_Item; +struct hoc_Item; class PlayRecord; class PlayRecList; class IvocVect; diff --git a/src/nrniv/finithnd.cpp b/src/nrniv/finithnd.cpp index 64f1d28432..7ba8acd5c9 100644 --- a/src/nrniv/finithnd.cpp +++ b/src/nrniv/finithnd.cpp @@ -13,46 +13,35 @@ Type 3 are at the very beginning of finitialize. ie structure changes are allowed. */ -#include +#include +#include #include #include #include #include -class FInitialHandler; -declarePtrList(FIHList, FInitialHandler) implementPtrList(FIHList, FInitialHandler) - - class FInitialHandler { +class FInitialHandler { public: FInitialHandler(int, const char*, Object*, Object* pyact = NULL); virtual ~FInitialHandler(); HocCommand* stmt_; int type_; - static FIHList* fihlist_[4]; + static std::vector fihlist_[4]; }; void nrn_fihexec(int type); void nrn_fihexec(int type) { - FIHList* fl = FInitialHandler::fihlist_[type]; - if (fl) { - int i, cnt; - cnt = fl->count(); - for (i = 0; i < cnt; ++i) { - FInitialHandler* f = fl->item(i); - f->stmt_->execute(); - } + for (auto& f: FInitialHandler::fihlist_[type]) { + f->stmt_->execute(); } } static double allprint(void* v) { - int type, i, cnt; - for (type = 0; type < 4; ++type) { - FIHList* fl = FInitialHandler::fihlist_[type]; - if (fl && fl->count() > 0) { - cnt = fl->count(); + for (int type = 0; type < 4; ++type) { + std::vector fl = FInitialHandler::fihlist_[type]; + if (!fl.empty()) { Printf("Type %d FInitializeHandler statements\n", type); - for (i = 0; i < cnt; ++i) { - FInitialHandler* f = fl->item(i); + for (auto& f: fl) { if (f->stmt_->pyobject()) { Printf("\t%s\n", hoc_object_name(f->stmt_->pyobject())); } else if (f->stmt_->object()) { @@ -66,7 +55,7 @@ static double allprint(void* v) { return 0.; } -static Member_func members[] = {"allprint", allprint, 0, 0}; +static Member_func members[] = {{"allprint", allprint}, {nullptr, nullptr}}; static void* finithnd_cons(Object*) { int type = 1; // default is after INITIAL blocks are called @@ -103,28 +92,23 @@ void FInitializeHandler_reg() { class2oc("FInitializeHandler", finithnd_cons, finithnd_destruct, members, NULL, NULL, NULL); } -FIHList* FInitialHandler::fihlist_[4]; +std::vector FInitialHandler::fihlist_[4]; FInitialHandler::FInitialHandler(int i, const char* s, Object* obj, Object* pyact) { - if (!fihlist_[i]) { - fihlist_[i] = new FIHList(10); - } type_ = i; if (pyact) { stmt_ = new HocCommand(pyact); } else { stmt_ = new HocCommand(s, obj); } - fihlist_[i]->append(this); + fihlist_[i].push_back(this); } FInitialHandler::~FInitialHandler() { delete stmt_; - int i, cnt; - cnt = fihlist_[type_]->count(); - for (i = 0; i < cnt; ++i) { - if (fihlist_[type_]->item(i) == this) { - fihlist_[type_]->remove(i); + for (auto it = fihlist_[type_].begin(); it != fihlist_[type_].end(); ++it) { + if ((*it) == this) { + fihlist_[type_].erase(it); return; } } diff --git a/src/nrniv/kschan.cpp b/src/nrniv/kschan.cpp index ae3f588574..4443e7d4ff 100644 --- a/src/nrniv/kschan.cpp +++ b/src/nrniv/kschan.cpp @@ -16,9 +16,8 @@ #define strdup _strdup #endif -declarePtrList(KSChanList, KSChan) implementPtrList(KSChanList, KSChan) - - static KSChanList* channels; +using KSChanList = std::vector; +static KSChanList* channels; extern char* hoc_symbol_units(Symbol*, const char*); extern void nrn_mk_table_check(); @@ -55,24 +54,24 @@ static void chkobj(void* v) { } static void check_table_thread_(double* p, Datum* ppvar, Datum* thread, NrnThread* vnt, int type) { - KSChan* c = channels->item(type); + KSChan* c = (*channels)[type]; c->check_table_thread((NrnThread*) vnt); } static void nrn_alloc(Prop* prop) { - KSChan* c = channels->item(prop->type); + KSChan* c = (*channels)[prop->type]; c->alloc(prop); } static void nrn_init(NrnThread* nt, Memb_list* ml, int type) { // printf("nrn_init\n"); - KSChan* c = channels->item(type); + KSChan* c = (*channels)[type]; c->init(ml->nodecount, ml->nodelist, ml->data, ml->pdata, nt); } static void nrn_cur(NrnThread* nt, Memb_list* ml, int type) { // printf("nrn_cur\n"); - KSChan* c = channels->item(type); + KSChan* c = (*channels)[type]; #if CACHEVEC if (use_cachevec) { c->cur(ml->nodecount, ml->nodeindices, ml->data, ml->pdata, nt); @@ -85,7 +84,7 @@ static void nrn_cur(NrnThread* nt, Memb_list* ml, int type) { static void nrn_jacob(NrnThread* nt, Memb_list* ml, int type) { // printf("nrn_jacob\n"); - KSChan* c = channels->item(type); + KSChan* c = (*channels)[type]; #if CACHEVEC if (use_cachevec) { c->jacob(ml->nodecount, ml->nodeindices, ml->data, ml->pdata, nt); @@ -98,7 +97,7 @@ static void nrn_jacob(NrnThread* nt, Memb_list* ml, int type) { static void nrn_state(NrnThread* nt, Memb_list* ml, int type) { // printf("nrn_state\n"); - KSChan* c = channels->item(type); + KSChan* c = (*channels)[type]; #if CACHEVEC if (use_cachevec) { c->state(ml->nodecount, ml->nodeindices, ml->nodelist, ml->data, ml->pdata, nt); @@ -111,28 +110,28 @@ static void nrn_state(NrnThread* nt, Memb_list* ml, int type) { static int ode_count(int type) { // printf("ode_count\n"); - KSChan* c = channels->item(type); + KSChan* c = (*channels)[type]; return c->count(); } static void ode_map(int ieq, double** pv, double** pvdot, double* p, Datum* pd, double* atol, int type) { // printf("ode_map\n"); - KSChan* c = channels->item(type); + KSChan* c = (*channels)[type]; c->map(ieq, pv, pvdot, p, pd, atol); } static void ode_spec(NrnThread*, Memb_list* ml, int type) { // printf("ode_spec\n"); - KSChan* c = channels->item(type); + KSChan* c = (*channels)[type]; c->spec(ml->nodecount, ml->nodelist, ml->data, ml->pdata); } static void ode_matsol(NrnThread* nt, Memb_list* ml, int type) { // printf("ode_matsol\n"); - KSChan* c = channels->item(type); + KSChan* c = (*channels)[type]; c->matsol(ml->nodecount, ml->nodelist, ml->data, ml->pdata, nt); } static void singchan(NrnThread* nt, Memb_list* ml, int type) { // printf("singchan_\n"); - KSChan* c = channels->item(type); + KSChan* c = (*channels)[type]; c->cv_sc_update(ml->nodecount, ml->nodelist, ml->data, ml->pdata, nt); } static void* hoc_create_pnt(Object* ho) { @@ -142,7 +141,7 @@ static void hoc_destroy_pnt(void* v) { // first free the KSSingleNodeData if it exists. Point_process* pp = (Point_process*) v; if (pp->prop) { - KSChan* c = channels->item(pp->prop->type); + KSChan* c = (*channels)[pp->prop->type]; c->destroy_pnt(pp); } } @@ -168,22 +167,17 @@ static double hoc_get_loc_pnt(void* v) { } static double hoc_nsingle(void* v) { Point_process* pp = (Point_process*) v; - KSChan* c = channels->item(pp->prop->type); + KSChan* c = (*channels)[pp->prop->type]; if (ifarg(1)) { c->nsingle(pp, (int) chkarg(1, 1, 1e9)); } return (double) c->nsingle(pp); } -static Member_func member_func[] = {"loc", - hoc_loc_pnt, - "has_loc", - hoc_has_loc, - "get_loc", - hoc_get_loc_pnt, - "nsingle", - hoc_nsingle, - 0, - 0}; +static Member_func member_func[] = {{"loc", hoc_loc_pnt}, + {"has_loc", hoc_has_loc}, + {"get_loc", hoc_get_loc_pnt}, + {"nsingle", hoc_nsingle}, + {nullptr, nullptr}}; void kschan_cvode_single_update() {} @@ -288,8 +282,6 @@ static double ks_erev(void* v) { } static double ks_vres(void* v) { - KSChan* ks = (KSChan*) v; - if (ifarg(1)) { KSSingle::vres_ = chkarg(1, 1e-9, 1e9); } @@ -297,8 +289,6 @@ static double ks_vres(void* v) { } static double ks_rseed(void* v) { - KSChan* ks = (KSChan*) v; - if (ifarg(1)) { KSSingle::idum_ = (unsigned int) chkarg(1, 0, 1e9); } @@ -651,9 +641,7 @@ static double kst_stoichiometry(void* v) { static double ks_pr(void* v) { KSChan* ks = (KSChan*) v; KSTransition* kt; - Symbol* s; - int i, j; Printf("%s type properties\n", hoc_object_name(ks->obj_)); Printf("name=%s is_point_=%s ion_=%s cond_model_=%d\n", ks->name_.string(), @@ -669,24 +657,24 @@ static double ks_pr(void* v) { ks->ivkstrans_, ks->iligtrans_); Printf(" default gmax=%g erev=%g\n", ks->gmax_deflt_, ks->erev_deflt_); - for (i = 0; i < ks->ngate_; ++i) { + for (int i = 0; i < ks->ngate_; ++i) { Printf(" gate %d index=%d nstate=%d power=%d\n", i, ks->gc_[i].sindex_, ks->gc_[i].nstate_, ks->gc_[i].power_); } - for (i = 0; i < ks->nligand_; ++i) { + for (int i = 0; i < ks->nligand_; ++i) { Printf(" ligand %d %s\n", i, ks->ligands_[i]->name); } - for (i = 0; i < ks->iligtrans_; ++i) { + for (int i = 0; i < ks->iligtrans_; ++i) { kt = ks->trans_ + i; Printf(" trans %d src=%d target=%d type=%d\n", i, kt->src_, kt->target_, kt->type_); Printf(" f0 type=%d f1 type=%d\n", kt->f0 ? kt->f0->type() : -1, kt->f1 ? kt->f1->type() : -1); } - for (i = ks->iligtrans_; i < ks->ntrans_; ++i) { + for (int i = ks->iligtrans_; i < ks->ntrans_; ++i) { kt = ks->trans_ + i; Printf(" trans %d src=%d target=%d type=%d ligindex=%d\n", i, @@ -699,7 +687,7 @@ static double ks_pr(void* v) { kt->f1 ? kt->f1->type() : -1); } Printf(" state names and fractional conductance\n"); - for (i = 0; i < ks->nstate_; ++i) { + for (int i = 0; i < ks->nstate_; ++i) { Printf(" %d %s %g\n", i, ks->state_[i].string(), ks->state_[i].f_); } return 1; @@ -707,97 +695,72 @@ static double ks_pr(void* v) { static Member_func ks_dmem[] = { // keeping c++ consistent with java - "setstructure", - ks_setstructure, - - "remove_state", - ks_remove_state, - "remove_transition", - ks_remove_transition, - - "ngate", - ks_ngate, - "nstate", - ks_nstate, - "ntrans", - ks_ntrans, - "nligand", - ks_nligand, - "is_point", - ks_is_point, - "single", - ks_single, - "pr", - ks_pr, - - "iv_type", - ks_iv_type, - "gmax", - ks_gmax, - "erev", - ks_erev, - "vres", - ks_vres, - "rseed", - ks_rseed, - "usetable", - ks_usetable, - 0, - 0}; - -static Member_ret_obj_func ks_omem[] = {"add_hhstate", - ks_add_hhstate, - "add_ksstate", - ks_add_ksstate, - "add_transition", - ks_add_transition, - "trans", - ks_trans, - "state", - ks_state, - "gate", - ks_gate, - 0, - 0}; - -static Member_ret_str_func ks_smem[] = {"name", ks_name, "ion", ks_ion, "ligand", ks_ligand, 0, 0}; - -static Member_func kss_dmem[] = {"frac", kss_frac, "index", kss_index, 0, 0}; - -static Member_ret_obj_func kss_omem[] = {"gate", kss_gate, 0, 0}; - -static Member_ret_str_func kss_smem[] = {"name", kss_name, 0, 0}; - -static Member_func ksg_dmem[] = - {"nstate", ksg_nstate, "power", ksg_power, "sindex", ksg_sindex, "index", ksg_index, 0, 0}; - -static Member_ret_obj_func ksg_omem[] = {0, 0}; - -static Member_ret_str_func ksg_smem[] = {0, 0}; - -static Member_func kst_dmem[] = {"set_f", - kst_set_f, - "index", - kst_index, - "type", - kst_type, - "ftype", - kst_ftype, - "ab", - kst_ab, - "inftau", - kst_inftau, - "f", - kst_f, - "stoichiometry", - kst_stoichiometry, - 0, - 0}; - -static Member_ret_obj_func kst_omem[] = - {"src", kst_src, "target", kst_target, "parm", kst_parm, 0, 0}; - -static Member_ret_str_func kst_smem[] = {"ligand", kst_ligand, 0, 0}; + {"setstructure", ks_setstructure}, + + {"remove_state", ks_remove_state}, + {"remove_transition", ks_remove_transition}, + + {"ngate", ks_ngate}, + {"nstate", ks_nstate}, + {"ntrans", ks_ntrans}, + {"nligand", ks_nligand}, + {"is_point", ks_is_point}, + {"single", ks_single}, + {"pr", ks_pr}, + + {"iv_type", ks_iv_type}, + {"gmax", ks_gmax}, + {"erev", ks_erev}, + {"vres", ks_vres}, + {"rseed", ks_rseed}, + {"usetable", ks_usetable}, + {nullptr, nullptr}}; + +static Member_ret_obj_func ks_omem[] = {{"add_hhstate", ks_add_hhstate}, + {"add_ksstate", ks_add_ksstate}, + {"add_transition", ks_add_transition}, + {"trans", ks_trans}, + {"state", ks_state}, + {"gate", ks_gate}, + {nullptr, nullptr}}; + +static Member_ret_str_func ks_smem[] = {{"name", ks_name}, + {"ion", ks_ion}, + {"ligand", ks_ligand}, + {nullptr, nullptr}}; + +static Member_func kss_dmem[] = {{"frac", kss_frac}, {"index", kss_index}, {nullptr, nullptr}}; + +static Member_ret_obj_func kss_omem[] = {{"gate", kss_gate}, {nullptr, nullptr}}; + +static Member_ret_str_func kss_smem[] = {{"name", kss_name}, {nullptr, nullptr}}; + +static Member_func ksg_dmem[] = {{"nstate", ksg_nstate}, + {"power", ksg_power}, + {"sindex", ksg_sindex}, + {"index", ksg_index}, + {nullptr, nullptr}}; + +static Member_ret_obj_func ksg_omem[] = {{nullptr, nullptr}}; + +static Member_ret_str_func ksg_smem[] = {{nullptr, nullptr}}; + +static Member_func kst_dmem[] = {{"set_f", kst_set_f}, + {"index", kst_index}, + {"type", kst_type}, + {"ftype", kst_ftype}, + {"ab", kst_ab}, + {"inftau", kst_inftau}, + {"f", kst_f}, + {"stoichiometry", kst_stoichiometry}, + {nullptr, nullptr}}; + +static Member_ret_obj_func kst_omem[] = {{"src", kst_src}, + {"target", kst_target}, + {"parm", kst_parm}, + {nullptr, nullptr}}; + +static Member_ret_str_func kst_smem[] = {{"ligand", kst_ligand}, {nullptr, nullptr}}; static void* ks_cons(Object* o) { /* @@ -886,21 +849,20 @@ void KSChan::add_channel(const char** m) { // printf("mechanism type is %d\n", mechtype_); hoc_register_cvode(mechtype_, ode_count, ode_map, ode_spec, ode_matsol); if (!channels) { - channels = new KSChanList(50); + channels = new KSChanList; } - while (channels->count() < mechtype_) { - channels->append(NULL); + while (channels->size() < mechtype_) { + channels->push_back(nullptr); } - channels->append(c); + channels->push_back(c); } KSChan::KSChan(Object* obj, bool is_p) { // printf("KSChan created\n"); - int i; nhhstate_ = 0; mechtype_ = -1; usetable(false, 0, 1., 0.); - ; + is_point_ = is_p; is_single_ = false; single_ = NULL; @@ -1511,10 +1473,8 @@ void KSChan::settype(KSTransition* t, int type, const char* lig) { } // printf("ilig=%d iligold=%d\n", ilig, iligold); bool add2list = true; - bool move = true; // if t already using a ligand, what is to be done with it if (t->type_ >= 2) { - move = false; // do not need to reorder the transition add2list = false; for (i = iligtrans_; i < ntrans_; ++i) { if (trans_[i].ligand_index_ == iligold && t->index_ != i) { @@ -2362,7 +2322,6 @@ Prop* KSChan::needion(Symbol* s, Node* nd, Prop* pm) { void KSChan::ion_consist() { // printf("KSChan::ion_consist\n"); int i, j; - Section* sec; Node* nd; hoc_Item* qsec; int mtype = rlsym_->subtype; @@ -2425,7 +2384,6 @@ void KSChan::ligand_consist(int j, int poff, Prop* p, Node* nd) { void KSChan::state_consist(int shift) { // shift when Nsingle winks in and out of existence // printf("KSChan::state_consist\n"); int i, j, ns; - Section* sec; Node* nd; hoc_Item* qsec; int mtype = rlsym_->subtype; @@ -3050,8 +3008,7 @@ void KSChan::matsol(int n, Node** nd, double** p, Datum** ppd, NrnThread* nt) { // from Cvode::do_nonode void KSChan::cv_sc_update(int n, Node** nd, double** pp, Datum** ppd, NrnThread* nt) { - int i, j; - double* s; + int i; if (nstate_) { for (i = 0; i < n; ++i) { if (pp[i][NSingleIndex] > .999) { @@ -3183,7 +3140,6 @@ static int ksusing(int type) { } void KSChan::usetable(bool use) { - int i; if (nhhstate_ == 0) { use = false; } diff --git a/src/nrniv/kschan.h b/src/nrniv/kschan.h index 2b4fec49d0..52611d265c 100644 --- a/src/nrniv/kschan.h +++ b/src/nrniv/kschan.h @@ -236,6 +236,7 @@ class KSGateComplex { class KSIv { public: + virtual ~KSIv() = default; // this one for ionic ohmic and nernst. virtual double cur(double g, double* p, Datum* pd, double v); virtual double jacob(double* p, Datum* pd, double v); diff --git a/src/nrniv/multisplit.cpp b/src/nrniv/multisplit.cpp index b02aa908d7..a6e663f5d7 100644 --- a/src/nrniv/multisplit.cpp +++ b/src/nrniv/multisplit.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include #include @@ -301,10 +301,10 @@ struct MultiSplitTransferInfo { }; using MultiSplitTable = std::unordered_map; -declarePtrList(MultiSplitList, MultiSplit) implementPtrList(MultiSplitList, MultiSplit) +using MultiSplitList = std::vector; #include - static MultiSplitControl* msc_; +static MultiSplitControl* msc_; void nrnmpi_multisplit(Section* sec, double x, int sid, int backbone_style) { if (!msc_) { @@ -382,7 +382,7 @@ void MultiSplitControl::multisplit(Section* sec, double x, int sid, int backbone if (!classical_root_to_multisplit_) { classical_root_to_multisplit_.reset(new MultiSplitTable()); classical_root_to_multisplit_->reserve(97); - multisplit_list_ = new MultiSplitList(); + multisplit_list_ = new MultiSplitList; } Node* nd = node_exact(sec, x); if (tree_changed) { @@ -427,7 +427,7 @@ void MultiSplitControl::multisplit(Section* sec, double x, int sid, int backbone ms->rmap_index_ = -1; ms->smap_index_ = -1; (*classical_root_to_multisplit_)[root] = ms; - multisplit_list_->append(ms); + multisplit_list_->push_back(ms); } } @@ -528,13 +528,12 @@ void MultiSplitControl::multisplit_clear() { nth_ = 0; del_msti(); if (classical_root_to_multisplit_) { - MultiSplit* ms; for (const auto& mspair: *classical_root_to_multisplit_) { delete mspair.second; } classical_root_to_multisplit_.reset(); delete multisplit_list_; - multisplit_list_ = 0; + multisplit_list_ = nullptr; } } @@ -572,12 +571,9 @@ void MultiSplitControl::exchange_setup() { // pieces on the same host, since each piece <-> reduced tree // independently of where the piece and reduced tree are located. int n = 0; - int nsbb = 0; // number of short backbone sid's - int nwc = 0; // number of backbonestyle=2 nodes. + int nwc = 0; // number of backbonestyle=2 nodes. if (classical_root_to_multisplit_) { - MultiSplit* ms; - for (i = 0; i < multisplit_list_->count(); ++i) { - ms = multisplit_list_->item(i); + for (MultiSplit* ms: *multisplit_list_) { ++n; if (ms->nd[1]) { ++n; @@ -588,9 +584,7 @@ void MultiSplitControl::exchange_setup() { ++nwc; } } else if (ms->backbone_style == 1) { - if (ms->nd[1]) { - nsbb += 2; - } else { // shouldn't be set anyway + if (!ms->nd[1]) { ms->backbone_style = 0; } } @@ -632,9 +626,7 @@ void MultiSplitControl::exchange_setup() { } if (classical_root_to_multisplit_) { i = 0; - MultiSplit* ms; - for (int ii = 0; ii < multisplit_list_->count(); ++ii) { - ms = multisplit_list_->item(ii); + for (MultiSplit* ms: *multisplit_list_) { sid[i] = ms->sid[0]; inode[i] = ms->nd[0]->v_node_index; threadid[i] = ms->ithread; @@ -834,9 +826,7 @@ nrnmpi_myid, i, allsid[i], all_bb_relation[i], mark[i]);} rt[j] = 0; } if (nwc) { - MultiSplit* ms; - for (int ii = 0; ii < multisplit_list_->count(); ++ii) { - ms = multisplit_list_->item(ii); + for (MultiSplit* ms: *multisplit_list_) { if (ms->backbone_style == 2) { for (j = 0; j < n; ++j) { // find the mark value if (sid[j] == ms->sid[0]) { @@ -949,8 +939,8 @@ bb_relation[j], rthost[j]); } // fill in the rest of the rthost[], mt->rthost, and rt - for (int ii = 0, j = 0; ii < multisplit_list_->count(); ++ii, ++j) { - MultiSplit* ms = multisplit_list_->item(ii); + j = 0; + for (MultiSplit* ms: *multisplit_list_) { if (ms->backbone_style == 2) { int jj = mark[displ[nrnmpi_myid] + j]; ms->rthost = rthost[jj]; @@ -960,6 +950,7 @@ bb_relation[j], rthost[j]); ++j; } } + ++j; } #if 0 for (int ii=0; ii < multisplit_list_->count(); ++ii) { @@ -1481,9 +1472,7 @@ secname(v_node[j]->sec), v_node[j]->sec_node_index_); if (nrtree_) { i = 0; int ib = 0; - MultiSplit* ms; - for (int ii = 0; ii < multisplit_list_->count(); ++ii) { - ms = multisplit_list_->item(ii); + for (MultiSplit* ms: *multisplit_list_) { NrnThread* _nt = nrn_threads + ms->ithread; MultiSplitThread& t = mth_[ms->ithread]; if (ms->rthost == nrnmpi_myid) { @@ -1643,24 +1632,23 @@ void nrn_multisplit_ptr_update() { } void MultiSplitControl::rt_map_update() { - for (int i = 0; i < multisplit_list_->count(); ++i) { - MultiSplit& ms = *multisplit_list_->item(i); - if (ms.rthost == nrnmpi_myid) { // reduced tree on this host - assert(ms.rt_); - assert(ms.rmap_index_ >= 0); - assert(ms.smap_index_ >= 0); - MultiSplitThread& t = mth_[ms.ithread]; - double** r = ms.rt_->rmap + ms.rmap_index_; - double** s = ms.rt_->smap + ms.smap_index_; + for (MultiSplit* ms: *multisplit_list_) { + if (ms->rthost == nrnmpi_myid) { // reduced tree on this host + assert(ms->rt_); + assert(ms->rmap_index_ >= 0); + assert(ms->smap_index_ >= 0); + MultiSplitThread& t = mth_[ms->ithread]; + double** r = ms->rt_->rmap + ms->rmap_index_; + double** s = ms->rt_->smap + ms->smap_index_; for (int j = 0; j < 2; ++j) - if (ms.nd[j]) { - *s++ = *r++ = &NODERHS(ms.nd[j]); - *s++ = *r++ = &NODED(ms.nd[j]); + if (ms->nd[j]) { + *s++ = *r++ = &NODERHS(ms->nd[j]); + *s++ = *r++ = &NODED(ms->nd[j]); } - if (ms.nd[1]) { // do sid1a and sid1b as well - assert(ms.back_index >= 0); - *r++ = t.sid1A + t.backAindex_[ms.back_index]; - *r++ = t.sid1B + t.backBindex_[ms.back_index]; + if (ms->nd[1]) { // do sid1a and sid1b as well + assert(ms->back_index >= 0); + *r++ = t.sid1A + t.backAindex_[ms->back_index]; + *r++ = t.sid1B + t.backBindex_[ms->back_index]; } } } @@ -1824,10 +1812,9 @@ void MultiSplitControl::prstruct() { nrnmpi_barrier(); if (id == nrnmpi_myid) { Printf("myid=%d\n", id); - Printf(" MultiSplit %ld\n", multisplit_list_->count()); - for (i = 0; i < multisplit_list_->count(); ++i) { - MultiSplit* ms = multisplit_list_->item(i); - Node* nd = ms->nd[0]; + Printf(" MultiSplit %ld\n", multisplit_list_->size()); + for (i = 0; i < multisplit_list_->size(); ++i) { + MultiSplit* ms = (*multisplit_list_)[i]; Printf(" %2d bbs=%d bi=%-2d rthost=%-4d %-4d %s{%d}", i, ms->backbone_style, @@ -2040,7 +2027,7 @@ void MultiSplitControl::multisplit_nocap_v_part3(NrnThread* _nt) { // So zero-area node information is fine. // But for non-zero area nodes, D is the sum of all zero-area // node d, and RHS is the sum of all zero-area node rhs. - int i, j; + int i; if (_nt->id == 0) for (i = 0; i < narea2buf_; ++i) { @@ -2547,7 +2534,6 @@ ReducedTree::ReducedTree(MultiSplitControl* ms, int rank, int mapsize) { } ReducedTree::~ReducedTree() { - int i; delete[] ip; delete[] rhs; delete[] smap; @@ -2953,7 +2939,7 @@ for (i=i1; i < backbone_end; ++i) { // exchange of d and rhs of sids has taken place and we can solve for the // backbone nodes void MultiSplitThread::bksub_backbone(NrnThread* _nt) { - int i, j, ip, ip1, ip2; + int i, j; double a, b, p, vsid1; // need to solve the 2x2 consisting of sid0 and sid1 points // this part has already been done for short backbones @@ -3172,9 +3158,7 @@ for (i=i1; i < i3; ++i) { backbone_begin = i2; backbone_long_begin = backbone_begin; if (classical_root_to_multisplit_) { - MultiSplit* ms; - for (int ii = 0; ii < multisplit_list_->count(); ++ii) { - ms = multisplit_list_->item(ii); + for (MultiSplit* ms: *multisplit_list_) { if (ms->nd[1]) { if (ms->nd[1]->_nt != nt) { continue; @@ -3447,7 +3431,7 @@ for (i=i1; i < i3; ++i) { } void MultiSplitControl::pmat(bool full) { - int it, i, ip, is; + int it, i, is; Printf("\n"); for (it = 0; it < nrn_nthread; ++it) { NrnThread* _nt = nrn_threads + it; @@ -3481,7 +3465,7 @@ void MultiSplitControl::pmat(bool full) { } void MultiSplitControl::pmatf(bool full) { - int it, i, ip, is; + int it, i, is; FILE* f; char fname[100]; @@ -3525,14 +3509,12 @@ void MultiSplitControl::pmatf(bool full) { void MultiSplitControl::pmat1(const char* s) { int it; double a, b, d, rhs; - MultiSplit* ms; for (it = 0; it < nrn_nthread; ++it) { NrnThread* _nt = nrn_threads + it; MultiSplitThread& t = mth_[it]; int i1 = 0; int i3 = _nt->end; - for (int ii = 0; ii < multisplit_list_->count(); ++ii) { - ms = multisplit_list_->item(ii); + for (MultiSplit* ms: *multisplit_list_) { int i = ms->nd[0]->v_node_index; if (i < i1 || i >= i3) { continue; diff --git a/src/nrniv/singlech.cpp b/src/nrniv/singlech.cpp index d37c14ade2..3746d13fc5 100644 --- a/src/nrniv/singlech.cpp +++ b/src/nrniv/singlech.cpp @@ -48,10 +48,7 @@ class SingleChanInfo { int n_; }; -declarePtrList(SingleChanInfoList, SingleChanInfo) - implementPtrList(SingleChanInfoList, SingleChanInfo) - - SingleChanInfoList* infolist; +std::vector infolist; static SingleChan* current_chan; #define NS 3 @@ -90,12 +87,9 @@ void SingleChanState::rate(int to_state, double value) { } void hoc_reg_singlechan(int type, void (*f)(...)) { - if (!infolist) { - infolist = new SingleChanInfoList(); - } SingleChanInfo* info = new SingleChanInfo(); info->type_ = type; - infolist->append(info); + infolist.push_back(info); (*f)(); #if 0 if (nrn_istty_) { @@ -105,7 +99,10 @@ void hoc_reg_singlechan(int type, void (*f)(...)) { } void _singlechan_declare(void (*f)(double, double*, Datum*), int* slist, int n) { - SingleChanInfo* info = infolist->item(infolist->count() - 1); + if (infolist.empty()) { + return; + } + SingleChanInfo* info = infolist.back(); info->f_ = f; info->slist_ = slist; info->n_ = n; @@ -121,10 +118,9 @@ SingleChan::SingleChan(const char* name) { r_ = NULL; erand_ = &SingleChan::erand1; nprop_ = new NrnProperty(name); - int i; - for (i = 0; i < infolist->count(); ++i) { - if (infolist->item(i)->type_ == nprop_->type()) { - info_ = infolist->item(i); + for (const auto& il: infolist) { + if (il->type_ == nprop_->type()) { + info_ = il; } } if (!info_) { @@ -377,28 +373,17 @@ static double cond_transitions(void* v) { return 1.; } -static Member_func members[] = {"state_transition", - state_transition, - "cond_transition", - cond_transition, - "set_rates", - set_rates, - "get_rates", - get_rates, - "cond", - cond, - "current_state", - current_state, - "current_cond", - current_cond, - "state_transitions", - state_transitions, - "cond_transitions", - cond_transitions, - "set_rand", - set_rand, - 0, - 0}; +static Member_func members[] = {{"state_transition", state_transition}, + {"cond_transition", cond_transition}, + {"set_rates", set_rates}, + {"get_rates", get_rates}, + {"cond", cond}, + {"current_state", current_state}, + {"current_cond", current_cond}, + {"state_transitions", state_transitions}, + {"cond_transitions", cond_transitions}, + {"set_rand", set_rand}, + {nullptr, nullptr}}; static void* cons(Object*) { SingleChan* s; diff --git a/src/nrniv/spaceplt.cpp b/src/nrniv/spaceplt.cpp index 3400e3234a..248cb5a846 100644 --- a/src/nrniv/spaceplt.cpp +++ b/src/nrniv/spaceplt.cpp @@ -3,7 +3,7 @@ #include "classreg.h" -#include +#include #include #include #include @@ -33,8 +33,7 @@ class SecPos { Section* sec; }; -declareList(SecPosList, SecPos); -implementList(SecPosList, SecPos); +using SecPosList = std::vector; class RangeExpr { public: @@ -278,14 +277,19 @@ static double from_vector(void* v) { return double(cnt); } -static Member_func s_members[] = {"begin", s_begin, "end", s_end, - "origin", s_origin, "d2root", s_d2root, - "left", s_left, "right", s_right, - "list", s_list, "color", s_color, - "to_vector", to_vector, "from_vector", from_vector, - 0, 0}; +static Member_func s_members[] = {{"begin", s_begin}, + {"end", s_end}, + {"origin", s_origin}, + {"d2root", s_d2root}, + {"left", s_left}, + {"right", s_right}, + {"list", s_list}, + {"color", s_color}, + {"to_vector", to_vector}, + {"from_vector", from_vector}, + {0, 0}}; -static Member_ret_obj_func rvp_retobj_members[] = {"vector", rvp_vector, 0, 0}; +static Member_ret_obj_func rvp_retobj_members[] = {{"vector", rvp_vector}, {0, 0}}; static void* s_cons(Object*) { char* var = NULL; @@ -333,7 +337,7 @@ RangeVarPlot::RangeVarPlot(const char* var, Object* pyobj) color_ = 1; begin_section_ = 0; end_section_ = 0; - sec_list_ = new SecPosList(50); + sec_list_ = new SecPosList; struc_changed_ = structure_change_cnt; shape_changed_ = nrn_shape_changed_; #if HAVE_IV @@ -434,16 +438,16 @@ void RangeVarPlot::x_end(float x, Section* sec) { } float RangeVarPlot::left() { - if (sec_list_->count()) { - return sec_list_->item(0).len + origin_; + if (!sec_list_->empty()) { + return sec_list_->front().len + origin_; } else { return origin_; } } float RangeVarPlot::right() { - if (sec_list_->count()) { - return sec_list_->item(sec_list_->count() - 1).len + origin_; + if (!sec_list_->empty()) { + return sec_list_->back().len + origin_; } else { return origin_; } @@ -534,7 +538,7 @@ void SpacePlot::expr(const char* expr) { #endif void RangeVarPlot::fill_pointers() { - long xcnt = sec_list_->count(); + long xcnt = sec_list_->size(); if (xcnt) { Symbol* sym; char buf[200]; @@ -553,8 +557,8 @@ void RangeVarPlot::fill_pointers() { bool does_exist; double* pval = NULL; for (long i = 0; i < xcnt; ++i) { - Section* sec = sec_list_->item(i).sec; - hoc_ac_ = sec_list_->item(i).x; + Section* sec = (*sec_list_)[i].sec; + hoc_ac_ = (*sec_list_)[i].x; if (rexp_) { does_exist = rexp_->exists(int(i)); } else { @@ -569,21 +573,21 @@ void RangeVarPlot::fill_pointers() { pval = hoc_val_pointer(buf); } if (noexist > 1) { - add(sec_list_->item(i - 1).len + origin_, 0); - add(sec_list_->item(i - 1).len + origin_, pval); + add((*sec_list_)[i - 1].len + origin_, 0); + add((*sec_list_)[i - 1].len + origin_, pval); } if (i == 1 && noexist == 1) { - add(sec_list_->item(i - 1).len + origin_, pval); + add((*sec_list_)[i - 1].len + origin_, pval); } - add(sec_list_->item(i).len + origin_, pval); + add((*sec_list_)[i].len + origin_, pval); noexist = 0; } else { if (noexist == 1) { - add(sec_list_->item(i - 1).len + origin_, pval); - add(sec_list_->item(i - 1).len + origin_, 0); + add((*sec_list_)[i - 1].len + origin_, pval); + add((*sec_list_)[i - 1].len + origin_, 0); } if (i == xcnt - 1 && noexist == 0) { - add(sec_list_->item(i).len + origin_, pval); + add((*sec_list_)[i].len + origin_, pval); } ++noexist; } @@ -594,11 +598,10 @@ void RangeVarPlot::fill_pointers() { void RangeVarPlot::list(Object* ob) { hoc_List* l = (hoc_List*) ob->u.this_pointer; - long i, cnt = sec_list_->count(); - Section* sec = NULL; - for (i = 0; i < cnt; ++i) { - if (sec_list_->item(i).sec != sec) { - sec = sec_list_->item(i).sec; + Section* sec = nullptr; + for (SecPos p: *sec_list_) { + if (p.sec != sec) { + sec = p.sec; if (sec) { hoc_l_lappendsec(l, sec); section_ref(sec); @@ -631,7 +634,7 @@ void SpacePlot::plot() { void RangeVarPlot::set_x() { if (!begin_section_ || !end_section_ || !begin_section_->prop || !end_section_->prop) { - sec_list_->remove_all(); + sec_list_->clear(); return; } SecPos spos; @@ -641,7 +644,7 @@ void RangeVarPlot::set_x() { sec1 = begin_section_; sec2 = end_section_; v_setup_vectors(); - sec_list_->remove_all(); // v_setup_vectors() may recurse once. + sec_list_->clear(); // v_setup_vectors() may recurse once. nd1 = node_exact(sec1, x_begin_); nd2 = node_exact(sec2, x_end_); @@ -669,7 +672,7 @@ void RangeVarPlot::set_x() { spos.x = nrn_arc_position(sec, nd); spos.len = d - x; // printf("%s(%g) at %g %g\n", secname(spos.sec), spos.x, spos.len, x); - sec_list_->append(spos); + sec_list_->push_back(spos); if (x == 0.) { sec = nrn_trueparent(sec); d += node_dist(sec, nd); @@ -685,9 +688,9 @@ void RangeVarPlot::set_x() { spos.x = nrn_arc_position(spos.sec, nd); spos.len = 0.; // printf("%s(%g) at %g root\n", secname(spos.sec), spos.x, spos.len); - sec_list_->append(spos); + sec_list_->push_back(spos); - long indx = sec_list_->count(); + long indx = sec_list_->size(); nd = nd2; sec = sec2; @@ -698,7 +701,7 @@ void RangeVarPlot::set_x() { spos.x = nrn_arc_position(sec, nd); spos.len = d + x; // printf("%s(%g) at %g\n", secname(spos.sec), spos.x, spos.len); - sec_list_->insert(indx, spos); + sec_list_->insert(sec_list_->begin() + indx, spos); if (x == 0.) { sec = nrn_trueparent(sec); d -= node_dist(sec, nd); @@ -762,12 +765,12 @@ RangeExpr::~RangeExpr() { void RangeExpr::fill() { - if (n_ != spl_->count()) { + if (n_ != spl_->size()) { if (val_) { delete[] val_; delete[] exist_; } - n_ = spl_->count(); + n_ = spl_->size(); if (n_) { val_ = new double[n_]; exist_ = new bool[n_]; @@ -775,8 +778,8 @@ void RangeExpr::fill() { } int temp = hoc_execerror_messages; for (long i = 0; i < n_; ++i) { - nrn_pushsec(spl_->item(i).sec); - hoc_ac_ = spl_->item(i).x; + nrn_pushsec((*spl_)[i].sec); + hoc_ac_ = (*spl_)[i].x; hoc_execerror_messages = 0; if (cmd_->pyobject()) { hoc_pushx(hoc_ac_); @@ -796,8 +799,8 @@ void RangeExpr::fill() { exist_[i] = false; #if 0 printf("RangeExpr: %s no exist at %s(%g)\n", - cmd_->name(), secname(spl_->item(i).sec), - spl_->item(i).x + cmd_->name(), secname((*spl_)[i].sec), + (*spl_)[i].x ); #endif } @@ -809,8 +812,8 @@ void RangeExpr::fill() { void RangeExpr::compute() { for (long i = 0; i < n_; ++i) { if (exist_[i]) { - nrn_pushsec(spl_->item(i).sec); - hoc_ac_ = spl_->item(i).x; + nrn_pushsec((*spl_)[i].sec); + hoc_ac_ = (*spl_)[i].x; if (cmd_->pyobject()) { hoc_pushx(hoc_ac_); int err = 1; // messages diff --git a/src/nrniv/splitcell.cpp b/src/nrniv/splitcell.cpp index 51583628ef..445aac9e84 100644 --- a/src/nrniv/splitcell.cpp +++ b/src/nrniv/splitcell.cpp @@ -1,10 +1,7 @@ #include <../../nrnconf.h> -#include -#include +#include #include -#include -#include #include #include @@ -20,8 +17,6 @@ setting up and transfer of matrix information. Note that gid information about the subtrees is no longer required by this implementation. */ -void nrnmpi_splitcell_connect(int that_host); // that_host must be adjacent to nrnmpi_myid - extern "C" int structure_change_cnt; #if PARANEURON @@ -30,22 +25,18 @@ extern void (*nrnmpi_splitcell_compute_)(); extern void nrnmpi_send_doubles(double*, int cnt, int dest, int tag); extern void nrnmpi_recv_doubles(double*, int cnt, int src, int tag); extern double nrnmpi_splitcell_wait_; -#endif -#if PARANEURON static int change_cnt_; static void transfer(); static void set_structure(); static void splitcell_compute(); -class SplitCell { - public: +struct SplitCell { Section* rootsec_; int that_host_; }; -declarePtrList(SplitCellList, SplitCell) - implementPtrList(SplitCellList, SplitCell) static SplitCellList* splitcell_list_; +static std::vector splitcell_list_; #define ip 0 #define im 2 @@ -54,14 +45,11 @@ static double* transfer_p_[4]; #endif +// that_host must be adjacent to nrnmpi_myid void nrnmpi_splitcell_connect(int that_host) { #if PARANEURON - int i; - if (!splitcell_list_) { - splitcell_list_ = new SplitCellList(); - } Section* rootsec = chk_access(); - if (abs(nrnmpi_myid - that_host) != 1) { + if (std::abs(nrnmpi_myid - that_host) != 1) { hoc_execerror("cells may be split only on adjacent hosts", 0); } if (that_host < 0 || that_host >= nrnmpi_numprocs) { @@ -70,10 +58,8 @@ void nrnmpi_splitcell_connect(int that_host) { if (rootsec->parentsec) { hoc_execerror(secname(rootsec), "is not a root section"); } - // printf("%d nrnmpi_splitcell_connect %s %d\n", nrnmpi_myid, - // secname(rootsec), that_host); nrnmpi_splitcell_compute_ = splitcell_compute; - for (i = 0; i < 2; ++i) + for (size_t i = 0; i < 2; ++i) if (that_host == nrnmpi_myid + i * 2 - 1) { if (splitcell_connected_[i]) { char buf[100]; @@ -82,10 +68,7 @@ void nrnmpi_splitcell_connect(int that_host) { } splitcell_connected_[i] = true; } - SplitCell* sc = new SplitCell(); - splitcell_list_->append(sc); - sc->rootsec_ = rootsec; - sc->that_host_ = that_host; + splitcell_list_.push_back({rootsec, that_host}); #else if (nrnmpi_myid == 0) { hoc_execerror("ParallelContext.splitcell not available.", @@ -105,27 +88,11 @@ void nrnmpi_split_clear() { } void splitcell_compute() { - int i; if (structure_change_cnt != change_cnt_) { set_structure(); change_cnt_ = structure_change_cnt; } transfer(); -#if 0 - for (i = 0; i < split_cnt_; ++i) { - SplitInfo& si = split_info_[i]; - if (si.that_host == nrnmpi_myid) { - SplitInfo& sj = split_info_[si.that_index]; - sj.d_that = *(si.d_this); - sj.rhs_that = *(si.rhs_this); - } - } - for (i = 0; i < split_cnt_; ++i) { - SplitInfo& si = split_info_[i]; - *(si.d_this) += si.d_that; - *(si.rhs_this) += si.rhs_that; - } -#endif } void transfer() { @@ -156,13 +123,7 @@ void transfer() { } void set_structure() { - int i, cnt; - if (!splitcell_list_) { - return; - } - cnt = splitcell_list_->count(); - for (i = 0; i < cnt; ++i) { - SplitCell& sc = *splitcell_list_->item(i); + for (auto& sc: splitcell_list_) { if (sc.that_host_ == nrnmpi_myid + 1) { transfer_p_[ip + 0] = &NODED(sc.rootsec_->parentnode); transfer_p_[ip + 1] = &NODERHS(sc.rootsec_->parentnode); diff --git a/test/pynrn/test_zptrlist.py b/test/pynrn/test_zptrlist.py new file mode 100644 index 0000000000..d00200b91f --- /dev/null +++ b/test/pynrn/test_zptrlist.py @@ -0,0 +1,76 @@ +from neuron import h + + +def test_random_play(): # for coverage of ptrlist changes #1815 + cv = h.CVode() + cv.active(0) + cv.cache_efficient(0) + h.secondorder = 0 + s = h.Section() + s.L = 10 + s.diam = 10 + ic = h.IClamp(s(0.5)) + ic.delay = 0 + ic.dur = 10 + ic.amp = 0 + r = h.Random() + r.Random123(1, 0, 0) + r.uniform(0.0, 0.001) + r.play(ic._ref_amp) + v_vec = h.Vector() + v_vec.record(s(0.5)._ref_v, sec=s) + h.dt = 0.025 + h.finitialize(0) + for _ in range(3): + h.fadvance() + std = h.Vector( + [0.0, 0.00046940111168614074, 0.004571699024450762, 0.01086603263672303] + ) + assert v_vec.c().sub(std).abs().sum() < 1e-15 + + +def test_hoc_list(): # for coverage of ptrlist changes in ivoc/oc_list.cpp + lst = h.List() + lst.append(h.Vector().append(0)) + lst.append(h.Vector().append(1)) + lst.insrt(1, h.Vector().append(2)) + assert [v.x[0] for v in lst] == [0.0, 2.0, 1.0] + + +def test_rvp(): # for coverage of ptrlist changes in nrniv/shape.cpp + d = [h.Section(name="d_" + str(i)) for i in range(3)] + for i in range(1, 3): + d[i].connect(d[i - 1](1)) + for s in d: + s.L = 10 + s.diam = 1 + s.insert("pas") + rvp = h.RangeVarPlot("v", d[0](0), d[2](1)) + assert rvp.left() == 0.0 + assert rvp.right() == 30.0 + sl = h.SectionList() + rvp.list(sl) + sz = sum([1 for _ in sl]) + assert sz == 3 + + +def test_finithnd(): + # ptrlist #1815 coverage of nrniv/finithnd.cpp + import sys, io + + def foo(): + pass + + fih = h.FInitializeHandler(foo) + oldstdout = sys.stdout + sys.stdout = mystdout = io.StringIO() + fih.allprint() + sys.stdout = oldstdout + assert "Type 1 FInitializeHandler statements" in mystdout.getvalue() + + +if __name__ == "__main__": + test_random_play() + test_hoc_list() + test_rvp() + test_finithnd()