diff --git a/src/nfagraph/ng_equivalence.cpp b/src/nfagraph/ng_equivalence.cpp index 383b6c75..6f8f6532 100644 --- a/src/nfagraph/ng_equivalence.cpp +++ b/src/nfagraph/ng_equivalence.cpp @@ -38,17 +38,16 @@ #include "ng_util.h" #include "util/compile_context.h" #include "util/graph_range.h" +#include "util/make_unique.h" #include "util/ue2_containers.h" #include +#include #include #include #include -#include - using namespace std; -using boost::ptr_vector; namespace ue2 { @@ -276,47 +275,47 @@ bool hasEdgeAsserts(NFAVertex v, const NGHolder &g) { // populate VertexInfo table static -ptr_vector getVertexInfos(const NGHolder &g) { +vector> getVertexInfos(const NGHolder &g) { const size_t num_verts = num_vertices(g); - ptr_vector infos; + vector> infos; infos.reserve(num_verts * 2); vector vertex_map; // indexed by vertex_index property vertex_map.resize(num_verts); for (auto v : vertices_range(g)) { - VertexInfo *vi = new VertexInfo(v, g); - - // insert our new shiny VertexInfo into the info map - infos.push_back(vi); - - vertex_map[g[v].index] = vi; + infos.push_back(make_unique(v, g)); + vertex_map[g[v].index] = infos.back().get(); } - // now, go through each vertex and populate its predecessor and successor lists - for (VertexInfo &cur_vi : infos) { - // find predecessors - for (const auto &e : in_edges_range(cur_vi.v, g)) { - NFAVertex u = source(e, g); - VertexInfo *vmi = vertex_map[g[u].index]; + // now, go through each vertex and populate its predecessor and successor + // lists + for (auto &vi : infos) { + assert(vi); + NFAVertex v = vi->v; - cur_vi.pred_cr |= vmi->cr; - cur_vi.pred.insert(vmi); + // find predecessors + for (const auto &e : in_edges_range(v, g)) { + NFAVertex u = source(e, g); + VertexInfo *u_vi = vertex_map[g[u].index]; + + vi->pred_cr |= u_vi->cr; + vi->pred.insert(u_vi); // also set up edge tops if (is_triggered(g) && u == g.start) { - cur_vi.edge_tops = g[e].tops; + vi->edge_tops = g[e].tops; } } // find successors - for (auto w : adjacent_vertices_range(cur_vi.v, g)) { - VertexInfo *vmi = vertex_map[g[w].index]; - cur_vi.succ_cr |= vmi->cr; - cur_vi.succ.insert(vmi); + for (auto w : adjacent_vertices_range(v, g)) { + VertexInfo *w_vi = vertex_map[g[w].index]; + vi->succ_cr |= w_vi->cr; + vi->succ.insert(w_vi); } - assert(!hasEdgeAsserts(cur_vi.v, g)); + assert(!hasEdgeAsserts(vi->v, g)); } return infos; @@ -324,7 +323,7 @@ ptr_vector getVertexInfos(const NGHolder &g) { // store equivalence class in VertexInfo for each vertex static -vector partitionGraph(ptr_vector &infos, +vector partitionGraph(vector> &infos, WorkQueue &work_queue, const NGHolder &g, EquivalenceType eq) { const size_t num_verts = infos.size(); @@ -349,28 +348,30 @@ vector partitionGraph(ptr_vector &infos, } // partition the graph based on CharReach - for (VertexInfo &vi : infos) { + for (auto &vi : infos) { + assert(vi); + ClassInfo::ClassDepth depth; if (eq == LEFT_EQUIVALENCE) { - depth = depths[vi.vert_index]; + depth = depths[vi->vert_index]; } else { - depth = rdepths[vi.vert_index]; + depth = rdepths[vi->vert_index]; } - ClassInfo ci(g, vi, depth, eq); + ClassInfo ci(g, *vi, depth, eq); auto ii = classinfomap.find(ci); if (ii == classinfomap.end()) { // vertex is in a new equivalence class by itself. unsigned eq_class = classes.size(); - vi.equivalence_class = eq_class; - classes.push_back({&vi}); + vi->equivalence_class = eq_class; + classes.push_back({vi.get()}); classinfomap.emplace(move(ci), eq_class); } else { // vertex is added to an existing class. unsigned eq_class = ii->second; - vi.equivalence_class = eq_class; - classes.at(eq_class).insert(&vi); + vi->equivalence_class = eq_class; + classes.at(eq_class).insert(vi.get()); // we now know that this particular class has more than one // vertex, so we add it to the work queue @@ -500,8 +501,9 @@ bool require_separate_eod_vertex(const VertexInfoSet &vert_infos, } static -void mergeClass(ptr_vector &infos, NGHolder &g, unsigned eq_class, - VertexInfoSet &cur_class_vertices, set *toRemove) { +void mergeClass(vector> &infos, NGHolder &g, + unsigned eq_class, VertexInfoSet &cur_class_vertices, + set *toRemove) { DEBUG_PRINTF("Replacing %zd vertices from equivalence class %u with a " "single vertex.\n", cur_class_vertices.size(), eq_class); @@ -529,9 +531,9 @@ void mergeClass(ptr_vector &infos, NGHolder &g, unsigned eq_class, * props */ g[new_v].reports.clear(); /* populated as we pull in succs */ - VertexInfo *new_vertex_info = new VertexInfo(new_v, g); // store this vertex in our global vertex list - infos.push_back(new_vertex_info); + infos.push_back(make_unique(new_v, g)); + VertexInfo *new_vertex_info = infos.back().get(); NFAVertex new_v_eod = NGHolder::null_vertex(); VertexInfo *new_vertex_info_eod = nullptr; @@ -539,8 +541,8 @@ void mergeClass(ptr_vector &infos, NGHolder &g, unsigned eq_class, if (require_separate_eod_vertex(cur_class_vertices, g)) { new_v_eod = clone_vertex(g, old_v); g[new_v_eod].reports.clear(); - new_vertex_info_eod = new VertexInfo(new_v_eod, g); - infos.push_back(new_vertex_info_eod); + infos.push_back(make_unique(new_v_eod, g)); + new_vertex_info_eod = infos.back().get(); } const auto &edgetops = (*cur_class_vertices.begin())->edge_tops; @@ -627,7 +629,8 @@ void mergeClass(ptr_vector &infos, NGHolder &g, unsigned eq_class, // report behaviour with a single vertex). static bool mergeEquivalentClasses(vector &classes, - ptr_vector &infos, NGHolder &g) { + vector> &infos, + NGHolder &g) { bool merged = false; set toRemove; @@ -657,7 +660,7 @@ bool reduceGraphEquivalences(NGHolder &g, EquivalenceType eq_type) { // get information on every vertex in the graph // new vertices are allocated here, and stored in infos - ptr_vector infos = getVertexInfos(g); + auto infos = getVertexInfos(g); // partition the graph auto classes = partitionGraph(infos, work_queue, g, eq_type);