Am I missing something? Are my expectations incorrect? Is this actually a bug (or two)? At the bottom is a decently small example that fails for me (some function bodies excised for brevity -- my concerns are pre-link). Is there a way to work around this without making my graph into a model of VertexAndEdgeListGraph? Since my graph is infinite, this would hardly seem sensible.
Thanks in advance for any assistance. Incidentally, if anyone's interested to see a working example of astar_search_no_init over an implicit graph, I'd be happy to clean up the code a little and post it.
#include <list>
#include <map>
#include <set>
#include <utility>
#include <boost/graph/filtered_graph.hpp>
#include <boost/graph/graph_concepts.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/operators.hpp>
using namespace boost;
using namespace std;
namespace Direction
{
enum id
{
MIN = 0,
N = MIN, S, E, W, NW, NE, SE, SW, NONE,
NUM_DIRECTIONS
};
}
struct XY : public boost::additive<XY,
boost::totally_ordered<XY,
boost::equivalent<XY>
> >
{
typedef int X;
typedef int Y;
XY(X x = 0, Y y = 0);
XY & operator=(XY const& that);
XY & operator+=(XY const& that);
bool operator<(XY const& that) const;
X x;
Y y;
};
std::ostream & operator<<(std::ostream & os, XY const& xy);
struct neighbor_iterator;
/*
* Model of:
* * Graph
* * IncidenceGraph
*/
struct XYGraph
{
XYGraph();
// Graph concept requirements
typedef XY vertex_descriptor;
typedef std::pair<XY, XY> edge_descriptor;
typedef undirected_tag directed_category;
typedef disallow_parallel_edge_tag edge_parallel_category;
typedef incidence_graph_tag traversal_category;
// IncidenceGraph concept requirements
typedef neighbor_iterator out_edge_iterator;
typedef int degree_size_type;
};
// IncidenceGraph concept requirements
std::pair<XYGraph::out_edge_iterator,
XYGraph::out_edge_iterator> out_edges(XYGraph::vertex_descriptor v, XYGraph const& g);
XYGraph::degree_size_type out_degree(XYGraph::vertex_descriptor v, XYGraph const& g);
XYGraph::vertex_descriptor source(XYGraph::edge_descriptor e, XYGraph const& g);
XYGraph::vertex_descriptor target(XYGraph::edge_descriptor e, XYGraph const& g);
// Iterator
struct neighbor_iterator :
public boost::forward_iterator_helper<neighbor_iterator, XY, std::ptrdiff_t, XY *, XY>
{
public:
neighbor_iterator();
neighbor_iterator(XY xy, Direction::id direction);
neighbor_iterator & operator=(neighbor_iterator const& that);
std::pair<XY,XY> operator*() const;
void operator++();
bool operator==(neighbor_iterator const& that) const;
};
namespace boost
{
template <> struct graph_traits<XYGraph>
{
typedef XYGraph G;
typedef G::vertex_descriptor vertex_descriptor;
typedef G::edge_descriptor edge_descriptor;
typedef G::out_edge_iterator out_edge_iterator;
typedef G::directed_category directed_category;
typedef G::edge_parallel_category edge_parallel_category;
typedef G::traversal_category traversal_category;
typedef G::degree_size_type degree_size_type;
// Shouldn't have to do this!
typedef void in_edge_iterator;
typedef void vertex_iterator;
typedef void vertices_size_type;
typedef void edge_iterator;
typedef void edges_size_type;
};
}
struct orthogonal_only
{
typedef pair<XY,XY> Edge;
bool operator()(Edge const& edge)
{
return edge.first.x == edge.second.x || edge.first.y == edge.second.y;
}
};
int main(int argc, char **argv)
{
BOOST_CONCEPT_ASSERT((IncidenceGraphConcept<XYGraph>));
// This fails
BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< filtered_graph<XYGraph, orthogonal_only> >));
return 0;
}