Chris@16: //======================================================================= Chris@16: // Copyright 1997, 1998, 1999, 2000 University of Notre Dame. Chris@16: // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: //======================================================================= Chris@16: // Chris@16: // Revision History: Chris@16: // 01 April 2001: Modified to use new header. (JMaddock) Chris@16: // Chris@16: #ifndef BOOST_GRAPH_GRAPH_SEARCH_VISITORS_HPP Chris@16: #define BOOST_GRAPH_GRAPH_SEARCH_VISITORS_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: // This is a bit more convenient than std::numeric_limits because Chris@16: // you don't have to explicitly provide type T. Chris@16: template Chris@16: inline T numeric_limits_max(T) { return (std::numeric_limits::max)(); } Chris@16: Chris@16: //======================================================================== Chris@16: // Event Tags Chris@16: Chris@16: namespace detail { Chris@16: // For partial specialization workaround Chris@16: enum event_visitor_enum Chris@16: { on_no_event_num, Chris@16: on_initialize_vertex_num, on_start_vertex_num, Chris@16: on_discover_vertex_num, on_finish_vertex_num, on_examine_vertex_num, Chris@16: on_examine_edge_num, on_tree_edge_num, on_non_tree_edge_num, Chris@16: on_gray_target_num, on_black_target_num, Chris@16: on_forward_or_cross_edge_num, on_back_edge_num, on_finish_edge_num, Chris@16: on_edge_relaxed_num, on_edge_not_relaxed_num, Chris@16: on_edge_minimized_num, on_edge_not_minimized_num Chris@16: }; Chris@16: Chris@16: template Chris@16: struct functor_to_visitor : Visitor Chris@16: { Chris@16: typedef Event event_filter; Chris@16: functor_to_visitor(const Visitor& visitor) : Visitor(visitor) {} Chris@16: }; Chris@16: Chris@16: } // namespace detail Chris@16: Chris@16: struct on_no_event { enum { num = detail::on_no_event_num }; }; Chris@16: Chris@16: struct on_initialize_vertex { Chris@16: enum { num = detail::on_initialize_vertex_num }; }; Chris@16: struct on_start_vertex { enum { num = detail::on_start_vertex_num }; }; Chris@16: struct on_discover_vertex { enum { num = detail::on_discover_vertex_num }; }; Chris@16: struct on_examine_vertex { enum { num = detail::on_examine_vertex_num }; }; Chris@16: struct on_finish_vertex { enum { num = detail::on_finish_vertex_num }; }; Chris@16: Chris@16: struct on_examine_edge { enum { num = detail::on_examine_edge_num }; }; Chris@16: struct on_tree_edge { enum { num = detail::on_tree_edge_num }; }; Chris@16: struct on_non_tree_edge { enum { num = detail::on_non_tree_edge_num }; }; Chris@16: struct on_gray_target { enum { num = detail::on_gray_target_num }; }; Chris@16: struct on_black_target { enum { num = detail::on_black_target_num }; }; Chris@16: struct on_forward_or_cross_edge { Chris@16: enum { num = detail::on_forward_or_cross_edge_num }; }; Chris@16: struct on_back_edge { enum { num = detail::on_back_edge_num }; }; Chris@16: struct on_finish_edge { enum { num = detail::on_finish_edge_num }; }; Chris@16: Chris@16: struct on_edge_relaxed { enum { num = detail::on_edge_relaxed_num }; }; Chris@16: struct on_edge_not_relaxed { Chris@16: enum { num = detail::on_edge_not_relaxed_num }; }; Chris@16: struct on_edge_minimized { enum { num = detail::on_edge_minimized_num }; }; Chris@16: struct on_edge_not_minimized { Chris@16: enum { num = detail::on_edge_not_minimized_num }; }; Chris@16: Chris@16: //======================================================================== Chris@16: // base_visitor and null_visitor Chris@16: Chris@16: // needed for MSVC workaround Chris@16: template Chris@16: struct base_visitor { Chris@16: typedef on_no_event event_filter; Chris@16: template Chris@16: void operator()(T, Graph&) { } Chris@16: }; Chris@16: Chris@16: struct null_visitor : public base_visitor { Chris@16: typedef on_no_event event_filter; Chris@16: template Chris@16: void operator()(T, Graph&) { } Chris@16: }; Chris@16: Chris@16: //======================================================================== Chris@16: // The invoke_visitors() function Chris@16: Chris@16: namespace detail { Chris@16: template Chris@16: inline void invoke_dispatch(Visitor& v, T x, Graph& g, mpl::true_) { Chris@16: v(x, g); Chris@16: } Chris@16: Chris@16: template Chris@16: inline void invoke_dispatch(Visitor&, T, Graph&, mpl::false_) Chris@16: { } Chris@16: } // namespace detail Chris@16: Chris@16: template Chris@16: inline void Chris@16: invoke_visitors(std::pair& vlist, T x, Graph& g, Tag tag) { Chris@16: typedef typename Visitor::event_filter Category; Chris@16: typedef typename is_same::type IsSameTag; Chris@16: detail::invoke_dispatch(vlist.first, x, g, IsSameTag()); Chris@16: invoke_visitors(vlist.second, x, g, tag); Chris@16: } Chris@16: template Chris@16: inline void Chris@16: invoke_visitors(Visitor& v, T x, Graph& g, Tag) { Chris@16: typedef typename Visitor::event_filter Category; Chris@16: typedef typename is_same::type IsSameTag; Chris@16: detail::invoke_dispatch(v, x, g, IsSameTag()); Chris@16: } Chris@16: Chris@16: //======================================================================== Chris@16: // predecessor_recorder Chris@16: Chris@16: template Chris@16: struct predecessor_recorder Chris@16: : public base_visitor > Chris@16: { Chris@16: typedef Tag event_filter; Chris@16: predecessor_recorder(PredecessorMap pa) : m_predecessor(pa) { } Chris@16: template Chris@16: void operator()(Edge e, const Graph& g) { Chris@16: put(m_predecessor, target(e, g), source(e, g)); Chris@16: } Chris@16: PredecessorMap m_predecessor; Chris@16: }; Chris@16: template Chris@16: predecessor_recorder Chris@16: record_predecessors(PredecessorMap pa, Tag) { Chris@16: return predecessor_recorder (pa); Chris@16: } Chris@16: Chris@16: //======================================================================== Chris@16: // edge_predecessor_recorder Chris@16: Chris@16: template Chris@16: struct edge_predecessor_recorder Chris@16: : public base_visitor > Chris@16: { Chris@16: typedef Tag event_filter; Chris@16: edge_predecessor_recorder(PredEdgeMap pa) : m_predecessor(pa) { } Chris@16: template Chris@16: void operator()(Edge e, const Graph& g) { Chris@16: put(m_predecessor, target(e, g), e); Chris@16: } Chris@16: PredEdgeMap m_predecessor; Chris@16: }; Chris@16: template Chris@16: edge_predecessor_recorder Chris@16: record_edge_predecessors(PredEdgeMap pa, Tag) { Chris@16: return edge_predecessor_recorder (pa); Chris@16: } Chris@16: Chris@16: //======================================================================== Chris@16: // distance_recorder Chris@16: Chris@16: template Chris@16: struct distance_recorder Chris@16: : public base_visitor > Chris@16: { Chris@16: typedef Tag event_filter; Chris@16: distance_recorder(DistanceMap pa) : m_distance(pa) { } Chris@16: template Chris@16: void operator()(Edge e, const Graph& g) { Chris@16: typename graph_traits::vertex_descriptor Chris@16: u = source(e, g), v = target(e, g); Chris@16: put(m_distance, v, get(m_distance, u) + 1); Chris@16: } Chris@16: DistanceMap m_distance; Chris@16: }; Chris@16: template Chris@16: distance_recorder Chris@16: record_distances(DistanceMap pa, Tag) { Chris@16: return distance_recorder (pa); Chris@16: } Chris@16: Chris@16: //======================================================================== Chris@16: // time_stamper Chris@16: Chris@16: Chris@16: template Chris@16: struct time_stamper Chris@16: : public base_visitor > Chris@16: { Chris@16: typedef Tag event_filter; Chris@16: time_stamper(TimeMap pa, TimeT& t) : m_time_pa(pa), m_time(t) { } Chris@16: template Chris@16: void operator()(Vertex u, const Graph&) { Chris@16: put(m_time_pa, u, ++m_time); Chris@16: } Chris@16: TimeMap m_time_pa; Chris@16: TimeT& m_time; Chris@16: }; Chris@16: template Chris@16: time_stamper Chris@16: stamp_times(TimeMap pa, TimeT& time_counter, Tag) { Chris@16: return time_stamper(pa, time_counter); Chris@16: } Chris@16: Chris@16: //======================================================================== Chris@16: // property_writer Chris@16: Chris@16: template Chris@16: struct property_writer Chris@16: : public base_visitor > Chris@16: { Chris@16: typedef Tag event_filter; Chris@16: Chris@16: property_writer(PA pa, OutputIterator out) : m_pa(pa), m_out(out) { } Chris@16: Chris@16: template Chris@16: void operator()(T x, Graph&) { *m_out++ = get(m_pa, x); } Chris@16: PA m_pa; Chris@16: OutputIterator m_out; Chris@16: }; Chris@16: template Chris@16: property_writer Chris@16: write_property(PA pa, OutputIterator out, Tag) { Chris@16: return property_writer(pa, out); Chris@16: } Chris@16: Chris@16: //======================================================================== Chris@16: // property_put Chris@16: Chris@16: /** Chris@16: * Functor which just sets a given value to a vertex or edge in a property map. Chris@16: */ Chris@16: Chris@16: template Chris@16: struct property_put Chris@16: { Chris@16: typedef EventTag event_filter; Chris@16: Chris@16: property_put (PropertyMap property_map, Chris@16: typename property_traits ::value_type value) : Chris@16: property_map_ (property_map), value_ (value) Chris@16: {} Chris@16: Chris@16: template Chris@16: void operator() (VertexOrEdge v, const Graph&) Chris@16: { Chris@16: put (property_map_, v, value_); Chris@16: } Chris@16: Chris@16: private: Chris@16: PropertyMap property_map_; Chris@16: typename property_traits ::value_type value_; Chris@16: }; Chris@16: Chris@16: /** Chris@16: * Creates a property_put functor which just sets a given value to a vertex or edge. Chris@16: * Chris@16: * @param property_map Given writeable property map Chris@16: * @param value Fixed value of the map Chris@16: * @param tag Event Filter Chris@16: * @return The functor. Chris@16: */ Chris@16: Chris@16: template Chris@16: inline property_put Chris@16: put_property (PropertyMap property_map, Chris@16: typename property_traits ::value_type value, Chris@16: EventTag) Chris@16: { Chris@16: return property_put (property_map, value); Chris@16: } Chris@16: Chris@16: #define BOOST_GRAPH_EVENT_STUB(Event,Kind) \ Chris@16: typedef ::boost::Event Event##_type; \ Chris@16: template \ Chris@16: Kind##_visitor, Visitors> > \ Chris@16: do_##Event(Visitor visitor) \ Chris@16: { \ Chris@16: typedef std::pair, \ Chris@16: Visitors> visitor_list; \ Chris@16: typedef Kind##_visitor result_type; \ Chris@16: return result_type(visitor_list(visitor, m_vis)); \ Chris@16: } Chris@16: Chris@16: } /* namespace boost */ Chris@16: Chris@16: #endif