Chris@16: //======================================================================= Chris@16: // Copyright 1997, 1998, 1999, 2000 University of Notre Dame. Chris@16: // Copyright 2010 Thomas Claveirole Chris@16: // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Thomas Claveirole 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: #ifndef BOOST_GRAPH_ADJACENCY_LIST_HPP Chris@16: #define BOOST_GRAPH_ADJACENCY_LIST_HPP Chris@16: Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #if !defined BOOST_NO_SLIST Chris@16: # ifdef BOOST_SLIST_HEADER Chris@16: # include BOOST_SLIST_HEADER Chris@16: # else Chris@16: # include Chris@16: # endif Chris@16: #endif Chris@16: Chris@16: #include 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: #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: //=========================================================================== Chris@16: // Selectors for the VertexList and EdgeList template parameters of Chris@16: // adjacency_list, and the container_gen traits class which is used Chris@16: // to map the selectors to the container type used to implement the Chris@16: // graph. Chris@16: Chris@16: #if !defined BOOST_NO_SLIST Chris@16: struct slistS {}; Chris@16: #endif Chris@16: Chris@16: struct vecS { }; Chris@16: struct listS { }; Chris@16: struct setS { }; Chris@16: struct mapS { }; Chris@16: struct multisetS { }; Chris@16: struct multimapS { }; Chris@16: struct hash_setS { }; Chris@16: struct hash_mapS { }; Chris@16: struct hash_multisetS { }; Chris@16: struct hash_multimapS { }; Chris@16: Chris@16: template Chris@16: struct container_gen { }; Chris@16: Chris@16: template Chris@16: struct container_gen { Chris@16: typedef std::list type; Chris@16: }; Chris@16: #if !defined BOOST_NO_SLIST Chris@16: template Chris@16: struct container_gen { Chris@16: typedef BOOST_STD_EXTENSION_NAMESPACE::slist type; Chris@16: }; Chris@16: #endif Chris@16: template Chris@16: struct container_gen { Chris@16: typedef std::vector type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct container_gen { Chris@16: typedef std::set type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct container_gen { Chris@16: typedef std::set type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct container_gen { Chris@16: typedef std::multiset type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct container_gen { Chris@16: typedef std::multiset type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct container_gen { Chris@16: typedef boost::unordered_set type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct container_gen { Chris@16: typedef boost::unordered_set type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct container_gen { Chris@16: typedef boost::unordered_multiset type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct container_gen { Chris@16: typedef boost::unordered_multiset type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct parallel_edge_traits { }; Chris@16: Chris@16: template <> Chris@16: struct parallel_edge_traits { Chris@16: typedef allow_parallel_edge_tag type; }; Chris@16: Chris@16: template <> Chris@16: struct parallel_edge_traits { Chris@16: typedef allow_parallel_edge_tag type; }; Chris@16: Chris@16: #if !defined BOOST_NO_SLIST Chris@16: template <> Chris@16: struct parallel_edge_traits { Chris@16: typedef allow_parallel_edge_tag type; }; Chris@16: #endif Chris@16: Chris@16: template <> Chris@16: struct parallel_edge_traits { Chris@16: typedef disallow_parallel_edge_tag type; }; Chris@16: Chris@16: template <> Chris@16: struct parallel_edge_traits { Chris@16: typedef allow_parallel_edge_tag type; }; Chris@16: Chris@16: template <> Chris@16: struct parallel_edge_traits { Chris@16: typedef disallow_parallel_edge_tag type; Chris@16: }; Chris@16: Chris@16: // mapS is obsolete, replaced with setS Chris@16: template <> Chris@16: struct parallel_edge_traits { Chris@16: typedef disallow_parallel_edge_tag type; }; Chris@16: Chris@16: template <> Chris@16: struct parallel_edge_traits { Chris@16: typedef disallow_parallel_edge_tag type; Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct parallel_edge_traits { Chris@16: typedef allow_parallel_edge_tag type; Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct parallel_edge_traits { Chris@16: typedef allow_parallel_edge_tag type; Chris@16: }; Chris@16: Chris@16: namespace detail { Chris@16: template struct is_random_access { Chris@16: enum { value = false}; Chris@16: typedef mpl::false_ type; Chris@16: }; Chris@16: template <> Chris@16: struct is_random_access { Chris@16: enum { value = true }; Chris@16: typedef mpl::true_ type; Chris@16: }; Chris@16: Chris@16: } // namespace detail Chris@16: Chris@16: template struct is_distributed_selector: mpl::false_ {}; Chris@16: Chris@16: Chris@16: //=========================================================================== Chris@16: // The adjacency_list_traits class, which provides a way to access Chris@16: // some of the associated types of an adjacency_list type without Chris@16: // having to first create the adjacency_list type. This is useful Chris@16: // when trying to create interior vertex or edge properties who's Chris@16: // value type is a vertex or edge descriptor. Chris@16: Chris@16: template Chris@16: struct adjacency_list_traits Chris@16: { Chris@16: typedef typename detail::is_random_access::type Chris@16: is_rand_access; Chris@16: typedef typename DirectedS::is_bidir_t is_bidir; Chris@16: typedef typename DirectedS::is_directed_t is_directed; Chris@16: Chris@16: typedef typename mpl::if_::type Chris@16: >::type directed_category; Chris@16: Chris@16: typedef typename parallel_edge_traits::type Chris@16: edge_parallel_category; Chris@16: Chris@16: typedef std::size_t vertices_size_type; Chris@16: typedef void* vertex_ptr; Chris@16: typedef typename mpl::if_::type vertex_descriptor; Chris@16: typedef detail::edge_desc_impl Chris@16: edge_descriptor; Chris@16: Chris@16: private: Chris@16: // Logic to figure out the edges_size_type Chris@16: struct dummy {}; Chris@16: typedef typename container_gen::type EdgeContainer; Chris@16: typedef typename DirectedS::is_bidir_t BidirectionalT; Chris@16: typedef typename DirectedS::is_directed_t DirectedT; Chris@16: typedef typename mpl::and_::type >::type on_edge_storage; Chris@16: public: Chris@16: typedef typename mpl::if_::type edges_size_type; Chris@16: Chris@16: }; Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: //=========================================================================== Chris@16: // The adjacency_list class. Chris@16: // Chris@16: Chris@16: template Chris@16: class adjacency_list Chris@16: : public detail::adj_list_gen< Chris@16: adjacency_list, Chris@16: VertexListS, OutEdgeListS, DirectedS, Chris@16: VertexProperty, EdgeProperty, Chris@16: GraphProperty, EdgeListS>::type, Chris@16: // Support for named vertices Chris@16: public graph::maybe_named_graph< Chris@16: adjacency_list, Chris@16: typename adjacency_list_traits::vertex_descriptor, Chris@16: VertexProperty> Chris@16: { Chris@16: public: Chris@16: typedef GraphProperty graph_property_type; Chris@16: typedef typename lookup_one_property::type graph_bundled; Chris@16: Chris@16: typedef VertexProperty vertex_property_type; Chris@16: typedef typename lookup_one_property::type vertex_bundled; Chris@16: Chris@16: typedef EdgeProperty edge_property_type; Chris@16: typedef typename lookup_one_property::type edge_bundled; Chris@16: Chris@16: private: Chris@16: typedef adjacency_list self; Chris@16: typedef typename detail::adj_list_gen< Chris@16: self, VertexListS, OutEdgeListS, DirectedS, Chris@16: vertex_property_type, edge_property_type, GraphProperty, EdgeListS Chris@16: >::type Base; Chris@16: Chris@16: public: Chris@16: typedef typename Base::stored_vertex stored_vertex; Chris@16: typedef typename Base::vertices_size_type vertices_size_type; Chris@16: typedef typename Base::edges_size_type edges_size_type; Chris@16: typedef typename Base::degree_size_type degree_size_type; Chris@16: typedef typename Base::vertex_descriptor vertex_descriptor; Chris@16: typedef typename Base::edge_descriptor edge_descriptor; Chris@16: typedef OutEdgeListS out_edge_list_selector; Chris@16: typedef VertexListS vertex_list_selector; Chris@16: typedef DirectedS directed_selector; Chris@16: typedef EdgeListS edge_list_selector; Chris@16: Chris@16: Chris@16: adjacency_list(const GraphProperty& p = GraphProperty()) Chris@16: : m_property(new graph_property_type(p)) Chris@16: { } Chris@16: Chris@16: adjacency_list(const adjacency_list& x) Chris@16: : Base(x), m_property(new graph_property_type(*x.m_property)) Chris@16: { } Chris@16: Chris@16: adjacency_list& operator=(const adjacency_list& x) { Chris@16: // TBD: probably should give the strong guarantee Chris@16: if (&x != this) { Chris@16: Base::operator=(x); Chris@16: Chris@16: // Copy/swap the ptr since we can't just assign it... Chris@16: property_ptr p(new graph_property_type(*x.m_property)); Chris@16: m_property.swap(p); Chris@16: } Chris@16: return *this; Chris@16: } Chris@16: Chris@16: // Required by Mutable Graph Chris@16: adjacency_list(vertices_size_type num_vertices, Chris@16: const GraphProperty& p = GraphProperty()) Chris@16: : Base(num_vertices), m_property(new graph_property_type(p)) Chris@16: { } Chris@16: Chris@16: // Required by Iterator Constructible Graph Chris@16: template Chris@16: adjacency_list(EdgeIterator first, EdgeIterator last, Chris@16: vertices_size_type n, Chris@16: edges_size_type = 0, Chris@16: const GraphProperty& p = GraphProperty()) Chris@16: : Base(n, first, last), m_property(new graph_property_type(p)) Chris@16: { } Chris@16: Chris@16: template Chris@16: adjacency_list(EdgeIterator first, EdgeIterator last, Chris@16: EdgePropertyIterator ep_iter, Chris@16: vertices_size_type n, Chris@16: edges_size_type = 0, Chris@16: const GraphProperty& p = GraphProperty()) Chris@16: : Base(n, first, last, ep_iter), m_property(new graph_property_type(p)) Chris@16: { } Chris@16: Chris@16: void swap(adjacency_list& x) { Chris@16: // Is there a more efficient way to do this? Chris@16: adjacency_list tmp(x); Chris@16: x = *this; Chris@16: *this = tmp; Chris@16: } Chris@16: Chris@16: void clear() Chris@16: { Chris@16: this->clearing_graph(); Chris@16: Base::clear(); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES Chris@16: // Directly access a vertex or edge bundle Chris@16: vertex_bundled& operator[](vertex_descriptor v) Chris@16: { return get(vertex_bundle, *this)[v]; } Chris@16: Chris@16: const vertex_bundled& operator[](vertex_descriptor v) const Chris@16: { return get(vertex_bundle, *this)[v]; } Chris@16: Chris@16: edge_bundled& operator[](edge_descriptor e) Chris@16: { return get(edge_bundle, *this)[e]; } Chris@16: Chris@16: const edge_bundled& operator[](edge_descriptor e) const Chris@16: { return get(edge_bundle, *this)[e]; } Chris@16: Chris@16: graph_bundled& operator[](graph_bundle_t) Chris@16: { return get_property(*this); } Chris@16: Chris@16: graph_bundled const& operator[](graph_bundle_t) const Chris@16: { return get_property(*this); } Chris@16: #endif Chris@16: Chris@16: // protected: (would be protected if friends were more portable) Chris@16: typedef scoped_ptr property_ptr; Chris@16: property_ptr m_property; Chris@16: }; Chris@16: Chris@16: #define ADJLIST_PARAMS \ Chris@16: typename OEL, typename VL, typename D, typename VP, typename EP, \ Chris@16: typename GP, typename EL Chris@16: #define ADJLIST adjacency_list Chris@16: Chris@16: template Chris@16: inline void set_property(ADJLIST& g, Tag tag, Value const& value) { Chris@16: get_property_value(*g.m_property, tag) = value; Chris@16: } Chris@16: Chris@16: template Chris@16: inline typename graph_property::type& Chris@16: get_property(ADJLIST& g, Tag tag) { Chris@16: return get_property_value(*g.m_property, tag); Chris@16: } Chris@16: Chris@16: template Chris@16: inline typename graph_property::type const& Chris@16: get_property(ADJLIST const& g, Tag tag) { Chris@16: return get_property_value(*g.m_property, tag); Chris@16: } Chris@16: Chris@16: // dwa 09/25/00 - needed to be more explicit so reverse_graph would work. Chris@16: template Chris@16: inline Vertex Chris@16: source(const detail::edge_base& e, Chris@16: const adjacency_list&) Chris@16: { Chris@16: return e.m_source; Chris@16: } Chris@16: Chris@16: template Chris@16: inline Vertex Chris@16: target(const detail::edge_base& e, Chris@16: const adjacency_list&) Chris@16: { Chris@16: return e.m_target; Chris@16: } Chris@16: Chris@16: // Mutability Traits Chris@16: template Chris@16: struct graph_mutability_traits { Chris@16: typedef mutable_property_graph_tag category; Chris@16: }; Chris@16: Chris@16: // Can't remove vertices from adjacency lists with VL==vecS Chris@16: template Chris@16: struct graph_mutability_traits< adjacency_list > { Chris@16: typedef add_only_property_graph_tag category; Chris@16: }; Chris@16: #undef ADJLIST_PARAMS Chris@16: #undef ADJLIST Chris@16: Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: Chris@16: #endif // BOOST_GRAPH_ADJACENCY_LIST_HPP