diff --git a/src/runtime/c/pgf/namespace.h b/src/runtime/c/pgf/namespace.h index 70a624acd..9cf9e8c25 100644 --- a/src/runtime/c/pgf/namespace.h +++ b/src/runtime/c/pgf/namespace.h @@ -631,6 +631,24 @@ void namespace_iter(Namespace map, PgfItor* itor, PgfExn *err) return; } +template +bool namespace_iter(Namespace map, std::function)> &f) +{ + if (map == 0) + return true; + + if (!namespace_iter(map->left, f)) + return false; + + if (!f(map->value)) + return false; + + if (!namespace_iter(map->right, f)) + return false; + + return true; +} + template void namespace_iter_prefix(Namespace map, PgfText *prefix, PgfItor* itor, PgfExn *err) { diff --git a/src/runtime/c/pgf/pgf.cxx b/src/runtime/c/pgf/pgf.cxx index 123a54169..6770cca71 100644 --- a/src/runtime/c/pgf/pgf.cxx +++ b/src/runtime/c/pgf/pgf.cxx @@ -463,23 +463,6 @@ void pgf_iter_categories(PgfDB *db, PgfRevision revision, } PGF_API_END } -struct PgfItorConcrHelper : PgfItor -{ - PgfDB *db; - txn_t txn_id; - PgfItor *itor; -}; - -static -void iter_concretes_helper(PgfItor *itor, PgfText *key, object value, PgfExn *err) -{ - PgfItorConcrHelper* helper = (PgfItorConcrHelper*) itor; - ref concr = value; - object rev = helper->db->register_revision(concr.tagged(), helper->txn_id); - helper->db->ref_count++; - helper->itor->fn(helper->itor, key, rev, err); -} - PGF_API void pgf_iter_concretes(PgfDB *db, PgfRevision revision, PgfItor *itor, PgfExn *err) @@ -490,13 +473,14 @@ void pgf_iter_concretes(PgfDB *db, PgfRevision revision, DB_scope scope(db, READER_SCOPE); ref pgf = db->revision2pgf(revision, &txn_id); - PgfItorConcrHelper helper; - helper.fn = iter_concretes_helper; - helper.db = db; - helper.txn_id = txn_id; - helper.itor = itor; - - namespace_iter(pgf->concretes, &helper, err); + std::function)> f = + [txn_id,db,itor,err](ref concr) { + object rev = db->register_revision(concr.tagged(), txn_id); + db->ref_count++; + itor->fn(itor, &concr->name, rev, err); + return (err->type == PGF_EXN_NONE); + }; + namespace_iter(pgf->concretes, f); } PGF_API_END } @@ -1609,30 +1593,19 @@ void pgf_create_category(PgfDB *db, PgfRevision revision, struct PGF_INTERNAL_DECL PgfDropItor : PgfItor { ref pgf; - ref concrete; - PgfText *name; }; -static -void iter_drop_cat_helper2(PgfItor *itor, PgfText *key, object value, PgfExn *err) -{ - ref concr = value; - PgfText* name = ((PgfDropItor*) itor)->name; - - drop_lin(concr, name); -} - static void iter_drop_cat_helper(PgfItor *itor, PgfText *key, object value, PgfExn *err) { ref pgf = ((PgfDropItor*) itor)->pgf; - PgfDropItor itor2; - itor2.fn = iter_drop_cat_helper2; - itor2.pgf = 0; - itor2.concrete = 0; - itor2.name = key; - namespace_iter(pgf->concretes, &itor2, err); + std::function)> f = + [key,err](ref concr) { + drop_lin(concr, key); + return (err->type == PGF_EXN_NONE); + }; + namespace_iter(pgf->concretes, f); ref fun; Namespace funs = @@ -1672,8 +1645,6 @@ void pgf_drop_category(PgfDB *db, PgfRevision revision, PgfDropItor itor; itor.fn = iter_drop_cat_helper; itor.pgf = pgf; - itor.concrete = 0; - itor.name = name; PgfProbspace funs_by_cat = probspace_delete_by_cat(pgf->abstract.funs_by_cat, &cat->name, &itor, err); diff --git a/src/runtime/c/pgf/reader.cxx b/src/runtime/c/pgf/reader.cxx index 118a6ae4e..f0a8b8366 100644 --- a/src/runtime/c/pgf/reader.cxx +++ b/src/runtime/c/pgf/reader.cxx @@ -373,11 +373,6 @@ struct PGF_INTERNAL_DECL PgfAbsCatCounts prob_t prob; }; -struct PGF_INTERNAL_DECL PgfProbItor : PgfItor -{ - Vector *cats; -}; - static PgfAbsCatCounts *find_counts(Vector *cats, PgfText *name) { @@ -399,38 +394,6 @@ PgfAbsCatCounts *find_counts(Vector *cats, PgfText *name) return NULL; } -static -void collect_counts(PgfItor *itor, PgfText *key, object value, PgfExn *err) -{ - PgfProbItor* prob_itor = (PgfProbItor*) itor; - ref absfun = value; - - PgfAbsCatCounts *counts = - find_counts(prob_itor->cats, &absfun->type->name); - if (counts != NULL) { - if (isnan(absfun->prob)) { - counts->n_nan_probs++; - } else { - counts->probs_sum += exp(-absfun->prob); - } - } -} - -static -void pad_probs(PgfItor *itor, PgfText *key, object value, PgfExn *err) -{ - PgfProbItor* prob_itor = (PgfProbItor*) itor; - ref absfun = value; - - if (isnan(absfun->prob)) { - PgfAbsCatCounts *counts = - find_counts(prob_itor->cats, &absfun->type->name); - if (counts != NULL) { - absfun->prob = counts->prob; - } - } -} - void PgfReader::read_abstract(ref abstract) { this->abstract = abstract; @@ -447,24 +410,42 @@ void PgfReader::read_abstract(ref abstract) abstract->cats = cats; if (probs_callback != NULL) { - PgfExn err; - err.type = PGF_EXN_NONE; - - PgfProbItor itor; - itor.cats = namespace_to_sorted_names(abstract->cats); - - itor.fn = collect_counts; - namespace_iter(abstract->funs, &itor, &err); - - for (size_t i = 0; i < itor.cats->len; i++) { - PgfAbsCatCounts *counts = &itor.cats->data[i]; + Vector *cats = namespace_to_sorted_names(abstract->cats); + + std::function)> collect_counts = + [cats](ref absfun) { + PgfAbsCatCounts *counts = + find_counts(cats, &absfun->type->name); + if (counts != NULL) { + if (isnan(absfun->prob)) { + counts->n_nan_probs++; + } else { + counts->probs_sum += exp(-absfun->prob); + } + } + return true; + }; + namespace_iter(abstract->funs, collect_counts); + + for (size_t i = 0; i < cats->len; i++) { + PgfAbsCatCounts *counts = &cats->data[i]; counts->prob = - logf((1-counts->probs_sum) / counts->n_nan_probs); } - itor.fn = pad_probs; - namespace_iter(abstract->funs, &itor, &err); - - free(itor.cats); + std::function)> pad_probs = + [cats](ref absfun) { + if (isnan(absfun->prob)) { + PgfAbsCatCounts *counts = + find_counts(cats, &absfun->type->name); + if (counts != NULL) { + absfun->prob = counts->prob; + } + } + return true; + }; + namespace_iter(abstract->funs, pad_probs); + + free(cats); } }