auto ecit = edge_cache.find(cache_key);
if (ecit == edge_cache.end()) {
DEBUG_PRINTF("adding edge %zu %zu\n", g[u].index, g[v].index);
- NFAEdge e = add_edge(u, v, g).first;
+ NFAEdge e = add_edge(u, v, g);
edge_cache.emplace(cache_key, e);
g[e].assert_flags = flags;
if (++assert_edge_count > MAX_ASSERT_EDGES) {
u32 min_bound = pr.bounds.min; // always finite
if (min_bound == 0) { // Vacuous case, we can only do this once.
assert(!edge(g.start, g.accept, g).second);
- NFAEdge e = add_edge(g.start, g.accept, g).first;
+ NFAEdge e = add_edge(g.start, g.accept, g);
g[e].tops.insert(top);
g[u].reports.insert(pr.reports.begin(), pr.reports.end());
min_bound = 1;
for (u32 i = 0; i < min_bound; i++) {
NFAVertex v = add_vertex(g);
g[v].char_reach = pr.reach;
- NFAEdge e = add_edge(u, v, g).first;
+ NFAEdge e = add_edge(u, v, g);
if (u == g.start) {
g[e].tops.insert(top);
}
if (head != u) {
add_edge(head, v, g);
}
- NFAEdge e = add_edge(u, v, g).first;
+ NFAEdge e = add_edge(u, v, g);
if (u == g.start) {
g[e].tops.insert(top);
}
// Similarly, connect (start, startDs) if necessary.
if (!edge(g.start, g.startDs, g).second) {
- auto e = add_edge(g.start, g.startDs, g).first;
+ NFAEdge e = add_edge(g.start, g.startDs, g);
tempEdges.push_back(e); // Remove edge later.
}
add_edge(vv, g.accept, g);
g[e].assert_flags = 0;
add_edge(u, vv, g[e], g);
- if (!edge(u, g.acceptEod, g).second) {
- add_edge(u, g.acceptEod, g[e], g);
- } else {
- /* there may already be a different edge from start to eod
- * if so we need to make it unconditional and alive
- */
- NFAEdge start_eod = edge(u, g.acceptEod, g).first;
-
+ /* there may already be a different edge from start to eod if so
+ * we need to make it unconditional and alive
+ */
+ if (NFAEdge start_eod = edge(u, g.acceptEod, g)) {
g[start_eod].assert_flags = 0;
dead->erase(start_eod);
-
+ } else {
+ add_edge(u, g.acceptEod, g[e], g);
}
dead->insert(e);
}
add_edge(vv, g.accept, g);
g[e].assert_flags = 0;
add_edge(u, vv, g[e], g);
- if (!edge(u, g.acceptEod, g).second) {
- add_edge(u, g.acceptEod, g[e], g);
- } else {
- /* there may already be a different edge from start to eod
- * if so we need to make it unconditional and alive
- */
- NFAEdge start_eod = edge(u, g.acceptEod, g).first;
-
+ /* there may already be a different edge from start to eod if so
+ * we need to make it unconditional and alive
+ */
+ if (NFAEdge start_eod = edge(u, g.acceptEod, g)) {
g[start_eod].assert_flags = 0;
dead->erase(start_eod);
-
+ } else {
+ add_edge(u, g.acceptEod, g[e], g);
}
dead->insert(e);
}
* boundaries. Assert resolution handles the badness coming from asserts.
* The only other source of trouble is startDs->accept connections.
*/
- bool exists;
- NFAEdge orig;
- tie(orig, exists) = edge(g.startDs, g.accept, g);
- if (g.utf8 && exists) {
+ NFAEdge orig = edge(g.startDs, g.accept, g);
+ if (g.utf8 && orig) {
DEBUG_PRINTF("rectifying %u\n", g.reportId);
Report ir = rm.getBasicInternalReport(g);
ReportID rep = rm.getInternalId(ir);
// assert that the edge doesn't already exist
assert(edge(u, v, *graph).second == false);
- pair<NFAEdge, bool> e = add_edge(u, v, *graph);
- assert(e.second);
- return e;
+ return add_edge(u, v, *graph);
}
void NFABuilderImpl::addEdge(Position startPos, Position endPos) {
pred_info->succ.erase(old_vertex_info);
// if edge doesn't exist, create it
- NFAEdge e = add_edge_if_not_present(pred_info->v, new_v, g).first;
+ NFAEdge e = add_edge_if_not_present(pred_info->v, new_v, g);
// put edge tops, if applicable
if (!edgetops.empty()) {
if (new_v_eod) {
NFAEdge ee = add_edge_if_not_present(pred_info->v, new_v_eod,
- g).first;
+ g);
// put edge tops, if applicable
if (!edgetops.empty()) {
if (it == allEdges.end()) {
// No reverse edge, add one.
NFAVertex u = source(fwd, g), v = target(fwd, g);
- NFAEdge rev = add_edge(v, u, g).first;
+ NFAEdge rev = add_edge(v, u, g);
it = allEdges.insert(make_pair(make_pair(vidx, uidx), rev)).first;
// Add to capacity map.
u32 revIndex = g[rev].index;
static
bool hasInEdgeTops(const NGHolder &g, NFAVertex v) {
- bool exists;
- NFAEdge e;
- tie(e, exists) = edge(g.start, v, g);
- return exists && !g[e].tops.empty();
+ NFAEdge e = edge(g.start, v, g);
+ return e && !g[e].tops.empty();
}
/** Transform (1), removal of redundant vertices. */
for (auto v : vertices_range(g)) {
assert(g[v].index < cyclic.size());
- bool c = edge(v, v, g).second;
- if (c) {
+ if (hasSelfLoop(v, g)) {
count++;
+ cyclic[g[v].index] = true;
}
- cyclic[g[v].index] = c;
}
return count;
g[v].char_reach = cr;
add_edge(u, v, g);
if (u == g.start) {
- g[edge(u, v, g).first].tops.insert(top);
+ g[edge(u, v, g)].tops.insert(top);
}
u = v;
}
for (NFAVertex v : tops) {
assert(!isLeafNode(v, g));
- const NFAEdge &e = add_edge(g.start, v, g).first;
+ const NFAEdge &e = add_edge(g.start, v, g);
tempEdges.push_back(e);
}
}
clearReports(g);
for (auto v : pred) {
- NFAEdge e = add_edge(v, g.accept, g).first;
+ NFAEdge e = add_edge(v, g.accept, g);
g[v].reports.insert(0);
if (is_triggered(g) && v == g.start) {
g[e].tops.insert(DEFAULT_TOP);
}
for (auto v : preds) {
- NFAEdge e = add_edge(v, prev, g).first;
+ NFAEdge e = add_edge(v, prev, g);
if (v == g.start && is_triggered(g)) {
g[e].tops.insert(DEFAULT_TOP);
}
g[v_new].s = lit;
for (const auto &e : in_edges_range(v, g)) {
- RoseInEdge e2 = add_edge(source(e, g), v_new, g[e], g).first;
+ RoseInEdge e2 = add_edge(source(e, g), v_new, g[e], g);
// FIXME: are we safe to share graphs here? For now, make our very
// own copy.
g[e2].graph = makeGraphCopy(g[e].graph.get());
}
for (const auto &e : out_edges_range(v, g)) {
- RoseInEdge e2 = add_edge(v_new, target(e, g), g[e], g).first;
+ RoseInEdge e2 = add_edge(v_new, target(e, g), g[e], g);
// FIXME: are we safe to share graphs here? For now, make our very
// own copy.
g[e2].graph = makeGraphCopy(g[e].graph.get());
for (auto pivot : pivots) {
assert(contains(*rhs_map, pivot));
- NFAEdge e = add_edge(rhs->start, (*rhs_map)[pivot], *rhs).first;
+ NFAEdge e = add_edge(rhs->start, (*rhs_map)[pivot], *rhs);
(*rhs)[e].tops.insert(DEFAULT_TOP);
}
a_count++;
- NFAEdge b_edge;
- bool has_b_edge;
- tie(b_edge, has_b_edge) = edge(b_ranking.at(i),
- b_ranking.at(sid), gb);
+ NFAEdge b_edge = edge(b_ranking.at(i), b_ranking.at(sid), gb);
- if (!has_b_edge) {
+ if (!b_edge) {
max = i;
DEBUG_PRINTF("lowering max to %u due to edge %zu->%u\n",
max, i, sid);
DEBUG_PRINTF("skipping common edge\n");
assert(edge(u, v, dest).second);
// Should never merge edges with different top values.
- assert(vic[e].tops == dest[edge(u, v, dest).first].tops);
+ assert(vic[e].tops == dest[edge(u, v, dest)].tops);
continue;
} else {
assert(is_any_accept(v, dest));
/* TODO: relax top checks if reports match */
// If both graphs have edge (start, accept), the tops must match.
- auto e1_accept = edge(h1.start, h1.accept, h1);
- auto e2_accept = edge(h2.start, h2.accept, h2);
- if (e1_accept.second && e2_accept.second &&
- h1[e1_accept.first].tops != h2[e2_accept.first].tops) {
+ NFAEdge e1_accept = edge(h1.start, h1.accept, h1);
+ NFAEdge e2_accept = edge(h2.start, h2.accept, h2);
+ if (e1_accept && e2_accept && h1[e1_accept].tops != h2[e2_accept].tops) {
return false;
}
// If both graphs have edge (start, acceptEod), the tops must match.
- auto e1_eod = edge(h1.start, h1.acceptEod, h1);
- auto e2_eod = edge(h2.start, h2.acceptEod, h2);
- if (e1_eod.second && e2_eod.second &&
- h1[e1_eod.first].tops != h2[e2_eod.first].tops) {
+ NFAEdge e1_eod = edge(h1.start, h1.acceptEod, h1);
+ NFAEdge e2_eod = edge(h2.start, h2.acceptEod, h2);
+ if (e1_eod && e2_eod && h1[e1_eod].tops != h2[e2_eod].tops) {
return false;
}
// If one graph has an edge to accept and the other has an edge to
// acceptEod, the reports must match for the merge to be safe.
- if ((e1_accept.second && e2_eod.second) ||
- (e2_accept.second && e1_eod.second)) {
+ if ((e1_accept && e2_eod) || (e2_accept && e1_eod)) {
if (h1[h1.start].reports != h2[h2.start].reports) {
return false;
}
if (edge(dest, t, g).second) {
continue;
}
- NFAEdge clone = add_edge(dest, t, g).first;
+ NFAEdge clone = add_edge(dest, t, g);
u32 idx = g[clone].index;
g[clone] = g[e];
g[clone].index = idx;
for (const auto &e : in_edges_range(s, g)) {
NFAVertex ss = source(e, g);
assert(!edge(ss, dest, g).second);
- NFAEdge clone = add_edge(ss, dest, g).first;
+ NFAEdge clone = add_edge(ss, dest, g);
u32 idx = g[clone].index;
g[clone] = g[e];
g[clone].index = idx;
}
bool matches_everywhere(const NGHolder &h) {
- NFAEdge e;
- bool exists;
- tie(e, exists) = edge(h.startDs, h.accept, h);
+ NFAEdge e = edge(h.startDs, h.accept, h);
- return exists && !h[e].assert_flags;
+ return e && !h[e].assert_flags;
}
bool is_virtual_start(NFAVertex v, const NGHolder &g) {
NFAVertex s = out_mapping[si];
NFAVertex t = out_mapping[ti];
- UNUSED bool added;
- NFAEdge e2;
- tie(e2, added) = add_edge(s, t, out);
- assert(added);
+ NFAEdge e2 = add_edge(s, t, out);
out[e2] = in[e];
}
* makes a more svelte graphy */
clear_in_edges(temp_map[pivot], *new_lhs);
NFAEdge pivot_edge = add_edge(temp_map[prev_v], temp_map[pivot],
- *new_lhs).first;
+ *new_lhs);
if (is_triggered(h) && prev_v == h.start) {
(*new_lhs)[pivot_edge].tops.insert(DEFAULT_TOP);
}
add_edge(lhs->accept, lhs->acceptEod, *lhs);
clearReports(*lhs);
for (NFAVertex v : splitters) {
- NFAEdge e = add_edge(v_map[v], lhs->accept, *lhs).first;
+ NFAEdge e = add_edge(v_map[v], lhs->accept, *lhs);
if (v == base_graph.start) {
(*lhs)[e].tops.insert(DEFAULT_TOP);
}
/* fill in report information */
g[v].reports.insert(reports.begin(), reports.end());
- RoseEdge e;
- bool added;
- tie(e, added) = add_edge(parent, v, g);
- assert(added);
+ RoseEdge e = add_edge(parent, v, g);
DEBUG_PRINTF("adding edge (%u, %u) to parent\n", minBound, maxBound);
g[e].minBound = minBound;
DEBUG_PRINTF("created anchored vertex %zu with lit id %u\n", g[v].index,
literalId);
- RoseEdge e = add_edge(build->anchored_root, v, g).first;
+ RoseEdge e = add_edge(build->anchored_root, v, g);
g[e].minBound = min_offset;
g[e].maxBound = max_offset;
RoseVertex p = pv.first;
- RoseEdge e;
- bool added;
- tie(e, added) = add_edge(p, w, g);
- assert(added);
+ RoseEdge e = add_edge(p, w, g);
DEBUG_PRINTF("adding edge (%u,%u) to parent\n", edge_props.minBound,
edge_props.maxBound);
g[e].minBound = edge_props.minBound;
for (const auto &pv : parents) {
const RoseInEdgeProps &edge_props = bd.ig[pv.second];
- RoseEdge e = add_edge(pv.first, g_v, tbi->g).first;
+ RoseEdge e = add_edge(pv.first, g_v, tbi->g);
g[e].minBound = edge_props.minBound;
g[e].maxBound = edge_props.maxBound;
g[e].history = selectHistory(*tbi, bd, pv.second, e);
g[v].left.graph = eod_leftfix;
g[v].left.leftfix_report = report_mapping.second;
g[v].left.lag = 0;
- RoseEdge e1 = add_edge(u, v, g).first;
+ RoseEdge e1 = add_edge(u, v, g);
g[e1].minBound = 0;
g[e1].maxBound = ROSE_BOUND_INF;
g[v].min_offset = add_rose_depth(g[u].min_offset,
g[w].reports = report_mapping.first;
g[w].min_offset = g[v].min_offset;
g[w].max_offset = g[v].max_offset;
- RoseEdge e = add_edge(v, w, g).first;
+ RoseEdge e = add_edge(v, w, g);
g[e].minBound = 0;
g[e].maxBound = 0;
g[e].history = ROSE_ROLE_HISTORY_LAST_BYTE;
g[w].reports = ig[iv].reports;
g[w].min_offset = g[u].min_offset;
g[w].max_offset = g[u].max_offset;
- RoseEdge e = add_edge(u, w, g).first;
+ RoseEdge e = add_edge(u, w, g);
g[e].minBound = 0;
g[e].maxBound = 0;
g[e].history = ROSE_ROLE_HISTORY_LAST_BYTE;
g[v].left.leftfix_report = mask_report;
} else {
// Make sure our edge bounds are correct.
- auto e = edge(parent, v, g).first;
+ RoseEdge e = edge(parent, v, g);
g[e].minBound = 0;
g[e].maxBound = anchored ? 0 : ROSE_BOUND_INF;
g[e].history = anchored ? ROSE_ROLE_HISTORY_ANCH
g[v].max_offset = v_max_offset;
if (eod) {
- auto e = add_edge(v, eod_v, g).first;
+ RoseEdge e = add_edge(v, eod_v, g);
g[e].minBound = 0;
g[e].maxBound = 0;
g[e].history = ROSE_ROLE_HISTORY_LAST_BYTE;
succ = u;
}
- NFAEdge e = add_edge(h.start, succ, h).first;
+ NFAEdge e = add_edge(h.start, succ, h);
h[e].tops.insert(DEFAULT_TOP);
return rhs;
g[v].max_offset = sai.max_bound + sai.literal.length();
lit_info.vertices.insert(v);
- RoseEdge e = add_edge(anchored_root, v, g).first;
+ RoseEdge e = add_edge(anchored_root, v, g);
g[e].minBound = sai.min_bound;
g[e].maxBound = sai.max_bound;
}
g[v].literals.insert(lit_id);
g[v].reports = reports;
- RoseEdge e = add_edge(tbi.root, v, g).first;
+ RoseEdge e = add_edge(tbi.root, v, g);
g[e].minBound = 0;
g[e].maxBound = ROSE_BOUND_INF;
g[v].min_offset = 1;
NFAVertex u = h->start;
for (auto it = s.begin() + s.length() - len; it != s.end(); ++it) {
NFAVertex v = addHolderVertex(*it, *h);
- NFAEdge e = add_edge(u, v, *h).first;
+ NFAEdge e = add_edge(u, v, *h);
if (u == h->start) {
(*h)[e].tops.insert(DEFAULT_TOP);
}
assert(g[e_old].maxBound >= bound_max);
setEdgeBounds(g, e_old, bound_min, bound_max);
} else {
- RoseEdge e_new;
- UNUSED bool added;
- tie(e_new, added) = add_edge(ar, v, g);
- assert(added);
+ RoseEdge e_new = add_edge(ar, v, g);
setEdgeBounds(g, e_new, bound_min, bound_max);
to_delete->push_back(e_old);
}
if (source(e_old, g) == ar) {
setEdgeBounds(g, e_old, ri.repeatMin + width, ri.repeatMax + width);
} else {
- RoseEdge e_new;
- UNUSED bool added;
- tie(e_new, added) = add_edge(ar, v, g);
- assert(added);
+ RoseEdge e_new = add_edge(ar, v, g);
setEdgeBounds(g, e_new, ri.repeatMin + width, ri.repeatMax + width);
to_delete->push_back(e_old);
}
return false;
}
- RoseEdge e;
- bool exists;
- tie(e, exists) = edge(build.root, u, g);
+ RoseEdge e = edge(build.root, u, g);
- if (!exists) {
+ if (!e) {
DEBUG_PRINTF("u=%zu is not a root role\n", g[u].index);
return false;
}
for (const auto &e : in_edges_range(v, g)) {
RoseVertex u = source(e, g);
DEBUG_PRINTF("u index=%zu\n", g[u].index);
- RoseEdge et;
- bool exists;
- tie (et, exists) = edge(u, t, g);
- if (exists) {
+ if (RoseEdge et = edge(u, t, g)) {
if (g[et].minBound <= g[e].minBound
&& g[et].maxBound >= g[e].maxBound) {
DEBUG_PRINTF("remove more constrained edge\n");
deadEdges.push_back(e);
}
} else {
- DEBUG_PRINTF("rehome edge: add %zu->%zu\n",
- g[u].index, g[t].index);
+ DEBUG_PRINTF("rehome edge: add %zu->%zu\n", g[u].index,
+ g[t].index);
add_edge(u, t, g[e], g);
deadEdges.push_back(e);
}
}
for (const auto &e_a : in_edges_range(a, g)) {
- bool exists;
- RoseEdge e;
- tie(e, exists) = edge(source(e_a, g), b, g);
- if (!exists || g[e].rose_top != g[e_a].rose_top) {
+ RoseEdge e = edge(source(e_a, g), b, g);
+ if (!e || g[e].rose_top != g[e_a].rose_top) {
DEBUG_PRINTF("bad tops\n");
return false;
}
bool hasCommonSuccWithBadBounds(RoseVertex a, RoseVertex b,
const RoseGraph &g) {
for (const auto &e_a : out_edges_range(a, g)) {
- bool exists;
- RoseEdge e;
- tie(e, exists) = edge(b, target(e_a, g), g);
- if (exists) {
+ if (RoseEdge e = edge(b, target(e_a, g), g)) {
if (g[e_a].maxBound < g[e].minBound
|| g[e].maxBound < g[e_a].minBound) {
return true;
bool hasCommonPredWithBadBounds(RoseVertex a, RoseVertex b,
const RoseGraph &g) {
for (const auto &e_a : in_edges_range(a, g)) {
- bool exists;
- RoseEdge e;
- tie(e, exists) = edge(source(e_a, g), b, g);
- if (exists) {
+ if (RoseEdge e = edge(source(e_a, g), b, g)) {
if (g[e_a].maxBound < g[e].minBound
|| g[e].maxBound < g[e_a].minBound) {
return true;
const bool equal_roses = hasEqualLeftfixes(a, b, g);
for (const auto &e_a : in_edges_range(a, g)) {
- bool exists;
- RoseEdge e;
- tie(e, exists) = edge(source(e_a, g), b, g);
- if (exists) {
+ if (RoseEdge e = edge(source(e_a, g), b, g)) {
DEBUG_PRINTF("common pred, e_r=%d r_t %u,%u\n",
(int)equal_roses, g[e].rose_top, g[e_a].rose_top);
if (!equal_roses) {
// We should be protected from merging common preds with tops leading
// to completely different repeats by earlier checks, but just in
// case...
- if (edge(source(e, g), a, g).second) {
- RoseEdge a_edge = edge(source(e, g), a, g).first;
+ if (RoseEdge a_edge = edge(source(e, g), a, g)) {
u32 a_top = g[a_edge].rose_top;
const PureRepeat &a_pr = m_castle->repeats[a_top]; // new report
if (pr != a_pr) {
edge_descriptor() : p(nullptr), serial(0) { }
explicit edge_descriptor(edge_node *pp) : p(pp), serial(pp->serial) { }
+ /* Convenice ctor to allow us to directly get an edge_descriptor from
+ * edge() and add_edge(). As we have null_edges and we always allow
+ * parallel edges, the bool component of the return from these functions
+ * is not required. */
+ edge_descriptor(const std::pair<edge_descriptor, bool> &tup)
+ : p(tup.first.p), serial(tup.first.serial) {
+ assert(tup.second == (bool)tup.first);
+ }
+
operator bool() const { return p; }
bool operator<(const edge_descriptor b) const {
if (p && b.p) {