Commit 31137b5b authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

Fix bug with edge filtering when inversion changes

This fixes issue #279.
parent df06590b
Pipeline #121 passed with stage
......@@ -75,7 +75,7 @@ boost::any check_reverse(const Graph& g, bool reverse, GraphInterface& gi)
reverse_graph_t;
reverse_graph_t rg(g);
return std::ref(*retrieve_graph_view(gi, rg).get());
return std::ref(*retrieve_graph_view(gi, rg));
}
return boost::any(std::ref(const_cast<Graph&>(g)));
......@@ -94,46 +94,44 @@ boost::any check_directed(const Graph &g, bool reverse, bool directed,
typedef UndirectedAdaptor<Graph> ug_t;
ug_t ug(g);
return std::ref(*retrieve_graph_view(gi, ug).get());
return std::ref(*retrieve_graph_view(gi, ug));
};
// this will check whether a graph is filtered and return the proper view
// encapsulated
template <class Graph, class EdgeFilter, class VertexFilter>
boost::any
check_filtered(const Graph &g, const EdgeFilter& edge_filter,
check_filtered(const Graph& g, const EdgeFilter& edge_filter,
const bool& e_invert, bool e_active, size_t max_eindex,
const VertexFilter& vertex_filter, const bool& v_invert,
bool v_active, GraphInterface& gi, bool reverse, bool directed)
{
#ifndef NO_GRAPH_FILTERING
MaskFilter<EdgeFilter> e_filter(const_cast<EdgeFilter&>(edge_filter),
e_invert);
MaskFilter<VertexFilter> v_filter(const_cast<VertexFilter&>(vertex_filter),
v_invert);
if (e_active)
if (e_active || v_active)
{
if (!v_active)
throw GraphException("Edge filter is active but vertex filter is not. This is a bug.");
MaskFilter<EdgeFilter>
e_filter(const_cast<EdgeFilter&>(edge_filter),
const_cast<bool&>(e_invert));
MaskFilter<VertexFilter>
v_filter(const_cast<VertexFilter&>(vertex_filter),
const_cast<bool&>(v_invert));
if (max_eindex > 0)
edge_filter.reserve(max_eindex);
if (num_vertices(g) > 0)
vertex_filter.reserve(num_vertices(g));
typedef filtered_graph<Graph, MaskFilter<EdgeFilter>,
MaskFilter<VertexFilter> > fg_t;
fg_t init(g, e_filter, v_filter);
fg_t& fg = *retrieve_graph_view(gi, init).get();
fg.m_edge_pred = e_filter;
fg.m_vertex_pred = v_filter;
fg_t& fg = *retrieve_graph_view(gi, init);
return check_directed(fg, reverse, directed, gi);
}
else
{
if (v_active)
throw GraphException("Vertex filter is active but edge filter is not. This is a bug.");
return check_directed(g, reverse, directed, gi);
}
#else
......
......@@ -139,26 +139,26 @@ class MaskFilter
public:
typedef typename boost::property_traits<DescriptorProperty>::value_type value_t;
MaskFilter(){}
MaskFilter(DescriptorProperty& filtered_property, bool invert)
: _filtered_property(&filtered_property), _invert(invert) {}
MaskFilter(DescriptorProperty& filtered_property, bool& invert)
: _filtered_property(&filtered_property), _invert(&invert) {}
template <class Descriptor>
inline bool operator() (Descriptor&& d) const
{
// ignore if masked
return get(*_filtered_property, std::forward<Descriptor>(d)) ^ _invert;
return get(*_filtered_property, std::forward<Descriptor>(d)) ^ *_invert;
// This is a critical section. It will be called for every vertex or
// edge in the graph, every time they're iterated through.
}
DescriptorProperty& get_filter() { return *_filtered_property; }
bool is_inverted() { return _invert; }
bool is_inverted() { return *_invert; }
private:
DescriptorProperty* _filtered_property;
bool _invert;
bool* _invert;
};
......@@ -530,12 +530,13 @@ retrieve_graph_view(GraphInterface& gi, Graph& init)
std::shared_ptr<g_t> new_g =
get_graph_ptr<g_t>(gi, init,
std::is_same<g_t, GraphInterface::multigraph_t>());
gptr = &new_g;
gview = new_g;
return new_g;
}
return *gptr;
}
} //graph_tool namespace
// Overload add_vertex() and add_edge() to filtered graphs, so that the new
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment