5

I have my custom vertex and edge properties

namespace boost { 
    enum vertex_diagonal_t{vertex_diagonal = 999};
    BOOST_INSTALL_PROPERTY(vertex, diagonal);
}
namespace boost { 
    enum edge_dominance_t{edge_dominance = 998};
    BOOST_INSTALL_PROPERTY(edge, dominance);
}

I create my adjacency list with boost::property

typedef boost::adjacency_list<
      boost::listS, 
      boost::vecS,
      boost::bidirectionalS,
      boost::property<boost::vertex_diagonal_t, const khut::diagonal*>,
      boost::property<boost::edge_dominance_t,  float>
    > diagonal_dominance_graph;
typedef boost::property_map<diagonal_dominance_graph, boost::vertex_diagonal_t>::type diagonal_map_type;
typedef boost::property_map<diagonal_dominance_graph, boost::edge_dominance_t>::type  dominance_map_type;

Now I want to loop through my own containers and add vertex

diagonal_dominance_graph graph;
  for(storage_type::const_iterator i = repo_begining.begin(); i != repo_begining.end(); ++i){
    diagonal_dominance_graph::vertex_descriptor dia_vertex = boost::add_vertex(graph);

    //>> ?? HOW CAN I write Properties to dia_vertex HERE ?

    //boost::property<boost::vertex_diagonal_t, const khut::diagonal*> p;
    //boost::put(p, dia_vertex);

  }

What I am not getting is How can I set properties of a vertex through vertex_descriptor. may be I am missing a simple function.

Please I don't need anything that makes BGL even more complex, or something that cleans and restructures the types in my example. I just need to know how to read/write properties through a vertex_descriptor or edge_descriptor

Neel Basu
  • 12,638
  • 12
  • 82
  • 146

1 Answers1

6

You're using property lists: they're documented here.

So in your example, you'd use

diagonal_map_type  vp = get(boost::vertex_diagonal, graph);

using storage_type = std::vector<int>;
storage_type repo_begining(10);

for(storage_type::const_iterator i = repo_begining.begin(); i != repo_begining.end(); ++i) {
    diagonal_dominance_graph::vertex_descriptor dia_vertex = boost::add_vertex(graph);


    khut::diagonal* v = nullptr;
    boost::put(vp, dia_vertex, v);
}

// likewise for edges
dominance_map_type ep = get(boost::edge_dominance, graph);

See it Live On Coliru

Bundled Properties

The very same documentation page says:

NOTE: The Boost Graph Library supports two interchangeable methods for specifying interior properties: bundled properties and property lists. The former is easier to use and requires less effort, whereas the latter is compatible with older, broken compilers and is backward-compatible with Boost versions prior to 1.32.0. If you absolutely require these compatibility features, read on to learn about property lists. Otherwise, we strongly suggest that you read about the bundled properties mechanism.

Boost 1.32 dates over 10 years ago! So, I'd suggest bundled properties:

Live On Coliru

#include <boost/graph/adjacency_list.hpp>

namespace khut {
    struct diagonal { };

    struct MyVertexProperties {
        diagonal const* diag_ptr;
    };

    struct MyEdgeProperties {
        float dominance;
    };
}

typedef boost::adjacency_list<
      boost::listS, 
      boost::vecS,
      boost::bidirectionalS,
      khut::MyVertexProperties,
      khut::MyEdgeProperties
    > diagonal_dominance_graph;

#include <iostream>


int main() {
    using namespace boost;

    diagonal_dominance_graph g;

    khut::diagonal d1, d2;
    {
        auto v1 = add_vertex(khut::MyVertexProperties { &d1 }, g);
        auto v2 = add_vertex(khut::MyVertexProperties { &d2 }, g);

        /*auto e1 = */add_edge(v1, v2, khut::MyEdgeProperties { 42.31415926 }, g);
    }

    for(diagonal_dominance_graph::vertex_descriptor vd : make_iterator_range(vertices(g)))
        std::cout << "Is diagonal d1? " << std::boolalpha << (&d1 == g[vd].diag_ptr) << "\n";
    for(diagonal_dominance_graph::edge_descriptor ed : make_iterator_range(edges(g)))
        std::cout << "Edge dominance: " << g[ed].dominance << "\n";
}

Prints

Is diagonal d1? true
Is diagonal d1? false
Edge dominance: 42.3142
sehe
  • 374,641
  • 47
  • 450
  • 633
  • I am not using C++11. and yes I can use my own structs as bundled properties. But how to handle old `boost::property` thing ? – Neel Basu Feb 26 '15 at 19:19
  • (Also, c++ has been c++11 for some years now. The fact that I used c++11 in my sample shouldn't detract anything from the usefulness for you. Just modify what needs modification) – sehe Feb 26 '15 at 22:07
  • Yes I agree that using boost::property is more complex than doing it with your own structures. But I'd like to know how to do it with boost::property. and I've seen some previous answers in So that instead of focusing on actual questions tend to restructure the classes, and typedefs in question's example. that I wanted to avoid :) – Neel Basu Feb 27 '15 at 07:02
  • @NeelBasu I've updated the answer with the sample I had given in the comment. It answers the question now :) – sehe Feb 28 '15 at 23:26
  • Thanks. So you need to do `boost::get` before adding any vertex to the graph. – Neel Basu Mar 02 '15 at 11:05
  • Nope. You can use `boost::get` to get the property map you want to use. You can call it whenever needed – sehe Mar 02 '15 at 11:08
  • Yes so you can get a property map that may **not** have the target vertex of which you are trying to set properties at that moment. However once you add some vertex that gets automatically populated in *that* map. so you can access that using `boost::get` – Neel Basu Mar 02 '15 at 11:14
  • One more question. what will be the return type of `boost::get(&MyVertexProperties::diag_ptr, graph)` ? in case of Bundled properties ? – Neel Basu Mar 02 '15 at 11:39
  • @NeelBasu it's in the docs under ["Properties maps from bundled properties"](http://www.boost.org/doc/libs/1_57_0/libs/graph/doc/bundles.html) – sehe Mar 02 '15 at 12:16
  • No the type is not clearly written on that page. I've another property of enum type colour. and I figured out the following `typedef boost::property_map< khut::util::diagonal::reduction::diagonal_dominance_graph, khut::util::diagonal::reduction::colors khut::util::diagonal::reduction::edge_properties::*>::type edge_colours_map_type;` as working at last – Neel Basu Mar 02 '15 at 16:21
  • @NeelBasu Which is exactly what that page, clearly, states: _"With bundled properties, we can just pass a member pointer as the property for get"_ and even, explicitly (redundantly) _"The type of the returned property map is property_map::type or property_map::const_type, depending on whether the graph map is non-constant or constant."_. That's basically all the content of that heading, modulo the example. – sehe Mar 02 '15 at 17:43