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: Chris@16: #ifndef BOOST_GRAPH_EDGE_LIST_HPP Chris@16: #define BOOST_GRAPH_EDGE_LIST_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: // Chris@16: // The edge_list class is an EdgeListGraph module that is constructed Chris@16: // from a pair of iterators whose value type is a pair of vertex Chris@16: // descriptors. Chris@16: // Chris@16: // For example: Chris@16: // Chris@16: // typedef std::pair E; Chris@16: // list elist; Chris@16: // ... Chris@16: // typedef edge_list::iterator> Graph; Chris@16: // Graph g(elist.begin(), elist.end()); Chris@16: // Chris@16: // If the iterators are random access, then Graph::edge_descriptor Chris@16: // is of Integral type, otherwise it is a struct, though it is Chris@16: // convertible to an Integral type. Chris@16: // Chris@16: Chris@16: struct edge_list_tag { }; Chris@16: Chris@16: // The implementation class for edge_list. Chris@16: template Chris@16: class edge_list_impl Chris@16: { Chris@16: public: Chris@16: typedef D edge_id; Chris@16: typedef T Vpair; Chris@16: typedef typename Vpair::first_type V; Chris@16: typedef V vertex_descriptor; Chris@16: typedef edge_list_tag graph_tag; Chris@16: typedef void edge_property_type; Chris@16: Chris@16: struct edge_descriptor Chris@16: { Chris@16: edge_descriptor() { } Chris@16: edge_descriptor(EdgeIter p, edge_id id) : _ptr(p), _id(id) { } Chris@16: operator edge_id() { return _id; } Chris@16: EdgeIter _ptr; Chris@16: edge_id _id; Chris@16: }; Chris@16: typedef edge_descriptor E; Chris@16: Chris@16: struct edge_iterator Chris@16: { Chris@16: typedef edge_iterator self; Chris@16: typedef E value_type; Chris@16: typedef E& reference; Chris@16: typedef E* pointer; Chris@16: typedef std::ptrdiff_t difference_type; Chris@16: typedef std::input_iterator_tag iterator_category; Chris@16: edge_iterator() { } Chris@16: edge_iterator(EdgeIter iter) : _iter(iter), _i(0) { } Chris@16: E operator*() { return E(_iter, _i); } Chris@16: self& operator++() { ++_iter; ++_i; return *this; } Chris@16: self operator++(int) { self t = *this; ++(*this); return t; } Chris@16: bool operator==(const self& x) { return _iter == x._iter; } Chris@16: bool operator!=(const self& x) { return _iter != x._iter; } Chris@16: EdgeIter _iter; Chris@16: edge_id _i; Chris@16: }; Chris@16: typedef void out_edge_iterator; Chris@16: typedef void in_edge_iterator; Chris@16: typedef void adjacency_iterator; Chris@16: typedef void vertex_iterator; Chris@16: }; Chris@16: Chris@16: template Chris@16: std::pair::edge_iterator, Chris@16: typename edge_list_impl::edge_iterator> Chris@16: edges(const edge_list_impl& g_) { Chris@16: const G& g = static_cast(g_); Chris@16: typedef typename edge_list_impl::edge_iterator edge_iterator; Chris@16: return std::make_pair(edge_iterator(g._first), edge_iterator(g._last)); Chris@16: } Chris@16: template Chris@16: typename edge_list_impl::vertex_descriptor Chris@16: source(typename edge_list_impl::edge_descriptor e, Chris@16: const edge_list_impl&) { Chris@16: return (*e._ptr).first; Chris@16: } Chris@16: template Chris@16: typename edge_list_impl::vertex_descriptor Chris@16: target(typename edge_list_impl::edge_descriptor e, Chris@16: const edge_list_impl&) { Chris@16: return (*e._ptr).second; Chris@16: } Chris@16: Chris@16: template Chris@16: class el_edge_property_map Chris@16: : public put_get_helper >{ Chris@16: public: Chris@16: typedef E key_type; Chris@16: typedef D value_type; Chris@16: typedef D reference; Chris@16: typedef readable_property_map_tag category; Chris@16: Chris@16: value_type operator[](key_type e) const { Chris@16: return e._i; Chris@16: } Chris@16: }; Chris@16: struct edge_list_edge_property_selector { Chris@16: template Chris@16: struct bind_ { Chris@16: typedef el_edge_property_map type; Chris@16: typedef type const_type; Chris@16: }; Chris@16: }; Chris@16: template <> Chris@16: struct edge_property_selector { Chris@16: typedef edge_list_edge_property_selector type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename property_map< edge_list_impl, edge_index_t>::type Chris@16: get(edge_index_t, const edge_list_impl&) { Chris@16: typedef typename property_map< edge_list_impl, Chris@16: edge_index_t>::type EdgeIndexMap; Chris@16: return EdgeIndexMap(); Chris@16: } Chris@16: Chris@16: template Chris@16: inline D Chris@16: get(edge_index_t, const edge_list_impl&, Chris@16: typename edge_list_impl::edge_descriptor e) { Chris@16: return e._i; Chris@16: } Chris@16: Chris@16: // A specialized implementation for when the iterators are random access. Chris@16: Chris@16: struct edge_list_ra_tag { }; Chris@16: Chris@16: template Chris@16: class edge_list_impl_ra Chris@16: { Chris@16: public: Chris@16: typedef D edge_id; Chris@16: typedef T Vpair; Chris@16: typedef typename Vpair::first_type V; Chris@16: typedef edge_list_ra_tag graph_tag; Chris@16: typedef void edge_property_type; Chris@16: Chris@16: typedef edge_id edge_descriptor; Chris@16: typedef V vertex_descriptor; Chris@16: typedef typename boost::integer_range::iterator edge_iterator; Chris@16: typedef void out_edge_iterator; Chris@16: typedef void in_edge_iterator; Chris@16: typedef void adjacency_iterator; Chris@16: typedef void vertex_iterator; Chris@16: }; Chris@16: Chris@16: template Chris@16: std::pair::edge_iterator, Chris@16: typename edge_list_impl_ra::edge_iterator> Chris@16: edges(const edge_list_impl_ra& g_) Chris@16: { Chris@16: const G& g = static_cast(g_); Chris@16: typedef typename edge_list_impl_ra::edge_iterator edge_iterator; Chris@16: return std::make_pair(edge_iterator(0), edge_iterator(g._last - g._first)); Chris@16: } Chris@16: template Chris@16: typename edge_list_impl_ra::vertex_descriptor Chris@16: source(typename edge_list_impl_ra::edge_descriptor e, Chris@16: const edge_list_impl_ra& g_) Chris@16: { Chris@16: const G& g = static_cast(g_); Chris@16: return g._first[e].first; Chris@16: } Chris@16: template Chris@16: typename edge_list_impl_ra::vertex_descriptor Chris@16: target(typename edge_list_impl_ra::edge_descriptor e, Chris@16: const edge_list_impl_ra& g_) Chris@16: { Chris@16: const G& g = static_cast(g_); Chris@16: return g._first[e].second; Chris@16: } Chris@16: template Chris@16: class el_ra_edge_property_map Chris@16: : public put_get_helper >{ Chris@16: public: Chris@16: typedef E key_type; Chris@16: typedef E value_type; Chris@16: typedef E reference; Chris@16: typedef readable_property_map_tag category; Chris@16: Chris@16: value_type operator[](key_type e) const { Chris@16: return e; Chris@16: } Chris@16: }; Chris@16: struct edge_list_ra_edge_property_selector { Chris@16: template Chris@16: struct bind_ { Chris@16: typedef el_ra_edge_property_map type; Chris@16: typedef type const_type; Chris@16: }; Chris@16: }; Chris@16: template <> Chris@16: struct edge_property_selector { Chris@16: typedef edge_list_ra_edge_property_selector type; Chris@16: }; Chris@16: template Chris@16: inline Chris@16: typename property_map< edge_list_impl_ra, edge_index_t>::type Chris@16: get(edge_index_t, const edge_list_impl_ra&) { Chris@16: typedef typename property_map< edge_list_impl_ra, Chris@16: edge_index_t>::type EdgeIndexMap; Chris@16: return EdgeIndexMap(); Chris@16: } Chris@16: Chris@16: template Chris@16: inline D Chris@16: get(edge_index_t, const edge_list_impl_ra&, Chris@16: typename edge_list_impl_ra::edge_descriptor e) { Chris@16: return e; Chris@16: } Chris@16: Chris@16: Chris@16: // Some helper classes for determining if the iterators are random access Chris@16: template Chris@16: struct is_random { Chris@16: enum { RET = false }; Chris@16: typedef mpl::false_ type; Chris@16: }; Chris@16: template <> Chris@16: struct is_random { Chris@16: enum { RET = true }; typedef mpl::true_ type; Chris@16: }; Chris@16: Chris@16: // The edge_list class conditionally inherits from one of the Chris@16: // above two classes. Chris@16: Chris@16: template ::value_type, Chris@16: class D = typename std::iterator_traits::difference_type, Chris@16: class Cat = typename std::iterator_traits::iterator_category> Chris@16: #else Chris@16: class T, Chris@16: class D, Chris@16: class Cat> Chris@16: #endif Chris@16: class edge_list Chris@16: : public mpl::if_< typename is_random::type, Chris@16: edge_list_impl_ra< edge_list, EdgeIter,T,D>, Chris@16: edge_list_impl< edge_list, EdgeIter,T,D> Chris@16: >::type Chris@16: { Chris@16: public: Chris@16: typedef directed_tag directed_category; Chris@16: typedef allow_parallel_edge_tag edge_parallel_category; Chris@16: typedef edge_list_graph_tag traversal_category; Chris@16: typedef std::size_t edges_size_type; Chris@16: typedef std::size_t vertices_size_type; Chris@16: typedef std::size_t degree_size_type; Chris@16: edge_list(EdgeIter first, EdgeIter last) : _first(first), _last(last) { Chris@16: m_num_edges = std::distance(first, last); Chris@16: } Chris@16: edge_list(EdgeIter first, EdgeIter last, edges_size_type E) Chris@16: : _first(first), _last(last), m_num_edges(E) { } Chris@16: Chris@16: EdgeIter _first, _last; Chris@16: edges_size_type m_num_edges; Chris@16: }; Chris@16: Chris@16: template Chris@16: std::size_t num_edges(const edge_list& el) { Chris@16: return el.m_num_edges; Chris@16: } Chris@16: Chris@16: #ifndef BOOST_NO_STD_ITERATOR_TRAITS Chris@16: template Chris@16: inline edge_list Chris@16: make_edge_list(EdgeIter first, EdgeIter last) Chris@16: { Chris@16: return edge_list(first, last); Chris@16: } Chris@16: #endif Chris@16: Chris@16: } /* namespace boost */ Chris@16: Chris@16: #endif /* BOOST_GRAPH_EDGE_LIST_HPP */