From 741b96e9131a98177d0dfef3fcedb5980d76c6d7 Mon Sep 17 00:00:00 2001 From: Jeremy Siek Date: Thu, 21 Sep 2000 03:31:19 +0000 Subject: [PATCH] property accessor interface changes [SVN r7752] --- include/boost/graph/breadth_first_search.hpp | 3 +- include/boost/graph/connected_components.hpp | 19 +- .../boost/graph/cuthill_mckee_ordering.hpp | 25 ++- include/boost/graph/depth_first_search.hpp | 2 +- include/boost/graph/detail/adjacency_list.hpp | 113 +++++------ .../boost/graph/detail/self_avoiding_walk.hpp | 12 +- .../boost/graph/dijkstra_shortest_paths.hpp | 43 ++-- include/boost/graph/graph_concepts.hpp | 113 ++++------- include/boost/graph/graph_utility.hpp | 18 +- .../graph/kruskal_minimum_spanning_tree.hpp | 2 +- .../graph/prim_minimum_spanning_tree.hpp | 10 +- include/boost/graph/properties.hpp | 144 +++++++++---- include/boost/graph/stanford_graph.hpp | 189 +++++++++++------- include/boost/graph/topological_sort.hpp | 2 +- include/boost/graph/transpose_graph.hpp | 2 +- include/boost/graph/uniform_cost_search.hpp | 9 +- 16 files changed, 390 insertions(+), 316 deletions(-) diff --git a/include/boost/graph/breadth_first_search.hpp b/include/boost/graph/breadth_first_search.hpp index 0458d6fa..ec77a7ff 100644 --- a/include/boost/graph/breadth_first_search.hpp +++ b/include/boost/graph/breadth_first_search.hpp @@ -61,8 +61,7 @@ namespace boost { typename graph_traits::vertex_descriptor s, BFSVisitor vis) { - breadth_first_search(g, s, vis, - get_vertex_property_accessor(g, vertex_color())); + breadth_first_search(g, s, vis, get(vertex_color(), g)); } // Variant (2) diff --git a/include/boost/graph/connected_components.hpp b/include/boost/graph/connected_components.hpp index 02c94b97..b65981b0 100644 --- a/include/boost/graph/connected_components.hpp +++ b/include/boost/graph/connected_components.hpp @@ -208,9 +208,8 @@ namespace boost { connected_components(Graph& G, DFSVisitor v, Components c, undirected_tag) { - return connected_components(G, v, c, - get_vertex_property_accessor(G, vertex_color()), - undirected_tag()); + return connected_components(G, v, c, get(vertex_color(), G), + undirected_tag()); } template @@ -219,10 +218,10 @@ namespace boost { directed_tag) { return connected_components(G, v, c, - get_vertex_property_accessor(G, vertex_discover_time()), - get_vertex_property_accessor(G, vertex_finish_time()), - get_vertex_property_accessor(G, vertex_color()), - directed_tag()); + get(vertex_discover_time(), G), + get(vertex_finish_time(), G), + get(vertex_color(), G), + directed_tag()); } template ::vertex_descriptor Vertex; return connected_components(G, v, c, - get_vertex_property_accessor(G, vertex_discover_time()), - get_vertex_property_accessor(G, vertex_finish_time()), - color, directed_tag()); + get(vertex_discover_time(), G), + get(vertex_finish_time(), G), + color, directed_tag()); } } // namespace detail diff --git a/include/boost/graph/cuthill_mckee_ordering.hpp b/include/boost/graph/cuthill_mckee_ordering.hpp index 2f6b90f3..b14e1031 100644 --- a/include/boost/graph/cuthill_mckee_ordering.hpp +++ b/include/boost/graph/cuthill_mckee_ordering.hpp @@ -68,14 +68,14 @@ namespace boost { inline void pop() { if ( !_size ) - Qsize = base::size(); + Qsize = base::size(); base::pop(); if ( _size == Qsize-1 ) { - _size = 0; - ++eccen; + _size = 0; + ++eccen; } else - ++_size; + ++_size; } @@ -120,7 +120,7 @@ namespace boost { template Vertex pseudo_peripheral_pair(Graph& G, const Vertex& u, int& ecc, - Color color, Degree degree) + Color color, Degree degree) { typename property_traits::value_type c = get(color, u); @@ -185,9 +185,9 @@ namespace boost { class Color, class Degree > inline void cuthill_mckee_ordering(Graph& G, - Vertex s, - OutputIterator inverse_permutation, - Color color, Degree degree) + Vertex s, + OutputIterator inverse_permutation, + Color color, Degree degree) { typedef typename property_traits::value_type DS; typename property_traits::value_type c = get(color, s); @@ -208,7 +208,7 @@ namespace boost { class Color, class Degree > inline void cuthill_mckee_ordering(Graph& G, OutputIterator inverse_permutation, - Color color, Degree degree) + Color color, Degree degree) { typedef typename boost::graph_traits::vertex_descriptor Vertex; typedef typename boost::graph_traits::vertex_iterator VerIter; @@ -224,11 +224,11 @@ namespace boost { template < class Graph, class OutputIterator, class Color > inline void cuthill_mckee_ordering(Graph& G, OutputIterator inverse_permutation, - Color color) + Color color) { typedef typename boost::graph_traits::vertex_descriptor Vertex; cuthill_mckee_ordering(G, inverse_permutation, color, - get_vertex_property_accessor(G, vertex_degree())); + get(vertex_degree(), G)); } template @@ -236,8 +236,7 @@ namespace boost { cuthill_mckee_ordering(Graph& G, OutputIterator inverse_permutation) { typedef typename boost::graph_traits::vertex_descriptor Vertex; - cuthill_mckee_ordering(G, inverse_permutation, - get_vertex_property_accessor(G, vertex_color())); + cuthill_mckee_ordering(G, inverse_permutation, get(vertex_color(), G)); } } /*namespace matrix_ordering*/ diff --git a/include/boost/graph/depth_first_search.hpp b/include/boost/graph/depth_first_search.hpp index a189585b..156115d6 100644 --- a/include/boost/graph/depth_first_search.hpp +++ b/include/boost/graph/depth_first_search.hpp @@ -61,7 +61,7 @@ namespace boost { depth_first_search(Graph& g, DFSVisitor v) { typedef typename graph_traits::vertex_descriptor Vertex; - depth_first_search(g, v, get_vertex_property_accessor(g, vertex_color())); + depth_first_search(g, v, get(vertex_color(), g)); } // Variant (2) diff --git a/include/boost/graph/detail/adjacency_list.hpp b/include/boost/graph/detail/adjacency_list.hpp index 115dc677..ca71e9ca 100644 --- a/include/boost/graph/detail/adjacency_list.hpp +++ b/include/boost/graph/detail/adjacency_list.hpp @@ -41,6 +41,9 @@ // REVISION HISTORY: // // $Log$ +// Revision 1.6 2000/09/21 03:31:19 jsiek +// property accessor interface changes +// // Revision 1.5 2000/09/20 19:30:09 jsiek // changed the name of the property tags: name_tag -> vertex_name, etc. // @@ -902,69 +905,63 @@ namespace boost { return g.in_edge_list(u).size(); } - // The get_edge_property() and get_vertex_property() functions - // have to be defined outside the class definition because - // of a VC++ bug triggered by the need for Tag to be templated - // independently of the adj_list_helper class. + namespace detail { + template + inline + typename boost::property_map::type + get(adj_list_helper&, Property, + boost::edge_property_tag) { + typedef typename Config::graph_type Graph; + typedef typename boost::property_map::type PA; + return PA(); + } + template + inline + typename boost::property_map::const_type + get(const adj_list_helper&, Property, + boost::edge_property_tag) { + typedef typename Config::graph_type Graph; + typedef typename boost::property_map::const_type PA; + return PA(); + } - template - inline - typename boost::edge_property_accessor::type - get_edge_property_accessor(const adj_list_helper&, Tag) { - typedef typename Config::graph_type Graph; - typedef typename boost::edge_property_accessor::type PA; - return PA(); - } + template + inline + typename boost::property_map::type + get(adj_list_helper& g, Property, + boost::vertex_property_tag) { + typedef typename Config::graph_type Graph; + typedef typename boost::property_map::type PA; + return PA(static_cast(g)); + } + template + inline + typename boost::property_map::const_type + get(const adj_list_helper& g, Property, + boost::vertex_property_tag) { + typedef typename Config::graph_type Graph; + typedef typename boost::property_map::const_type PA; + return PA(static_cast(g)); + } + } // namespace detail - template + template inline - typename boost::edge_property_accessor::type - get_edge_property(const adj_list_helper&, Tag) { - typedef typename Config::graph_type Graph; - typedef typename boost::edge_property_accessor::type PA; - return PA(); + typename boost::property_map::type + get(Property t, adj_list_helper& g) { + typedef typename Property::kind Kind; + return detail::get(g, t, Kind()); } - - template + template inline - typename boost::vertex_property_accessor::type - get_vertex_property_accessor(adj_list_helper& g, Tag) { - typedef typename Config::graph_type Graph; - typedef typename boost::vertex_property_accessor::type PA; - return PA(static_cast(g)); - } - template - inline - typename boost::vertex_property_accessor::const_type - get_vertex_property_accessor(const adj_list_helper& g, Tag) { - typedef typename Config::graph_type Graph; - typedef typename boost::vertex_property_accessor - ::const_type PA; - return PA(static_cast(g)); - } - - template - inline - typename boost::vertex_property_accessor::type - get_vertex_property(adj_list_helper& g, Tag) { - typedef typename Config::graph_type Graph; - typedef typename boost::vertex_property_accessor::type PA; - return PA(static_cast(g)); - } - template - inline - typename boost::vertex_property_accessor::const_type - get_vertex_property(const adj_list_helper& g, Tag) { - typedef typename Config::graph_type Graph; - typedef typename boost::vertex_property_accessor - ::const_type PA; - return PA(static_cast(g)); + typename boost::property_map::const_type + get(Property t, const adj_list_helper& g) { + typedef typename Property::kind Kind; + return detail::get(g, t, Kind()); } //========================================================================= diff --git a/include/boost/graph/detail/self_avoiding_walk.hpp b/include/boost/graph/detail/self_avoiding_walk.hpp index 220a7f31..3d63c24c 100644 --- a/include/boost/graph/detail/self_avoiding_walk.hpp +++ b/include/boost/graph/detail/self_avoiding_walk.hpp @@ -412,15 +412,9 @@ namespace boost { template inline - SAW_visitor< typename detail::property_accessor_adaptor::type, - HList, - typename detail::property_accessor_adaptor::type > - visit_SAW( Triangle t, HList hl, Iterator i) { - typedef typename detail::property_accessor_adaptor::type - TriangleD; - typedef typename detail::property_accessor_adaptor::type - IteratorD; - return SAW_visitor(t, hl, i); + SAW_visitor + visit_SAW(Triangle t, HList hl, Iterator i) { + return SAW_visitor(t, hl, i); } template diff --git a/include/boost/graph/dijkstra_shortest_paths.hpp b/include/boost/graph/dijkstra_shortest_paths.hpp index ac3ba425..ab8be1fd 100644 --- a/include/boost/graph/dijkstra_shortest_paths.hpp +++ b/include/boost/graph/dijkstra_shortest_paths.hpp @@ -36,39 +36,41 @@ namespace boost { // Variant (1) template inline void - dijkstra_shortest_paths(VertexListGraph& g, - typename graph_traits::vertex_descriptor s) + dijkstra_shortest_paths + (VertexListGraph& g, + typename graph_traits::vertex_descriptor s) { - dijkstra_shortest_paths(g, s, - get_vertex_property_accessor(G, vertex_distance())); + dijkstra_shortest_paths(g, s, get(vertex_distance(), g)); } // Variant (2) template inline void - dijkstra_shortest_paths(VertexListGraph& g, - typename graph_traits::vertex_descriptor s, - DistancePA d) + dijkstra_shortest_paths + (VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + DistancePA d) { null_visitor null_vis; dijkstra_shortest_paths(g, s, d, - get_edge_property_accessor(g, edge_weight()), - get_vertex_property_accessor(g, vertex_color()), - get_vertex_property_accessor(g, vertex_index()), + get(edge_weight(), g), + get(vertex_color(), g), + get(vertex_index(), g), make_ucs_visitor(null_vis)); } // Variant (3) template inline void - dijkstra_shortest_paths(VertexListGraph& g, - typename graph_traits::vertex_descriptor s, - DistancePA d, UniformCostVisitor visit) + dijkstra_shortest_paths + (VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + DistancePA d, UniformCostVisitor visit) { dijkstra_shortest_paths(g, s, d, - get_edge_property_accessor(g, edge_weight()), - get_vertex_property_accessor(g, vertex_color()), - get_vertex_property_accessor(g, vertex_index()), + get(edge_weight(), g), + get(vertex_color(), g), + get(vertex_index(), g), visit); } @@ -76,10 +78,11 @@ namespace boost { template inline void - dijkstra_shortest_paths(VertexListGraph& g, - typename graph_traits::vertex_descriptor s, - DistancePA distance, WeightPA weight, ColorPA color, ID_PA id, - UniformCostVisitor vis) + dijkstra_shortest_paths + (VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + DistancePA distance, WeightPA weight, ColorPA color, ID_PA id, + UniformCostVisitor vis) { typedef typename property_traits::value_type D; typedef typename property_traits::value_type W; diff --git a/include/boost/graph/graph_concepts.hpp b/include/boost/graph/graph_concepts.hpp index d0e563a4..062e3437 100644 --- a/include/boost/graph/graph_concepts.hpp +++ b/include/boost/graph/graph_concepts.hpp @@ -253,107 +253,78 @@ namespace boost { G g; }; - template + template + struct PropertyGraph_concept + { + typedef typename property_map::type PMap; + typedef typename property_map::const_type const_PMap; + void constraints() { + REQUIRE(G, Graph); + REQUIRE2(PMap, X, ReadWritePropertyAccessor); + REQUIRE2(const_PMap, X, ReadablePropertyAccessor); + + PMap pmap = get(Property(), g); +#if 0 + pval = get(Property(), g, x); + put(Property(), g, x, pval); +#endif + ignore_unused_variable_warning(pmap); + } + void const_constraints(const G& g) { + const_PMap pmap = get(Property(), g); +#if 0 + pval = get(Property(), g, x); +#endif + ignore_unused_variable_warning(pmap); + } + G g; + X x; + typename property_traits::value_type pval; + }; + +#if 0 + template struct VertexPropertyGraph_concept { typedef typename graph_traits::vertex_descriptor Vertex; - typedef typename vertex_property_accessor::type PA; - typedef typename vertex_property_accessor::const_type const_PA; + typedef typename property_map::type PA; + typedef typename property_map::const_type const_PA; void constraints() { REQUIRE(G, Graph); REQUIRE2(PA, Vertex, ReadWritePropertyAccessor); REQUIRE2(const_PA, Vertex, ReadablePropertyAccessor); - PA pa = get_vertex_property_accessor(g, Tag()); + PA pa = get(Property(), g); ignore_unused_variable_warning(pa); } void const_constraints(const G& g) { - const_PA pa = get_vertex_property_accessor(g, Tag()); + const_PA pa = get(Property(), g); ignore_unused_variable_warning(pa); } G g; }; - template + template struct EdgePropertyGraph_concept { typedef typename graph_traits::edge_descriptor Edge; - typedef typename edge_property_accessor::type PA; - typedef typename edge_property_accessor::const_type const_PA; + typedef typename property_map::type PA; + typedef typename property_map::const_type const_PA; void constraints() { REQUIRE(G, Graph); REQUIRE2(PA, Edge, ReadWritePropertyAccessor); REQUIRE2(const_PA, Edge, ReadablePropertyAccessor); - PA pa = get_edge_property_accessor(g, Tag()); + PA pa = get(Property(), g); } void const_constraints(const G& g) { - const_PA pa = get_edge_property_accessor(g, Tag()); + const_PA pa = get(Property(), g); } G g; }; - -#if 0 - struct initialize_shortest_paths { - void operator()(Vertex v) { - - } - }; - - dijkstra_shortest_paths( - make_visitor( - make_pair(initialize_shortest_paths(), - initialize_vertex_tag()), - make_pair(predecessor_recorder(p.begin()), - explore_edge_tag()) - ) - ); - - bellman_ford_shortest_paths( - make_visitor( - make_pair(initialize_shortest_paths(), - initialize_vertex_tag()), - make_pair(predecessor_recorder(p.begin()), - relax_edge_tag()) - ) - ); - /* - Advantages: - 1. visitor functionality separate from callback event point - 2. unifies UserVisitor edge category stuff with rest of visitor - callback events - 3. easy to extend to different algorithms. Each algorithm says - which tags it will invoke. - - Disadvantages: - 1. more complicated for user - 2. deeper template nesting, perhaps compiler problems - - */ - - - // T is a Vertex or Edge depending on the Tag - template - struct Visitor_concept { - void constraints () { - visitor(x, g, tag); - } - Visitor visitor; - Graph g; - T x; - Tag tag; - }; - - template - struct controling_visitor { - template - void visit( ) { - - } - VisitorList m_list; - }; #endif +#if 0 template struct Visitor_concept { @@ -401,8 +372,10 @@ namespace boost { REQUIRE4(V2, Vertex, Edge, Graph, UserVisitor); } }; +#endif #endif + // This needs to move out of the graph library template struct Buffer_concept { diff --git a/include/boost/graph/graph_utility.hpp b/include/boost/graph/graph_utility.hpp index 21d9c0e3..55bd6baa 100644 --- a/include/boost/graph/graph_utility.hpp +++ b/include/boost/graph/graph_utility.hpp @@ -117,26 +117,26 @@ namespace boost { } template void print_graph(const IncidenceGraph& G) { - print_graph(G, get_vertex_property_accessor(G, vertex_index())); + print_graph(G, get(vertex_index(), G)); } template void print_edges(const EdgeListGraph& G, Name name) { - typename graph_traits::edge_iterator ei,ei_end; - for (boost::tie(ei,ei_end) = edges(G); ei != ei_end; ++ei) - std::cout << "(" << get(name,source(*ei,G)) - << "," << get(name,target(*ei,G)) << ") "; + typename graph_traits::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(G); ei != ei_end; ++ei) + std::cout << "(" << get(name, source(*ei, G)) + << "," << get(name, target(*ei, G)) << ") "; std::cout << std::endl; } template void print_edges2(const EdgeListGraph& G, VertexName vname, EdgeName ename) { - typename graph_traits::edge_iterator ei,ei_end; - for (boost::tie(ei,ei_end) = edges(G); ei != ei_end; ++ei) - std::cout << get(ename,*ei) << "(" << get(vname,source(*ei,G)) - << "," << get(vname,target(*ei,G)) << ") "; + typename graph_traits::edge_iterator ei, ei_end; + for (boost::tie(ei, ei_end) = edges(G); ei != ei_end; ++ei) + std::cout << get(ename, *ei) << "(" << get(vname, source(*ei, G)) + << "," << get(vname, target(*ei, G)) << ") "; std::cout << std::endl; } diff --git a/include/boost/graph/kruskal_minimum_spanning_tree.hpp b/include/boost/graph/kruskal_minimum_spanning_tree.hpp index df34fe51..7e42f9e5 100644 --- a/include/boost/graph/kruskal_minimum_spanning_tree.hpp +++ b/include/boost/graph/kruskal_minimum_spanning_tree.hpp @@ -64,7 +64,7 @@ namespace boost { { typedef typename graph_traits::edge_descriptor Edge; kruskal_minimum_spanning_tree(G, spanning_tree_edges, rank, parent, - get_edge_property_accessor(G, edge_weight())); + get(edge_weight(), G)); } // Variant (2) diff --git a/include/boost/graph/prim_minimum_spanning_tree.hpp b/include/boost/graph/prim_minimum_spanning_tree.hpp index eda45806..2ba17251 100644 --- a/include/boost/graph/prim_minimum_spanning_tree.hpp +++ b/include/boost/graph/prim_minimum_spanning_tree.hpp @@ -48,8 +48,7 @@ namespace boost { inline void prim_minimum_spanning_tree(Graph& G, Vertex s) { - prim_minimum_spanning_tree(G, s, - get_vertex_property_accessor(G, vertex_distance())); + prim_minimum_spanning_tree(G, s, get(vertex_distance(), G)); } // Variant (2) @@ -67,10 +66,9 @@ namespace boost { prim_minimum_spanning_tree(Graph& G, Vertex s, Distance d, UniformCostVisitor visit) { - prim_minimum_spanning_tree(G, s, d, - get_edge_property_accessor(G, edge_weight()), - get_vertex_property_accessor(G, vertex_color()), - get_vertex_property_accessor(G, vertex_index()), + prim_minimum_spanning_tree(G, s, d, get(edge_weight(), G), + get(vertex_color(), G), + get(vertex_index(), G), visit); } diff --git a/include/boost/graph/properties.hpp b/include/boost/graph/properties.hpp index b35b2bd5..78ffc69f 100644 --- a/include/boost/graph/properties.hpp +++ b/include/boost/graph/properties.hpp @@ -37,7 +37,8 @@ namespace boost { inline default_color_type black(default_color_type) { return black_color; } namespace detail { - // These enums are only used in the no partial specialzation workaround + // These enum's are only necessary for a workaround for compilers that + // don't do partial specialization (like VC++). enum property_tag_num { NO_PLUGIN_TAG, ID_PLUGIN_TAG, NAME_PLUGIN_TAG, WEIGHT_PLUGIN_TAG, @@ -47,95 +48,158 @@ namespace boost { }; } // namespace detail - // The enum's are only necessary for a workaround for compilers that - // don't do partial specialization (like VC++). + + struct graph_property_tag { }; + struct vertex_property_tag { }; + struct edge_property_tag { }; struct vertex_index { + typedef vertex_property_tag kind; + enum { num = detail::ID_PLUGIN_TAG }; + }; + struct edge_index { + typedef edge_property_tag kind; enum { num = detail::ID_PLUGIN_TAG }; }; struct graph_name { + typedef graph_property_tag kind; enum { num = detail::NAME_PLUGIN_TAG }; }; struct vertex_name { + typedef vertex_property_tag kind; enum { num = detail::NAME_PLUGIN_TAG }; }; struct edge_name { + typedef edge_property_tag kind; enum { num = detail::NAME_PLUGIN_TAG }; }; struct edge_weight { + typedef edge_property_tag kind; enum { num = detail::WEIGHT_PLUGIN_TAG }; }; struct vertex_distance { + typedef vertex_property_tag kind; enum { num = detail::DISTANCE_PLUGIN_TAG }; }; struct vertex_color { + typedef vertex_property_tag kind; enum { num = detail::COLOR_PLUGIN_TAG }; }; struct vertex_degree { + typedef vertex_property_tag kind; enum { num = detail::DEGREE_PLUGIN_TAG }; }; struct vertex_out_degree { + typedef vertex_property_tag kind; enum { num = detail::OUT_DEGREE_PLUGIN_TAG }; }; struct vertex_in_degree { + typedef vertex_property_tag kind; enum { num = detail::IN_DEGREE_PLUGIN_TAG }; }; struct vertex_discover_time { + typedef vertex_property_tag kind; enum { num = detail::DISCOVER_TIME_PLUGIN_TAG }; }; struct vertex_finish_time { + typedef vertex_property_tag kind; enum { num = detail::FINISH_TIME_PLUGIN_TAG }; }; - struct foo_edge_property_selector { - template - struct bind { - typedef void type; - typedef void const_type; + namespace detail { + + struct dummy_edge_property_selector { + template + struct bind { + typedef void type; + typedef void const_type; + }; }; - }; + struct dummy_vertex_property_selector { + template + struct bind { + typedef void type; + typedef void const_type; + }; + }; + + } // namespace detail + + // Graph classes can either partially specialize property_map + // or they can specialize these two selector classes. template struct edge_property_selector { - typedef foo_edge_property_selector type; - }; - - struct foo_vertex_property_selector { - template - struct bind { - typedef void type; - typedef void const_type; - }; + typedef detail::dummy_edge_property_selector type; }; template struct vertex_property_selector { - typedef foo_vertex_property_selector type; + typedef detail::dummy_vertex_property_selector type; }; - template - struct edge_property_accessor { - typedef typename Graph::directed_category Directed; - typedef typename Graph::edge_plugin_type Plugin; - typedef typename Graph::graph_tag graph_tag; - typedef typename edge_property_selector::type Selector; - typedef typename Selector::template bind - Bind; - typedef typename Bind::type type; - typedef typename Bind::const_type const_type; - }; - template - class vertex_property_accessor { - typedef typename Graph::vertex_plugin_type Plugin; - typedef typename Graph::graph_tag graph_tag; - typedef typename vertex_property_selector::type Selector; - typedef typename Selector::template bind - Bind; + namespace detail { + + template + struct edge_property_map { + typedef typename Graph::directed_category Directed; + typedef typename Graph::edge_plugin_type Plugin; + typedef typename Graph::graph_tag graph_tag; + typedef typename edge_property_selector::type Selector; + typedef typename Selector::template bind + Bind; + typedef typename Bind::type type; + typedef typename Bind::const_type const_type; + }; + template + class vertex_property_map { + typedef typename Graph::vertex_plugin_type Plugin; + typedef typename Graph::graph_tag graph_tag; + typedef typename vertex_property_selector::type Selector; + typedef typename Selector::template bind + Bind; + public: + typedef typename Bind::type type; + typedef typename Bind::const_type const_type; + }; + + // This selects the kind of property map, whether is maps from + // edges or from vertices. + // + // It is overly complicated because it's a workaround for + // partial specialization. + template + struct property_map_kind_selector { }; + + struct choose_vertex_property_map { + template + struct bind { + typedef vertex_property_map type; + }; + }; + struct choose_edge_property_map { + template + struct bind { + typedef edge_property_map type; + }; + }; + template <> struct property_map_kind_selector { + typedef choose_vertex_property_map type; + }; + template <> struct property_map_kind_selector { + typedef choose_edge_property_map type; + }; + } // namespace detail + + template + class property_map { + typedef typename Property::kind Kind; + typedef typename detail::property_map_kind_selector::type Selector; + typedef typename Selector::bind::type Map; public: - typedef typename Bind::type type; - typedef typename Bind::const_type const_type; + typedef typename Map::type type; + typedef typename Map::const_type const_type; }; - } // namespace boost #endif /* BOOST_GRAPH_PROPERTIES_HPPA */ diff --git a/include/boost/graph/stanford_graph.hpp b/include/boost/graph/stanford_graph.hpp index 38c182d6..bcfe7244 100644 --- a/include/boost/graph/stanford_graph.hpp +++ b/include/boost/graph/stanford_graph.hpp @@ -245,7 +245,7 @@ namespace boost { inline long operator[](Vertex* v) const { return v - _g->vertices; } Graph* _g; }; - inline sgb_vertex_id_accessor get_vertex_property_accessor(Graph* g, vertex_index) { + inline sgb_vertex_id_accessor get(vertex_index, Graph* g) { return sgb_vertex_id_accessor(g); } @@ -258,21 +258,47 @@ namespace boost { typedef Vertex* key_type; inline char* operator[](Vertex* v) const { return v->name; } }; - inline sgb_vertex_name_accessor get_vertex_property_accessor(Graph* g, vertex_name) { + inline sgb_vertex_name_accessor get(vertex_name, Graph* g) { return sgb_vertex_name_accessor(); } // Vertex Property Tags - template struct u_tag { typedef T type; }; - template struct v_tag { typedef T type; }; - template struct w_tag { typedef T type; }; - template struct x_tag { typedef T type; }; - template struct y_tag { typedef T type; }; - template struct z_tag { typedef T type; }; + template struct u_property { + typedef vertex_property_tag kind; + typedef T type; + }; + template struct v_property { + typedef vertex_property_tag kind; + typedef T type; + }; + template struct w_property { + typedef vertex_property_tag kind; + typedef T type; + }; + template struct x_property { + typedef vertex_property_tag kind; + typedef T type; + }; + template struct y_property { + typedef vertex_property_tag kind; + typedef T type; + }; + template struct z_property { + typedef vertex_property_tag kind; + typedef T type; + }; // Edge Property Tags - template struct a_tag { typedef T type; }; - template struct b_tag { typedef T type; }; - struct length_tag { }; + template struct a_property { + typedef edge_property_tag kind; + typedef T type; + }; + template struct b_property { + typedef edge_property_tag kind; + typedef T type; + }; + struct edge_length { + typedef edge_property_tag kind; + }; // Vertex Utility Accessor @@ -285,7 +311,7 @@ namespace boost { #define GET_VERTEX_UTIL_FIELD(X) \ template \ - inline T& get_util_field(Vertex* v, X##_tag) { \ + inline T& get_util_field(Vertex* v, X##_property) { \ return get_util(v->X, T()); } GET_VERTEX_UTIL_FIELD(u) @@ -296,7 +322,7 @@ namespace boost { #define GET_EDGE_UTIL_FIELD(X) \ template \ - inline T& get_util_field(Arc* e, X##_tag) { \ + inline T& get_util_field(Arc* e, X##_property) { \ return get_util(e->X, T()); } GET_EDGE_UTIL_FIELD(a) @@ -320,7 +346,7 @@ namespace boost { #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template inline sgb_vertex_util_accessor - get_vertex_property_accessor(Graph* g, Tag) { + get_property_map(Tag, Graph* g, vertex_property_tag) { return sgb_vertex_util_accessor(); } #endif @@ -340,7 +366,7 @@ namespace boost { } }; inline sgb_edge_length_accessor - get_edge_property_accessor(Graph* g, length_tag) { + get(edge_length, Graph* g) { return sgb_edge_length_accessor(); } @@ -362,101 +388,126 @@ namespace boost { #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template inline sgb_edge_util_accessor - get_edge_property_accessor(Graph* g, Tag) { + get_property_map(Tag, Graph* g, edge_property_tag) { return sgb_edge_util_accessor(); } + template + struct sgb_util_accessor { }; + template struct sgb_util_accessor { + typedef typename sgb_vertex_util_accessor::type type; + }; + template struct sgb_util_accessor { + typedef typename sgb_edge_util_accessor::type type; + }; +#if 0 + template + inline typename sgb_util_accessor::type + get(Tag t, Graph* g) { + typedef typename Tag::kind Kind; + return get_property_map(t, g, Kind()); + } +#endif #endif // Property Accessor Traits Classes template <> - struct edge_property_accessor { + struct property_map { typedef sgb_edge_length_accessor type; }; template <> - struct vertex_property_accessor { + struct property_map { typedef sgb_vertex_id_accessor type; }; template <> - struct vertex_property_accessor { + struct property_map { typedef sgb_vertex_name_accessor type; }; #ifdef BOOST_GRAPH_PARTIAL_SPECIALIZATION + namespace detail { + template + struct choose_property_map { }; + template + struct choose_property_map { + typedef sgb_edge_util_accessor type; + }; + template + struct choose_property_map { + typedef sgb_vertex_util_accessor type; + }; + } // namespace detail template - struct edge_property_accessor { - typedef sgb_edge_util_accessor type; - }; - template - struct vertex_property_accessor { - typedef sgb_vertex_util_accessor type; + struct property_map { + typedef typename PropertyTag::kind Kind; + typedef typename detail::choose_property_map::type type; }; #else #define SGB_VERTEX_UTIL_ACCESSOR(TAG,TYPE) \ inline sgb_vertex_util_accessor< TAG > \ - get_vertex_property_accessor(Graph* g, TAG ) { \ + get(TAG, Graph* g) { \ return sgb_vertex_util_accessor< TAG >(); \ } \ - template <> struct vertex_property_accessor > { \ + template <> struct property_map > { \ typedef sgb_vertex_util_accessor< TAG > type; \ } -SGB_VERTEX_UTIL_ACCESSOR(u_tag,Vertex*); -SGB_VERTEX_UTIL_ACCESSOR(u_tag,Arc*); -SGB_VERTEX_UTIL_ACCESSOR(u_tag,Graph*); -SGB_VERTEX_UTIL_ACCESSOR(u_tag,long); -SGB_VERTEX_UTIL_ACCESSOR(u_tag,char*); +SGB_VERTEX_UTIL_ACCESSOR(u_property, Vertex*); +SGB_VERTEX_UTIL_ACCESSOR(u_property, Arc*); +SGB_VERTEX_UTIL_ACCESSOR(u_property, Graph*); +SGB_VERTEX_UTIL_ACCESSOR(u_property, long); +SGB_VERTEX_UTIL_ACCESSOR(u_property, char*); -SGB_VERTEX_UTIL_ACCESSOR(v_tag,Vertex*); -SGB_VERTEX_UTIL_ACCESSOR(v_tag,Arc*); -SGB_VERTEX_UTIL_ACCESSOR(v_tag,Graph*); -SGB_VERTEX_UTIL_ACCESSOR(v_tag,long); -SGB_VERTEX_UTIL_ACCESSOR(v_tag,char*); +SGB_VERTEX_UTIL_ACCESSOR(v_property, Vertex*); +SGB_VERTEX_UTIL_ACCESSOR(v_property, Arc*); +SGB_VERTEX_UTIL_ACCESSOR(v_property, Graph*); +SGB_VERTEX_UTIL_ACCESSOR(v_property, long); +SGB_VERTEX_UTIL_ACCESSOR(v_property, char*); -SGB_VERTEX_UTIL_ACCESSOR(w_tag,Vertex*); -SGB_VERTEX_UTIL_ACCESSOR(w_tag,Arc*); -SGB_VERTEX_UTIL_ACCESSOR(w_tag,Graph*); -SGB_VERTEX_UTIL_ACCESSOR(w_tag,long); -SGB_VERTEX_UTIL_ACCESSOR(w_tag,char*); +SGB_VERTEX_UTIL_ACCESSOR(w_property, Vertex*); +SGB_VERTEX_UTIL_ACCESSOR(w_property, Arc*); +SGB_VERTEX_UTIL_ACCESSOR(w_property, Graph*); +SGB_VERTEX_UTIL_ACCESSOR(w_property, long); +SGB_VERTEX_UTIL_ACCESSOR(w_property, char*); -SGB_VERTEX_UTIL_ACCESSOR(x_tag,Vertex*); -SGB_VERTEX_UTIL_ACCESSOR(x_tag,Arc*); -SGB_VERTEX_UTIL_ACCESSOR(x_tag,Graph*); -SGB_VERTEX_UTIL_ACCESSOR(x_tag,long); -SGB_VERTEX_UTIL_ACCESSOR(x_tag,char*); +SGB_VERTEX_UTIL_ACCESSOR(x_property, Vertex*); +SGB_VERTEX_UTIL_ACCESSOR(x_property, Arc*); +SGB_VERTEX_UTIL_ACCESSOR(x_property, Graph*); +SGB_VERTEX_UTIL_ACCESSOR(x_property, long); +SGB_VERTEX_UTIL_ACCESSOR(x_property, char*); -SGB_VERTEX_UTIL_ACCESSOR(y_tag,Vertex*); -SGB_VERTEX_UTIL_ACCESSOR(y_tag,Arc*); -SGB_VERTEX_UTIL_ACCESSOR(y_tag,Graph*); -SGB_VERTEX_UTIL_ACCESSOR(y_tag,long); -SGB_VERTEX_UTIL_ACCESSOR(y_tag,char*); +SGB_VERTEX_UTIL_ACCESSOR(y_property, Vertex*); +SGB_VERTEX_UTIL_ACCESSOR(y_property, Arc*); +SGB_VERTEX_UTIL_ACCESSOR(y_property, Graph*); +SGB_VERTEX_UTIL_ACCESSOR(y_property, long); +SGB_VERTEX_UTIL_ACCESSOR(y_property, char*); -SGB_VERTEX_UTIL_ACCESSOR(z_tag,Vertex*); -SGB_VERTEX_UTIL_ACCESSOR(z_tag,Arc*); -SGB_VERTEX_UTIL_ACCESSOR(z_tag,Graph*); -SGB_VERTEX_UTIL_ACCESSOR(z_tag,long); -SGB_VERTEX_UTIL_ACCESSOR(z_tag,char*); +SGB_VERTEX_UTIL_ACCESSOR(z_property, Vertex*); +SGB_VERTEX_UTIL_ACCESSOR(z_property, Arc*); +SGB_VERTEX_UTIL_ACCESSOR(z_property, Graph*); +SGB_VERTEX_UTIL_ACCESSOR(z_property, long); +SGB_VERTEX_UTIL_ACCESSOR(z_property, char*); #define SGB_EDGE_UTIL_ACCESSOR(TAG,TYPE) \ inline sgb_edge_util_accessor< TAG > \ - get_edge_property_accessor(Graph* g, TAG ) { \ + get(TAG, Graph*) { \ return sgb_edge_util_accessor< TAG >(); \ } \ - template <> struct edge_property_accessor > { \ + template <> struct property_map > { \ typedef sgb_edge_util_accessor< TAG > type; \ } -SGB_EDGE_UTIL_ACCESSOR(a_tag,Vertex*); -SGB_EDGE_UTIL_ACCESSOR(a_tag,Arc*); -SGB_EDGE_UTIL_ACCESSOR(a_tag,Graph*); -SGB_EDGE_UTIL_ACCESSOR(a_tag,long); -SGB_EDGE_UTIL_ACCESSOR(a_tag,char*); +SGB_EDGE_UTIL_ACCESSOR(a_property, Vertex*); +SGB_EDGE_UTIL_ACCESSOR(a_property, Arc*); +SGB_EDGE_UTIL_ACCESSOR(a_property, Graph*); +SGB_EDGE_UTIL_ACCESSOR(a_property, long); +SGB_EDGE_UTIL_ACCESSOR(a_property, char*); -SGB_EDGE_UTIL_ACCESSOR(b_tag,Vertex*); -SGB_EDGE_UTIL_ACCESSOR(b_tag,Arc*); -SGB_EDGE_UTIL_ACCESSOR(b_tag,Graph*); -SGB_EDGE_UTIL_ACCESSOR(b_tag,long); -SGB_EDGE_UTIL_ACCESSOR(b_tag,char*); +SGB_EDGE_UTIL_ACCESSOR(b_property, Vertex*); +SGB_EDGE_UTIL_ACCESSOR(b_property, Arc*); +SGB_EDGE_UTIL_ACCESSOR(b_property, Graph*); +SGB_EDGE_UTIL_ACCESSOR(b_property, long); +SGB_EDGE_UTIL_ACCESSOR(b_property, char*); #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION diff --git a/include/boost/graph/topological_sort.hpp b/include/boost/graph/topological_sort.hpp index 21f074f5..6c334951 100644 --- a/include/boost/graph/topological_sort.hpp +++ b/include/boost/graph/topological_sort.hpp @@ -79,7 +79,7 @@ namespace boost { inline void topological_sort(Graph& G, OutputIterator iter, DFSVisitor visit) { - topological_sort(G, iter, get_vertex_property(G,vertex_color()), visit); + topological_sort(G, iter, get(vertex_color(), G), visit); } template diff --git a/include/boost/graph/transpose_graph.hpp b/include/boost/graph/transpose_graph.hpp index 856ace13..7594dca7 100644 --- a/include/boost/graph/transpose_graph.hpp +++ b/include/boost/graph/transpose_graph.hpp @@ -53,7 +53,7 @@ namespace boost { template void transpose_graph(const Graph1& G1, Graph2& G2) { - transpose_graph(G1, G2, get_vertex_property(G1, vertex_index())); + transpose_graph(G1, G2, get(vertex_index(), G1)); } diff --git a/include/boost/graph/uniform_cost_search.hpp b/include/boost/graph/uniform_cost_search.hpp index 5604dbbf..2fda9cd3 100644 --- a/include/boost/graph/uniform_cost_search.hpp +++ b/include/boost/graph/uniform_cost_search.hpp @@ -93,10 +93,8 @@ namespace boost { { typedef typename graph_traits::edge_descriptor Edge; typedef typename graph_traits::vertex_descriptor V; - uniform_cost_search(g, s, - get_vertex_property_accessor(G, vertex_distance()), - get_edge_property_accessor(G, edge_weight()), - compare, combine); + uniform_cost_search(g, s, get(vertex_distance(), G), + get(edge_weight(), G), compare, combine); } // Variant (2) @@ -110,8 +108,7 @@ namespace boost { { null_visitor null_vis; uniform_cost_search(g, s, d, w, - get_vertex_property_accessor(g, vertex_color()), - get_vertex_property_accessor(g, vertex_index()), + get(vertex_color(), g), get(vertex_index(), g), compare, combine, make_ucs_visitor(null_vis)); }