adjacency_list.hpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. //=======================================================================
  2. // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
  3. // Copyright 2010 Thomas Claveirole
  4. // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Thomas Claveirole
  5. //
  6. // Distributed under the Boost Software License, Version 1.0. (See
  7. // accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //=======================================================================
  10. #ifndef BOOST_GRAPH_ADJACENCY_LIST_HPP
  11. #define BOOST_GRAPH_ADJACENCY_LIST_HPP
  12. #include <boost/config.hpp>
  13. #include <vector>
  14. #include <list>
  15. #include <set>
  16. #include <boost/unordered_set.hpp>
  17. #include <boost/scoped_ptr.hpp>
  18. #include <boost/graph/graph_traits.hpp>
  19. #include <boost/graph/graph_mutability_traits.hpp>
  20. #include <boost/graph/graph_selectors.hpp>
  21. #include <boost/property_map/property_map.hpp>
  22. #include <boost/mpl/if.hpp>
  23. #include <boost/mpl/and.hpp>
  24. #include <boost/mpl/not.hpp>
  25. #include <boost/mpl/bool.hpp>
  26. #include <boost/graph/detail/edge.hpp>
  27. #include <boost/type_traits/is_same.hpp>
  28. #include <boost/detail/workaround.hpp>
  29. #include <boost/graph/properties.hpp>
  30. #include <boost/graph/named_graph.hpp>
  31. namespace boost
  32. {
  33. //===========================================================================
  34. // Selectors for the VertexList and EdgeList template parameters of
  35. // adjacency_list, and the container_gen traits class which is used
  36. // to map the selectors to the container type used to implement the
  37. // graph.
  38. struct vecS
  39. {
  40. };
  41. struct listS
  42. {
  43. };
  44. struct setS
  45. {
  46. };
  47. struct mapS
  48. {
  49. };
  50. struct multisetS
  51. {
  52. };
  53. struct multimapS
  54. {
  55. };
  56. struct hash_setS
  57. {
  58. };
  59. struct hash_mapS
  60. {
  61. };
  62. struct hash_multisetS
  63. {
  64. };
  65. struct hash_multimapS
  66. {
  67. };
  68. template < class Selector, class ValueType > struct container_gen
  69. {
  70. };
  71. template < class ValueType > struct container_gen< listS, ValueType >
  72. {
  73. typedef std::list< ValueType > type;
  74. };
  75. template < class ValueType > struct container_gen< vecS, ValueType >
  76. {
  77. typedef std::vector< ValueType > type;
  78. };
  79. template < class ValueType > struct container_gen< mapS, ValueType >
  80. {
  81. typedef std::set< ValueType > type;
  82. };
  83. template < class ValueType > struct container_gen< setS, ValueType >
  84. {
  85. typedef std::set< ValueType > type;
  86. };
  87. template < class ValueType > struct container_gen< multisetS, ValueType >
  88. {
  89. typedef std::multiset< ValueType > type;
  90. };
  91. template < class ValueType > struct container_gen< multimapS, ValueType >
  92. {
  93. typedef std::multiset< ValueType > type;
  94. };
  95. template < class ValueType > struct container_gen< hash_setS, ValueType >
  96. {
  97. typedef boost::unordered_set< ValueType > type;
  98. };
  99. template < class ValueType > struct container_gen< hash_mapS, ValueType >
  100. {
  101. typedef boost::unordered_set< ValueType > type;
  102. };
  103. template < class ValueType > struct container_gen< hash_multisetS, ValueType >
  104. {
  105. typedef boost::unordered_multiset< ValueType > type;
  106. };
  107. template < class ValueType > struct container_gen< hash_multimapS, ValueType >
  108. {
  109. typedef boost::unordered_multiset< ValueType > type;
  110. };
  111. template < class StorageSelector > struct parallel_edge_traits
  112. {
  113. };
  114. template <> struct parallel_edge_traits< vecS >
  115. {
  116. typedef allow_parallel_edge_tag type;
  117. };
  118. template <> struct parallel_edge_traits< listS >
  119. {
  120. typedef allow_parallel_edge_tag type;
  121. };
  122. template <> struct parallel_edge_traits< setS >
  123. {
  124. typedef disallow_parallel_edge_tag type;
  125. };
  126. template <> struct parallel_edge_traits< multisetS >
  127. {
  128. typedef allow_parallel_edge_tag type;
  129. };
  130. template <> struct parallel_edge_traits< hash_setS >
  131. {
  132. typedef disallow_parallel_edge_tag type;
  133. };
  134. // mapS is obsolete, replaced with setS
  135. template <> struct parallel_edge_traits< mapS >
  136. {
  137. typedef disallow_parallel_edge_tag type;
  138. };
  139. template <> struct parallel_edge_traits< hash_mapS >
  140. {
  141. typedef disallow_parallel_edge_tag type;
  142. };
  143. template <> struct parallel_edge_traits< hash_multisetS >
  144. {
  145. typedef allow_parallel_edge_tag type;
  146. };
  147. template <> struct parallel_edge_traits< hash_multimapS >
  148. {
  149. typedef allow_parallel_edge_tag type;
  150. };
  151. namespace detail
  152. {
  153. template < class Directed > struct is_random_access
  154. {
  155. enum
  156. {
  157. value = false
  158. };
  159. typedef mpl::false_ type;
  160. };
  161. template <> struct is_random_access< vecS >
  162. {
  163. enum
  164. {
  165. value = true
  166. };
  167. typedef mpl::true_ type;
  168. };
  169. } // namespace detail
  170. template < typename Selector > struct is_distributed_selector : mpl::false_
  171. {
  172. };
  173. //===========================================================================
  174. // The adjacency_list_traits class, which provides a way to access
  175. // some of the associated types of an adjacency_list type without
  176. // having to first create the adjacency_list type. This is useful
  177. // when trying to create interior vertex or edge properties who's
  178. // value type is a vertex or edge descriptor.
  179. template < class OutEdgeListS = vecS, class VertexListS = vecS,
  180. class DirectedS = directedS, class EdgeListS = listS >
  181. struct adjacency_list_traits
  182. {
  183. typedef
  184. typename detail::is_random_access< VertexListS >::type is_rand_access;
  185. typedef typename DirectedS::is_bidir_t is_bidir;
  186. typedef typename DirectedS::is_directed_t is_directed;
  187. typedef typename mpl::if_< is_bidir, bidirectional_tag,
  188. typename mpl::if_< is_directed, directed_tag,
  189. undirected_tag >::type >::type directed_category;
  190. typedef typename parallel_edge_traits< OutEdgeListS >::type
  191. edge_parallel_category;
  192. typedef std::size_t vertices_size_type;
  193. typedef void* vertex_ptr;
  194. typedef typename mpl::if_< is_rand_access, vertices_size_type,
  195. vertex_ptr >::type vertex_descriptor;
  196. typedef detail::edge_desc_impl< directed_category, vertex_descriptor >
  197. edge_descriptor;
  198. private:
  199. // Logic to figure out the edges_size_type
  200. struct dummy
  201. {
  202. };
  203. typedef typename container_gen< EdgeListS, dummy >::type EdgeContainer;
  204. typedef typename DirectedS::is_bidir_t BidirectionalT;
  205. typedef typename DirectedS::is_directed_t DirectedT;
  206. typedef typename mpl::and_< DirectedT,
  207. typename mpl::not_< BidirectionalT >::type >::type on_edge_storage;
  208. public:
  209. typedef typename mpl::if_< on_edge_storage, std::size_t,
  210. typename EdgeContainer::size_type >::type edges_size_type;
  211. };
  212. } // namespace boost
  213. #include <boost/graph/detail/adjacency_list.hpp>
  214. namespace boost
  215. {
  216. //===========================================================================
  217. // The adjacency_list class.
  218. //
  219. template < class OutEdgeListS = vecS, // a Sequence or an AssociativeContainer
  220. class VertexListS = vecS, // a Sequence or a RandomAccessContainer
  221. class DirectedS = directedS, class VertexProperty = no_property,
  222. class EdgeProperty = no_property, class GraphProperty = no_property,
  223. class EdgeListS = listS >
  224. class adjacency_list
  225. : // Support for named vertices
  226. // This needs to be inherited from first to ensure it's initialized before the
  227. // "base" (i.e. detail::adj_list_gen), because the "base" might indirectly
  228. // call functions on it during its construction.
  229. public graph::maybe_named_graph<
  230. adjacency_list< OutEdgeListS, VertexListS, DirectedS, VertexProperty,
  231. EdgeProperty, GraphProperty, EdgeListS >,
  232. typename adjacency_list_traits< OutEdgeListS, VertexListS, DirectedS,
  233. EdgeListS >::vertex_descriptor,
  234. VertexProperty >,
  235. public detail::adj_list_gen<
  236. adjacency_list< OutEdgeListS, VertexListS, DirectedS, VertexProperty,
  237. EdgeProperty, GraphProperty, EdgeListS >,
  238. VertexListS, OutEdgeListS, DirectedS, VertexProperty, EdgeProperty,
  239. GraphProperty, EdgeListS >::type
  240. {
  241. public:
  242. typedef GraphProperty graph_property_type;
  243. typedef typename lookup_one_property< GraphProperty, graph_bundle_t >::type
  244. graph_bundled;
  245. typedef VertexProperty vertex_property_type;
  246. typedef
  247. typename lookup_one_property< VertexProperty, vertex_bundle_t >::type
  248. vertex_bundled;
  249. typedef EdgeProperty edge_property_type;
  250. typedef typename lookup_one_property< EdgeProperty, edge_bundle_t >::type
  251. edge_bundled;
  252. private:
  253. typedef adjacency_list self;
  254. typedef typename detail::adj_list_gen< self, VertexListS, OutEdgeListS,
  255. DirectedS, vertex_property_type, edge_property_type, GraphProperty,
  256. EdgeListS >::type Base;
  257. public:
  258. typedef typename Base::stored_vertex stored_vertex;
  259. typedef typename Base::vertices_size_type vertices_size_type;
  260. typedef typename Base::edges_size_type edges_size_type;
  261. typedef typename Base::degree_size_type degree_size_type;
  262. typedef typename Base::vertex_descriptor vertex_descriptor;
  263. typedef typename Base::edge_descriptor edge_descriptor;
  264. typedef OutEdgeListS out_edge_list_selector;
  265. typedef VertexListS vertex_list_selector;
  266. typedef DirectedS directed_selector;
  267. typedef EdgeListS edge_list_selector;
  268. adjacency_list(const GraphProperty& p = GraphProperty())
  269. : m_property(new graph_property_type(p))
  270. {
  271. }
  272. adjacency_list(const adjacency_list& x)
  273. : Base(x), m_property(new graph_property_type(*x.m_property))
  274. {
  275. }
  276. adjacency_list& operator=(const adjacency_list& x)
  277. {
  278. // TBD: probably should give the strong guarantee
  279. if (&x != this)
  280. {
  281. Base::operator=(x);
  282. // Copy/swap the ptr since we can't just assign it...
  283. property_ptr p(new graph_property_type(*x.m_property));
  284. m_property.swap(p);
  285. }
  286. return *this;
  287. }
  288. // Required by Mutable Graph
  289. adjacency_list(vertices_size_type num_vertices,
  290. const GraphProperty& p = GraphProperty())
  291. : Base(num_vertices), m_property(new graph_property_type(p))
  292. {
  293. }
  294. // Required by Iterator Constructible Graph
  295. template < class EdgeIterator >
  296. adjacency_list(EdgeIterator first, EdgeIterator last, vertices_size_type n,
  297. edges_size_type = 0, const GraphProperty& p = GraphProperty())
  298. : Base(n, first, last), m_property(new graph_property_type(p))
  299. {
  300. }
  301. template < class EdgeIterator, class EdgePropertyIterator >
  302. adjacency_list(EdgeIterator first, EdgeIterator last,
  303. EdgePropertyIterator ep_iter, vertices_size_type n, edges_size_type = 0,
  304. const GraphProperty& p = GraphProperty())
  305. : Base(n, first, last, ep_iter), m_property(new graph_property_type(p))
  306. {
  307. }
  308. void swap(adjacency_list& x)
  309. {
  310. // Is there a more efficient way to do this?
  311. adjacency_list tmp(x);
  312. x = *this;
  313. *this = tmp;
  314. }
  315. void clear()
  316. {
  317. this->clearing_graph();
  318. Base::clear();
  319. }
  320. #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
  321. // Directly access a vertex or edge bundle
  322. vertex_bundled& operator[](vertex_descriptor v)
  323. {
  324. return get(vertex_bundle, *this)[v];
  325. }
  326. const vertex_bundled& operator[](vertex_descriptor v) const
  327. {
  328. return get(vertex_bundle, *this)[v];
  329. }
  330. edge_bundled& operator[](edge_descriptor e)
  331. {
  332. return get(edge_bundle, *this)[e];
  333. }
  334. const edge_bundled& operator[](edge_descriptor e) const
  335. {
  336. return get(edge_bundle, *this)[e];
  337. }
  338. graph_bundled& operator[](graph_bundle_t) { return get_property(*this); }
  339. graph_bundled const& operator[](graph_bundle_t) const
  340. {
  341. return get_property(*this);
  342. }
  343. #endif
  344. // protected: (would be protected if friends were more portable)
  345. typedef scoped_ptr< graph_property_type > property_ptr;
  346. property_ptr m_property;
  347. };
  348. #define ADJLIST_PARAMS \
  349. typename OEL, typename VL, typename D, typename VP, typename EP, \
  350. typename GP, typename EL
  351. #define ADJLIST adjacency_list< OEL, VL, D, VP, EP, GP, EL >
  352. template < ADJLIST_PARAMS, typename Tag, typename Value >
  353. inline void set_property(ADJLIST& g, Tag tag, Value const& value)
  354. {
  355. get_property_value(*g.m_property, tag) = value;
  356. }
  357. template < ADJLIST_PARAMS, typename Tag >
  358. inline typename graph_property< ADJLIST, Tag >::type& get_property(
  359. ADJLIST& g, Tag tag)
  360. {
  361. return get_property_value(*g.m_property, tag);
  362. }
  363. template < ADJLIST_PARAMS, typename Tag >
  364. inline typename graph_property< ADJLIST, Tag >::type const& get_property(
  365. ADJLIST const& g, Tag tag)
  366. {
  367. return get_property_value(*g.m_property, tag);
  368. }
  369. // dwa 09/25/00 - needed to be more explicit so reverse_graph would work.
  370. template < class Directed, class Vertex, class OutEdgeListS, class VertexListS,
  371. class DirectedS, class VertexProperty, class EdgeProperty,
  372. class GraphProperty, class EdgeListS >
  373. inline Vertex source(const detail::edge_base< Directed, Vertex >& e,
  374. const adjacency_list< OutEdgeListS, VertexListS, DirectedS, VertexProperty,
  375. EdgeProperty, GraphProperty, EdgeListS >&)
  376. {
  377. return e.m_source;
  378. }
  379. template < class Directed, class Vertex, class OutEdgeListS, class VertexListS,
  380. class DirectedS, class VertexProperty, class EdgeProperty,
  381. class GraphProperty, class EdgeListS >
  382. inline Vertex target(const detail::edge_base< Directed, Vertex >& e,
  383. const adjacency_list< OutEdgeListS, VertexListS, DirectedS, VertexProperty,
  384. EdgeProperty, GraphProperty, EdgeListS >&)
  385. {
  386. return e.m_target;
  387. }
  388. // Mutability Traits
  389. template < ADJLIST_PARAMS > struct graph_mutability_traits< ADJLIST >
  390. {
  391. typedef mutable_property_graph_tag category;
  392. };
  393. // Can't remove vertices from adjacency lists with VL==vecS
  394. template < typename OEL, typename D, typename VP, typename EP, typename GP,
  395. typename EL >
  396. struct graph_mutability_traits< adjacency_list< OEL, vecS, D, VP, EP, GP, EL > >
  397. {
  398. typedef add_only_property_graph_tag category;
  399. };
  400. #undef ADJLIST_PARAMS
  401. #undef ADJLIST
  402. } // namespace boost
  403. #endif // BOOST_GRAPH_ADJACENCY_LIST_HPP