diff --git a/include/boost/graph/adjacency_list.hpp b/include/boost/graph/adjacency_list.hpp index 5034fec5..7b121637 100644 --- a/include/boost/graph/adjacency_list.hpp +++ b/include/boost/graph/adjacency_list.hpp @@ -51,11 +51,6 @@ namespace boost { // adjacency_list, and the container_gen traits class which is used // to map the selectors to the container type used to implement the // graph. - // - // The main container_gen traits class uses partial specialization, - // so we also include a workaround. - -#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #if !defined BOOST_NO_SLIST struct slistS {}; @@ -130,93 +125,6 @@ namespace boost { typedef boost::unordered_multiset type; }; -#else // !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -#if !defined BOOST_NO_SLIST - struct slistS { - template - struct bind_ { typedef BOOST_STD_EXTENSION_NAMESPACE::slist type; }; - }; -#endif - - struct vecS { - template - struct bind_ { typedef std::vector type; }; - }; - - struct listS { - template - struct bind_ { typedef std::list type; }; - }; - - struct setS { - template - struct bind_ { typedef std::set > type; }; - }; - - - struct mapS { - template - struct bind_ { typedef std::set > type; }; - }; - - struct multisetS { - template - struct bind_ { typedef std::multiset > type; }; - }; - - struct multimapS { - template - struct bind_ { typedef std::multiset > type; }; - }; - - struct hash_setS { - template - struct bind_ { typedef boost::unordered_set type; }; - }; - - struct hash_mapS { - template - struct bind_ { typedef boost::unordered_set type; }; - }; - - struct hash_multisetS { - template - struct bind_ { typedef boost::unordered_multiset type; }; - }; - - struct hash_multimapS { - template - struct bind_ { typedef boost::unordered_multiset type; }; - }; - - template struct container_selector { - typedef vecS type; - }; - -#define BOOST_CONTAINER_SELECTOR(NAME) \ - template <> struct container_selector { \ - typedef NAME type; \ - } - - BOOST_CONTAINER_SELECTOR(vecS); - BOOST_CONTAINER_SELECTOR(listS); - BOOST_CONTAINER_SELECTOR(mapS); - BOOST_CONTAINER_SELECTOR(setS); - BOOST_CONTAINER_SELECTOR(multisetS); - BOOST_CONTAINER_SELECTOR(hash_mapS); -#if !defined BOOST_NO_SLIST - BOOST_CONTAINER_SELECTOR(slistS); -#endif - - template - struct container_gen { - typedef typename container_selector::type Select; - typedef typename Select:: template bind_::type type; - }; - -#endif // !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template struct parallel_edge_traits { }; @@ -354,13 +262,7 @@ namespace boost { adjacency_list, VertexListS, OutEdgeListS, DirectedS, -#if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES) - typename detail::retag_property_list::type, - typename detail::retag_property_list::type, -#else VertexProperty, EdgeProperty, -#endif GraphProperty, EdgeListS>::type, // Support for named vertices public graph::maybe_named_graph< @@ -371,25 +273,14 @@ namespace boost { VertexProperty> { public: -#if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES) - typedef typename graph_detail::graph_prop::property graph_property_type; - typedef typename graph_detail::graph_prop::bundle graph_bundled; - - typedef typename graph_detail::vertex_prop::property vertex_property_type; - typedef typename graph_detail::vertex_prop::bundle vertex_bundled; - - typedef typename graph_detail::edge_prop::property edge_property_type; - typedef typename graph_detail::edge_prop::bundle edge_bundled; -#else typedef GraphProperty graph_property_type; - typedef no_graph_bundle graph_bundled; + typedef typename lookup_one_property::type graph_bundled; typedef VertexProperty vertex_property_type; - typedef no_vertex_bundle vertex_bundled; + typedef typename lookup_one_property::type vertex_bundled; typedef EdgeProperty edge_property_type; - typedef no_edge_bundle edge_bundled; -#endif + typedef typename lookup_one_property::type edge_bundled; private: typedef adjacency_list self; @@ -545,58 +436,6 @@ namespace boost { return e.m_target; } - // Support for bundled properties -#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES - template - inline - typename property_map, T Bundle::*>::type - get(T Bundle::* p, adjacency_list& g) - { - typedef typename property_map, T Bundle::*>::type - result_type; - return result_type(&g, p); - } - - template - inline - typename property_map, T Bundle::*>::const_type - get(T Bundle::* p, adjacency_list const & g) - { - typedef typename property_map, T Bundle::*>::const_type - result_type; - return result_type(&g, p); - } - - template - inline T - get(T Bundle::* p, adjacency_list const & g, const Key& key) - { - return get(get(p, g), key); - } - - template - inline void - put(T Bundle::* p, adjacency_list& g, const Key& key, const T& value) - { - put(get(p, g), key, value); - } - -#endif - // Mutability Traits template struct graph_mutability_traits { diff --git a/include/boost/graph/adjacency_list_io.hpp b/include/boost/graph/adjacency_list_io.hpp index 547c0290..aaba8a43 100644 --- a/include/boost/graph/adjacency_list_io.hpp +++ b/include/boost/graph/adjacency_list_io.hpp @@ -40,7 +40,7 @@ namespace boost { template std::istream& operator >> ( std::istream& in, property& p ) { - in >> p.m_value >> *(static_cast(&p)); // houpla !! + in >> p.m_value >> p.m_base; // houpla !! return in; } @@ -65,7 +65,7 @@ template void get ( property& p, const V& v, Stag s ) { - get( *(static_cast(&p)),v,s ); + get( p.m_base,v,s ); } template @@ -82,7 +82,7 @@ void getSubset ( property& p, const property& s ) { get( p, s.m_value, Stag() ); - getSubset( p, Snext(s) ); + getSubset( p, s.m_base ); } template #include #include +#include #include #include #include @@ -29,7 +30,10 @@ #include #include #include -#include +#include +#include +#include +#include namespace boost { @@ -484,25 +488,14 @@ namespace boost { BOOST_STATIC_ASSERT(!(is_same::value)); #endif -#if !defined(BOOST_GRAPH_NO_BUNDLED_PROPERTIES) - typedef typename graph_detail::graph_prop::property graph_property_type; - typedef typename graph_detail::graph_prop::bundle graph_bundled; - - typedef typename graph_detail::vertex_prop::property vertex_property_type; - typedef typename graph_detail::vertex_prop::bundle vertex_bundled; - - typedef typename graph_detail::edge_prop::property edge_property_type; - typedef typename graph_detail::edge_prop::bundle edge_bundled; -#else typedef GraphProperty graph_property_type; - typedef no_graph_bundle graph_bundled; + typedef typename lookup_one_property::type graph_bundled; typedef VertexProperty vertex_property_type; - typedef no_vertex_bundle vertex_bundled; + typedef typename lookup_one_property::type vertex_bundled; typedef EdgeProperty edge_property_type; - typedef no_edge_bundle edge_bundled; -#endif + typedef typename lookup_one_property::type edge_bundled; public: // should be private typedef typename mpl::if_::type, @@ -640,16 +633,16 @@ namespace boost { #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES // Directly access a vertex or edge bundle vertex_bundled& operator[](vertex_descriptor v) - { return get(vertex_bundle, *this)[v]; } + { return get(vertex_bundle, *this, v); } const vertex_bundled& operator[](vertex_descriptor v) const - { return get(vertex_bundle, *this)[v]; } + { return get(vertex_bundle, *this, v); } edge_bundled& operator[](edge_descriptor e) - { return get(edge_bundle, *this)[e]; } + { return get(edge_bundle, *this, e); } const edge_bundled& operator[](edge_descriptor e) const - { return get(edge_bundle, *this)[e]; } + { return get(edge_bundle, *this, e); } graph_bundled& operator[](graph_bundle_t) { return get_property(*this); } @@ -1035,256 +1028,194 @@ namespace boost { //========================================================================= // Functions required by the PropertyGraph concept + template + struct adj_mat_pm_helper; + + template + struct adj_mat_pm_helper { + typedef typename graph_traits >::vertex_descriptor arg_type; + typedef typed_identity_property_map vi_map_type; + typedef iterator_property_map::iterator, vi_map_type> all_map_type; + typedef iterator_property_map::const_iterator, vi_map_type> all_map_const_type; + typedef transform_value_property_map< + detail::lookup_one_property_f, + all_map_type> + type; + typedef transform_value_property_map< + detail::lookup_one_property_f, + all_map_const_type> + const_type; + typedef typename property_traits::reference single_nonconst_type; + typedef typename property_traits::reference single_const_type; + + static type get_nonconst(adjacency_matrix& g, Prop prop) { + return type(prop, all_map_type(g.m_vertex_properties.begin(), vi_map_type())); + } + + static const_type get_const(const adjacency_matrix& g, Prop prop) { + return const_type(prop, all_map_const_type(g.m_vertex_properties.begin(), vi_map_type())); + } + + static single_nonconst_type get_nonconst_one(adjacency_matrix& g, Prop prop, arg_type v) { + return lookup_one_property::lookup(g.m_vertex_properties[v], prop); + } + + static single_const_type get_const_one(const adjacency_matrix& g, Prop prop, arg_type v) { + return lookup_one_property::lookup(g.m_vertex_properties[v], prop); + } + }; + + template + struct adj_mat_pm_helper { + typedef typename graph_traits >::edge_descriptor edge_descriptor; + + template + struct lookup_property_from_edge { + Tag tag; + lookup_property_from_edge(Tag tag): tag(tag) {} + typedef typename boost::mpl::if_::type ep_type_nonref; + typedef ep_type_nonref& ep_type; + typedef typename lookup_one_property::type& result_type; + result_type operator()(edge_descriptor e) const { + return lookup_one_property::lookup(*static_cast(e.get_property()), tag); + } + }; + + typedef function_property_map< + lookup_property_from_edge, + typename graph_traits >::edge_descriptor> type; + typedef function_property_map< + lookup_property_from_edge, + typename graph_traits >::edge_descriptor> const_type; + typedef edge_descriptor arg_type; + typedef typename lookup_property_from_edge::result_type single_nonconst_type; + typedef typename lookup_property_from_edge::result_type single_const_type; + + static type get_nonconst(adjacency_matrix& g, Tag tag) { + return type(tag); + } + + static const_type get_const(const adjacency_matrix& g, Tag tag) { + return const_type(tag); + } + + static single_nonconst_type get_nonconst_one(adjacency_matrix& g, Tag tag, edge_descriptor e) { + return lookup_one_property::lookup(*static_cast(e.get_property()), tag); + } + + static single_const_type get_const_one(const adjacency_matrix& g, Tag tag, edge_descriptor e) { + return lookup_one_property::lookup(*static_cast(e.get_property()), tag); + } + }; + + template + struct property_map, Tag> + : adj_mat_pm_helper, Tag>::type> {}; + + template + typename property_map, Tag>::type + get(Tag tag, adjacency_matrix& g) { + return property_map, Tag>::get_nonconst(g, tag); + } + + template + typename property_map, Tag>::const_type + get(Tag tag, const adjacency_matrix& g) { + return property_map, Tag>::get_const(g, tag); + } + + template + typename property_map, Tag>::single_nonconst_type + get(Tag tag, adjacency_matrix& g, typename property_map, Tag>::arg_type a) { + return property_map, Tag>::get_nonconst_one(g, tag, a); + } + + template + typename property_map, Tag>::single_const_type + get(Tag tag, const adjacency_matrix& g, typename property_map, Tag>::arg_type a) { + return property_map, Tag>::get_const_one(g, tag, a); + } + + template + void + put(Tag tag, + adjacency_matrix& g, + typename property_map, Tag>::arg_type a, + typename property_map, Tag>::single_const_type val) { + property_map, Tag>::get_nonconst_one(g, tag, a) = val; + } + // O(1) template inline void - set_property(adjacency_matrix& g, Tag, const Value& value) + set_property(adjacency_matrix& g, Tag tag, const Value& value) { - get_property_value(g.m_property, Tag()) = value; + get_property_value(g.m_property, tag) = value; } template inline typename graph_property, Tag>::type& - get_property(adjacency_matrix& g, Tag) + get_property(adjacency_matrix& g, Tag tag) { - return get_property_value(g.m_property, Tag()); + return get_property_value(g.m_property, tag); } template inline const typename graph_property, Tag>::type& - get_property(const adjacency_matrix& g, Tag) + get_property(const adjacency_matrix& g, Tag tag) { - return get_property_value(g.m_property, Tag()); + return get_property_value(g.m_property, tag); } //========================================================================= // Vertex Property Map - template - class adj_matrix_vertex_property_map - : public put_get_helper > - { - public: - typedef T value_type; - typedef R reference; - typedef Vertex key_type; - typedef boost::lvalue_property_map_tag category; - adj_matrix_vertex_property_map() { } - adj_matrix_vertex_property_map(GraphPtr g) : m_g(g) { } - inline reference operator[](key_type v) const { - return get_property_value(m_g->m_vertex_properties[v], Tag()); - } - GraphPtr m_g; + template + struct property_map, vertex_index_t> { + typedef typename adjacency_matrix::vertex_descriptor Vertex; + typedef typed_identity_property_map type; + typedef type const_type; }; - template - struct adj_matrix_vertex_id_map - : public boost::put_get_helper > - { - typedef Vertex value_type; - typedef Vertex reference; - typedef Vertex key_type; - typedef boost::readable_property_map_tag category; - adj_matrix_vertex_id_map() { } - template - inline adj_matrix_vertex_id_map(const Graph&) { } - inline value_type operator[](key_type v) const { return v; } - }; - - namespace detail { - - struct adj_matrix_any_vertex_pa { - template - struct bind_ { - typedef typename property_value::type Value; - typedef typename boost::graph_traits::vertex_descriptor Vertex; - - typedef adj_matrix_vertex_property_map type; - typedef adj_matrix_vertex_property_map const_type; - }; - }; - struct adj_matrix_id_vertex_pa { - template - struct bind_ { - typedef typename Graph::vertex_descriptor Vertex; - typedef adj_matrix_vertex_id_map type; - typedef adj_matrix_vertex_id_map const_type; - }; - }; - - template - struct adj_matrix_choose_vertex_pa_helper { - typedef adj_matrix_any_vertex_pa type; - }; - template <> - struct adj_matrix_choose_vertex_pa_helper { - typedef adj_matrix_id_vertex_pa type; - }; - - template - struct adj_matrix_choose_vertex_pa { - typedef typename adj_matrix_choose_vertex_pa_helper::type Helper; - typedef typename Helper::template bind_ Bind; - typedef typename Bind::type type; - typedef typename Bind::const_type const_type; - }; - - struct adj_matrix_vertex_property_selector { - template - struct bind_ { - typedef adj_matrix_choose_vertex_pa Choice; - typedef typename Choice::type type; - typedef typename Choice::const_type const_type; - }; - }; - - } // namespace detail - - template <> - struct vertex_property_selector { - typedef detail::adj_matrix_vertex_property_selector type; - }; - - //========================================================================= - // Edge Property Map - - - template - class adj_matrix_edge_property_map - : public put_get_helper > - { - public: - typedef T value_type; - typedef R reference; - typedef detail::matrix_edge_desc_impl key_type; - typedef boost::lvalue_property_map_tag category; - inline reference operator[](key_type e) const { - Property& p = *(Property*)e.get_property(); - return get_property_value(p, Tag()); - } - }; - struct adj_matrix_edge_property_selector { - template - struct bind_ { - typedef typename property_value::type T; - typedef typename Graph::vertex_descriptor Vertex; - typedef adj_matrix_edge_property_map type; - typedef adj_matrix_edge_property_map const_type; - }; - }; - template <> - struct edge_property_selector { - typedef adj_matrix_edge_property_selector type; - }; - - //========================================================================= - // Functions required by PropertyGraph - - namespace detail { - - template - typename boost::property_map, - Property>::type - get_dispatch(adjacency_matrix& g, Property, - vertex_property_tag) - { - typedef adjacency_matrix Graph; - typedef typename boost::property_map, - Property>::type PA; - return PA(&g); - } - template - typename boost::property_map, - Property>::type - get_dispatch(adjacency_matrix&, Property, - edge_property_tag) - { - typedef typename boost::property_map, - Property>::type PA; - return PA(); - } - template - typename boost::property_map, - Property>::const_type - get_dispatch(const adjacency_matrix& g, Property, - vertex_property_tag) - { - typedef adjacency_matrix Graph; - typedef typename boost::property_map, - Property>::const_type PA; - return PA(&g); - } - template - typename boost::property_map, - Property>::const_type - get_dispatch(const adjacency_matrix&, Property, - edge_property_tag) - { - typedef typename boost::property_map, - Property>::const_type PA; - return PA(); - } - - } // namespace detail - - template - inline - typename property_map, Property>::type - get(Property p, adjacency_matrix& g) - { - typedef typename property_kind::type Kind; - return detail::get_dispatch(g, p, Kind()); + template + typename property_map, vertex_index_t>::const_type + get(vertex_index_t, adjacency_matrix&) { + return typename property_map, vertex_index_t>::const_type(); } - template - inline - typename property_map, Property>::const_type - get(Property p, const adjacency_matrix& g) - { - typedef typename property_kind::type Kind; - return detail::get_dispatch(g, p, Kind()); + template + typename adjacency_matrix::vertex_descriptor + get(vertex_index_t, + adjacency_matrix&, + typename adjacency_matrix::vertex_descriptor v) { + return v; } - template - inline - typename property_traits< - typename property_map, Property>::const_type - >::value_type - get(Property p, const adjacency_matrix& g, - const Key& key) - { - return get(get(p, g), key); + template + typename property_map, vertex_index_t>::const_type + get(vertex_index_t, const adjacency_matrix&) { + return typename property_map, vertex_index_t>::const_type(); } - template - inline void - put(Property p, adjacency_matrix& g, - const Key& key, const Value& value) - { - typedef adjacency_matrix Graph; - typedef typename boost::property_map::type Map; - Map pmap = get(p, g); - put(pmap, key, value); + template + typename adjacency_matrix::vertex_descriptor + get(vertex_index_t, + const adjacency_matrix&, + typename adjacency_matrix::vertex_descriptor v) { + return v; } //========================================================================= @@ -1298,63 +1229,10 @@ namespace boost { return n; } - // Support for bundled properties -#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES - template - inline - typename property_map, - T Bundle::*>::type - get(T Bundle::* p, adjacency_matrix& g) - { - typedef typename property_map, - T Bundle::*>::type - result_type; - return result_type(&g, p); - } - - template - inline - typename property_map, - T Bundle::*>::const_type - get(T Bundle::* p, adjacency_matrix const & g) - { - typedef typename property_map, - T Bundle::*>::const_type - result_type; - return result_type(&g, p); - } - - template - inline T - get(T Bundle::* p, adjacency_matrix const & g, - const Key& key) - { - return get(get(p, g), key); - } - - template - inline void - put(T Bundle::* p, adjacency_matrix& g, - const Key& key, const T& value) - { - put(get(p, g), key, value); - } - -#endif - -#define ADJMAT_PARAMS \ - typename D, typename VP, typename EP, typename GP, typename A -#define ADJMAT adjacency_matrix -template -struct graph_mutability_traits { - typedef mutable_edge_property_graph_tag category; +template +struct graph_mutability_traits > { + typedef mutable_edge_property_graph_tag category; }; -#undef ADJMAT_PARAMS -#undef ADJMAT } // namespace boost diff --git a/include/boost/graph/bellman_ford_shortest_paths.hpp b/include/boost/graph/bellman_ford_shortest_paths.hpp index c80ebe7c..e102d922 100644 --- a/include/boost/graph/bellman_ford_shortest_paths.hpp +++ b/include/boost/graph/bellman_ford_shortest_paths.hpp @@ -171,7 +171,7 @@ namespace boost { bool bellman_dispatch2 (VertexAndEdgeListGraph& g, - detail::error_property_not_found, + param_not_found, Size N, WeightMap weight, PredecessorMap pred, DistanceMap distance, const bgl_named_params& params) { diff --git a/include/boost/graph/betweenness_centrality.hpp b/include/boost/graph/betweenness_centrality.hpp index 052f0633..a4de1753 100644 --- a/include/boost/graph/betweenness_centrality.hpp +++ b/include/boost/graph/betweenness_centrality.hpp @@ -498,14 +498,14 @@ namespace detail { namespace graph { }; template<> - struct brandes_betweenness_centrality_dispatch1 + struct brandes_betweenness_centrality_dispatch1 { template static void run(const Graph& g, CentralityMap centrality, EdgeCentralityMap edge_centrality_map, VertexIndexMap vertex_index, - error_property_not_found) + param_not_found) { brandes_betweenness_centrality_dispatch2(g, centrality, edge_centrality_map, vertex_index); @@ -532,7 +532,7 @@ brandes_betweenness_centrality(const Graph& g, { typedef bgl_named_params named_params; - typedef typename property_value::type ew; + typedef typename get_param_type::type ew; detail::graph::brandes_betweenness_centrality_dispatch1::run( g, choose_param(get_param(params, vertex_centrality), diff --git a/include/boost/graph/biconnected_components.hpp b/include/boost/graph/biconnected_components.hpp index 0fdbad0d..f31b24a1 100644 --- a/include/boost/graph/biconnected_components.hpp +++ b/include/boost/graph/biconnected_components.hpp @@ -209,7 +209,7 @@ namespace boost }; template <> - struct bicomp_dispatch3 + struct bicomp_dispatch3 { template& params, - error_property_not_found) + param_not_found) { typedef typename graph_traits::vertex_descriptor vertex_t; std::vector pred(num_vertices(g)); @@ -243,7 +243,7 @@ namespace boost DiscoverTimeMap dtm, const bgl_named_params& params, LowPointMap lowpt) { - typedef typename property_value< bgl_named_params, + typedef typename get_param_type< bgl_named_params, vertex_predecessor_t>::type dispatch_type; return bicomp_dispatch3::apply @@ -254,7 +254,7 @@ namespace boost template <> - struct bicomp_dispatch2 + struct bicomp_dispatch2 { template apply (const Graph& g, ComponentMap comp, OutputIterator out, VertexIndexMap index_map, DiscoverTimeMap dtm, const bgl_named_params& params, - error_property_not_found) + param_not_found) { typedef typename graph_traits::vertices_size_type vertices_size_type; std::vector lowpt(num_vertices(g)); vertices_size_type vst(0); - typedef typename property_value< bgl_named_params, + typedef typename get_param_type< bgl_named_params, vertex_predecessor_t>::type dispatch_type; return bicomp_dispatch3::apply @@ -288,7 +288,7 @@ namespace boost ComponentMap comp, OutputIterator out, VertexIndexMap index_map, const bgl_named_params& params, DiscoverTimeMap dtm) { - typedef typename property_value< bgl_named_params, + typedef typename get_param_type< bgl_named_params, vertex_lowpoint_t>::type dispatch_type; return bicomp_dispatch2::apply @@ -298,20 +298,20 @@ namespace boost }; template <> - struct bicomp_dispatch1 + struct bicomp_dispatch1 { template static std::pair apply(const Graph& g, ComponentMap comp, OutputIterator out, VertexIndexMap index_map, - const bgl_named_params& params, error_property_not_found) + const bgl_named_params& params, param_not_found) { typedef typename graph_traits::vertices_size_type vertices_size_type; std::vector discover_time(num_vertices(g)); vertices_size_type vst(0); - typedef typename property_value< bgl_named_params, + typedef typename get_param_type< bgl_named_params, vertex_lowpoint_t>::type dispatch_type; return bicomp_dispatch2::apply @@ -329,14 +329,14 @@ namespace boost biconnected_components(const Graph& g, ComponentMap comp, OutputIterator out, DiscoverTimeMap dtm, LowPointMap lowpt) { - typedef detail::error_property_not_found dispatch_type; + typedef param_not_found dispatch_type; return detail::bicomp_dispatch3::apply (g, comp, out, get(vertex_index, g), dtm, lowpt, bgl_named_params(0), - detail::error_property_not_found()); + param_not_found()); } template & params) { - typedef typename property_value< bgl_named_params, + typedef typename get_param_type< bgl_named_params, vertex_discover_time_t>::type dispatch_type; return detail::bicomp_dispatch1::apply(g, comp, out, diff --git a/include/boost/graph/breadth_first_search.hpp b/include/boost/graph/breadth_first_search.hpp index f65e4757..3af85f3f 100644 --- a/include/boost/graph/breadth_first_search.hpp +++ b/include/boost/graph/breadth_first_search.hpp @@ -53,11 +53,12 @@ namespace boost { }; + // Multiple-source version template + class ColorMap, class SourceIterator> void breadth_first_visit (const IncidenceGraph& g, - typename graph_traits::vertex_descriptor s, + SourceIterator sources_begin, SourceIterator sources_end, Buffer& Q, BFSVisitor vis, ColorMap color) { BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); @@ -70,8 +71,11 @@ namespace boost { typedef color_traits Color; typename GTraits::out_edge_iterator ei, ei_end; - put(color, s, Color::gray()); vis.discover_vertex(s, g); - Q.push(s); + for (; sources_begin != sources_end; ++sources_begin) { + Vertex s = *sources_begin; + put(color, s, Color::gray()); vis.discover_vertex(s, g); + Q.push(s); + } while (! Q.empty()) { Vertex u = Q.top(); Q.pop(); vis.examine_vertex(u, g); for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) { @@ -89,12 +93,25 @@ namespace boost { } // end while } // breadth_first_visit + // Single-source version + template + void breadth_first_visit + (const IncidenceGraph& g, + typename graph_traits::vertex_descriptor s, + Buffer& Q, BFSVisitor vis, ColorMap color) + { + typename graph_traits::vertex_descriptor sources[1] = {s}; + breadth_first_visit(g, sources, sources + 1, Q, vis, color); + } - template void breadth_first_search (const VertexListGraph& g, - typename graph_traits::vertex_descriptor s, + SourceIterator sources_begin, SourceIterator sources_end, Buffer& Q, BFSVisitor vis, ColorMap color) { // Initialization @@ -105,7 +122,18 @@ namespace boost { vis.initialize_vertex(*i, g); put(color, *i, Color::white()); } - breadth_first_visit(g, s, Q, vis, color); + breadth_first_visit(g, sources_begin, sources_end, Q, vis, color); + } + + template + void breadth_first_search + (const VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + Buffer& Q, BFSVisitor vis, ColorMap color) + { + typename graph_traits::vertex_descriptor sources[1] = {s}; + breadth_first_search(g, sources, sources + 1, Q, vis, color); } namespace graph { struct bfs_visitor_event_not_overridden {}; } @@ -270,13 +298,13 @@ namespace boost { }; template <> - struct bfs_dispatch { + struct bfs_dispatch { template static void apply (VertexListGraph& g, typename graph_traits::vertex_descriptor s, const bgl_named_params& params, - detail::error_property_not_found) + param_not_found) { null_visitor null_vis; @@ -307,8 +335,7 @@ namespace boost { // graph is not really const since we may write to property maps // of the graph. VertexListGraph& ng = const_cast(g); - typedef typename property_value< bgl_named_params, - vertex_color_t>::type C; + typedef typename get_param_type< vertex_color_t, bgl_named_params >::type C; detail::bfs_dispatch::apply(ng, s, params, get_param(params, vertex_color)); } diff --git a/include/boost/graph/compressed_sparse_row_graph.hpp b/include/boost/graph/compressed_sparse_row_graph.hpp index 75e61659..f4ff2dc8 100644 --- a/include/boost/graph/compressed_sparse_row_graph.hpp +++ b/include/boost/graph/compressed_sparse_row_graph.hpp @@ -42,6 +42,7 @@ #include #include #include +#include #ifdef BOOST_GRAPH_NO_BUNDLED_PROPERTIES # error The Compressed Sparse Row graph only supports bundled properties. @@ -195,8 +196,8 @@ class compressed_sparse_row_graph::property graph_property_type; - typedef typename graph_detail::graph_prop::bundle graph_bundled; + typedef GraphProperty graph_property_type; + typedef typename lookup_one_property::type graph_bundled; typedef detail::compressed_sparse_row_structure forward_type; @@ -746,8 +747,8 @@ class compressed_sparse_row_graph::property graph_property_type; - typedef typename graph_detail::graph_prop::bundle graph_bundled; + typedef GraphProperty graph_property_type; + typedef typename lookup_one_property::type graph_bundled; // typedef GraphProperty graph_property_type; typedef detail::compressed_sparse_row_structure forward_type; @@ -1404,6 +1405,61 @@ get_property(const BOOST_CSR_GRAPH_TYPE& g, Tag) return get_property_value(g.m_property, Tag()); } +template +struct property_map { + typedef typename detail::property_kind_from_graph::type kind; + typedef typename boost::mpl::if_< + boost::is_same, + vertex_all_t, + typename boost::mpl::if_< + boost::is_same, + edge_all_t, + graph_all_t>::type>::type all_tag; + typedef typename property_traits::type>::key_type key_type; + typedef typename property_traits::type>::value_type plist_type; + typedef transform_value_property_map, typename property_map::type> type; + typedef transform_value_property_map, typename property_map::const_type> const_type; +}; + +template +typename property_map::type +get(Tag tag, BOOST_CSR_GRAPH_TYPE& g) { + return typename property_map::type(tag, get(typename property_map::all_tag(), g)); +} + +template +typename property_map::const_type +get(Tag tag, const BOOST_CSR_GRAPH_TYPE& g) { + return typename property_map::const_type(tag, get(typename property_map::all_tag(), g)); +} + +template +typename property_traits::type>::reference +get(Tag tag, BOOST_CSR_GRAPH_TYPE& g, typename property_map::key_type k) { + typedef typename property_map::all_tag all_tag; + typedef typename property_map::type outer_pm; + return lookup_one_property::value_type, Tag>::lookup(get(all_tag(), g, k), tag); +} + +template +typename property_traits::const_type>::reference +get(Tag tag, const BOOST_CSR_GRAPH_TYPE& g, typename property_map::key_type k) { + typedef typename property_map::all_tag all_tag; + typedef typename property_map::const_type outer_pm; + return lookup_one_property::value_type, Tag>::lookup(get(all_tag(), g, k), tag); +} + +template +void +put(Tag tag, + BOOST_CSR_GRAPH_TYPE& g, + typename property_map::key_type k, + typename lookup_one_property::plist_type, Tag>::type val) { + typedef typename property_map::all_tag all_tag; + typedef typename property_map::type outer_pm; + lookup_one_property::plist_type, Tag>::lookup(get(all_tag(), g, k), tag) = val; +} + template struct property_map { @@ -1419,14 +1475,14 @@ struct property_map }; template -struct property_map +struct property_map { typedef typename BOOST_CSR_GRAPH_TYPE::inherited_vertex_properties::vertex_map_type type; typedef typename BOOST_CSR_GRAPH_TYPE::inherited_vertex_properties::const_vertex_map_type const_type; }; template -struct property_map +struct property_map { typedef typename BOOST_CSR_GRAPH_TYPE::forward_type::inherited_edge_properties::edge_map_type type; typedef typename BOOST_CSR_GRAPH_TYPE::forward_type::inherited_edge_properties::const_edge_map_type const_type; @@ -1447,6 +1503,21 @@ get(vertex_index_t, return v; } +template +inline typed_identity_property_map +get(vertex_index_t, BOOST_CSR_GRAPH_TYPE&) +{ + return typed_identity_property_map(); +} + +template +inline Vertex +get(vertex_index_t, + BOOST_CSR_GRAPH_TYPE&, Vertex v) +{ + return v; +} + template inline typename property_map::const_type get(edge_index_t, const BOOST_CSR_GRAPH_TYPE&) @@ -1465,125 +1536,102 @@ get(edge_index_t, const BOOST_CSR_GRAPH_TYPE&, } template -inline typename property_map::type -get(vertex_bundle_t, BOOST_CSR_GRAPH_TYPE& g) +inline typename property_map::const_type +get(edge_index_t, BOOST_CSR_GRAPH_TYPE&) +{ + typedef typename property_map::const_type + result_type; + return result_type(); +} + +template +inline EdgeIndex +get(edge_index_t, BOOST_CSR_GRAPH_TYPE&, + typename BOOST_CSR_GRAPH_TYPE::edge_descriptor e) +{ + return e.idx; +} + +template +inline typename property_map::type +get(vertex_all_t, BOOST_CSR_GRAPH_TYPE& g) { return g.get_vertex_bundle(get(vertex_index, g)); } template -inline typename property_map::const_type -get(vertex_bundle_t, const BOOST_CSR_GRAPH_TYPE& g) +inline typename property_map::const_type +get(vertex_all_t, const BOOST_CSR_GRAPH_TYPE& g) { return g.get_vertex_bundle(get(vertex_index, g)); } template inline VertexProperty& -get(vertex_bundle_t, +get(vertex_all_t, BOOST_CSR_GRAPH_TYPE& g, Vertex v) { - return get(vertex_bundle, g)[v]; + return get(vertex_all, g)[v]; } template inline const VertexProperty& -get(vertex_bundle_t, +get(vertex_all_t, const BOOST_CSR_GRAPH_TYPE& g, Vertex v) { - return get(vertex_bundle, g)[v]; + return get(vertex_all, g)[v]; } template inline void -put(vertex_bundle_t, +put(vertex_all_t, BOOST_CSR_GRAPH_TYPE& g, Vertex v, const VertexProperty& val) { - put(get(vertex_bundle, g), v, val); + put(get(vertex_all, g), v, val); } template -inline typename property_map::type -get(edge_bundle_t, BOOST_CSR_GRAPH_TYPE& g) +inline typename property_map::type +get(edge_all_t, BOOST_CSR_GRAPH_TYPE& g) { return g.m_forward.get_edge_bundle(get(edge_index, g)); } template -inline typename property_map::const_type -get(edge_bundle_t, const BOOST_CSR_GRAPH_TYPE& g) +inline typename property_map::const_type +get(edge_all_t, const BOOST_CSR_GRAPH_TYPE& g) { return g.m_forward.get_edge_bundle(get(edge_index, g)); } template inline EdgeProperty& -get(edge_bundle_t, +get(edge_all_t, BOOST_CSR_GRAPH_TYPE& g, const typename BOOST_CSR_GRAPH_TYPE::edge_descriptor& e) { - return get(edge_bundle, g)[e]; + return get(edge_all, g)[e]; } template inline const EdgeProperty& -get(edge_bundle_t, +get(edge_all_t, const BOOST_CSR_GRAPH_TYPE& g, const typename BOOST_CSR_GRAPH_TYPE::edge_descriptor& e) { - return get(edge_bundle, g)[e]; + return get(edge_all, g)[e]; } template inline void -put(edge_bundle_t, +put(edge_all_t, BOOST_CSR_GRAPH_TYPE& g, const typename BOOST_CSR_GRAPH_TYPE::edge_descriptor& e, const EdgeProperty& val) { - put(get(edge_bundle, g), e, val); -} - -template -inline -typename property_map::type -get(T Bundle::* p, BOOST_CSR_GRAPH_TYPE& g) -{ - typedef typename property_map::type - result_type; - return result_type(&g, p); -} - -template -inline -typename property_map::const_type -get(T Bundle::* p, BOOST_CSR_GRAPH_TYPE const & g) -{ - typedef typename property_map::const_type - result_type; - return result_type(&g, p); -} - -template -inline T -get(T Bundle::* p, BOOST_CSR_GRAPH_TYPE const & g, - const Key& key) -{ - return get(get(p, g), key); -} - -template -inline void -put(T Bundle::* p, BOOST_CSR_GRAPH_TYPE& g, - const Key& key, const T& value) -{ - put(get(p, g), key, value); + put(get(edge_all, g), e, val); } #undef BOOST_CSR_GRAPH_TYPE diff --git a/include/boost/graph/copy.hpp b/include/boost/graph/copy.hpp index 0dc6c664..21bb0fb0 100644 --- a/include/boost/graph/copy.hpp +++ b/include/boost/graph/copy.hpp @@ -280,7 +280,7 @@ namespace boost { typedef choose_copier_parameter type; }; template <> - struct choose_edge_copy { + struct choose_edge_copy { typedef choose_default_edge_copier type; }; template @@ -314,7 +314,7 @@ namespace boost { typedef choose_copier_parameter type; }; template <> - struct choose_vertex_copy { + struct choose_vertex_copy { typedef choose_default_vertex_copier type; }; template diff --git a/include/boost/graph/detail/adjacency_list.hpp b/include/boost/graph/detail/adjacency_list.hpp index 100c44ba..a3ea40aa 100644 --- a/include/boost/graph/detail/adjacency_list.hpp +++ b/include/boost/graph/detail/adjacency_list.hpp @@ -37,11 +37,6 @@ #include #include -// Symbol truncation problems with MSVC, trying to shorten names. -#define stored_edge se_ -#define stored_edge_property sep_ -#define stored_edge_iter sei_ - /* Outline for this file: @@ -67,11 +62,6 @@ */ -#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) -// Stay out of the way of the concept checking class -# define Graph Graph_ -#endif - namespace boost { namespace detail { @@ -1511,10 +1501,16 @@ namespace boost { typedef typename Config::edges_size_type edges_size_type; typedef typename Config::degree_size_type degree_size_type; typedef typename Config::StoredEdge StoredEdge; + typedef typename Config::vertex_property_type vertex_property_type; typedef typename Config::edge_property_type edge_property_type; + typedef typename Config::graph_property_type graph_property_type; typedef typename Config::global_edgelist_selector global_edgelist_selector; + + typedef typename lookup_one_property::type vertex_bundled; + typedef typename lookup_one_property::type edge_bundled; + typedef typename lookup_one_property::type graph_bundled; }; template @@ -1645,43 +1641,43 @@ namespace boost { inline typename boost::property_map::type - get_dispatch(adj_list_helper&, Property, + get_dispatch(adj_list_helper&, Property p, boost::edge_property_tag) { typedef typename Config::graph_type Graph; typedef typename boost::property_map::type PA; - return PA(); + return PA(p); } template inline typename boost::property_map::const_type - get_dispatch(const adj_list_helper&, Property, + get_dispatch(const adj_list_helper&, Property p, boost::edge_property_tag) { typedef typename Config::graph_type Graph; typedef typename boost::property_map::const_type PA; - return PA(); + return PA(p); } template inline typename boost::property_map::type - get_dispatch(adj_list_helper& g, Property, + get_dispatch(adj_list_helper& g, Property p, boost::vertex_property_tag) { typedef typename Config::graph_type Graph; typedef typename boost::property_map::type PA; - return PA(&static_cast(g)); + return PA(&static_cast(g), p); } template inline typename boost::property_map::const_type - get_dispatch(const adj_list_helper& g, Property, + get_dispatch(const adj_list_helper& g, Property p, boost::vertex_property_tag) { typedef typename Config::graph_type Graph; typedef typename boost::property_map::const_type PA; const Graph& cg = static_cast(g); - return PA(&cg); + return PA(&cg, p); } } // namespace detail @@ -1691,7 +1687,7 @@ namespace boost { inline typename boost::property_map::type get(Property p, adj_list_helper& g) { - typedef typename property_kind::type Kind; + typedef typename detail::property_kind_from_graph, Property>::type Kind; return detail::get_dispatch(g, p, Kind()); } template @@ -1699,7 +1695,7 @@ namespace boost { typename boost::property_map::const_type get(Property p, const adj_list_helper& g) { - typedef typename property_kind::type Kind; + typedef typename detail::property_kind_from_graph, Property>::type Kind; return detail::get_dispatch(g, p, Kind()); } @@ -2427,15 +2423,15 @@ namespace boost { typedef Reference reference; typedef typename Graph::vertex_descriptor key_type; typedef boost::lvalue_property_map_tag category; - inline adj_list_vertex_property_map() { } - inline adj_list_vertex_property_map(const Graph*) { } + inline adj_list_vertex_property_map(const Graph* = 0, Tag tag = Tag()): m_tag(tag) { } inline Reference operator[](key_type v) const { StoredVertex* sv = (StoredVertex*)v; - return get_property_value(sv->m_property, Tag()); + return get_property_value(sv->m_property, m_tag); } inline Reference operator()(key_type v) const { return this->operator[](v); } + Tag m_tag; }; template @@ -2449,8 +2445,7 @@ namespace boost { typedef PropRef reference; typedef typename Graph::vertex_descriptor key_type; typedef boost::lvalue_property_map_tag category; - inline adj_list_vertex_all_properties_map() { } - inline adj_list_vertex_all_properties_map(const Graph*) { } + inline adj_list_vertex_all_properties_map(const Graph* = 0, vertex_all_t = vertex_all_t()) { } inline PropRef operator[](key_type v) const { StoredVertex* sv = (StoredVertex*)v; return sv->m_property; @@ -2473,15 +2468,15 @@ namespace boost { typedef Reference reference; typedef typename boost::graph_traits::vertex_descriptor key_type; typedef boost::lvalue_property_map_tag category; - vec_adj_list_vertex_property_map() { } - vec_adj_list_vertex_property_map(GraphPtr g) : m_g(g) { } + vec_adj_list_vertex_property_map(GraphPtr g = 0, Tag tag = Tag()) : m_g(g), m_tag(tag) { } inline Reference operator[](key_type v) const { - return get_property_value(m_g->m_vertices[v].m_property, Tag()); + return get_property_value(m_g->m_vertices[v].m_property, m_tag); } inline Reference operator()(key_type v) const { return this->operator[](v); } GraphPtr m_g; + Tag m_tag; }; template @@ -2495,8 +2490,7 @@ namespace boost { typedef PropertyRef reference; typedef typename boost::graph_traits::vertex_descriptor key_type; typedef boost::lvalue_property_map_tag category; - vec_adj_list_vertex_all_properties_map() { } - vec_adj_list_vertex_all_properties_map(GraphPtr g) : m_g(g) { } + vec_adj_list_vertex_all_properties_map(GraphPtr g = 0, vertex_all_t = vertex_all_t()) : m_g(g) { } inline PropertyRef operator[](key_type v) const { return m_g->m_vertices[v].m_property; } @@ -2542,7 +2536,7 @@ namespace boost { typedef boost::readable_property_map_tag category; inline vec_adj_list_vertex_id_map() { } template - inline vec_adj_list_vertex_id_map(const Graph&) { } + inline vec_adj_list_vertex_id_map(const Graph&, vertex_index_t) { } inline value_type operator[](key_type v) const { return v; } inline value_type operator()(key_type v) const { return v; } }; @@ -2579,17 +2573,11 @@ namespace boost { }; }; namespace detail { - template - struct adj_list_choose_vertex_pa_helper { - typedef adj_list_any_vertex_pa type; - }; - template <> - struct adj_list_choose_vertex_pa_helper { - typedef adj_list_all_vertex_pa type; - }; template struct adj_list_choose_vertex_pa { - typedef typename adj_list_choose_vertex_pa_helper::type Helper; + typedef typename + boost::mpl::if_, adj_list_all_vertex_pa, adj_list_any_vertex_pa>::type + Helper; typedef typename Helper::template bind_ Bind; typedef typename Bind::type type; typedef typename Bind::const_type const_type; @@ -2629,13 +2617,16 @@ namespace boost { Tag> > { + Tag tag; + explicit adj_list_edge_property_map(Tag tag = Tag()): tag(tag) {} + typedef Value value_type; typedef Ref reference; typedef detail::edge_desc_impl key_type; typedef boost::lvalue_property_map_tag category; inline Ref operator[](key_type e) const { Property& p = *(Property*)e.get_property(); - return get_property_value(p, Tag()); + return get_property_value(p, tag); } inline Ref operator()(key_type e) const { return this->operator[](e); @@ -2650,6 +2641,7 @@ namespace boost { PropPtr, Vertex> > { + explicit adj_list_edge_all_properties_map(edge_all_t = edge_all_t()) {} typedef Property value_type; typedef PropRef reference; typedef detail::edge_desc_impl key_type; @@ -2793,15 +2785,6 @@ namespace boost { #endif -#undef stored_edge -#undef stored_edge_property -#undef stored_edge_iter - -#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) -// Stay out of the way of the concept checking class -#undef Graph -#endif - #endif // BOOST_GRAPH_DETAIL_DETAIL_ADJACENCY_LIST_CCT /* diff --git a/include/boost/graph/directed_graph.hpp b/include/boost/graph/directed_graph.hpp index 0bf02519..a20539ff 100644 --- a/include/boost/graph/directed_graph.hpp +++ b/include/boost/graph/directed_graph.hpp @@ -33,14 +33,12 @@ template < class directed_graph { public: - typedef typename graph_detail::graph_prop::property graph_property_type; - typedef typename graph_detail::graph_prop::bundle graph_bundled; - - typedef typename graph_detail::vertex_prop::property vertex_property_type; - typedef typename graph_detail::vertex_prop::bundle vertex_bundled; - - typedef typename graph_detail::edge_prop::property edge_property_type; - typedef typename graph_detail::edge_prop::bundle edge_bundled; + typedef GraphProp graph_property_type; + typedef VertexProp vertex_property_type; + typedef EdgeProp edge_property_type; + typedef typename lookup_one_property::type graph_bundled; + typedef typename lookup_one_property::type vertex_bundled; + typedef typename lookup_one_property::type edge_bundled; private: // Wrap the user-specified properties with an index. @@ -590,35 +588,6 @@ void set_property(DIRECTED_GRAPH& g, Property p, Value v) { return set_property(g.impl(), p, v); } -#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES - -template -inline typename property_map::type -get(Type Bundle::* p, DIRECTED_GRAPH& g) { - typedef typename property_map< - DIRECTED_GRAPH, Type Bundle::* - >::type return_type; - return return_type(&g, p); -} - -template -inline typename property_map::const_type -get(Type Bundle::* p, DIRECTED_GRAPH const& g) { - typedef typename property_map< - DIRECTED_GRAPH, Type Bundle::* - >::const_type return_type; - return return_type(&g, p); -} - -template -inline Type get(Type Bundle::* p, DIRECTED_GRAPH const& g, Key const& k) -{ return get(p, g.impl(), k); } - -template -inline void put(Type Bundle::* p, DIRECTED_GRAPH& g, Key const& k, Value const& v) -{ put(p, g.impl(), k, v); } -#endif - // Vertex index management template diff --git a/include/boost/graph/edmonds_karp_max_flow.hpp b/include/boost/graph/edmonds_karp_max_flow.hpp index 6aba1d05..62d1271c 100644 --- a/include/boost/graph/edmonds_karp_max_flow.hpp +++ b/include/boost/graph/edmonds_karp_max_flow.hpp @@ -140,7 +140,7 @@ namespace boost { } }; template<> - struct edmonds_karp_dispatch2 { + struct edmonds_karp_dispatch2 { template static typename edge_capacity_value::type apply @@ -149,7 +149,7 @@ namespace boost { typename graph_traits::vertex_descriptor sink, PredMap pred, const bgl_named_params& params, - detail::error_property_not_found) + param_not_found) { typedef typename graph_traits::edge_descriptor edge_descriptor; typedef typename graph_traits::vertices_size_type size_type; @@ -183,13 +183,13 @@ namespace boost { const bgl_named_params& params, PredMap pred) { - typedef typename property_value< bgl_named_params, vertex_color_t>::type C; + typedef typename get_param_type< bgl_named_params, vertex_color_t>::type C; return edmonds_karp_dispatch2::apply (g, src, sink, pred, params, get_param(params, vertex_color)); } }; template<> - struct edmonds_karp_dispatch1 { + struct edmonds_karp_dispatch1 { template static typename edge_capacity_value::type @@ -198,7 +198,7 @@ namespace boost { typename graph_traits::vertex_descriptor src, typename graph_traits::vertex_descriptor sink, const bgl_named_params& params, - detail::error_property_not_found) + param_not_found) { typedef typename graph_traits::edge_descriptor edge_descriptor; typedef typename graph_traits::vertices_size_type size_type; @@ -206,7 +206,7 @@ namespace boost { num_vertices(g) : 1; std::vector pred_vec(n); - typedef typename property_value< bgl_named_params, vertex_color_t>::type C; + typedef typename get_param_type< bgl_named_params, vertex_color_t>::type C; return edmonds_karp_dispatch2::apply (g, src, sink, make_iterator_property_map(pred_vec.begin(), choose_const_pmap @@ -227,7 +227,7 @@ namespace boost { typename graph_traits::vertex_descriptor sink, const bgl_named_params& params) { - typedef typename property_value< bgl_named_params, vertex_predecessor_t>::type Pred; + typedef typename get_param_type< bgl_named_params, vertex_predecessor_t>::type Pred; return detail::edmonds_karp_dispatch1::apply (g, src, sink, params, get_param(params, vertex_predecessor)); } diff --git a/include/boost/graph/fruchterman_reingold.hpp b/include/boost/graph/fruchterman_reingold.hpp index 4ce502e8..b10ced64 100644 --- a/include/boost/graph/fruchterman_reingold.hpp +++ b/include/boost/graph/fruchterman_reingold.hpp @@ -363,7 +363,7 @@ namespace detail { }; template<> - struct fr_force_directed_layout + struct fr_force_directed_layout { template& params) { typedef typename Topology::point_difference_type PointDiff; @@ -404,7 +404,7 @@ fruchterman_reingold_force_directed_layout const Topology& topology, const bgl_named_params& params) { - typedef typename property_value, + typedef typename get_param_type, vertex_displacement_t>::type D; detail::fr_force_directed_layout::run diff --git a/include/boost/graph/graph_traits.hpp b/include/boost/graph/graph_traits.hpp index fad82f9d..eb0232d8 100644 --- a/include/boost/graph/graph_traits.hpp +++ b/include/boost/graph/graph_traits.hpp @@ -15,8 +15,11 @@ #include /* Primarily for std::pair */ #include #include +#include #include #include +#include +#include #include #include #include @@ -218,28 +221,31 @@ namespace boost { //?? not the right place ?? Lee typedef boost::forward_traversal_tag multi_pass_input_iterator_tag; - // Forward declare graph_bundle_t property name (from - // boost/graph/properties.hpp, which includes this file) for - // bundled_result. - enum graph_bundle_t {graph_bundle}; + namespace detail { + BOOST_MPL_HAS_XXX_TRAIT_DEF(graph_property_type) + BOOST_MPL_HAS_XXX_TRAIT_DEF(edge_property_type) + BOOST_MPL_HAS_XXX_TRAIT_DEF(vertex_property_type) + + template struct get_graph_property_type {typedef typename G::graph_property_type type;}; + template struct get_edge_property_type {typedef typename G::edge_property_type type;}; + template struct get_vertex_property_type {typedef typename G::vertex_property_type type;}; + } template - struct graph_property_type { - typedef typename G::graph_property_type type; - }; + struct graph_property_type + : boost::mpl::eval_if, + detail::get_graph_property_type, + boost::mpl::void_> {}; template - struct edge_property_type { - typedef typename G::edge_property_type type; - }; + struct edge_property_type + : boost::mpl::eval_if, + detail::get_edge_property_type, + boost::mpl::void_> {}; template - struct vertex_property_type { - typedef typename G::vertex_property_type type; - }; - - struct no_bundle { }; - struct no_graph_bundle : no_bundle { }; - struct no_vertex_bundle : no_bundle { }; - struct no_edge_bundle : no_bundle { }; + struct vertex_property_type + : boost::mpl::eval_if, + detail::get_vertex_property_type, + boost::mpl::void_> {}; template struct graph_bundle_type { @@ -281,7 +287,7 @@ namespace boost { // A helper metafunction for determining whether or not a type is // bundled. template - struct is_no_bundle : mpl::bool_::value> + struct is_no_bundle : mpl::bool_::value> { }; } // namespace graph_detail diff --git a/include/boost/graph/named_function_params.hpp b/include/boost/graph/named_function_params.hpp index c5e35fa5..ea4690b6 100644 --- a/include/boost/graph/named_function_params.hpp +++ b/include/boost/graph/named_function_params.hpp @@ -111,15 +111,16 @@ namespace boost { BOOST_BGL_ONE_PARAM_REF(max_priority_queue, max_priority_queue) template - struct bgl_named_params : public Base + struct bgl_named_params { typedef bgl_named_params self; typedef Base next_type; typedef Tag tag_type; typedef T value_type; bgl_named_params(T v = T()) : m_value(v) { } - bgl_named_params(T v, const Base& b) : Base(b), m_value(v) { } + bgl_named_params(T v, const Base& b) : m_value(v), m_base(b) { } T m_value; + Base m_base; #define BOOST_BGL_ONE_PARAM_REF(name, key) \ template \ @@ -182,145 +183,142 @@ BOOST_BGL_DECLARE_NAMED_PARAMS //=========================================================================== // Functions for extracting parameters from bgl_named_params - template + template + struct lookup_named_param {}; + + template + struct lookup_named_param > { + typedef T type; + static const T& get(const bgl_named_params& p) { + return p.m_value; + } + }; + + template + struct lookup_named_param > { + typedef typename lookup_named_param::type type; + static const type& get(const bgl_named_params& p) { + return lookup_named_param::get(p.m_base); + } + }; + + template + struct lookup_named_param_def { + typedef Def type; + static const Def& get(const Args&, const Def& def) {return def;} + }; + + template + struct lookup_named_param_def, Def> { + typedef T type; + static const type& get(const bgl_named_params& p, const Def&) { + return p.m_value; + } + }; + + template + struct lookup_named_param_def, Def> { + typedef typename lookup_named_param_def::type type; + static const type& get(const bgl_named_params& p, const Def& def) { + return lookup_named_param_def::get(p.m_base, def); + } + }; + + struct param_not_found {}; + + template + struct get_param_type: + lookup_named_param_def {}; + + template inline - typename property_value< bgl_named_params, Tag2>::type - get_param(const bgl_named_params& p, Tag2 tag2) - { - enum { match = detail::same_property::value }; - typedef typename - property_value< bgl_named_params, Tag2>::type T2; - T2* t2 = 0; - typedef detail::property_value_dispatch Dispatcher; - return Dispatcher::const_get_value(p, t2, tag2); + const typename lookup_named_param_def::type& + get_param(const Args& p, Tag) { + return lookup_named_param_def::get(p, param_not_found()); } - - namespace detail { - // MSVC++ workaround - template - struct choose_param_helper { - template struct result { typedef Param type; }; - template - static const Param& apply(const Param& p, const Default&) { return p; } - }; - template <> - struct choose_param_helper { - template struct result { typedef Default type; }; - template - static const Default& apply(const error_property_not_found&, const Default& d) - { return d; } - }; - } // namespace detail - template - const typename detail::choose_param_helper

::template result::type& - choose_param(const P& param, const Default& d) { - return detail::choose_param_helper

::apply(param, d); + const P& choose_param(const P& param, const Default&) { + return param; + } + + template + Default choose_param(const param_not_found&, const Default& d) { + return d; } template inline bool is_default_param(const T&) { return false; } - inline bool is_default_param(const detail::error_property_not_found&) + inline bool is_default_param(const param_not_found&) { return true; } namespace detail { + template + struct const_type_as_type {typedef typename T::const_type type;}; + } // namespace detail + - struct choose_parameter { - template - struct bind_ { - typedef const P& const_result_type; - typedef const P& result_type; - typedef P type; - }; + // Use this function instead of choose_param() when you want + // to avoid requiring get(tag, g) when it is not used. + namespace detail { + template + struct choose_impl_result: + boost::mpl::eval_if< + boost::is_same, + boost::mpl::eval_if< + GraphIsConst, + detail::const_type_as_type >, + property_map >, + boost::mpl::identity > {}; - template - static typename bind_::const_result_type - const_apply(const P& p, const Graph&, Tag&) - { return p; } + // Parameters are (NotFound, GraphIsConst, Graph, Param, Tag) + template + typename property_map::const_type + choose_impl(boost::mpl::true_, boost::mpl::true_, const Graph& g, const Param&, PropertyTag tag) { + return get(tag, g); + } - template - static typename bind_::result_type - apply(const P& p, Graph&, Tag&) - { return p; } - }; + template + typename property_map::type + choose_impl(boost::mpl::true_, boost::mpl::false_, Graph& g, const Param&, PropertyTag tag) { + return get(tag, g); + } - struct choose_default_param { - template - struct bind_ { - typedef typename property_map::type - result_type; - typedef typename property_map::const_type - const_result_type; - typedef typename property_map::const_type - type; - }; + template + Param + choose_impl(boost::mpl::false_, GraphIsConst, const Graph&, const Param& p, PropertyTag) { + return p; + } + } - template - static typename bind_::const_result_type - const_apply(const P&, const Graph& g, Tag tag) { - return get(tag, g); - } - template - static typename bind_::result_type - apply(const P&, Graph& g, Tag tag) { - return get(tag, g); - } - }; + template + typename detail::choose_impl_result::type + choose_const_pmap(const Param& p, const Graph& g, PropertyTag tag) + { + return detail::choose_impl(boost::mpl::bool_::value>(), + boost::mpl::true_(), g, p, tag); + } - template - struct choose_property_map { - typedef choose_parameter type; - }; - template <> - struct choose_property_map { - typedef choose_default_param type; - }; + template + typename detail::choose_impl_result::type + choose_pmap(const Param& p, Graph& g, PropertyTag tag) + { + return detail::choose_impl(boost::mpl::bool_::value>(), + boost::mpl::false_(), g, p, tag); + } - template - struct choose_pmap_helper { - typedef typename choose_property_map::type Selector; - typedef typename Selector:: template bind_ Bind; - typedef Bind type; - typedef typename Bind::result_type result_type; - typedef typename Bind::const_result_type const_result_type; - typedef typename Bind::type result; - }; + namespace detail { // used in the max-flow algorithms template struct edge_capacity_value { typedef bgl_named_params Params; - typedef typename property_value< Params, edge_capacity_t>::type Param; - typedef typename detail::choose_pmap_helper::result CapacityEdgeMap; + typedef typename detail::choose_impl_result::type, edge_capacity_t>::type CapacityEdgeMap; typedef typename property_traits::value_type type; }; - } // namespace detail - - - // Use this function instead of choose_param() when you want - // to avoid requiring get(tag, g) when it is not used. - template - typename - detail::choose_pmap_helper::const_result_type - choose_const_pmap(const Param& p, const Graph& g, PropertyTag tag) - { - typedef typename - detail::choose_pmap_helper::Selector Choice; - return Choice::const_apply(p, g, tag); - } - - template - typename detail::choose_pmap_helper::result_type - choose_pmap(const Param& p, Graph& g, PropertyTag tag) - { - typedef typename - detail::choose_pmap_helper::Selector Choice; - return Choice::apply(p, g, tag); } // Declare all new tags @@ -353,7 +351,7 @@ BOOST_BGL_DECLARE_NAMED_PARAMS typedef convert_bgl_params_to_boost_parameter rest_conv; typedef boost::parameter::aux::arg_list type; static type conv(const T& x) { - return type(tagged_arg_type(x.m_value), rest_conv::conv(x)); + return type(tagged_arg_type(x.m_value), rest_conv::conv(x.m_base)); } }; @@ -362,7 +360,7 @@ BOOST_BGL_DECLARE_NAMED_PARAMS typedef convert_bgl_params_to_boost_parameter rest_conv; typedef typename rest_conv::type type; static type conv(const bgl_named_params& x) { - return rest_conv::conv(x); + return rest_conv::conv(x.m_base); } }; @@ -375,7 +373,7 @@ BOOST_BGL_DECLARE_NAMED_PARAMS template <> struct convert_bgl_params_to_boost_parameter { typedef boost::parameter::aux::empty_arg_list type; - static type conv(const boost::no_property&) {return type();} + static type conv(const boost::no_named_parameters&) {return type();} }; struct bgl_parameter_not_found_type {}; diff --git a/include/boost/graph/named_graph.hpp b/include/boost/graph/named_graph.hpp index 38f4ca0e..f49c0970 100644 --- a/include/boost/graph/named_graph.hpp +++ b/include/boost/graph/named_graph.hpp @@ -155,51 +155,6 @@ struct internal_vertex_constructor > : internal_vertex_constructor { }; #endif -/******************************************************************* - * Named graph-specific metafunctions * - *******************************************************************/ -namespace detail { - /** @internal - * Extracts the type of a bundled vertex property from a vertex - * property. The primary template matches when we have hit the end - * of the @c property<> list. - */ - template - struct extract_bundled_vertex - { - typedef VertexProperty type; - }; - - /** @internal - * Recursively extract the bundled vertex property from a vertex - * property. - */ - template - struct extract_bundled_vertex > - : extract_bundled_vertex - { }; - - /** - * We have found the bundled vertex property type, marked with - * vertex_bundle_t. - */ - template - struct extract_bundled_vertex > - { - typedef T type; - }; - - /** - * Translate @c no_property into @c error_property_not_found when we - * have failed to extract a bundled vertex property type. - */ - template<> - struct extract_bundled_vertex - { - typedef boost::detail::error_property_not_found type; - }; -} - /******************************************************************* * Named graph mixin * *******************************************************************/ @@ -228,7 +183,7 @@ public: typedef typename internal_vertex_name::type extract_name_type; /// The type of the "bundled" property, from which the name can be /// extracted. - typedef typename detail::extract_bundled_vertex::type + typedef typename lookup_one_property::type bundled_vertex_property_type; /// The type of the function object that generates vertex properties @@ -477,7 +432,7 @@ struct maybe_named_graph { /// The type of the "bundled" property, from which the name can be /// extracted. - typedef typename detail::extract_bundled_vertex::type + typedef typename lookup_one_property::type bundled_vertex_property_type; /// Notify the named_graph that we have added the given vertex. This diff --git a/include/boost/graph/neighbor_bfs.hpp b/include/boost/graph/neighbor_bfs.hpp index 4585f2e2..edfcbbb4 100644 --- a/include/boost/graph/neighbor_bfs.hpp +++ b/include/boost/graph/neighbor_bfs.hpp @@ -250,13 +250,13 @@ namespace boost { }; template <> - struct neighbor_bfs_dispatch { + struct neighbor_bfs_dispatch { template static void apply (VertexListGraph& g, typename graph_traits::vertex_descriptor s, const bgl_named_params& params, - detail::error_property_not_found) + param_not_found) { std::vector color_vec(num_vertices(g)); null_visitor null_vis; @@ -288,7 +288,7 @@ namespace boost { // graph is not really const since we may write to property maps // of the graph. VertexListGraph& ng = const_cast(g); - typedef typename property_value< bgl_named_params, + typedef typename get_param_type< bgl_named_params, vertex_color_t>::type C; detail::neighbor_bfs_dispatch::apply(ng, s, params, get_param(params, vertex_color)); diff --git a/include/boost/graph/properties.hpp b/include/boost/graph/properties.hpp index bc498bbf..40a39da7 100644 --- a/include/boost/graph/properties.hpp +++ b/include/boost/graph/properties.hpp @@ -68,26 +68,20 @@ namespace boost { struct vertex_property_tag { }; struct edge_property_tag { }; -#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION // See examples/edge_property.cpp for how to use this. #define BOOST_INSTALL_PROPERTY(KIND, NAME) \ template <> struct property_kind { \ typedef KIND##_property_tag type; \ } -#else -#define BOOST_INSTALL_PROPERTY(KIND, NAME) \ - template <> struct property_kind { \ - typedef KIND##_property_tag type; \ - } -#endif #define BOOST_DEF_PROPERTY(KIND, NAME) \ enum KIND##_##NAME##_t { KIND##_##NAME }; \ BOOST_INSTALL_PROPERTY(KIND, NAME) - BOOST_DEF_PROPERTY(vertex, all); - BOOST_DEF_PROPERTY(edge, all); - BOOST_DEF_PROPERTY(graph, all); + // These three are defined in boost/pending/property.hpp + BOOST_INSTALL_PROPERTY(vertex, all); + BOOST_INSTALL_PROPERTY(edge, all); + BOOST_INSTALL_PROPERTY(graph, all); BOOST_DEF_PROPERTY(vertex, index); BOOST_DEF_PROPERTY(vertex, index1); BOOST_DEF_PROPERTY(vertex, index2); @@ -128,10 +122,10 @@ namespace boost { BOOST_DEF_PROPERTY(graph, visitor); // These tags are used for property bundles - // BOOST_DEF_PROPERTY(graph, bundle); -- needed in graph_traits.hpp, so enum is defined there + // These three are defined in boost/pending/property.hpp BOOST_INSTALL_PROPERTY(graph, bundle); - BOOST_DEF_PROPERTY(vertex, bundle); - BOOST_DEF_PROPERTY(edge, bundle); + BOOST_INSTALL_PROPERTY(vertex, bundle); + BOOST_INSTALL_PROPERTY(edge, bundle); // These tags are used to denote the owners and local descriptors // for the vertices and edges of a distributed graph. @@ -148,6 +142,25 @@ namespace boost { namespace detail { + template + struct property_kind_from_graph: property_kind {}; + +#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES + template + struct property_kind_from_graph { + typedef typename boost::mpl::if_< + boost::is_same::type>, + vertex_property_tag, + typename boost::mpl::if_< + boost::is_same::type>, + edge_property_tag, + typename boost::mpl::if_< + boost::is_same::type>, + graph_property_tag, + void>::type>::type>::type type; + }; +#endif + struct dummy_edge_property_selector { template struct bind_ { @@ -213,45 +226,16 @@ namespace boost { 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. - 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 { - // VC++ gets confused if this isn't defined, even though - // this never gets used. - typedef choose_vertex_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 struct property_map { // private: - typedef typename property_kind::type Kind; - typedef typename detail::property_map_kind_selector::type Selector; - typedef typename Selector::template bind_ Bind; - typedef typename Bind::type Map; + typedef typename detail::property_kind_from_graph::type Kind; + typedef typename mpl::if_< + is_same, + detail::edge_property_map, + detail::vertex_property_map >::type Map; public: typedef typename Map::type type; typedef typename Map::const_type const_type; @@ -273,16 +257,8 @@ namespace boost { >::type type; }; - template - class vertex_property { - public: - typedef typename Graph::vertex_property_type type; - }; - template - class edge_property { - public: - typedef typename Graph::edge_property_type type; - }; + template class vertex_property: vertex_property_type {}; + template class edge_property: edge_property_type {}; template class degree_property_map @@ -383,99 +359,6 @@ namespace boost { # define BOOST_GRAPH_NO_BUNDLED_PROPERTIES #endif -#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES - template - struct bundle_property_map - : put_get_helper > - { - typedef Descriptor key_type; - typedef typename remove_const::type value_type; - typedef T& reference; - typedef lvalue_property_map_tag category; - - bundle_property_map() { } - bundle_property_map(Graph* g_, T Bundle::* pm_) : g(g_), pm(pm_) {} - - reference operator[](key_type k) const { return (*g)[k].*pm; } - private: - Graph* g; - T Bundle::* pm; - }; - - namespace detail { - template - struct is_vertex_bundle - : mpl::and_, - mpl::and_ >, - mpl::not_ > > > - { }; - } - - // Specialize the property map template to generate bundled property maps. - template - struct property_map - { - private: - typedef graph_traits traits; - typedef typename Graph::vertex_bundled vertex_bundled; - typedef typename Graph::edge_bundled edge_bundled; - typedef typename mpl::if_c<(detail::is_vertex_bundle::value), - typename traits::vertex_descriptor, - typename traits::edge_descriptor>::type - descriptor; - typedef typename mpl::if_c<(detail::is_vertex_bundle::value), - vertex_bundled, - edge_bundled>::type - actual_bundle; - - public: - typedef bundle_property_map type; - typedef bundle_property_map - const_type; - }; -#endif - -// These metafunctions help implement the process of determining the vertex -// and edge properties of a graph. -namespace graph_detail { - template - struct retagged_property { - typedef typename Retag::type type; - }; - - // Search the normalized PropList (as returned by retagged<>::type) for - // the given bundle. Return the type error if no such bundle can be found. - template - struct retagged_bundle { - typedef typename property_value::type Value; - typedef typename mpl::if_< - is_same, no_bundle, Value - >::type type; - }; - - template - class normal_property { - // Normalize the property into a property list. - typedef detail::retag_property_list List; - public: - // Extract the normalized property and bundle types. - typedef typename retagged_property::type property; - typedef typename retagged_bundle::type bundle; - }; - - template - struct graph_prop : normal_property - { }; - - template - struct vertex_prop : normal_property - { }; - - template - struct edge_prop : normal_property - { }; -} // namespace graph_detail - // NOTE: These functions are declared, but never defined since they need to // be overloaded by graph implementations. However, we need them to be // declared for the functions below. @@ -498,17 +381,11 @@ get_property(Graph& g) { template inline typename graph_property::type const& -get_property(Graph const& g) { +get_property(const Graph& g) { return get_property(g, graph_bundle); } #endif } // namespace boost -#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) -// Stay out of the way of the concept checking class -# undef Graph -# undef RandomAccessIterator -#endif - -#endif /* BOOST_GRAPH_PROPERTIES_HPPA */ +#endif /* BOOST_GRAPH_PROPERTIES_HPP */ diff --git a/include/boost/graph/reverse_graph.hpp b/include/boost/graph/reverse_graph.hpp index 48c4e057..84509a33 100644 --- a/include/boost/graph/reverse_graph.hpp +++ b/include/boost/graph/reverse_graph.hpp @@ -358,36 +358,23 @@ namespace detail { } }; - struct reverse_graph_vertex_property_selector { - template - struct bind_ { - typedef typename ReverseGraph::base_type Graph; - typedef property_map PMap; - typedef typename PMap::type type; - typedef typename PMap::const_type const_type; - }; - }; - - struct reverse_graph_edge_property_selector { - template - struct bind_ { - typedef typename ReverseGraph::base_type Graph; - typedef property_map PMap; - typedef reverse_graph_edge_property_map type; - typedef reverse_graph_edge_property_map const_type; - }; - }; - } // namespace detail -template <> -struct vertex_property_selector { - typedef detail::reverse_graph_vertex_property_selector type; +template +struct property_map, Property> { + typedef boost::is_same::type, edge_property_tag> is_edge_prop; + typedef typename property_map::type orig_type; + typedef typename property_map::const_type orig_const_type; + typedef typename boost::mpl::if_, orig_type>::type type; + typedef typename boost::mpl::if_, orig_const_type>::type const_type; }; -template <> -struct edge_property_selector { - typedef detail::reverse_graph_edge_property_selector type; +template +struct property_map, Property> { + typedef boost::is_same::type, edge_property_tag> is_edge_prop; + typedef typename property_map::const_type orig_const_type; + typedef typename boost::mpl::if_, orig_const_type>::type const_type; + typedef const_type type; }; template @@ -407,7 +394,7 @@ get(Property p, const reverse_graph& g) template typename property_traits< - typename property_map::const_type + typename property_map, Property>::const_type >::value_type get(Property p, const reverse_graph& g, const Key& k) { @@ -459,6 +446,23 @@ struct property_map, edge_underlying_t> { typedef detail::underlying_edge_desc_map_type const_type; }; +template +detail::underlying_edge_desc_map_type::edge_descriptor> +get(edge_underlying_t, + reverse_graph& g) +{ + return detail::underlying_edge_desc_map_type::edge_descriptor>(); +} + +template +typename graph_traits::edge_descriptor +get(edge_underlying_t, + reverse_graph& g, + const typename graph_traits >::edge_descriptor& k) +{ + return k.underlying_descx; +} + template detail::underlying_edge_desc_map_type::edge_descriptor> get(edge_underlying_t, diff --git a/include/boost/graph/strong_components.hpp b/include/boost/graph/strong_components.hpp index ba5d4590..61345bdc 100644 --- a/include/boost/graph/strong_components.hpp +++ b/include/boost/graph/strong_components.hpp @@ -131,7 +131,7 @@ namespace boost { template <> - struct strong_comp_dispatch2 { + struct strong_comp_dispatch2 { template inline static typename property_traits::value_type @@ -139,7 +139,7 @@ namespace boost { ComponentMap comp, RootMap r_map, const bgl_named_params& params, - detail::error_property_not_found) + param_not_found) { typedef typename graph_traits::vertices_size_type size_type; size_type n = num_vertices(g) > 0 ? num_vertices(g) : 1; @@ -179,7 +179,7 @@ namespace boost { } }; template <> - struct strong_comp_dispatch1 { + struct strong_comp_dispatch1 { template @@ -187,7 +187,7 @@ namespace boost { apply(const Graph& g, ComponentMap comp, const bgl_named_params& params, - detail::error_property_not_found) + param_not_found) { typedef typename graph_traits::vertex_descriptor Vertex; typename std::vector::size_type diff --git a/include/boost/graph/subgraph.hpp b/include/boost/graph/subgraph.hpp index 1860c8ce..2f529add 100644 --- a/include/boost/graph/subgraph.hpp +++ b/include/boost/graph/subgraph.hpp @@ -103,13 +103,11 @@ public: typedef typename Traits::in_edge_iterator in_edge_iterator; - typedef typename Graph::edge_property_type edge_property_type; - typedef typename Graph::vertex_property_type vertex_property_type; - typedef typename Graph::vertex_bundled vertex_bundled; - typedef typename Graph::edge_bundled edge_bundled; + typedef typename edge_property_type::type edge_property_type; + typedef typename vertex_property_type::type vertex_property_type; typedef subgraph_tag graph_tag; typedef Graph graph_type; - typedef typename Graph::graph_property_type graph_property_type; + typedef typename graph_property_type::type graph_property_type; // Create the main graph, the root of the subgraph tree subgraph() @@ -348,9 +346,6 @@ public: // Probably shouldn't be public.... } }; -#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES -// TODO: I don't think these are required since the default metafunction -// returns Graph::vertex_bundled. template struct vertex_bundle_type > : vertex_bundle_type @@ -360,7 +355,11 @@ template struct edge_bundle_type > : edge_bundle_type { }; -#endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES + +template +struct graph_bundle_type > + : graph_bundle_type +{ }; //=========================================================================== // Functions special to the Subgraph Class @@ -786,18 +785,19 @@ public: subgraph_global_property_map() { } - subgraph_global_property_map(GraphPtr g) - : m_g(g) + subgraph_global_property_map(GraphPtr g, Tag tag) + : m_g(g), m_tag(tag) { } reference operator[](key_type e) const { - PropertyMap pmap = get(Tag(), m_g->root().m_graph); + PropertyMap pmap = get(m_tag, m_g->root().m_graph); return m_g->is_root() ? pmap[e] : pmap[m_g->local_to_global(e)]; } GraphPtr m_g; + Tag m_tag; }; /** @@ -824,17 +824,18 @@ public: subgraph_local_property_map() { } - subgraph_local_property_map(GraphPtr g) - : m_g(g) + subgraph_local_property_map(GraphPtr g, Tag tag) + : m_g(g), m_tag(tag) { } reference operator[](key_type e) const { // Get property map on the underlying graph. - PropertyMap pmap = get(Tag(), m_g->m_graph); + PropertyMap pmap = get(m_tag, m_g->m_graph); return pmap[e]; } GraphPtr m_g; + Tag m_tag; }; namespace detail { @@ -949,139 +950,37 @@ struct edge_property_selector { typedef detail::subgraph_property_generator type; }; -#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES -/** @internal - * This property map implements local or global bundled property access on - * an underlying graph. The LocalGlobal template template parameter must be - * one of the local_property or global_property templates. - */ -template < - typename Graph, typename Descriptor, typename Bundle, typename T, - template class LocalGlobal> -struct subgraph_lg_bundle_property_map - : put_get_helper< - T&, - subgraph_lg_bundle_property_map - > -{ -private: - typedef LocalGlobal Wrap; -public: - typedef Descriptor key_type; - typedef typename remove_const::type value_type; - typedef T& reference; - typedef lvalue_property_map_tag category; - - subgraph_lg_bundle_property_map() - { } - - subgraph_lg_bundle_property_map(Graph* g, T Bundle::* p) - : m_g(g), m_prop(p) - { } - - reference operator[](key_type k) const - { return (*m_g)[Wrap(k)].*m_prop; } - -private: - Graph* m_g; - T Bundle::* m_prop; -}; - -// Specialize the property map template to generate bundled property maps. -// NOTE: I'm cheating (actually double-dipping) with the local/global subgraph -// property templates. I'm not using them store descriptors, just specialize -// the property map template for specific lookups. -namespace graph_detail { - // Help decoding some of the types required for property map definitions. - template - struct bundled_subgraph_pmap_helper { - typedef subgraph Subgraph; - typedef graph_traits Traits; - typedef typename Subgraph::vertex_bundled VertBundled; - typedef typename Subgraph::edge_bundled EdgeBundled; - - // Deduce the descriptor from the template params - typedef typename mpl::if_< - detail::is_vertex_bundle, - typename Traits::vertex_descriptor, typename Traits::edge_descriptor - >::type Desc; - - // Deduce the bundled property type - typedef typename mpl::if_< - detail::is_vertex_bundle, - VertBundled, EdgeBundled - >::type Prop; - }; -} // namespace graph_detail - -template -struct property_map, local_property > - : graph_detail::bundled_subgraph_pmap_helper -{ -private: - typedef graph_detail::bundled_subgraph_pmap_helper Base; - typedef typename Base::Subgraph Subgraph; - typedef typename Base::Desc Desc; - typedef typename Base::Prop Prop; -public: - typedef subgraph_lg_bundle_property_map< - Subgraph, Desc, Prop, T, local_property - > type; - typedef subgraph_lg_bundle_property_map< - Subgraph const, Desc, Prop, T const, local_property - > const_type; -}; - -template -struct property_map, global_property > - : graph_detail::bundled_subgraph_pmap_helper -{ -private: - typedef graph_detail::bundled_subgraph_pmap_helper Base; - typedef typename Base::Subgraph Subgraph; - typedef typename Base::Desc Desc; - typedef typename Base::Prop Prop; -public: - typedef subgraph_lg_bundle_property_map< - Subgraph, Desc, Prop, T, global_property - > type; - typedef subgraph_lg_bundle_property_map< - Subgraph const, Desc, Prop, T const, global_property - > const_type; -}; -#endif - // ================================================== // get(p, g), get(p, g, k), and put(p, g, k, v) // ================================================== template typename property_map, Property>::type -get(Property, subgraph& g) { +get(Property p, subgraph& g) { typedef typename property_map< subgraph, Property>::type PMap; - return PMap(&g); + return PMap(&g, p); } template typename property_map, Property>::const_type -get(Property, const subgraph& g) { +get(Property p, const subgraph& g) { typedef typename property_map< subgraph, Property>::const_type PMap; - return PMap(&g); + return PMap(&g, p); } template typename property_traits< typename property_map, Property>::const_type >::value_type -get(Property, const subgraph& g, const Key& k) { +get(Property p, const subgraph& g, const Key& k) { typedef typename property_map< subgraph, Property>::const_type PMap; - PMap pmap(&g); + PMap pmap(&g, p); return pmap[k]; } template -void put(Property, subgraph& g, const Key& k, const Value& val) { +void put(Property p, subgraph& g, const Key& k, const Value& val) { typedef typename property_map< subgraph, Property>::type PMap; - PMap pmap(&g); + PMap pmap(&g, p); pmap[k] = val; } @@ -1091,20 +990,20 @@ void put(Property, subgraph& g, const Key& k, const Value& val) { // ================================================== template typename property_map, global_property >::type -get(global_property, subgraph& g) { +get(global_property p, subgraph& g) { typedef typename property_map< subgraph, global_property >::type Map; - return Map(&g); + return Map(&g, p.value); } template typename property_map, global_property >::const_type -get(global_property, const subgraph& g) { +get(global_property p, const subgraph& g) { typedef typename property_map< subgraph, global_property >::const_type Map; - return Map(&g); + return Map(&g, p.value); } // ================================================== @@ -1113,112 +1012,22 @@ get(global_property, const subgraph& g) { // ================================================== template typename property_map, local_property >::type -get(local_property, subgraph& g) { +get(local_property p, subgraph& g) { typedef typename property_map< subgraph, local_property >::type Map; - return Map(&g); + return Map(&g, p.value); } template typename property_map, local_property >::const_type -get(local_property, const subgraph& g) { +get(local_property p, const subgraph& g) { typedef typename property_map< subgraph, local_property >::const_type Map; - return Map(&g); -} - -#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES -// ================================================== -// get(bundle(p), g) -// ================================================== - -template -inline typename property_map, T Bundle::*>::type -get(T Bundle::* p, subgraph& g) { - typedef typename property_map, T Bundle::*>::type Map; - return Map(&g, p); -} - -template -inline typename property_map, T Bundle::*>::const_type -get(T Bundle::* p, subgraph const& g) { - typedef typename property_map, T Bundle::*>::const_type Map; - return Map(&g, p); -} - -template -inline Type get(Type Bundle::* p, subgraph const& g, Key const& k) -{ return get(get(p, g), k); } - -template -inline void put(Type Bundle::* p, Graph& g, Key const& k, Value const& v) -{ put(get(p, g), k, v); } - -// ========================================================= -// Local bundled, get - -template -inline typename property_map< - subgraph, local_property ->::type -get(local_property p, subgraph& g) { - typedef typename property_map< - subgraph, local_property - >::type Map; return Map(&g, p.value); } -template -inline typename property_map< - subgraph, local_property ->::const_type -get(local_property p, subgraph const& g) { - typedef typename property_map< - subgraph, local_property - >::const_type Map; - return Map(&g, p.value); -} - -template -inline Type get(local_property p, subgraph const& g, - Key const& k) -{ return get(get(p, g), k); } - -// ========================================================= -// Global bundled, get - -template -inline typename property_map< - subgraph, global_property ->::type -get(global_property p, subgraph& g) { - typedef typename property_map< - subgraph, global_property - >::type Map; - return Map(&g, p.value); -} - -template -inline typename property_map< - subgraph, global_property ->::const_type -get(global_property p, subgraph const& g) { - typedef typename property_map< - subgraph, global_property - >::const_type Map; - return Map(&g, p.value); -} - -template -inline Type get(global_property p, subgraph const& g, - Key const& k) -{ return get(get(p, g), k); } - -#endif - template inline typename graph_property::type& get_property(subgraph& g, Tag tag) { diff --git a/include/boost/graph/undirected_dfs.hpp b/include/boost/graph/undirected_dfs.hpp index df31d22b..0dcc9c28 100644 --- a/include/boost/graph/undirected_dfs.hpp +++ b/include/boost/graph/undirected_dfs.hpp @@ -188,7 +188,7 @@ namespace boost { }; template <> - struct udfs_dispatch { + struct udfs_dispatch { template @@ -196,7 +196,7 @@ namespace boost { apply(const Graph& g, DFSVisitor vis, Vertex start_vertex, const bgl_named_params& params, EdgeColorMap edge_color, - detail::error_property_not_found) + param_not_found) { std::vector color_vec(num_vertices(g)); default_color_type c = white_color; // avoid warning about un-init @@ -219,7 +219,7 @@ namespace boost { undirected_dfs(const Graph& g, const bgl_named_params& params) { - typedef typename property_value< bgl_named_params, + typedef typename get_param_type< bgl_named_params, vertex_color_t>::type C; detail::udfs_dispatch::apply (g, diff --git a/include/boost/graph/undirected_graph.hpp b/include/boost/graph/undirected_graph.hpp index 3178b42a..884f5dbe 100644 --- a/include/boost/graph/undirected_graph.hpp +++ b/include/boost/graph/undirected_graph.hpp @@ -38,14 +38,12 @@ template < class undirected_graph { public: - typedef typename graph_detail::graph_prop::property graph_property_type; - typedef typename graph_detail::graph_prop::bundle graph_bundled; - - typedef typename graph_detail::vertex_prop::property vertex_property_type; - typedef typename graph_detail::vertex_prop::bundle vertex_bundled; - - typedef typename graph_detail::edge_prop::property edge_property_type; - typedef typename graph_detail::edge_prop::bundle edge_bundled; + typedef GraphProp graph_property_type; + typedef VertexProp vertex_property_type; + typedef EdgeProp edge_property_type; + typedef typename lookup_one_property::type graph_bundled; + typedef typename lookup_one_property::type vertex_bundled; + typedef typename lookup_one_property::type edge_bundled; private: // Embed indices into the vertex type. @@ -530,36 +528,12 @@ remove_in_edge_if(typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH& g) { return remove_in_edge_if(v, pred, g.impl()); } -// Helper code for working with property maps -namespace detail { - struct undirected_graph_vertex_property_selector { - template - struct bind_ { - typedef typename UndirectedGraph::graph_type Graph; - typedef property_map PropertyMap; - typedef typename PropertyMap::type type; - typedef typename PropertyMap::const_type const_type; - }; - }; - - struct undirected_graph_edge_property_selector { - template - struct bind_ { - typedef typename UndirectedGraph::graph_type Graph; - typedef property_map PropertyMap; - typedef typename PropertyMap::type type; - typedef typename PropertyMap::const_type const_type; - }; - }; -} // namespace detail - -template <> -struct vertex_property_selector -{ typedef detail::undirected_graph_vertex_property_selector type; }; - -template <> -struct edge_property_selector -{ typedef detail::undirected_graph_edge_property_selector type; }; +template +struct property_map { + typedef typename UNDIRECTED_GRAPH::graph_type Graph; + typedef typename property_map::type type; + typedef typename property_map::const_type const_type; +}; // PropertyGraph concepts template @@ -599,36 +573,6 @@ template inline void set_property(UNDIRECTED_GRAPH& g, Property p, Value v) { return set_property(g.impl(), p, v); } -#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES -template -inline typename property_map::type -get(Type Bundle::* p, UNDIRECTED_GRAPH& g) { - typedef typename property_map< - UNDIRECTED_GRAPH, Type Bundle::* - >::type return_type; - return return_type(&g, p); -} - -template -inline typename property_map::const_type -get(Type Bundle::* p, UNDIRECTED_GRAPH const& g) { - typedef typename property_map< - UNDIRECTED_GRAPH, Type Bundle::* - >::const_type return_type; - return return_type(&g, p); -} - -template -inline Type -get(Type Bundle::* p, UNDIRECTED_GRAPH const& g, Key const& k) -{ return get(p, g.impl(), k); } - -template -inline void -put(Type Bundle::* p, UNDIRECTED_GRAPH& g, Key const& k, Value const& v) -{ put(p, g.impl(), k, v); } -#endif - // Indexed Vertex graph template diff --git a/include/boost/pending/detail/property.hpp b/include/boost/pending/detail/property.hpp index 09e8866c..42c7ce07 100644 --- a/include/boost/pending/detail/property.hpp +++ b/include/boost/pending/detail/property.hpp @@ -13,147 +13,8 @@ namespace boost { namespace detail { - template - struct same_property { - enum { value = is_same::value }; - }; - struct error_property_not_found { }; - template - struct property_value_dispatch { - template - inline static T& get_value(PropertyTag& p, T*, Tag) { - return p.m_value; - } - template - inline static const T& const_get_value(const PropertyTag& p, T*, Tag) { - return p.m_value; - } - }; - - template - struct property_value_end { - template struct result { typedef T type; }; - - template - inline static T& get_value(PropertyList& p, T* t, Tag tag) { - typedef typename PropertyList::next_type Next; - typedef typename Next::tag_type Next_tag; - enum { match = same_property::value }; - return property_value_dispatch - ::get_value(static_cast(p), t, tag); - } - template - inline static const T& const_get_value(const PropertyList& p, T* t, Tag tag) { - typedef typename PropertyList::next_type Next; - typedef typename Next::tag_type Next_tag; - enum { match = same_property::value }; - return property_value_dispatch - ::const_get_value(static_cast(p), t, tag); - } - }; - template <> - struct property_value_end { - template struct result { - typedef detail::error_property_not_found type; - }; - - // Stop the recursion and return error - template - inline static detail::error_property_not_found& - get_value(no_property&, T*, Tag) { - static error_property_not_found s_prop_not_found; - return s_prop_not_found; - } - template - inline static const detail::error_property_not_found& - const_get_value(const no_property&, T*, Tag) { - static error_property_not_found s_prop_not_found; - return s_prop_not_found; - } - }; - - template <> - struct property_value_dispatch<0> { - template - inline static typename property_value_end::template result::type& - get_value(PropertyList& p, T* t, Tag tag) { - return property_value_end::get_value(p, t, tag); - } - template - inline static const typename property_value_end::template result::type& - const_get_value(const PropertyList& p, T* t, Tag tag) { - return property_value_end::const_get_value(p, t, tag); - } - }; - - template - struct build_property_tag_value_alist - { - typedef typename PropertyList::next_type NextProperty; - typedef typename PropertyList::value_type Value; - typedef typename PropertyList::tag_type Tag; - typedef typename build_property_tag_value_alist::type Next; - typedef std::pair< std::pair, Next> type; - }; - template <> - struct build_property_tag_value_alist - { - typedef no_property type; - }; - -#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template - struct extract_value { - typedef error_property_not_found type; - }; - template - struct extract_value< std::pair,Rest>, Tag2> { - typedef typename extract_value::type type; - }; - template - struct extract_value< std::pair,Rest>, Tag> { - typedef Value type; - }; -#else - // VC++ workaround: - // The main idea here is to replace partial specialization with - // nested template member classes. Of course there is the - // further complication that the outer class of the nested - // template class cannot itself be a template class. - // Hence the need for the ev_selector. -JGS - - struct recursive_extract; - struct end_extract; - - template - struct ev_selector { typedef recursive_extract type; }; - template <> - struct ev_selector { typedef end_extract type; }; - - struct recursive_extract { - template - struct bind_ { - typedef typename TagValueAList::first_type AListFirst; - typedef typename AListFirst::first_type Tag2; - typedef typename AListFirst::second_type Value; - enum { match = same_property::value }; - typedef typename TagValueAList::second_type Next; - typedef typename ev_selector::type Extractor; - typedef typename boost::ct_if< match, Value, - typename Extractor::template bind_::type - >::type type; - }; - }; - struct end_extract { - template - struct bind_ { - typedef error_property_not_found type; - }; - }; -#endif //!defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - } // namespace detail } // namespace boost diff --git a/include/boost/pending/property.hpp b/include/boost/pending/property.hpp index c9880458..93b3cd84 100644 --- a/include/boost/pending/property.hpp +++ b/include/boost/pending/property.hpp @@ -7,32 +7,146 @@ #define BOOST_PROPERTY_HPP #include +#include +#include +#include namespace boost { - struct no_property { - typedef no_property tag_type; - typedef no_property next_type; - typedef no_property value_type; - enum { num = 0 }; - typedef void kind; - }; + struct no_property {}; template - struct property : public Base { + struct property { typedef Base next_type; typedef Tag tag_type; typedef T value_type; -#if BOOST_WORKAROUND (__GNUC__, < 3) - property() { } -#else - property() : m_value() { } -#endif - property(const T& v) : m_value(v) { } - property(const T& v, const Base& b) : Base(b), m_value(v) { } + property(const T& v = T()) : m_value(v) { } + property(const T& v, const Base& b) : m_value(v), m_base(b) { } // copy constructor and assignment operator will be generated by compiler T m_value; + Base m_base; + }; + + // Kinds of properties + template + struct property_kind { + typedef typename PropertyTag::kind type; + }; + + // Some standard properties defined independently of Boost.Graph: + enum vertex_all_t {vertex_all}; + enum edge_all_t {edge_all}; + enum graph_all_t {graph_all}; + enum vertex_bundle_t {vertex_bundle}; + enum edge_bundle_t {edge_bundle}; + enum graph_bundle_t {graph_bundle}; + + // Code to look up one property in a property list: + template + struct lookup_one_property_internal {BOOST_STATIC_CONSTANT(bool, found = false);}; + + // Special-case properties (vertex_all, edge_all, graph_all) +#define BGL_ALL_PROP(tag) \ + template \ + struct lookup_one_property_internal { \ + BOOST_STATIC_CONSTANT(bool, found = true); \ + typedef T type; \ + static T& lookup(T& x, tag) {return x;} \ + static const T& lookup(const T& x, tag) {return x;} \ + }; \ + template \ + struct lookup_one_property_internal, tag> { /* Avoid ambiguity */ \ + BOOST_STATIC_CONSTANT(bool, found = true); \ + typedef property type; \ + static type& lookup(type& x, tag) {return x;} \ + static const type& lookup(const type& x, tag) {return x;} \ + }; + + BGL_ALL_PROP(vertex_all_t) + BGL_ALL_PROP(edge_all_t) + BGL_ALL_PROP(graph_all_t) +#undef BGL_ALL_PROP + + // *_bundled; these need to be macros rather than inheritance to resolve ambiguities + #define BGL_DO_ONE_BUNDLE_TYPE(kind) \ + template \ + struct lookup_one_property_internal { \ + BOOST_STATIC_CONSTANT(bool, found = true); \ + typedef T type; \ + static T& lookup(T& x, BOOST_JOIN(kind, _bundle_t)) {return x;} \ + static const T& lookup(const T& x, BOOST_JOIN(kind, _bundle_t)) {return x;} \ + }; \ + \ + template \ + struct lookup_one_property_internal, BOOST_JOIN(kind, _bundle_t)>: lookup_one_property_internal { \ + private: \ + typedef lookup_one_property_internal base_type; \ + public: \ + static typename base_type::type& lookup(property& p, BOOST_JOIN(kind, _bundle_t)) {return base_type::lookup(p.m_base, BOOST_JOIN(kind, _bundle_t)());} \ + static const typename base_type::type& lookup(const property& p, BOOST_JOIN(kind, _bundle_t)) {return base_type::lookup(p.m_base, BOOST_JOIN(kind, _bundle_t)());} \ + }; \ + + BGL_DO_ONE_BUNDLE_TYPE(vertex) + BGL_DO_ONE_BUNDLE_TYPE(edge) + BGL_DO_ONE_BUNDLE_TYPE(graph) +#undef BGL_DO_ONE_BUNDLE_TYPE + + // Normal old-style properties; second case also handles chaining of bundled property accesses + template + struct lookup_one_property_internal, Tag> { + BOOST_STATIC_CONSTANT(bool, found = true); + typedef property prop; + typedef T type; + template + static typename enable_if, T&>::type + lookup(U& prop, const Tag&) {return prop.m_value;} + template + static typename enable_if, const T&>::type + lookup(const U& prop, const Tag&) {return prop.m_value;} + }; + + template + struct lookup_one_property_internal, PropName>: lookup_one_property_internal { + private: + typedef lookup_one_property_internal base_type; + public: + template + static typename enable_if >, typename base_type::type&>::type + lookup(PL& prop, const PropName& tag) { + return base_type::lookup(prop.m_base, tag); + } + template + static typename enable_if >, const typename base_type::type&>::type + lookup(const PL& prop, const PropName& tag) { + return base_type::lookup(prop.m_base, tag); + } + }; + + // Pointer-to-member access to bundled properties +#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES + template + struct lookup_one_property_internal { + BOOST_STATIC_CONSTANT(bool, found = true); + typedef R type; + static R& lookup(T& x, R T::*ptr) {return x.*ptr;} + static const R& lookup(const T& x, R T::*ptr) {return x.*ptr;} + }; +#endif + + // Version of above handling const property lists properly + template + struct lookup_one_property: lookup_one_property_internal {}; + + template + struct lookup_one_property { + BOOST_STATIC_CONSTANT(bool, found = (lookup_one_property_internal::found)); + typedef const typename lookup_one_property_internal::type type; + template + static typename enable_if, const typename lookup_one_property_internal::type&>::type + lookup(const U& p, Tag tag) { + return lookup_one_property_internal::lookup(p, tag); + } }; // The BGL properties specialize property_kind and @@ -41,11 +155,6 @@ namespace boost { // instead with a nested kind type and num. Also, we may want to // switch BGL back to using class types for properties at some point. - template - struct property_kind { - typedef typename PropertyTag::kind type; - }; - template struct has_property : boost::mpl::true_ {}; template <> @@ -58,45 +167,18 @@ namespace boost { namespace boost { template - struct property_value { -#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - typedef typename detail::build_property_tag_value_alist::type AList; - typedef typename detail::extract_value::type type; -#else - typedef typename detail::build_property_tag_value_alist::type AList; - typedef typename detail::ev_selector::type Extractor; - typedef typename Extractor::template bind_::type type; -#endif - }; + struct property_value: lookup_one_property {}; - template - inline detail::error_property_not_found - get_property_value(const no_property&, Tag2) { - return detail::error_property_not_found(); + template + inline typename lookup_one_property::type& + get_property_value(PropertyList& p, Tag tag) { + return lookup_one_property::lookup(p, tag); } - template - inline typename property_value, Tag2>::type& - get_property_value(property& p, Tag2 tag2) { - BOOST_STATIC_CONSTANT(bool, - match = (detail::same_property::value)); - typedef property Prop; - typedef typename property_value::type T2; - T2* t2 = 0; - typedef detail::property_value_dispatch Dispatcher; - return Dispatcher::get_value(p, t2, tag2); - } - template - inline - const typename property_value, Tag2>::type& - get_property_value(const property& p, Tag2 tag2) { - BOOST_STATIC_CONSTANT(bool, - match = (detail::same_property::value)); - typedef property Prop; - typedef typename property_value::type T2; - T2* t2 = 0; - typedef detail::property_value_dispatch Dispatcher; - return Dispatcher::const_get_value(p, t2, tag2); + template + inline const typename lookup_one_property::type& + get_property_value(const PropertyList& p, Tag tag) { + return lookup_one_property::lookup(p, tag); } namespace detail { @@ -107,7 +189,6 @@ namespace boost { : mpl::bool_::value> { }; -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) /** @internal @name Retag Property List * This metafunction is used internally to normalize a property if it is * actually modeling a property. Specifically this is used in Boost.Graph @@ -159,7 +240,40 @@ namespace boost { typedef no_property retagged; }; //@} -#endif + + template + class lookup_one_property_f; + + template struct lookup_one_property_f_result; + + template + struct lookup_one_property_f_result(PList)> { + typedef typename lookup_one_property::type type; + }; + + template + struct lookup_one_property_f_result(PList&)> { + typedef typename lookup_one_property::type& type; + }; + + template + struct lookup_one_property_f_result(const PList&)> { + typedef const typename lookup_one_property::type& type; + }; + + template + class lookup_one_property_f { + Tag tag; + public: + lookup_one_property_f(Tag tag): tag(tag) {} + template struct result: lookup_one_property_f_result {}; + + typename lookup_one_property_f_result::type + operator()(PList& pl) const { + return lookup_one_property::lookup(pl, tag); + } + }; + } // namespace detail } // namesapce boost