adjacency_matrix.hpp 45 KB

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