edge_list.hpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. //=======================================================================
  2. // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
  3. // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //=======================================================================
  9. //
  10. #ifndef BOOST_GRAPH_EDGE_LIST_HPP
  11. #define BOOST_GRAPH_EDGE_LIST_HPP
  12. #include <iterator>
  13. #include <boost/config.hpp>
  14. #include <boost/mpl/if.hpp>
  15. #include <boost/mpl/bool.hpp>
  16. #include <boost/range/irange.hpp>
  17. #include <boost/graph/graph_traits.hpp>
  18. #include <boost/graph/properties.hpp>
  19. namespace boost
  20. {
  21. //
  22. // The edge_list class is an EdgeListGraph module that is constructed
  23. // from a pair of iterators whose value type is a pair of vertex
  24. // descriptors.
  25. //
  26. // For example:
  27. //
  28. // typedef std::pair<int,int> E;
  29. // list<E> elist;
  30. // ...
  31. // typedef edge_list<list<E>::iterator> Graph;
  32. // Graph g(elist.begin(), elist.end());
  33. //
  34. // If the iterators are random access, then Graph::edge_descriptor
  35. // is of Integral type, otherwise it is a struct, though it is
  36. // convertible to an Integral type.
  37. //
  38. struct edge_list_tag
  39. {
  40. };
  41. // The implementation class for edge_list.
  42. template < class G, class EdgeIter, class T, class D > class edge_list_impl
  43. {
  44. public:
  45. typedef D edge_id;
  46. typedef T Vpair;
  47. typedef typename Vpair::first_type V;
  48. typedef V vertex_descriptor;
  49. typedef edge_list_tag graph_tag;
  50. typedef void edge_property_type;
  51. struct edge_descriptor
  52. {
  53. edge_descriptor() {}
  54. edge_descriptor(EdgeIter p, edge_id id) : _ptr(p), _id(id) {}
  55. operator edge_id() { return _id; }
  56. EdgeIter _ptr;
  57. edge_id _id;
  58. };
  59. typedef edge_descriptor E;
  60. struct edge_iterator
  61. {
  62. typedef edge_iterator self;
  63. typedef E value_type;
  64. typedef E& reference;
  65. typedef E* pointer;
  66. typedef std::ptrdiff_t difference_type;
  67. typedef std::input_iterator_tag iterator_category;
  68. edge_iterator() {}
  69. edge_iterator(EdgeIter iter) : _iter(iter), _i(0) {}
  70. E operator*() { return E(_iter, _i); }
  71. self& operator++()
  72. {
  73. ++_iter;
  74. ++_i;
  75. return *this;
  76. }
  77. self operator++(int)
  78. {
  79. self t = *this;
  80. ++(*this);
  81. return t;
  82. }
  83. bool operator==(const self& x) { return _iter == x._iter; }
  84. bool operator!=(const self& x) { return _iter != x._iter; }
  85. EdgeIter _iter;
  86. edge_id _i;
  87. };
  88. typedef void out_edge_iterator;
  89. typedef void in_edge_iterator;
  90. typedef void adjacency_iterator;
  91. typedef void vertex_iterator;
  92. };
  93. template < class G, class EI, class T, class D >
  94. std::pair< typename edge_list_impl< G, EI, T, D >::edge_iterator,
  95. typename edge_list_impl< G, EI, T, D >::edge_iterator >
  96. edges(const edge_list_impl< G, EI, T, D >& g_)
  97. {
  98. const G& g = static_cast< const G& >(g_);
  99. typedef typename edge_list_impl< G, EI, T, D >::edge_iterator edge_iterator;
  100. return std::make_pair(edge_iterator(g._first), edge_iterator(g._last));
  101. }
  102. template < class G, class EI, class T, class D >
  103. typename edge_list_impl< G, EI, T, D >::vertex_descriptor source(
  104. typename edge_list_impl< G, EI, T, D >::edge_descriptor e,
  105. const edge_list_impl< G, EI, T, D >&)
  106. {
  107. return (*e._ptr).first;
  108. }
  109. template < class G, class EI, class T, class D >
  110. typename edge_list_impl< G, EI, T, D >::vertex_descriptor target(
  111. typename edge_list_impl< G, EI, T, D >::edge_descriptor e,
  112. const edge_list_impl< G, EI, T, D >&)
  113. {
  114. return (*e._ptr).second;
  115. }
  116. template < class D, class E >
  117. class el_edge_property_map
  118. : public put_get_helper< D, el_edge_property_map< D, E > >
  119. {
  120. public:
  121. typedef E key_type;
  122. typedef D value_type;
  123. typedef D reference;
  124. typedef readable_property_map_tag category;
  125. value_type operator[](key_type e) const { return e._i; }
  126. };
  127. struct edge_list_edge_property_selector
  128. {
  129. template < class Graph, class Property, class Tag > struct bind_
  130. {
  131. typedef el_edge_property_map< typename Graph::edge_id,
  132. typename Graph::edge_descriptor >
  133. type;
  134. typedef type const_type;
  135. };
  136. };
  137. template <> struct edge_property_selector< edge_list_tag >
  138. {
  139. typedef edge_list_edge_property_selector type;
  140. };
  141. template < class G, class EI, class T, class D >
  142. typename property_map< edge_list_impl< G, EI, T, D >, edge_index_t >::type get(
  143. edge_index_t, const edge_list_impl< G, EI, T, D >&)
  144. {
  145. typedef typename property_map< edge_list_impl< G, EI, T, D >,
  146. edge_index_t >::type EdgeIndexMap;
  147. return EdgeIndexMap();
  148. }
  149. template < class G, class EI, class T, class D >
  150. inline D get(edge_index_t, const edge_list_impl< G, EI, T, D >&,
  151. typename edge_list_impl< G, EI, T, D >::edge_descriptor e)
  152. {
  153. return e._i;
  154. }
  155. // A specialized implementation for when the iterators are random access.
  156. struct edge_list_ra_tag
  157. {
  158. };
  159. template < class G, class EdgeIter, class T, class D > class edge_list_impl_ra
  160. {
  161. public:
  162. typedef D edge_id;
  163. typedef T Vpair;
  164. typedef typename Vpair::first_type V;
  165. typedef edge_list_ra_tag graph_tag;
  166. typedef void edge_property_type;
  167. typedef edge_id edge_descriptor;
  168. typedef V vertex_descriptor;
  169. typedef typename boost::integer_range< edge_id >::iterator edge_iterator;
  170. typedef void out_edge_iterator;
  171. typedef void in_edge_iterator;
  172. typedef void adjacency_iterator;
  173. typedef void vertex_iterator;
  174. };
  175. template < class G, class EI, class T, class D >
  176. std::pair< typename edge_list_impl_ra< G, EI, T, D >::edge_iterator,
  177. typename edge_list_impl_ra< G, EI, T, D >::edge_iterator >
  178. edges(const edge_list_impl_ra< G, EI, T, D >& g_)
  179. {
  180. const G& g = static_cast< const G& >(g_);
  181. typedef
  182. typename edge_list_impl_ra< G, EI, T, D >::edge_iterator edge_iterator;
  183. return std::make_pair(edge_iterator(0), edge_iterator(g._last - g._first));
  184. }
  185. template < class G, class EI, class T, class D >
  186. typename edge_list_impl_ra< G, EI, T, D >::vertex_descriptor source(
  187. typename edge_list_impl_ra< G, EI, T, D >::edge_descriptor e,
  188. const edge_list_impl_ra< G, EI, T, D >& g_)
  189. {
  190. const G& g = static_cast< const G& >(g_);
  191. return g._first[e].first;
  192. }
  193. template < class G, class EI, class T, class D >
  194. typename edge_list_impl_ra< G, EI, T, D >::vertex_descriptor target(
  195. typename edge_list_impl_ra< G, EI, T, D >::edge_descriptor e,
  196. const edge_list_impl_ra< G, EI, T, D >& g_)
  197. {
  198. const G& g = static_cast< const G& >(g_);
  199. return g._first[e].second;
  200. }
  201. template < class E >
  202. class el_ra_edge_property_map
  203. : public put_get_helper< E, el_ra_edge_property_map< E > >
  204. {
  205. public:
  206. typedef E key_type;
  207. typedef E value_type;
  208. typedef E reference;
  209. typedef readable_property_map_tag category;
  210. value_type operator[](key_type e) const { return e; }
  211. };
  212. struct edge_list_ra_edge_property_selector
  213. {
  214. template < class Graph, class Property, class Tag > struct bind_
  215. {
  216. typedef el_ra_edge_property_map< typename Graph::edge_descriptor > type;
  217. typedef type const_type;
  218. };
  219. };
  220. template <> struct edge_property_selector< edge_list_ra_tag >
  221. {
  222. typedef edge_list_ra_edge_property_selector type;
  223. };
  224. template < class G, class EI, class T, class D >
  225. inline typename property_map< edge_list_impl_ra< G, EI, T, D >,
  226. edge_index_t >::type
  227. get(edge_index_t, const edge_list_impl_ra< G, EI, T, D >&)
  228. {
  229. typedef typename property_map< edge_list_impl_ra< G, EI, T, D >,
  230. edge_index_t >::type EdgeIndexMap;
  231. return EdgeIndexMap();
  232. }
  233. template < class G, class EI, class T, class D >
  234. inline D get(edge_index_t, const edge_list_impl_ra< G, EI, T, D >&,
  235. typename edge_list_impl_ra< G, EI, T, D >::edge_descriptor e)
  236. {
  237. return e;
  238. }
  239. // Some helper classes for determining if the iterators are random access
  240. template < class Cat > struct is_random
  241. {
  242. enum
  243. {
  244. RET = false
  245. };
  246. typedef mpl::false_ type;
  247. };
  248. template <> struct is_random< std::random_access_iterator_tag >
  249. {
  250. enum
  251. {
  252. RET = true
  253. };
  254. typedef mpl::true_ type;
  255. };
  256. // The edge_list class conditionally inherits from one of the
  257. // above two classes.
  258. template < class EdgeIter,
  259. #if !defined BOOST_NO_STD_ITERATOR_TRAITS
  260. class T = typename std::iterator_traits< EdgeIter >::value_type,
  261. class D = typename std::iterator_traits< EdgeIter >::difference_type,
  262. class Cat = typename std::iterator_traits< EdgeIter >::iterator_category >
  263. #else
  264. class T, class D, class Cat >
  265. #endif
  266. class edge_list
  267. : public mpl::if_< typename is_random< Cat >::type,
  268. edge_list_impl_ra< edge_list< EdgeIter, T, D, Cat >, EdgeIter, T, D >,
  269. edge_list_impl< edge_list< EdgeIter, T, D, Cat >, EdgeIter, T, D > >::type
  270. {
  271. public:
  272. typedef directed_tag directed_category;
  273. typedef allow_parallel_edge_tag edge_parallel_category;
  274. typedef edge_list_graph_tag traversal_category;
  275. typedef std::size_t edges_size_type;
  276. typedef std::size_t vertices_size_type;
  277. typedef std::size_t degree_size_type;
  278. edge_list(EdgeIter first, EdgeIter last) : _first(first), _last(last)
  279. {
  280. m_num_edges = std::distance(first, last);
  281. }
  282. edge_list(EdgeIter first, EdgeIter last, edges_size_type E)
  283. : _first(first), _last(last), m_num_edges(E)
  284. {
  285. }
  286. EdgeIter _first, _last;
  287. edges_size_type m_num_edges;
  288. };
  289. template < class EdgeIter, class T, class D, class Cat >
  290. std::size_t num_edges(const edge_list< EdgeIter, T, D, Cat >& el)
  291. {
  292. return el.m_num_edges;
  293. }
  294. #ifndef BOOST_NO_STD_ITERATOR_TRAITS
  295. template < class EdgeIter >
  296. inline edge_list< EdgeIter > make_edge_list(EdgeIter first, EdgeIter last)
  297. {
  298. return edge_list< EdgeIter >(first, last);
  299. }
  300. #endif
  301. } /* namespace boost */
  302. #endif /* BOOST_GRAPH_EDGE_LIST_HPP */