diff --git a/include/boost/graph/breadth_first_search.hpp b/include/boost/graph/breadth_first_search.hpp index 030ab282..1a6e31cd 100644 --- a/include/boost/graph/breadth_first_search.hpp +++ b/include/boost/graph/breadth_first_search.hpp @@ -112,15 +112,11 @@ namespace boost { namespace detail { - struct normal_bfs_tag { }; - struct neighbor_bfs_tag { }; - template + class ColorMap> void bfs_impl(const IncidenceGraph& g, typename graph_traits::vertex_descriptor s, - Buffer& Q, BFSVisitor vis, ColorMap color, - Directedness, normal_bfs_tag) + Buffer& Q, BFSVisitor vis, ColorMap color) { function_requires< IncidenceGraphConcept >(); typedef graph_traits GTraits; @@ -151,6 +147,7 @@ namespace boost { Q.push(v); } else { vis.non_tree_edge(e, g); + if (v_color == Color::gray()) vis.gray_target(e, g); else @@ -161,94 +158,11 @@ namespace boost { vis.finish_vertex(u, g); } // while } - - template - void bfs_impl - (const BidirectionalGraph& g, - typename graph_traits::vertex_descriptor s, - Buffer& Q, BFSVisitor vis, ColorMap color, directed_tag, - neighbor_bfs_tag) - { - function_requires< BidirectionalGraphConcept >(); - typedef graph_traits GTraits; - typedef typename GTraits::vertex_descriptor Vertex; - typedef typename GTraits::edge_descriptor Edge; - function_requires< BFSVisitorConcept >(); - function_requires< ReadWritePropertyMapConcept >(); - typedef typename property_traits::value_type ColorValue; - typedef color_traits Color; - - put(color, s, Color::gray()); - vis.discover_vertex(s, g); - Q.push(s); - while (! Q.empty()) { - Vertex u = Q.top(); - Q.pop(); // pop before push to avoid problem if Q is priority_queue. - vis.examine_vertex(u, g); - - typename GTraits::out_edge_iterator ei, ei_end; - for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) { - Edge e = *ei; - vis.examine_edge(e, g); - Vertex v = target(e, g); - ColorValue v_color = get(color, v); - if (v_color == Color::white()) { - vis.tree_edge(e, g); - put(color, v, Color::gray()); - vis.discover_vertex(v, g); - Q.push(v); - } else { - vis.non_tree_edge(e, g); - if (v_color == Color::gray()) - vis.gray_target(e, g); - else - vis.black_target(e, g); - } - } // for out-edges - - typename GTraits::in_edge_iterator in_ei, in_ei_end; - for (tie(in_ei, in_ei_end) = in_edges(u, g); - in_ei != in_ei_end; ++in_ei) { - Edge e = *in_ei; - vis.examine_edge(e, g); - Vertex v = source(e, g); - ColorValue v_color = get(color, v); - if (v_color == Color::white()) { - vis.tree_edge(e, g); - put(color, v, Color::gray()); - vis.discover_vertex(v, g); - Q.push(v); - } else { - vis.non_tree_edge(e, g); - if (v_color == Color::gray()) - vis.gray_target(e, g); - else - vis.black_target(e, g); - } - } // for in-edges - - put(color, u, Color::black()); - vis.finish_vertex(u, g); - } // while - } - - // Just use the normal BFS for undirected graphs - template - void bfs_impl - (const IncidenceGraph& g, - typename graph_traits::vertex_descriptor s, - Buffer& Q, BFSVisitor vis, ColorMap color, - undirected_tag tag, neighbor_bfs_tag) - { - bfs_impl(g, s, Q, vis, color, tag, normal_bfs_tag()); - } - + template + class P, class T, class R> void bfs_helper - (BFSKind kind, VertexListGraph& g, + (VertexListGraph& g, typename graph_traits::vertex_descriptor s, ColorMap color, BFSVisitor vis, @@ -268,12 +182,10 @@ namespace boost { put(color, *i, Color::white()); vis.initialize_vertex(*i, g); } - typename graph_traits::directed_category - directedness; bfs_impl (g, s, choose_param(get_param(params, buffer_param_t()), Qref).ref, - vis, color, directedness, kind); + vis, color); } //------------------------------------------------------------------------- @@ -283,15 +195,15 @@ namespace boost { template struct bfs_dispatch { - template + template static void apply - (BFSKind kind, VertexListGraph& g, + (VertexListGraph& g, typename graph_traits::vertex_descriptor s, const bgl_named_params& params, ColorMap color) { bfs_helper - (kind, g, s, color, + (g, s, color, choose_param(get_param(params, graph_visitor), make_bfs_visitor(null_visitor())), params); @@ -300,11 +212,9 @@ namespace boost { template <> struct bfs_dispatch { - template + template static void apply - (BFSKind kind, - VertexListGraph& g, + (VertexListGraph& g, typename graph_traits::vertex_descriptor s, const bgl_named_params& params, detail::error_property_not_found) @@ -313,7 +223,7 @@ namespace boost { null_visitor null_vis; bfs_helper - (kind, g, s, + (g, s, make_iterator_property_map (color_vec.begin(), choose_const_pmap(get_param(params, vertex_index), @@ -334,27 +244,14 @@ namespace boost { typename graph_traits::vertex_descriptor s, const bgl_named_params& params) { - // The graph is passed by *const* reference so that graph adaptors (temporaries) - // can be passed into this function. However, the graph is not really const - // since we may write to property maps of the graph. + // The graph is passed by *const* reference so that graph adaptors + // (temporaries) can be passed into this function. However, the + // 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; - detail::bfs_dispatch::apply(detail::normal_bfs_tag(), ng, s, params, - get_param(params, vertex_color)); - } - - template - void neighbor_breadth_first_search - (const VertexListGraph& g, - typename graph_traits::vertex_descriptor s, - const bgl_named_params& params) - { - // The graph is passed by *const* reference so that graph adaptors (temporaries) - // can be passed into this function. However, the 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; - detail::bfs_dispatch::apply(detail::neighbor_bfs_tag(), ng, s, params, + typedef typename property_value< bgl_named_params, + vertex_color_t>::type C; + detail::bfs_dispatch::apply(ng, s, params, get_param(params, vertex_color)); } @@ -373,39 +270,12 @@ namespace boost { queue_t Q; detail::wrap_ref Qref(Q); - typename graph_traits::directed_category directedness; - - detail::bfs_impl + breadth_first_search (g, s, choose_param(get_param(params, buffer_param_t()), Qref).ref, choose_param(get_param(params, graph_visitor), make_bfs_visitor(null_visitor())), - choose_pmap(get_param(params, vertex_color), g, vertex_color), - directedness, detail::normal_bfs_tag() - ); - } - - template - void neighbor_breadth_first_visit - (IncidenceGraph& g, - typename graph_traits::vertex_descriptor s, - const bgl_named_params& params) - { - typedef graph_traits Traits; - // Buffer default - typedef boost::queue queue_t; - queue_t Q; - detail::wrap_ref Qref(Q); - - typename graph_traits::directed_category directedness; - - detail::bfs_impl - (g, s, - choose_param(get_param(params, buffer_param_t()), Qref).ref, - choose_param(get_param(params, graph_visitor), - make_bfs_visitor(null_visitor())), - choose_pmap(get_param(params, vertex_color), g, vertex_color), - directedness, detail::neighbor_bfs_tag() + choose_pmap(get_param(params, vertex_color), g, vertex_color) ); }