How do I "specialize boost::property_map directly"?  This might be the key to the problem.  


My current shot in the dark is to try:

template<>
struct boost::property_map<ImplicitRingGraph, boost::edge_weight_t> {
typedef EdgeWeightMap type;
typedef EdgeWeightMap const_type;
};

which gives me the error

implicit.hpp:116: error: specialization of ‘template<class Graph, class Property> struct boost::property_map’ in different namespace
/opt/local/include/boost/graph/properties.hpp:244: error:   from definition of ‘template<class Graph, class Property> struct boost::property_map’



On Thu, Jun 24, 2010 at 5:22 PM, W.P. McNeill <billmcn@gmail.com> wrote:
Thanks for your help.  Getting a little closer.

Once I get the edge properties working I'll look at traversal concepts other than AdjacencyGraphs.  So far this has been the easy part for me.

I have been looking at the grid graph, but I couldn't figure out how to add weights to the edges of a grid graph.  I can't find a simple example of an implicit graph with properties.  (Which is why I'm trying to write one now.)

What do you mean by "Write an empty struct that inherits from all of the ones that you are going to model"?  I didn't think there were concept base classes to inherit from.

Changing the property typedef in the implicit graph struct to 

    typedef boost::property<boost::edge_weight_t, float> edge_property_type;

making the get() functions take constant graph object references, and checking against the ReadablePropertyGraphConcept improves the compilation.  I now no longer have pages of errors, which makes me think I'm on the right track.

I still have two errors, both of which I'm confused about.

1. graph_concepts.hpp:390: error: conversion from ‘EdgeWeightMap’ to non-scalar type ‘boost::typed_identity_property_map<size_t>’ requested

This is the same as before.  This error makes me feel like I've got the wrong return value for one of my get() functions, but after double-checking they look right.


2. property_map.hpp:318: error: no match for ‘operator[]’ in ‘(const boost::typed_identity_property_map<size_t>&)((const boost::typed_identity_property_map<size_t>*)(& pa))[k]’

I didn't think any concept required operator[], so I'm not sure why this is happening.  Line 318 is inside the inline get() function of the put_get_helper(), but I'm not using put_get_helper() in my code.


On Thu, Jun 24, 2010 at 1:25 PM, W.P. McNeill <billmcn@gmail.com> wrote:
I am writing a stripped-down implicit graph that I hope can be a useful template for others working with the Boost Graph library.  The project is hosted at github.  Excerpts from the source are in this email, and the full source is viewable online at http://github.com/wpm/Boost-Implicit-Graph-Example.

I am currently getting errors from the concept checking code which I don't understand and am looking for suggestions as to what I am doing wrong.

This is graph class.

struct ImplicitRingGraph {
ImplicitRingGraph(size_t n):n(n) {};

// Graph concept
typedef size_t vertex_descriptor;
typedef boost::undirected_tag directed_category;
typedef boost::disallow_parallel_edge_tag edge_parallel_category;
typedef boost::adjacency_graph_tag traversal_category;

// AdjacencyGraph concept
typedef RingAdjacencyIterator adjacency_iterator;

// PropertyGraph concept
typedef boost::edge_weight_t edge_property_type;

// Additional types required by the concept-checking code.
typedef std::pair<vertex_descriptor, vertex_descriptor> edge_descriptor;
typedef size_t vertices_size_type;
typedef size_t edges_size_type;
typedef size_t degree_size_type;
typedef void out_edge_iterator;
typedef void in_edge_iterator;
typedef void vertex_iterator;
typedef void edge_iterator;

// The number of vertices in the graph.
size_t n;
};
typedef boost::graph_traits<ImplicitRingGraph>::edge_descriptor Edge;


I want the edges to have weights, so it models the PropertyGraph concept.  The following functions implement the valid expressions.


EdgeWeightMap get(boost::edge_weight_t, ImplicitRingGraph& g) {
return EdgeWeightMap();
}


EdgeWeight get(boost::edge_weight_t tag, ImplicitRingGraph& g, Edge e) {
return get(tag, g)[e];
}


(Definitions of Edge, EdgeWeight, and EdgeWeightMap are visible online.  I also define an adjacency iterator that is not shown here.)

I can write code that reads an edge weight.

ImplicitRingGraph g(5); 
EdgeWeightMap m = get(boost::edge_weight, g);
boost::graph_traits<ImplicitRingGraph>::edge_descriptor e(0, 1);
EdgeWeight w = get(boost::edge_weight, g, e);

However I get errors when I try to use the concept checking code.

function_requires< 
PropertyGraphConcept<ImplicitRingGraph,
Edge,
edge_weight_t>
>();


The full error printout is huge, but there appear to be three relevant problems.

1. graph_concepts.hpp:406: error: conversion from ‘EdgeWeightMap’ to non-scalar type ‘boost::typed_identity_property_map<size_t>’ requested

The line in graph_concepts.hpp is

        Map pmap = get(Property(), g);

inside the concept check for PropertyGraph.  It looks to me like I have a function to handle this.  I don't understand where boost::typed_identity_property_map<size_t> is coming from.


2. graph_concepts.hpp:408: error: no matching function for call to ‘put(boost::edge_weight_t, ImplicitRingGraph&, Edge&, size_t&)’

I didn't write any put() functions so I understand why I'm getting this.  However, I would like the edge weights to be readable but not writeable (myEdgeWeightMap models a ReadablePropertyMap), and I can't figure out how to specify the read-only property in the graph defintion.


3. graph_concepts.hpp:390: error: no matching function for call to ‘get(boost::edge_weight_t, const ImplicitRingGraph&)’
graph_concepts.hpp:391: error: no matching function for call to ‘get(boost::edge_weight_t, const ImplicitRingGraph&, Edge&)’

Should I create functions identical to what  I've already written, except with constant modifiers in front of the graph type?  That feels like redundant source.


Thanks for any help you can give.  Hopefully, a completed version of this example would be a useful resource for other BGL developers.