Reputation: 334
I'm using the Boost graph library exploiting the following definitions
template <typename Vertex>
using graph = boost::adjacency_list<boost::listS,
boost::vecS,
boost::bidirectionalS,
Vertex>
template <typename Vertex>
using vertex = typename graph<Vertex>::vertex_descriptor;
where the template parameter Vertex
is employed to use the BGL with bundled properties.
I'm not that confident with boost at the moment and I'd like to understand if is there a way to get the begin()
and end()
iterators of the "bundled property list".
In other words, let's assume I have this struct
struct City
{
string name;
int population;
vector<int> zipcodes;
};
and I want to use it as template parameter for my graph. I know I can iterate over vertexes like this
(assuming g
is my adjacency list)
for(auto vd : boost::make_iterator_range(vertices(g))
{
auto v = g[*vd];
// do something with v
}
yet I'd like to do this
for(auto & v : some_iterator)
// v is a city ...
is there any way to do this ?
Upvotes: 1
Views: 278
Reputation: 392863
I've adapted my code from your now-deleted question to the more specific example. By now you already realize you are NOT in fact iterating vertices, but their bundles.
I suggest you use a transforming/indirected iterator adaptor. The easiest way I can think of is to use Boost Range Adaptors, specifically using transformed
:
#include <boost/graph/adjacency_list.hpp>
#include <boost/range/adaptors.hpp>
using boost::adaptors::transformed;
template <typename Vertex> struct Wrapper {
using graph = boost::adjacency_list<boost::listS, boost::vecS,
boost::bidirectionalS, Vertex>;
using vertex = typename graph::vertex_descriptor;
auto bundles() {
auto accessor = [map = get(boost::vertex_bundle, _g)](vertex v) -> auto& {
return map[v];
};
return vertices(_g) | transformed(accessor);
}
auto bundles() const {
auto accessor = [map = get(boost::vertex_bundle, _g)](vertex v) -> auto& {
return map[v];
};
return vertices(_g) | transformed(accessor);
}
private:
graph _g {5};
};
struct City {
std::string name;
int population;
std::vector<int> zipcodes;
};
static int id_gen = 0;
struct Sample2 { int id = ++id_gen; };
#include <iostream>
#include <iomanip>
int main() {
Wrapper<City> demo;
for (City& c : demo.bundles()) {
c.name = "name " + std::to_string(rand() % 100);
c.population = rand() % 128 * 190'000;
c.zipcodes = {1234, 2345};
}
auto const& const_ref = demo;
for (City const& c : const_ref.bundles()) {
std::cout << std::quoted(c.name) << ", population " << c.population << "\n";
}
}
Prints
"name 83", population 13300000
"name 77", population 21850000
"name 93", population 24130000
"name 86", population 20520000
"name 49", population 14630000
Upvotes: 1