#include <map>
#include <string>
#include <vector>
#include <iostream>
#include <boost/graph/adjacency_list.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/graph/filtered_graph.hpp>
#include <boost/graph/graph_utility.hpp>
template <typename F> struct EdgeProperty {
F features;
EdgeProperty() = default;
EdgeProperty(const F& f) : features(f) {}
};
template <typename EM, typename F>
struct filtered_edge {
F filters;
EM emap;
filtered_edge() = default;
filtered_edge(EM emap_, F filters_) : emap(emap_), filters(filters_) {}
template <typename E> bool operator()(const E& e) {
auto e_prop = get(emap, e);
auto e_feat = e_prop.features;
for (auto it: e_feat) {
if (get(e_feat, it.first) != it.second) {
return false;
}
}
return true;
}
};
template<typename G, typename F> G get_filtered_graph(G& g, F& filters) {
typedef filtered_edge<boost::property_map<G, EdgeProperty<F> >, F> filter_fn;
filter_fn filter{get(&EdgeProperty<F>::features, g), filters};
boost::filtered_graph<G, filter_fn> fg(g, filter);
return fg;
}
typedef std::map<std::string, int> dict;
typedef boost::adjacency_list<
boost::vecS,
boost::vecS,
boost::directedS,
boost::no_property,
EdgeProperty<dict>
> Graph;
Graph create_empty_graph() noexcept {
return {};
}
int main() {
const char* name = "ABCDE";
auto g = create_empty_graph();
auto v0 = boost::add_vertex(g);
auto v1 = boost::add_vertex(g);
auto v2 = boost::add_vertex(g);
dict d01;
d01["a"] = 1;
dict d12;
d12["b"] = 1;
dict fil;
fil["a"] = 1;
auto ep01 = EdgeProperty<dict>{
dict{}
};
boost::add_edge(v0, v1, d01, g);
boost::add_edge(v1, v2, d12, g);
std::cout << "Before filter" << std::endl;
boost::print_graph(g, name);
auto fg = get_filtered_graph(g, fil);
std::cout << "After filter" << std::endl;
boost::print_graph(fg, name);
Graph ga;
}