Skip to content

Commit

Permalink
Add and use algorithms for managing iterable (#2534)
Browse files Browse the repository at this point in the history
Basic algorithms:
- `void apply_to_first(iterable, value, function)` apply `function` to the first `value` of `iterable`. If not found, do nothing.
- `void erase_first(iterable, value)` erase the first `value` of the `iterable`.

Algorithms designed for range-based for loops:
- `THINGS enumerate(iterable)` return a pair of `index` and `value` from an `iterable` forward.
- `THINGS renumerate(iterable)` return a pair of `index` and `value` from an `iterable` backward.
- `THINGS reverse(iterable)` return the `value` of `iterable` in a backward way.
- `THINGS range(iterable)` return all the `index` from a `iterable` forward.
  • Loading branch information
alkino authored Oct 3, 2023
1 parent 5868cdd commit d9855f6
Show file tree
Hide file tree
Showing 17 changed files with 388 additions and 251 deletions.
13 changes: 6 additions & 7 deletions src/ivoc/ivocrand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "classreg.h"
#include "oc2iv.h"
#include "nrnisaac.h"
#include "utils/enumerate.h"

#include <vector>
#include <ocnotify.h>
Expand Down Expand Up @@ -183,13 +184,11 @@ void RandomPlay::play() {
*px_ = (*(r_->rand))();
}
void RandomPlay::list_remove() {
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_->erase(it);
unref_deferred();
break;
}
if (auto it = std::find(random_play_list_->begin(), random_play_list_->end(), this);
it != random_play_list_->end()) {
// printf("RandomPlay %p removed from list cnt=%d i=%d %p\n", this, cnt, i);
random_play_list_->erase(it);
unref_deferred();
}
}
void RandomPlay::update(Observable*) {
Expand Down
11 changes: 5 additions & 6 deletions src/ivoc/ocpicker.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <../../nrnconf.h>
#if HAVE_IV // to end of file

#include <algorithm>
#include <OS/list.h>
#include <InterViews/hit.h>
#include <stdio.h>
Expand Down Expand Up @@ -103,16 +104,14 @@ void StandardPicker::event(const Event& e) {
}

void StandardPicker::unbind(int m, EventButton eb) {
long cnt = handlers_[m]->size();
for (long i = 0, j = 0; i < cnt; ++i) {
ButtonHandler* b = handlers_[m]->at(j);
for (auto& b: *handlers_[m]) {
if (b->eb_ == Event::any || b->eb_ == eb) {
delete b;
handlers_[m]->erase(handlers_[m]->begin() + j);
} else {
++j;
b = nullptr;
}
}
handlers_[m]->erase(std::remove(handlers_[m]->begin(), handlers_[m]->end(), nullptr),
handlers_[m]->end());
}

void StandardPicker::bind(int m, EventButton eb, OcHandler* h) {
Expand Down
37 changes: 14 additions & 23 deletions src/ivoc/scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#include "scenepic.h"
#include "idraw.h"
#include "ivoc.h"
#include "utils/enumerate.h"

#define Scene_Move_Text_ "MoveText Graph"
#define Scene_ChangeColor_ "ChangeColor Graph"
Expand Down Expand Up @@ -311,10 +312,7 @@ Scene::~Scene() {
// without first deleteing all the views.
assert(views_->empty());

if (auto it = std::find(scene_list->begin(), scene_list->end(), this);
it != scene_list->end()) {
scene_list->erase(it);
}
erase_first(*scene_list, this);
delete views_;
}

Expand All @@ -335,14 +333,12 @@ void Scene::append_view(XYView* v) {
}

void Scene::remove_view(XYView* v) {
if (auto it = std::find(views_->begin(), views_->end(), v); it != views_->end()) {
views_->erase(it);
}
erase_first(*views_, v);
}

void Scene::dismiss() {
for (auto it = views_->rbegin(); it != views_->rend(); ++it) {
OcViewGlyph* g = (*it)->parent();
for (auto&& item: reverse(*views_)) {
OcViewGlyph* g = item->parent();
if (g && g->has_window()) {
g->window()->dismiss();
g->window(NULL);
Expand Down Expand Up @@ -513,8 +509,8 @@ void Scene::replace(GlyphIndex index, Glyph* glyph) {
}

GlyphIndex Scene::glyph_index(const Glyph* g) {
for (std::size_t i = 0; i < info_->size(); ++i) {
if ((*info_)[i].glyph_ == g) {
for (const auto&& [i, info]: enumerate(*info_)) {
if (info.glyph_ == g) {
return i;
}
}
Expand All @@ -536,7 +532,7 @@ void Scene::request(Requisition& req) const {

void Scene::allocate(Canvas* c, const Allocation& a, Extension& ext) {
// printf("Scene::allocate\n");
for (GlyphIndex index = 0; index < info_->size(); ++index) {
for (std::size_t index: range(*info_)) {
check_allocation(index);
}
ext.set(c, a);
Expand Down Expand Up @@ -693,14 +689,12 @@ void Scene::pick(Canvas* c, const Allocation& a, int depth, Hit& h) {
if (background_ != NULL) {
background_->pick(c, a, depth, h);
}
GlyphIndex count = info_->size();
// pick with some extra epsilon in canvas coords
Coord epsx = XYView::current_pick_view()->x_pick_epsilon();
Coord epsy = XYView::current_pick_view()->y_pick_epsilon();

bool are_fixed = false;
for (GlyphIndex index = 0; index < count; ++index) {
SceneInfo& info = (*info_)[index];
for (auto&& [index, info]: enumerate(*info_)) {
if (info.status_ & SceneInfoFixed) {
are_fixed = true;
} else if (info.glyph_ != NULL && (info.status_ & SceneInfoShowing)) {
Expand All @@ -720,8 +714,7 @@ void Scene::pick(Canvas* c, const Allocation& a, int depth, Hit& h) {
const Transformer& tv = XYView::current_pick_view()->s2o();
float scx, scy, tmp;
tv.matrix(scx, tmp, tmp, scy, tmp, tmp);
for (GlyphIndex index = 0; index < count; ++index) {
SceneInfo& info = (*info_)[index];
for (auto&& [index, info]: enumerate(*info_)) {
if ((info.status_ & SceneInfoFixed) && info.glyph_ != NULL &&
(info.status_ & SceneInfoShowing)) {
Allocation a = info.allocation_;
Expand Down Expand Up @@ -752,13 +745,11 @@ void Scene::pick(Canvas* c, const Allocation& a, int depth, Hit& h) {
}

long Scene::scene_list_index(Scene* s) {
std::size_t cnt = scene_list->size();
for (std::size_t i = 0; i < cnt; ++i) {
if (s == scene_list->at(i)) {
return i;
}
auto it = std::find(scene_list->begin(), scene_list->end(), s);
if (it == scene_list->end()) {
return -1;
}
return -1;
return std::distance(scene_list->begin(), it);
}

void Scene::save_all(std::ostream& o) {
Expand Down
9 changes: 4 additions & 5 deletions src/ivoc/scenepic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "apwindow.h"
#include "utility.h"
#include "oc2iv.h"
#include "utils/enumerate.h"

#define Scene_SceneMover_ "Translate Scene"
#define Scene_SceneZoom_ "ZoomInOut Scene"
Expand Down Expand Up @@ -309,9 +310,7 @@ MenuItem* ScenePicker::add_radio_menu(const char* name, OcHandler* h, int tool,
}

long ScenePickerImpl::info_index(const char* name) {
std::size_t cnt = bil_->size();
for (std::size_t i = 0; i < cnt; ++i) {
ButtonItemInfo* b = bil_->at(i);
for (const auto&& [i, b]: enumerate(*bil_)) {
if (strcmp(b->name_.string(), name) == 0) {
return i;
}
Expand Down Expand Up @@ -410,8 +409,8 @@ ScenePickerImpl::ScenePickerImpl(Scene* scene)
ScenePickerImpl::~ScenePickerImpl() {
Resource::unref(menu_);
Resource::unref(tg_);
for (auto it = bil_->rbegin(); it != bil_->rend(); ++it) {
delete *it;
for (ButtonItemInfo* bii: *bil_) {
delete bii;
}
delete bil_;
}
Expand Down
38 changes: 10 additions & 28 deletions src/ivoc/symdir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <OS/string.h>
#include <stdio.h>
#include "ocobserv.h"
#include "utils/enumerate.h"

#include "nrniv_mf.h"
#include "nrnoc2iv.h"
Expand Down Expand Up @@ -60,32 +61,16 @@ class SymDirectoryImpl: public Observer {
void sort();
};

static int compare_entries(const void* k1, const void* k2) {
SymbolItem* e1 = *((SymbolItem**) k1);
SymbolItem* e2 = *((SymbolItem**) k2);
static int compare_entries(const SymbolItem* e1, const SymbolItem* e2) {
int i = strcmp(e1->name().string(), e2->name().string());
if (i == 0) {
if (e1->array_index() > e2->array_index()) {
i = 1;
} else {
i = -1;
}
return e1->array_index() > e2->array_index();
}
return i;
return i > 0;
};

void SymDirectoryImpl::sort() {
std::size_t cnt = symbol_lists_.size();
SymbolItem** slist = new SymbolItem*[cnt];
for (std::size_t i = 0; i < cnt; ++i) {
slist[i] = symbol_lists_[i];
}
qsort(slist, cnt, sizeof(SymbolItem*), compare_entries);
symbol_lists_.clear();
for (std::size_t i = 0; i < cnt; ++i) {
symbol_lists_.push_back(slist[i]);
}
delete[] slist;
std::sort(symbol_lists_.begin(), symbol_lists_.end(), compare_entries);
}

// SymDirectory
Expand Down Expand Up @@ -307,9 +292,8 @@ int SymDirectory::array_index(int i) const {
}

int SymDirectory::index(const String& name) const {
long cnt = count();
for (long i = 0; i < cnt; ++i) {
if (name == impl_->symbol_lists_[i]->name()) {
for (const auto&& [i, symbol]: enumerate(impl_->symbol_lists_)) {
if (name == symbol->name()) {
return i;
}
}
Expand Down Expand Up @@ -451,8 +435,7 @@ void SymDirectoryImpl::load(int type) {
}

void SymDirectoryImpl::load(int type, Symlist* sl) {
Symbol* sym;
for (sym = sl->first; sym; sym = sym->next) {
for (Symbol* sym = sl->first; sym; sym = sym->next) {
if (type == -1) {
switch (sym->type) {
case SECTION:
Expand Down Expand Up @@ -490,9 +473,8 @@ void SymDirectoryImpl::load_aliases() {
IvocAliases* a = (IvocAliases*) obj_->aliases;
if (!a)
return;
for (const auto& kv: a->symtab_) {
Symbol* s = kv.second;
append(s, NULL, obj_);
for (const auto& [_, s]: a->symtab_) {
append(s, nullptr, obj_);
}
}

Expand Down
32 changes: 13 additions & 19 deletions src/ivoc/xmenu.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@

#include <../../nrnconf.h>

#include "oc2iv.h"
#include "classreg.h"
#include "gui-redirect.h"
#include "utils/enumerate.h"

#if HAVE_IV // to end of file except for a few small fragments.

Expand Down Expand Up @@ -992,8 +992,8 @@ void HocPanel::map_window(int scroll) {
// HocPanel
static void var_freed(void* pd, int size) {
if (hoc_panel_list) {
for (auto it = hoc_panel_list->rbegin(); it != hoc_panel_list->rend(); ++it) {
(*it)->check_valid_pointers(pd, size);
for (auto&& elem: reverse(*hoc_panel_list)) {
elem->check_valid_pointers(pd, size);
}
}
}
Expand Down Expand Up @@ -1034,10 +1034,7 @@ HocPanel::~HocPanel() {
for (auto& item: elist_) {
item->HocItem::unref();
}
if (auto it = std::find(hoc_panel_list->begin(), hoc_panel_list->end(), this);
it != hoc_panel_list->end()) {
hoc_panel_list->erase(it);
}
erase_first(*hoc_panel_list, this);
ilist_.clear();
ilist_.shrink_to_fit();
elist_.clear();
Expand Down Expand Up @@ -1073,10 +1070,7 @@ void HocPanel::keep_updated(HocUpdateItem* hui, bool add) {
if (add) {
update_list_->push_back(hui);
} else {
if (auto it = std::find(update_list_->begin(), update_list_->end(), hui);
it != update_list_->end()) {
update_list_->erase(it);
}
erase_first(*update_list_, hui);
}
}

Expand Down Expand Up @@ -2279,22 +2273,22 @@ void Oc::notifyHocValue() {
ParseTopLevel ptl;
ptl.save();
if (hoc_panel_list) {
for (auto it = hoc_panel_list->rbegin(); it != hoc_panel_list->rend(); ++it) {
(*it)->notifyHocValue();
for (auto&& e: reverse(*hoc_panel_list)) {
e->notifyHocValue();
}
}
ptl.restore();
}

void HocPanel::notifyHocValue() {
for (auto it = elist_.rbegin(); it != elist_.rend(); ++it) {
(*it)->update_hoc_item();
for (auto&& e: reverse(elist_)) {
e->update_hoc_item();
}
}

void HocPanel::check_valid_pointers(void* v, int size) {
for (auto it = elist_.rbegin(); it != elist_.rend(); ++it) {
(*it)->check_pointer(v, size);
for (auto&& e: reverse(elist_)) {
e->check_pointer(v, size);
}
}

Expand All @@ -2321,8 +2315,8 @@ void HocVarLabel::check_pointer(void* v, int) {
}

void HocPanel::data_path(HocDataPaths* hdp, bool append) {
for (auto it = elist_.rbegin(); it != elist_.rend(); ++it) {
(*it)->data_path(hdp, append);
for (auto&& e: reverse(elist_)) {
e->data_path(hdp, append);
}
}

Expand Down
Loading

0 comments on commit d9855f6

Please sign in to comment.