adjacency_matrix.hpp 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297
  1. //=======================================================================
  2. // Copyright 2001 University of Notre Dame.
  3. // Copyright 2006 Trustees of Indiana University
  4. // Authors: Jeremy G. Siek and Douglas Gregor <dgregor@cs.indiana.edu>
  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_ADJACENCY_MATRIX_HPP
  11. #define BOOST_ADJACENCY_MATRIX_HPP
  12. #include <boost/config.hpp>
  13. #include <vector>
  14. #include <memory>
  15. #include <iterator>
  16. #include <boost/assert.hpp>
  17. #include <boost/limits.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/mpl/if.hpp>
  22. #include <boost/mpl/bool.hpp>
  23. #include <boost/graph/adjacency_iterator.hpp>
  24. #include <boost/graph/detail/edge.hpp>
  25. #include <boost/iterator/iterator_adaptor.hpp>
  26. #include <boost/iterator/filter_iterator.hpp>
  27. #include <boost/range/irange.hpp>
  28. #include <boost/graph/properties.hpp>
  29. #include <boost/tuple/tuple.hpp>
  30. #include <boost/static_assert.hpp>
  31. #include <boost/type_traits.hpp>
  32. #include <boost/property_map/property_map.hpp>
  33. #include <boost/property_map/transform_value_property_map.hpp>
  34. #include <boost/property_map/function_property_map.hpp>
  35. namespace boost
  36. {
  37. namespace detail
  38. {
  39. template < class Directed, class Vertex >
  40. class matrix_edge_desc_impl : public edge_desc_impl< Directed, Vertex >
  41. {
  42. typedef edge_desc_impl< Directed, Vertex > Base;
  43. public:
  44. matrix_edge_desc_impl() {}
  45. matrix_edge_desc_impl(
  46. bool exists, Vertex s, Vertex d, const void* ep = 0)
  47. : Base(s, d, ep), m_exists(exists)
  48. {
  49. }
  50. bool exists() const { return m_exists; }
  51. private:
  52. bool m_exists;
  53. };
  54. struct does_edge_exist
  55. {
  56. template < class Edge > bool operator()(const Edge& e) const
  57. {
  58. return e.exists();
  59. }
  60. };
  61. // Note to self... The int for get_edge_exists and set_edge exist helps
  62. // make these calls unambiguous.
  63. template < typename EdgeProperty >
  64. bool get_edge_exists(
  65. const std::pair< bool, EdgeProperty >& stored_edge, int)
  66. {
  67. return stored_edge.first;
  68. }
  69. template < typename EdgeProperty >
  70. void set_edge_exists(
  71. std::pair< bool, EdgeProperty >& stored_edge, bool flag, int)
  72. {
  73. stored_edge.first = flag;
  74. }
  75. template < typename EdgeProxy >
  76. bool get_edge_exists(const EdgeProxy& edge_proxy, ...)
  77. {
  78. return edge_proxy;
  79. }
  80. template < typename EdgeProxy >
  81. EdgeProxy& set_edge_exists(EdgeProxy& edge_proxy, bool flag, ...)
  82. {
  83. edge_proxy = flag;
  84. return edge_proxy; // just to avoid never used warning
  85. }
  86. // NOTE: These functions collide with the get_property function for
  87. // accessing bundled graph properties. Be excplicit when using them.
  88. template < typename EdgeProperty >
  89. const EdgeProperty& get_edge_property(
  90. const std::pair< bool, EdgeProperty >& stored_edge)
  91. {
  92. return stored_edge.second;
  93. }
  94. template < typename EdgeProperty >
  95. EdgeProperty& get_edge_property(
  96. std::pair< bool, EdgeProperty >& stored_edge)
  97. {
  98. return stored_edge.second;
  99. }
  100. template < typename StoredEdgeProperty, typename EdgeProperty >
  101. inline void set_edge_property(
  102. std::pair< bool, StoredEdgeProperty >& stored_edge,
  103. const EdgeProperty& ep, int)
  104. {
  105. stored_edge.second = ep;
  106. }
  107. inline const no_property& get_edge_property(const char&)
  108. {
  109. static no_property s_prop;
  110. return s_prop;
  111. }
  112. inline no_property& get_edge_property(char&)
  113. {
  114. static no_property s_prop;
  115. return s_prop;
  116. }
  117. template < typename EdgeProxy, typename EdgeProperty >
  118. inline void set_edge_property(EdgeProxy, const EdgeProperty&, ...)
  119. {
  120. }
  121. //=======================================================================
  122. // Directed Out Edge Iterator
  123. template < typename VertexDescriptor, typename MatrixIter,
  124. typename VerticesSizeType, typename EdgeDescriptor >
  125. struct dir_adj_matrix_out_edge_iter
  126. : iterator_adaptor< dir_adj_matrix_out_edge_iter< VertexDescriptor,
  127. MatrixIter, VerticesSizeType, EdgeDescriptor >,
  128. MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
  129. std::ptrdiff_t >
  130. {
  131. typedef iterator_adaptor<
  132. dir_adj_matrix_out_edge_iter< VertexDescriptor, MatrixIter,
  133. VerticesSizeType, EdgeDescriptor >,
  134. MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
  135. std::ptrdiff_t >
  136. super_t;
  137. dir_adj_matrix_out_edge_iter() {}
  138. dir_adj_matrix_out_edge_iter(const MatrixIter& i,
  139. const VertexDescriptor& src, const VerticesSizeType& n)
  140. : super_t(i), m_src(src), m_targ(0), m_n(n)
  141. {
  142. }
  143. void increment()
  144. {
  145. ++this->base_reference();
  146. ++m_targ;
  147. }
  148. inline EdgeDescriptor dereference() const
  149. {
  150. return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src,
  151. m_targ, &get_edge_property(*this->base()));
  152. }
  153. VertexDescriptor m_src, m_targ;
  154. VerticesSizeType m_n;
  155. };
  156. //=======================================================================
  157. // Directed In Edge Iterator
  158. template < typename VertexDescriptor, typename MatrixIter,
  159. typename VerticesSizeType, typename EdgeDescriptor >
  160. struct dir_adj_matrix_in_edge_iter
  161. : iterator_adaptor< dir_adj_matrix_in_edge_iter< VertexDescriptor,
  162. MatrixIter, VerticesSizeType, EdgeDescriptor >,
  163. MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
  164. std::ptrdiff_t >
  165. {
  166. typedef iterator_adaptor<
  167. dir_adj_matrix_in_edge_iter< VertexDescriptor, MatrixIter,
  168. VerticesSizeType, EdgeDescriptor >,
  169. MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
  170. std::ptrdiff_t >
  171. super_t;
  172. dir_adj_matrix_in_edge_iter() {}
  173. dir_adj_matrix_in_edge_iter(const MatrixIter& i, const MatrixIter& last,
  174. const VertexDescriptor& tgt, const VerticesSizeType& n)
  175. : super_t(i), m_last(last), m_src(0), m_targ(tgt), m_n(n)
  176. {
  177. }
  178. void increment()
  179. {
  180. if (VerticesSizeType(m_last - this->base_reference()) >= m_n)
  181. {
  182. this->base_reference() += m_n;
  183. ++m_src;
  184. }
  185. else
  186. {
  187. this->base_reference() = m_last;
  188. }
  189. }
  190. inline EdgeDescriptor dereference() const
  191. {
  192. return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src,
  193. m_targ, &get_edge_property(*this->base()));
  194. }
  195. MatrixIter m_last;
  196. VertexDescriptor m_src, m_targ;
  197. VerticesSizeType m_n;
  198. };
  199. //=======================================================================
  200. // Undirected Out Edge Iterator
  201. template < typename VertexDescriptor, typename MatrixIter,
  202. typename VerticesSizeType, typename EdgeDescriptor >
  203. struct undir_adj_matrix_out_edge_iter
  204. : iterator_adaptor< undir_adj_matrix_out_edge_iter< VertexDescriptor,
  205. MatrixIter, VerticesSizeType, EdgeDescriptor >,
  206. MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
  207. std::ptrdiff_t >
  208. {
  209. typedef iterator_adaptor<
  210. undir_adj_matrix_out_edge_iter< VertexDescriptor, MatrixIter,
  211. VerticesSizeType, EdgeDescriptor >,
  212. MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
  213. std::ptrdiff_t >
  214. super_t;
  215. undir_adj_matrix_out_edge_iter() {}
  216. undir_adj_matrix_out_edge_iter(const MatrixIter& i,
  217. const VertexDescriptor& src, const VerticesSizeType& n)
  218. : super_t(i), m_src(src), m_inc(src), m_targ(0), m_n(n)
  219. {
  220. }
  221. void increment()
  222. {
  223. if (m_targ < m_src) // first half
  224. {
  225. ++this->base_reference();
  226. }
  227. else if (m_targ < m_n - 1)
  228. { // second half
  229. ++m_inc;
  230. this->base_reference() += m_inc;
  231. }
  232. else
  233. { // past-the-end
  234. this->base_reference() += m_n - m_src;
  235. }
  236. ++m_targ;
  237. }
  238. inline EdgeDescriptor dereference() const
  239. {
  240. return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src,
  241. m_targ, &get_edge_property(*this->base()));
  242. }
  243. VertexDescriptor m_src, m_inc, m_targ;
  244. VerticesSizeType m_n;
  245. };
  246. //=======================================================================
  247. // Undirected In Edge Iterator
  248. template < typename VertexDescriptor, typename MatrixIter,
  249. typename VerticesSizeType, typename EdgeDescriptor >
  250. struct undir_adj_matrix_in_edge_iter
  251. : iterator_adaptor< undir_adj_matrix_in_edge_iter< VertexDescriptor,
  252. MatrixIter, VerticesSizeType, EdgeDescriptor >,
  253. MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
  254. std::ptrdiff_t >
  255. {
  256. typedef iterator_adaptor<
  257. undir_adj_matrix_in_edge_iter< VertexDescriptor, MatrixIter,
  258. VerticesSizeType, EdgeDescriptor >,
  259. MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
  260. std::ptrdiff_t >
  261. super_t;
  262. undir_adj_matrix_in_edge_iter() {}
  263. undir_adj_matrix_in_edge_iter(const MatrixIter& i,
  264. const VertexDescriptor& src, const VerticesSizeType& n)
  265. : super_t(i), m_src(src), m_inc(src), m_targ(0), m_n(n)
  266. {
  267. }
  268. void increment()
  269. {
  270. if (m_targ < m_src) // first half
  271. {
  272. ++this->base_reference();
  273. }
  274. else if (m_targ < m_n - 1)
  275. { // second half
  276. ++m_inc;
  277. this->base_reference() += m_inc;
  278. }
  279. else
  280. { // past-the-end
  281. this->base_reference() += m_n - m_src;
  282. }
  283. ++m_targ;
  284. }
  285. inline EdgeDescriptor dereference() const
  286. {
  287. return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_targ,
  288. m_src, &get_edge_property(*this->base()));
  289. }
  290. VertexDescriptor m_src, m_inc, m_targ;
  291. VerticesSizeType m_n;
  292. };
  293. //=======================================================================
  294. // Edge Iterator
  295. template < typename Directed, typename MatrixIter,
  296. typename VerticesSizeType, typename EdgeDescriptor >
  297. struct adj_matrix_edge_iter
  298. : iterator_adaptor< adj_matrix_edge_iter< Directed, MatrixIter,
  299. VerticesSizeType, EdgeDescriptor >,
  300. MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
  301. std::ptrdiff_t >
  302. {
  303. typedef iterator_adaptor< adj_matrix_edge_iter< Directed, MatrixIter,
  304. VerticesSizeType, EdgeDescriptor >,
  305. MatrixIter, EdgeDescriptor, use_default, EdgeDescriptor,
  306. std::ptrdiff_t >
  307. super_t;
  308. adj_matrix_edge_iter() {}
  309. adj_matrix_edge_iter(const MatrixIter& i, const MatrixIter& start,
  310. const VerticesSizeType& n)
  311. : super_t(i), m_start(start), m_src(0), m_targ(0), m_n(n)
  312. {
  313. }
  314. void increment()
  315. {
  316. increment_dispatch(this->base_reference(), Directed());
  317. }
  318. void increment_dispatch(MatrixIter& i, directedS)
  319. {
  320. ++i;
  321. if (m_targ == m_n - 1)
  322. {
  323. m_targ = 0;
  324. ++m_src;
  325. }
  326. else
  327. {
  328. ++m_targ;
  329. }
  330. }
  331. void increment_dispatch(MatrixIter& i, undirectedS)
  332. {
  333. ++i;
  334. if (m_targ == m_src)
  335. {
  336. m_targ = 0;
  337. ++m_src;
  338. }
  339. else
  340. {
  341. ++m_targ;
  342. }
  343. }
  344. inline EdgeDescriptor dereference() const
  345. {
  346. return EdgeDescriptor(get_edge_exists(*this->base(), 0), m_src,
  347. m_targ, &get_edge_property(*this->base()));
  348. }
  349. MatrixIter m_start;
  350. VerticesSizeType m_src, m_targ, m_n;
  351. };
  352. } // namespace detail
  353. //=========================================================================
  354. // Adjacency Matrix Traits
  355. template < typename Directed = directedS > class adjacency_matrix_traits
  356. {
  357. typedef typename Directed::is_directed_t is_directed;
  358. public:
  359. // The bidirectionalS tag is not allowed with the adjacency_matrix
  360. // graph type. Instead, use directedS, which also provides the
  361. // functionality required for a Bidirectional Graph (in_edges,
  362. // in_degree, etc.).
  363. BOOST_STATIC_ASSERT(!(is_same< Directed, bidirectionalS >::value));
  364. typedef typename mpl::if_< is_directed, bidirectional_tag,
  365. undirected_tag >::type directed_category;
  366. typedef disallow_parallel_edge_tag edge_parallel_category;
  367. typedef std::size_t vertex_descriptor;
  368. typedef detail::matrix_edge_desc_impl< directed_category,
  369. vertex_descriptor >
  370. edge_descriptor;
  371. };
  372. struct adjacency_matrix_class_tag
  373. {
  374. };
  375. struct adj_matrix_traversal_tag : public virtual adjacency_matrix_tag,
  376. public virtual vertex_list_graph_tag,
  377. public virtual incidence_graph_tag,
  378. public virtual adjacency_graph_tag,
  379. public virtual edge_list_graph_tag
  380. {
  381. };
  382. //=========================================================================
  383. // Adjacency Matrix Class
  384. template < typename Directed = directedS, typename VertexProperty = no_property,
  385. typename EdgeProperty = no_property, typename GraphProperty = no_property,
  386. typename Allocator = std::allocator< bool > >
  387. class adjacency_matrix
  388. {
  389. typedef adjacency_matrix self;
  390. typedef adjacency_matrix_traits< Directed > Traits;
  391. public:
  392. // The bidirectionalS tag is not allowed with the adjacency_matrix
  393. // graph type. Instead, use directedS, which also provides the
  394. // functionality required for a Bidirectional Graph (in_edges,
  395. // in_degree, etc.).
  396. BOOST_STATIC_ASSERT(!(is_same< Directed, bidirectionalS >::value));
  397. typedef GraphProperty graph_property_type;
  398. typedef typename lookup_one_property< GraphProperty, graph_bundle_t >::type
  399. graph_bundled;
  400. typedef VertexProperty vertex_property_type;
  401. typedef
  402. typename lookup_one_property< VertexProperty, vertex_bundle_t >::type
  403. vertex_bundled;
  404. typedef EdgeProperty edge_property_type;
  405. typedef typename lookup_one_property< EdgeProperty, edge_bundle_t >::type
  406. edge_bundled;
  407. public: // should be private
  408. typedef
  409. typename mpl::if_< typename has_property< edge_property_type >::type,
  410. std::pair< bool, edge_property_type >, char >::type StoredEdge;
  411. #if defined(BOOST_NO_STD_ALLOCATOR)
  412. typedef std::vector< StoredEdge > Matrix;
  413. #else
  414. #if defined(BOOST_NO_CXX11_ALLOCATOR)
  415. typedef typename Allocator::template rebind< StoredEdge >::other Alloc;
  416. #else
  417. typedef typename std::allocator_traits< Allocator >::template rebind_alloc<
  418. StoredEdge >
  419. Alloc;
  420. #endif
  421. typedef std::vector< StoredEdge, Alloc > Matrix;
  422. #endif
  423. typedef typename Matrix::iterator MatrixIter;
  424. typedef typename Matrix::size_type size_type;
  425. public:
  426. // Graph concept required types
  427. typedef typename Traits::vertex_descriptor vertex_descriptor;
  428. typedef typename Traits::edge_descriptor edge_descriptor;
  429. typedef typename Traits::directed_category directed_category;
  430. typedef typename Traits::edge_parallel_category edge_parallel_category;
  431. typedef adj_matrix_traversal_tag traversal_category;
  432. static vertex_descriptor null_vertex()
  433. {
  434. return (std::numeric_limits< vertex_descriptor >::max)();
  435. }
  436. // private: if friends worked, these would be private
  437. typedef detail::dir_adj_matrix_out_edge_iter< vertex_descriptor, MatrixIter,
  438. size_type, edge_descriptor >
  439. DirOutEdgeIter;
  440. typedef detail::undir_adj_matrix_out_edge_iter< vertex_descriptor,
  441. MatrixIter, size_type, edge_descriptor >
  442. UnDirOutEdgeIter;
  443. typedef typename mpl::if_< typename Directed::is_directed_t, DirOutEdgeIter,
  444. UnDirOutEdgeIter >::type unfiltered_out_edge_iter;
  445. typedef detail::dir_adj_matrix_in_edge_iter< vertex_descriptor, MatrixIter,
  446. size_type, edge_descriptor >
  447. DirInEdgeIter;
  448. typedef detail::undir_adj_matrix_in_edge_iter< vertex_descriptor,
  449. MatrixIter, size_type, edge_descriptor >
  450. UnDirInEdgeIter;
  451. typedef typename mpl::if_< typename Directed::is_directed_t, DirInEdgeIter,
  452. UnDirInEdgeIter >::type unfiltered_in_edge_iter;
  453. typedef detail::adj_matrix_edge_iter< Directed, MatrixIter, size_type,
  454. edge_descriptor >
  455. unfiltered_edge_iter;
  456. public:
  457. // IncidenceGraph concept required types
  458. typedef filter_iterator< detail::does_edge_exist, unfiltered_out_edge_iter >
  459. out_edge_iterator;
  460. typedef size_type degree_size_type;
  461. // BidirectionalGraph required types
  462. typedef filter_iterator< detail::does_edge_exist, unfiltered_in_edge_iter >
  463. in_edge_iterator;
  464. // AdjacencyGraph required types
  465. typedef typename adjacency_iterator_generator< self, vertex_descriptor,
  466. out_edge_iterator >::type adjacency_iterator;
  467. // VertexListGraph required types
  468. typedef size_type vertices_size_type;
  469. typedef integer_range< vertex_descriptor > VertexList;
  470. typedef typename VertexList::iterator vertex_iterator;
  471. // EdgeListGraph required types
  472. typedef size_type edges_size_type;
  473. typedef filter_iterator< detail::does_edge_exist, unfiltered_edge_iter >
  474. edge_iterator;
  475. // PropertyGraph required types
  476. typedef adjacency_matrix_class_tag graph_tag;
  477. // Constructor required by MutableGraph
  478. adjacency_matrix(
  479. vertices_size_type n_vertices, const GraphProperty& p = GraphProperty())
  480. : m_matrix(Directed::is_directed ? (n_vertices * n_vertices)
  481. : (n_vertices * (n_vertices + 1) / 2))
  482. , m_vertex_set(0, n_vertices)
  483. , m_vertex_properties(n_vertices)
  484. , m_num_edges(0)
  485. , m_property(p)
  486. {
  487. }
  488. template < typename EdgeIterator >
  489. adjacency_matrix(EdgeIterator first, EdgeIterator last,
  490. vertices_size_type n_vertices, const GraphProperty& p = GraphProperty())
  491. : m_matrix(Directed::is_directed ? (n_vertices * n_vertices)
  492. : (n_vertices * (n_vertices + 1) / 2))
  493. , m_vertex_set(0, n_vertices)
  494. , m_vertex_properties(n_vertices)
  495. , m_num_edges(0)
  496. , m_property(p)
  497. {
  498. for (; first != last; ++first)
  499. {
  500. add_edge(first->first, first->second, *this);
  501. }
  502. }
  503. template < typename EdgeIterator, typename EdgePropertyIterator >
  504. adjacency_matrix(EdgeIterator first, EdgeIterator last,
  505. EdgePropertyIterator ep_iter, vertices_size_type n_vertices,
  506. const GraphProperty& p = GraphProperty())
  507. : m_matrix(Directed::is_directed ? (n_vertices * n_vertices)
  508. : (n_vertices * (n_vertices + 1) / 2))
  509. , m_vertex_set(0, n_vertices)
  510. , m_vertex_properties(n_vertices)
  511. , m_num_edges(0)
  512. , m_property(p)
  513. {
  514. for (; first != last; ++first, ++ep_iter)
  515. {
  516. add_edge(first->first, first->second, *ep_iter, *this);
  517. }
  518. }
  519. #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
  520. // Directly access a vertex or edge bundle
  521. vertex_bundled& operator[](vertex_descriptor v)
  522. {
  523. return get(vertex_bundle, *this, v);
  524. }
  525. const vertex_bundled& operator[](vertex_descriptor v) const
  526. {
  527. return get(vertex_bundle, *this, v);
  528. }
  529. edge_bundled& operator[](edge_descriptor e)
  530. {
  531. return get(edge_bundle, *this, e);
  532. }
  533. const edge_bundled& operator[](edge_descriptor e) const
  534. {
  535. return get(edge_bundle, *this, e);
  536. }
  537. graph_bundled& operator[](graph_bundle_t) { return get_property(*this); }
  538. const graph_bundled& operator[](graph_bundle_t) const
  539. {
  540. return get_property(*this);
  541. }
  542. #endif
  543. // private: if friends worked, these would be private
  544. typename Matrix::const_reference get_edge(
  545. vertex_descriptor u, vertex_descriptor v) const
  546. {
  547. if (Directed::is_directed)
  548. return m_matrix[u * m_vertex_set.size() + v];
  549. else
  550. {
  551. if (v > u)
  552. std::swap(u, v);
  553. return m_matrix[u * (u + 1) / 2 + v];
  554. }
  555. }
  556. typename Matrix::reference get_edge(
  557. vertex_descriptor u, vertex_descriptor v)
  558. {
  559. if (Directed::is_directed)
  560. return m_matrix[u * m_vertex_set.size() + v];
  561. else
  562. {
  563. if (v > u)
  564. std::swap(u, v);
  565. return m_matrix[u * (u + 1) / 2 + v];
  566. }
  567. }
  568. Matrix m_matrix;
  569. VertexList m_vertex_set;
  570. std::vector< vertex_property_type > m_vertex_properties;
  571. size_type m_num_edges;
  572. graph_property_type m_property;
  573. };
  574. //=========================================================================
  575. // Functions required by the AdjacencyMatrix concept
  576. template < typename D, typename VP, typename EP, typename GP, typename A >
  577. std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor,
  578. bool >
  579. edge(typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u,
  580. typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v,
  581. const adjacency_matrix< D, VP, EP, GP, A >& g)
  582. {
  583. bool exists = detail::get_edge_exists(g.get_edge(u, v), 0);
  584. typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor e(
  585. exists, u, v, &detail::get_edge_property(g.get_edge(u, v)));
  586. return std::make_pair(e, exists);
  587. }
  588. //=========================================================================
  589. // Functions required by the IncidenceGraph concept
  590. // O(1)
  591. template < typename VP, typename EP, typename GP, typename A >
  592. std::pair<
  593. typename adjacency_matrix< directedS, VP, EP, GP, A >::out_edge_iterator,
  594. typename adjacency_matrix< directedS, VP, EP, GP, A >::out_edge_iterator >
  595. out_edges(
  596. typename adjacency_matrix< directedS, VP, EP, GP, A >::vertex_descriptor u,
  597. const adjacency_matrix< directedS, VP, EP, GP, A >& g_)
  598. {
  599. typedef adjacency_matrix< directedS, VP, EP, GP, A > Graph;
  600. Graph& g = const_cast< Graph& >(g_);
  601. typename Graph::vertices_size_type offset = u * g.m_vertex_set.size();
  602. typename Graph::MatrixIter f = g.m_matrix.begin() + offset;
  603. typename Graph::MatrixIter l = f + g.m_vertex_set.size();
  604. typename Graph::unfiltered_out_edge_iter first(f, u, g.m_vertex_set.size()),
  605. last(l, u, g.m_vertex_set.size());
  606. detail::does_edge_exist pred;
  607. typedef typename Graph::out_edge_iterator out_edge_iterator;
  608. return std::make_pair(out_edge_iterator(pred, first, last),
  609. out_edge_iterator(pred, last, last));
  610. }
  611. // O(1)
  612. template < typename VP, typename EP, typename GP, typename A >
  613. std::pair<
  614. typename adjacency_matrix< undirectedS, VP, EP, GP, A >::out_edge_iterator,
  615. typename adjacency_matrix< undirectedS, VP, EP, GP, A >::out_edge_iterator >
  616. out_edges(
  617. typename adjacency_matrix< undirectedS, VP, EP, GP, A >::vertex_descriptor
  618. u,
  619. const adjacency_matrix< undirectedS, VP, EP, GP, A >& g_)
  620. {
  621. typedef adjacency_matrix< undirectedS, VP, EP, GP, A > Graph;
  622. Graph& g = const_cast< Graph& >(g_);
  623. typename Graph::vertices_size_type offset = u * (u + 1) / 2;
  624. typename Graph::MatrixIter f = g.m_matrix.begin() + offset;
  625. typename Graph::MatrixIter l = g.m_matrix.end();
  626. typename Graph::unfiltered_out_edge_iter first(f, u, g.m_vertex_set.size()),
  627. last(l, u, g.m_vertex_set.size());
  628. detail::does_edge_exist pred;
  629. typedef typename Graph::out_edge_iterator out_edge_iterator;
  630. return std::make_pair(out_edge_iterator(pred, first, last),
  631. out_edge_iterator(pred, last, last));
  632. }
  633. // O(N)
  634. template < typename D, typename VP, typename EP, typename GP, typename A >
  635. typename adjacency_matrix< D, VP, EP, GP, A >::degree_size_type out_degree(
  636. typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u,
  637. const adjacency_matrix< D, VP, EP, GP, A >& g)
  638. {
  639. typename adjacency_matrix< D, VP, EP, GP, A >::degree_size_type n = 0;
  640. typename adjacency_matrix< D, VP, EP, GP, A >::out_edge_iterator f, l;
  641. for (boost::tie(f, l) = out_edges(u, g); f != l; ++f)
  642. ++n;
  643. return n;
  644. }
  645. // O(1)
  646. template < typename D, typename VP, typename EP, typename GP, typename A,
  647. typename Dir, typename Vertex >
  648. typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor source(
  649. const detail::matrix_edge_desc_impl< Dir, Vertex >& e,
  650. const adjacency_matrix< D, VP, EP, GP, A >&)
  651. {
  652. return e.m_source;
  653. }
  654. // O(1)
  655. template < typename D, typename VP, typename EP, typename GP, typename A,
  656. typename Dir, typename Vertex >
  657. typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor target(
  658. const detail::matrix_edge_desc_impl< Dir, Vertex >& e,
  659. const adjacency_matrix< D, VP, EP, GP, A >&)
  660. {
  661. return e.m_target;
  662. }
  663. //=========================================================================
  664. // Functions required by the BidirectionalGraph concept
  665. // O(1)
  666. template < typename VP, typename EP, typename GP, typename A >
  667. std::pair<
  668. typename adjacency_matrix< directedS, VP, EP, GP, A >::in_edge_iterator,
  669. typename adjacency_matrix< directedS, VP, EP, GP, A >::in_edge_iterator >
  670. in_edges(
  671. typename adjacency_matrix< directedS, VP, EP, GP, A >::vertex_descriptor u,
  672. const adjacency_matrix< directedS, VP, EP, GP, A >& g_)
  673. {
  674. typedef adjacency_matrix< directedS, VP, EP, GP, A > Graph;
  675. Graph& g = const_cast< Graph& >(g_);
  676. typename Graph::MatrixIter f = g.m_matrix.begin() + u;
  677. typename Graph::MatrixIter l = g.m_matrix.end();
  678. typename Graph::unfiltered_in_edge_iter first(
  679. f, l, u, g.m_vertex_set.size()),
  680. last(l, l, u, g.m_vertex_set.size());
  681. detail::does_edge_exist pred;
  682. typedef typename Graph::in_edge_iterator in_edge_iterator;
  683. return std::make_pair(in_edge_iterator(pred, first, last),
  684. in_edge_iterator(pred, last, last));
  685. }
  686. // O(1)
  687. template < typename VP, typename EP, typename GP, typename A >
  688. std::pair<
  689. typename adjacency_matrix< undirectedS, VP, EP, GP, A >::in_edge_iterator,
  690. typename adjacency_matrix< undirectedS, VP, EP, GP, A >::in_edge_iterator >
  691. in_edges(
  692. typename adjacency_matrix< undirectedS, VP, EP, GP, A >::vertex_descriptor
  693. u,
  694. const adjacency_matrix< undirectedS, VP, EP, GP, A >& g_)
  695. {
  696. typedef adjacency_matrix< undirectedS, VP, EP, GP, A > Graph;
  697. Graph& g = const_cast< Graph& >(g_);
  698. typename Graph::vertices_size_type offset = u * (u + 1) / 2;
  699. typename Graph::MatrixIter f = g.m_matrix.begin() + offset;
  700. typename Graph::MatrixIter l = g.m_matrix.end();
  701. typename Graph::unfiltered_in_edge_iter first(f, u, g.m_vertex_set.size()),
  702. last(l, u, g.m_vertex_set.size());
  703. detail::does_edge_exist pred;
  704. typedef typename Graph::in_edge_iterator in_edge_iterator;
  705. return std::make_pair(in_edge_iterator(pred, first, last),
  706. in_edge_iterator(pred, last, last));
  707. }
  708. // O(N)
  709. template < typename D, typename VP, typename EP, typename GP, typename A >
  710. typename adjacency_matrix< D, VP, EP, GP, A >::degree_size_type in_degree(
  711. typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u,
  712. const adjacency_matrix< D, VP, EP, GP, A >& g)
  713. {
  714. typename adjacency_matrix< D, VP, EP, GP, A >::degree_size_type n = 0;
  715. typename adjacency_matrix< D, VP, EP, GP, A >::in_edge_iterator f, l;
  716. for (boost::tie(f, l) = in_edges(u, g); f != l; ++f)
  717. ++n;
  718. return n;
  719. }
  720. //=========================================================================
  721. // Functions required by the AdjacencyGraph concept
  722. template < typename D, typename VP, typename EP, typename GP, typename A >
  723. std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::adjacency_iterator,
  724. typename adjacency_matrix< D, VP, EP, GP, A >::adjacency_iterator >
  725. adjacent_vertices(
  726. typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u,
  727. const adjacency_matrix< D, VP, EP, GP, A >& g_)
  728. {
  729. typedef adjacency_matrix< D, VP, EP, GP, A > Graph;
  730. const Graph& cg = static_cast< const Graph& >(g_);
  731. Graph& g = const_cast< Graph& >(cg);
  732. typedef typename Graph::adjacency_iterator adjacency_iterator;
  733. typename Graph::out_edge_iterator first, last;
  734. boost::tie(first, last) = out_edges(u, g);
  735. return std::make_pair(
  736. adjacency_iterator(first, &g), adjacency_iterator(last, &g));
  737. }
  738. //=========================================================================
  739. // Functions required by the VertexListGraph concept
  740. template < typename D, typename VP, typename EP, typename GP, typename A >
  741. std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::vertex_iterator,
  742. typename adjacency_matrix< D, VP, EP, GP, A >::vertex_iterator >
  743. vertices(const adjacency_matrix< D, VP, EP, GP, A >& g_)
  744. {
  745. typedef adjacency_matrix< D, VP, EP, GP, A > Graph;
  746. Graph& g = const_cast< Graph& >(g_);
  747. return std::make_pair(g.m_vertex_set.begin(), g.m_vertex_set.end());
  748. }
  749. template < typename D, typename VP, typename EP, typename GP, typename A >
  750. typename adjacency_matrix< D, VP, EP, GP, A >::vertices_size_type num_vertices(
  751. const adjacency_matrix< D, VP, EP, GP, A >& g)
  752. {
  753. return g.m_vertex_set.size();
  754. }
  755. //=========================================================================
  756. // Functions required by the EdgeListGraph concept
  757. template < typename D, typename VP, typename EP, typename GP, typename A >
  758. std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::edge_iterator,
  759. typename adjacency_matrix< D, VP, EP, GP, A >::edge_iterator >
  760. edges(const adjacency_matrix< D, VP, EP, GP, A >& g_)
  761. {
  762. typedef adjacency_matrix< D, VP, EP, GP, A > Graph;
  763. Graph& g = const_cast< Graph& >(g_);
  764. typename Graph::unfiltered_edge_iter first(
  765. g.m_matrix.begin(), g.m_matrix.begin(), g.m_vertex_set.size()),
  766. last(g.m_matrix.end(), g.m_matrix.begin(), g.m_vertex_set.size());
  767. detail::does_edge_exist pred;
  768. typedef typename Graph::edge_iterator edge_iterator;
  769. return std::make_pair(
  770. edge_iterator(pred, first, last), edge_iterator(pred, last, last));
  771. }
  772. // O(1)
  773. template < typename D, typename VP, typename EP, typename GP, typename A >
  774. typename adjacency_matrix< D, VP, EP, GP, A >::edges_size_type num_edges(
  775. const adjacency_matrix< D, VP, EP, GP, A >& g)
  776. {
  777. return g.m_num_edges;
  778. }
  779. //=========================================================================
  780. // Functions required by the MutableGraph concept
  781. // O(1)
  782. template < typename D, typename VP, typename EP, typename GP, typename A,
  783. typename EP2 >
  784. std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor,
  785. bool >
  786. add_edge(typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u,
  787. typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v,
  788. const EP2& ep, adjacency_matrix< D, VP, EP, GP, A >& g)
  789. {
  790. typedef typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor
  791. edge_descriptor;
  792. if (detail::get_edge_exists(g.get_edge(u, v), 0) == false)
  793. {
  794. ++(g.m_num_edges);
  795. detail::set_edge_property(g.get_edge(u, v), EP(ep), 0);
  796. detail::set_edge_exists(g.get_edge(u, v), true, 0);
  797. return std::make_pair(edge_descriptor(true, u, v,
  798. &detail::get_edge_property(g.get_edge(u, v))),
  799. true);
  800. }
  801. else
  802. return std::make_pair(edge_descriptor(true, u, v,
  803. &detail::get_edge_property(g.get_edge(u, v))),
  804. false);
  805. }
  806. // O(1)
  807. template < typename D, typename VP, typename EP, typename GP, typename A >
  808. std::pair< typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor,
  809. bool >
  810. add_edge(typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u,
  811. typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v,
  812. adjacency_matrix< D, VP, EP, GP, A >& g)
  813. {
  814. EP ep;
  815. return add_edge(u, v, ep, g);
  816. }
  817. // O(1)
  818. template < typename D, typename VP, typename EP, typename GP, typename A >
  819. void remove_edge(
  820. typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor u,
  821. typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v,
  822. adjacency_matrix< D, VP, EP, GP, A >& g)
  823. {
  824. // Don'remove the edge unless it already exists.
  825. if (detail::get_edge_exists(g.get_edge(u, v), 0))
  826. {
  827. --(g.m_num_edges);
  828. detail::set_edge_exists(g.get_edge(u, v), false, 0);
  829. }
  830. }
  831. // O(1)
  832. template < typename D, typename VP, typename EP, typename GP, typename A >
  833. void remove_edge(
  834. typename adjacency_matrix< D, VP, EP, GP, A >::edge_descriptor e,
  835. adjacency_matrix< D, VP, EP, GP, A >& g)
  836. {
  837. remove_edge(source(e, g), target(e, g), g);
  838. }
  839. template < typename D, typename VP, typename EP, typename GP, typename A >
  840. inline typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor
  841. add_vertex(adjacency_matrix< D, VP, EP, GP, A >& g)
  842. {
  843. // UNDER CONSTRUCTION
  844. BOOST_ASSERT(false);
  845. return *vertices(g).first;
  846. }
  847. template < typename D, typename VP, typename EP, typename GP, typename A,
  848. typename VP2 >
  849. inline typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor
  850. add_vertex(const VP2& /*vp*/, adjacency_matrix< D, VP, EP, GP, A >& g)
  851. {
  852. // UNDER CONSTRUCTION
  853. BOOST_ASSERT(false);
  854. return *vertices(g).first;
  855. }
  856. template < typename D, typename VP, typename EP, typename GP, typename A >
  857. inline void remove_vertex(
  858. typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor /*u*/,
  859. adjacency_matrix< D, VP, EP, GP, A >& /*g*/)
  860. {
  861. // UNDER CONSTRUCTION
  862. BOOST_ASSERT(false);
  863. }
  864. // O(V)
  865. template < typename VP, typename EP, typename GP, typename A >
  866. void clear_vertex(
  867. typename adjacency_matrix< directedS, VP, EP, GP, A >::vertex_descriptor u,
  868. adjacency_matrix< directedS, VP, EP, GP, A >& g)
  869. {
  870. typename adjacency_matrix< directedS, VP, EP, GP, A >::vertex_iterator vi,
  871. vi_end;
  872. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  873. remove_edge(u, *vi, g);
  874. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  875. remove_edge(*vi, u, g);
  876. }
  877. // O(V)
  878. template < typename VP, typename EP, typename GP, typename A >
  879. void clear_vertex(
  880. typename adjacency_matrix< undirectedS, VP, EP, GP, A >::vertex_descriptor
  881. u,
  882. adjacency_matrix< undirectedS, VP, EP, GP, A >& g)
  883. {
  884. typename adjacency_matrix< undirectedS, VP, EP, GP, A >::vertex_iterator vi,
  885. vi_end;
  886. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  887. remove_edge(u, *vi, g);
  888. }
  889. //=========================================================================
  890. // Functions required by the PropertyGraph concept
  891. template < typename D, typename VP, typename EP, typename GP, typename A,
  892. typename Prop, typename Kind >
  893. struct adj_mat_pm_helper;
  894. template < typename D, typename VP, typename EP, typename GP, typename A,
  895. typename Prop >
  896. struct adj_mat_pm_helper< D, VP, EP, GP, A, Prop, vertex_property_tag >
  897. {
  898. typedef typename graph_traits<
  899. adjacency_matrix< D, VP, EP, GP, A > >::vertex_descriptor arg_type;
  900. typedef typed_identity_property_map< arg_type > vi_map_type;
  901. typedef iterator_property_map< typename std::vector< VP >::iterator,
  902. vi_map_type >
  903. all_map_type;
  904. typedef iterator_property_map< typename std::vector< VP >::const_iterator,
  905. vi_map_type >
  906. all_map_const_type;
  907. typedef transform_value_property_map<
  908. detail::lookup_one_property_f< VP, Prop >, all_map_type >
  909. type;
  910. typedef transform_value_property_map<
  911. detail::lookup_one_property_f< const VP, Prop >, all_map_const_type >
  912. const_type;
  913. typedef typename property_traits< type >::reference single_nonconst_type;
  914. typedef typename property_traits< const_type >::reference single_const_type;
  915. static type get_nonconst(adjacency_matrix< D, VP, EP, GP, A >& g, Prop prop)
  916. {
  917. return type(
  918. prop, all_map_type(g.m_vertex_properties.begin(), vi_map_type()));
  919. }
  920. static const_type get_const(
  921. const adjacency_matrix< D, VP, EP, GP, A >& g, Prop prop)
  922. {
  923. return const_type(prop,
  924. all_map_const_type(g.m_vertex_properties.begin(), vi_map_type()));
  925. }
  926. static single_nonconst_type get_nonconst_one(
  927. adjacency_matrix< D, VP, EP, GP, A >& g, Prop prop, arg_type v)
  928. {
  929. return lookup_one_property< VP, Prop >::lookup(
  930. g.m_vertex_properties[v], prop);
  931. }
  932. static single_const_type get_const_one(
  933. const adjacency_matrix< D, VP, EP, GP, A >& g, Prop prop, arg_type v)
  934. {
  935. return lookup_one_property< const VP, Prop >::lookup(
  936. g.m_vertex_properties[v], prop);
  937. }
  938. };
  939. template < typename D, typename VP, typename EP, typename GP, typename A,
  940. typename Tag >
  941. struct adj_mat_pm_helper< D, VP, EP, GP, A, Tag, edge_property_tag >
  942. {
  943. typedef typename graph_traits<
  944. adjacency_matrix< D, VP, EP, GP, A > >::edge_descriptor edge_descriptor;
  945. template < typename IsConst > struct lookup_property_from_edge
  946. {
  947. Tag tag;
  948. lookup_property_from_edge(Tag tag) : tag(tag) {}
  949. typedef typename boost::mpl::if_< IsConst, const EP, EP >::type
  950. ep_type_nonref;
  951. typedef ep_type_nonref& ep_type;
  952. typedef typename lookup_one_property< ep_type_nonref, Tag >::type&
  953. result_type;
  954. result_type operator()(edge_descriptor e) const
  955. {
  956. return lookup_one_property< ep_type_nonref, Tag >::lookup(
  957. *static_cast< ep_type_nonref* >(e.get_property()), tag);
  958. }
  959. };
  960. typedef function_property_map<
  961. lookup_property_from_edge< boost::mpl::false_ >,
  962. typename graph_traits<
  963. adjacency_matrix< D, VP, EP, GP, A > >::edge_descriptor >
  964. type;
  965. typedef function_property_map<
  966. lookup_property_from_edge< boost::mpl::true_ >,
  967. typename graph_traits<
  968. adjacency_matrix< D, VP, EP, GP, A > >::edge_descriptor >
  969. const_type;
  970. typedef edge_descriptor arg_type;
  971. typedef
  972. typename lookup_property_from_edge< boost::mpl::false_ >::result_type
  973. single_nonconst_type;
  974. typedef typename lookup_property_from_edge< boost::mpl::true_ >::result_type
  975. single_const_type;
  976. static type get_nonconst(adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag)
  977. {
  978. return type(tag);
  979. }
  980. static const_type get_const(
  981. const adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag)
  982. {
  983. return const_type(tag);
  984. }
  985. static single_nonconst_type get_nonconst_one(
  986. adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag, edge_descriptor e)
  987. {
  988. return lookup_one_property< EP, Tag >::lookup(
  989. *static_cast< EP* >(e.get_property()), tag);
  990. }
  991. static single_const_type get_const_one(
  992. const adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag,
  993. edge_descriptor e)
  994. {
  995. return lookup_one_property< const EP, Tag >::lookup(
  996. *static_cast< const EP* >(e.get_property()), tag);
  997. }
  998. };
  999. template < typename D, typename VP, typename EP, typename GP, typename A,
  1000. typename Tag >
  1001. struct property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >
  1002. : adj_mat_pm_helper< D, VP, EP, GP, A, Tag,
  1003. typename detail::property_kind_from_graph<
  1004. adjacency_matrix< D, VP, EP, GP, A >, Tag >::type >
  1005. {
  1006. };
  1007. template < typename D, typename VP, typename EP, typename GP, typename A,
  1008. typename Tag >
  1009. typename property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::type get(
  1010. Tag tag, adjacency_matrix< D, VP, EP, GP, A >& g)
  1011. {
  1012. return property_map< adjacency_matrix< D, VP, EP, GP, A >,
  1013. Tag >::get_nonconst(g, tag);
  1014. }
  1015. template < typename D, typename VP, typename EP, typename GP, typename A,
  1016. typename Tag >
  1017. typename property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::const_type
  1018. get(Tag tag, const adjacency_matrix< D, VP, EP, GP, A >& g)
  1019. {
  1020. return property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::get_const(
  1021. g, tag);
  1022. }
  1023. template < typename D, typename VP, typename EP, typename GP, typename A,
  1024. typename Tag >
  1025. typename property_map< adjacency_matrix< D, VP, EP, GP, A >,
  1026. Tag >::single_nonconst_type
  1027. get(Tag tag, adjacency_matrix< D, VP, EP, GP, A >& g,
  1028. typename property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::arg_type
  1029. a)
  1030. {
  1031. return property_map< adjacency_matrix< D, VP, EP, GP, A >,
  1032. Tag >::get_nonconst_one(g, tag, a);
  1033. }
  1034. template < typename D, typename VP, typename EP, typename GP, typename A,
  1035. typename Tag >
  1036. typename property_map< adjacency_matrix< D, VP, EP, GP, A >,
  1037. Tag >::single_const_type
  1038. get(Tag tag, const adjacency_matrix< D, VP, EP, GP, A >& g,
  1039. typename property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::arg_type
  1040. a)
  1041. {
  1042. return property_map< adjacency_matrix< D, VP, EP, GP, A >,
  1043. Tag >::get_const_one(g, tag, a);
  1044. }
  1045. template < typename D, typename VP, typename EP, typename GP, typename A,
  1046. typename Tag >
  1047. void put(Tag tag, adjacency_matrix< D, VP, EP, GP, A >& g,
  1048. typename property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::arg_type
  1049. a,
  1050. typename property_map< adjacency_matrix< D, VP, EP, GP, A >,
  1051. Tag >::single_const_type val)
  1052. {
  1053. property_map< adjacency_matrix< D, VP, EP, GP, A >, Tag >::get_nonconst_one(
  1054. g, tag, a)
  1055. = val;
  1056. }
  1057. // O(1)
  1058. template < typename D, typename VP, typename EP, typename GP, typename A,
  1059. typename Tag, typename Value >
  1060. inline void set_property(
  1061. adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag, const Value& value)
  1062. {
  1063. get_property_value(g.m_property, tag) = value;
  1064. }
  1065. template < typename D, typename VP, typename EP, typename GP, typename A,
  1066. typename Tag >
  1067. inline
  1068. typename graph_property< adjacency_matrix< D, VP, EP, GP, A >, Tag >::type&
  1069. get_property(adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag)
  1070. {
  1071. return get_property_value(g.m_property, tag);
  1072. }
  1073. template < typename D, typename VP, typename EP, typename GP, typename A,
  1074. typename Tag >
  1075. inline const typename graph_property< adjacency_matrix< D, VP, EP, GP, A >,
  1076. Tag >::type&
  1077. get_property(const adjacency_matrix< D, VP, EP, GP, A >& g, Tag tag)
  1078. {
  1079. return get_property_value(g.m_property, tag);
  1080. }
  1081. //=========================================================================
  1082. // Vertex Property Map
  1083. template < typename D, typename VP, typename EP, typename GP, typename A >
  1084. struct property_map< adjacency_matrix< D, VP, EP, GP, A >, vertex_index_t >
  1085. {
  1086. typedef
  1087. typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor Vertex;
  1088. typedef typed_identity_property_map< Vertex > type;
  1089. typedef type const_type;
  1090. };
  1091. template < typename D, typename VP, typename EP, typename GP, typename A >
  1092. typename property_map< adjacency_matrix< D, VP, EP, GP, A >,
  1093. vertex_index_t >::const_type
  1094. get(vertex_index_t, adjacency_matrix< D, VP, EP, GP, A >&)
  1095. {
  1096. return typename property_map< adjacency_matrix< D, VP, EP, GP, A >,
  1097. vertex_index_t >::const_type();
  1098. }
  1099. template < typename D, typename VP, typename EP, typename GP, typename A >
  1100. typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor get(
  1101. vertex_index_t, adjacency_matrix< D, VP, EP, GP, A >&,
  1102. typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v)
  1103. {
  1104. return v;
  1105. }
  1106. template < typename D, typename VP, typename EP, typename GP, typename A >
  1107. typename property_map< adjacency_matrix< D, VP, EP, GP, A >,
  1108. vertex_index_t >::const_type
  1109. get(vertex_index_t, const adjacency_matrix< D, VP, EP, GP, A >&)
  1110. {
  1111. return typename property_map< adjacency_matrix< D, VP, EP, GP, A >,
  1112. vertex_index_t >::const_type();
  1113. }
  1114. template < typename D, typename VP, typename EP, typename GP, typename A >
  1115. typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor get(
  1116. vertex_index_t, const adjacency_matrix< D, VP, EP, GP, A >&,
  1117. typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor v)
  1118. {
  1119. return v;
  1120. }
  1121. //=========================================================================
  1122. // Other Functions
  1123. template < typename D, typename VP, typename EP, typename GP, typename A >
  1124. typename adjacency_matrix< D, VP, EP, GP, A >::vertex_descriptor vertex(
  1125. typename adjacency_matrix< D, VP, EP, GP, A >::vertices_size_type n,
  1126. const adjacency_matrix< D, VP, EP, GP, A >&)
  1127. {
  1128. return n;
  1129. }
  1130. template < typename D, typename VP, typename EP, typename GP, typename A >
  1131. struct graph_mutability_traits< adjacency_matrix< D, VP, EP, GP, A > >
  1132. {
  1133. typedef mutable_edge_property_graph_tag category;
  1134. };
  1135. } // namespace boost
  1136. #endif // BOOST_ADJACENCY_MATRIX_HPP