adjacency_matrix.hpp 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239
  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. 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. BOOST_STATIC_ASSERT(!(is_same<Directed, bidirectionalS>::value));
  398. typedef typename mpl::if_<is_directed,
  399. bidirectional_tag, undirected_tag>::type
  400. directed_category;
  401. typedef disallow_parallel_edge_tag edge_parallel_category;
  402. typedef std::size_t vertex_descriptor;
  403. typedef detail::matrix_edge_desc_impl<directed_category,
  404. vertex_descriptor> edge_descriptor;
  405. };
  406. struct adjacency_matrix_class_tag { };
  407. struct adj_matrix_traversal_tag :
  408. public virtual adjacency_matrix_tag,
  409. public virtual vertex_list_graph_tag,
  410. public virtual incidence_graph_tag,
  411. public virtual adjacency_graph_tag,
  412. public virtual edge_list_graph_tag { };
  413. //=========================================================================
  414. // Adjacency Matrix Class
  415. template <typename Directed = directedS,
  416. typename VertexProperty = no_property,
  417. typename EdgeProperty = no_property,
  418. typename GraphProperty = no_property,
  419. typename Allocator = std::allocator<bool> >
  420. class adjacency_matrix {
  421. typedef adjacency_matrix self;
  422. typedef adjacency_matrix_traits<Directed> Traits;
  423. public:
  424. // The bidirectionalS tag is not allowed with the adjacency_matrix
  425. // graph type. Instead, use directedS, which also provides the
  426. // functionality required for a Bidirectional Graph (in_edges,
  427. // in_degree, etc.).
  428. BOOST_STATIC_ASSERT(!(is_same<Directed, bidirectionalS>::value));
  429. typedef GraphProperty graph_property_type;
  430. typedef typename lookup_one_property<GraphProperty, graph_bundle_t>::type graph_bundled;
  431. typedef VertexProperty vertex_property_type;
  432. typedef typename lookup_one_property<VertexProperty, vertex_bundle_t>::type vertex_bundled;
  433. typedef EdgeProperty edge_property_type;
  434. typedef typename lookup_one_property<EdgeProperty, edge_bundle_t>::type edge_bundled;
  435. public: // should be private
  436. typedef typename mpl::if_<typename has_property<edge_property_type>::type,
  437. std::pair<bool, edge_property_type>, char>::type StoredEdge;
  438. #if defined(BOOST_NO_STD_ALLOCATOR)
  439. typedef std::vector<StoredEdge> Matrix;
  440. #else
  441. #if defined(BOOST_NO_CXX11_ALLOCATOR)
  442. typedef typename Allocator::template rebind<StoredEdge>::other Alloc;
  443. #else
  444. typedef typename std::allocator_traits<Allocator>::template rebind_alloc<StoredEdge> Alloc;
  445. #endif
  446. typedef std::vector<StoredEdge, Alloc> Matrix;
  447. #endif
  448. typedef typename Matrix::iterator MatrixIter;
  449. typedef typename Matrix::size_type size_type;
  450. public:
  451. // Graph concept required types
  452. typedef typename Traits::vertex_descriptor vertex_descriptor;
  453. typedef typename Traits::edge_descriptor edge_descriptor;
  454. typedef typename Traits::directed_category directed_category;
  455. typedef typename Traits::edge_parallel_category edge_parallel_category;
  456. typedef adj_matrix_traversal_tag traversal_category;
  457. static vertex_descriptor null_vertex()
  458. {
  459. return (std::numeric_limits<vertex_descriptor>::max)();
  460. }
  461. //private: if friends worked, these would be private
  462. typedef detail::dir_adj_matrix_out_edge_iter<
  463. vertex_descriptor, MatrixIter, size_type, edge_descriptor
  464. > DirOutEdgeIter;
  465. typedef detail::undir_adj_matrix_out_edge_iter<
  466. vertex_descriptor, MatrixIter, size_type, edge_descriptor
  467. > UnDirOutEdgeIter;
  468. typedef typename mpl::if_<
  469. typename Directed::is_directed_t, DirOutEdgeIter, UnDirOutEdgeIter
  470. >::type unfiltered_out_edge_iter;
  471. typedef detail::dir_adj_matrix_in_edge_iter<
  472. vertex_descriptor, MatrixIter, size_type, edge_descriptor
  473. > DirInEdgeIter;
  474. typedef detail::undir_adj_matrix_in_edge_iter<
  475. vertex_descriptor, MatrixIter, size_type, edge_descriptor
  476. > UnDirInEdgeIter;
  477. typedef typename mpl::if_<
  478. typename Directed::is_directed_t, DirInEdgeIter, UnDirInEdgeIter
  479. >::type unfiltered_in_edge_iter;
  480. typedef detail::adj_matrix_edge_iter<
  481. Directed, MatrixIter, size_type, edge_descriptor
  482. > unfiltered_edge_iter;
  483. public:
  484. // IncidenceGraph concept required types
  485. typedef filter_iterator<detail::does_edge_exist, unfiltered_out_edge_iter>
  486. out_edge_iterator;
  487. typedef size_type degree_size_type;
  488. // BidirectionalGraph required types
  489. typedef filter_iterator<detail::does_edge_exist, unfiltered_in_edge_iter>
  490. in_edge_iterator;
  491. // AdjacencyGraph required types
  492. typedef typename adjacency_iterator_generator<self,
  493. vertex_descriptor, out_edge_iterator>::type adjacency_iterator;
  494. // VertexListGraph required types
  495. typedef size_type vertices_size_type;
  496. typedef integer_range<vertex_descriptor> VertexList;
  497. typedef typename VertexList::iterator vertex_iterator;
  498. // EdgeListGraph required types
  499. typedef size_type edges_size_type;
  500. typedef filter_iterator<
  501. detail::does_edge_exist, unfiltered_edge_iter
  502. > edge_iterator;
  503. // PropertyGraph required types
  504. typedef adjacency_matrix_class_tag graph_tag;
  505. // Constructor required by MutableGraph
  506. adjacency_matrix(vertices_size_type n_vertices,
  507. const GraphProperty& p = GraphProperty())
  508. : m_matrix(Directed::is_directed ?
  509. (n_vertices * n_vertices)
  510. : (n_vertices * (n_vertices + 1) / 2)),
  511. m_vertex_set(0, n_vertices),
  512. m_vertex_properties(n_vertices),
  513. m_num_edges(0),
  514. m_property(p) { }
  515. template <typename EdgeIterator>
  516. adjacency_matrix(EdgeIterator first,
  517. EdgeIterator last,
  518. vertices_size_type n_vertices,
  519. const GraphProperty& p = GraphProperty())
  520. : m_matrix(Directed::is_directed ?
  521. (n_vertices * n_vertices)
  522. : (n_vertices * (n_vertices + 1) / 2)),
  523. m_vertex_set(0, n_vertices),
  524. m_vertex_properties(n_vertices),
  525. m_num_edges(0),
  526. m_property(p)
  527. {
  528. for (; first != last; ++first) {
  529. add_edge(first->first, first->second, *this);
  530. }
  531. }
  532. template <typename EdgeIterator, typename EdgePropertyIterator>
  533. adjacency_matrix(EdgeIterator first,
  534. EdgeIterator last,
  535. EdgePropertyIterator ep_iter,
  536. vertices_size_type n_vertices,
  537. const GraphProperty& p = GraphProperty())
  538. : m_matrix(Directed::is_directed ?
  539. (n_vertices * n_vertices)
  540. : (n_vertices * (n_vertices + 1) / 2)),
  541. m_vertex_set(0, n_vertices),
  542. m_vertex_properties(n_vertices),
  543. m_num_edges(0),
  544. m_property(p)
  545. {
  546. for (; first != last; ++first, ++ep_iter) {
  547. add_edge(first->first, first->second, *ep_iter, *this);
  548. }
  549. }
  550. #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
  551. // Directly access a vertex or edge bundle
  552. vertex_bundled& operator[](vertex_descriptor v)
  553. { return get(vertex_bundle, *this, v); }
  554. const vertex_bundled& operator[](vertex_descriptor v) const
  555. { return get(vertex_bundle, *this, v); }
  556. edge_bundled& operator[](edge_descriptor e)
  557. { return get(edge_bundle, *this, e); }
  558. const edge_bundled& operator[](edge_descriptor e) const
  559. { return get(edge_bundle, *this, e); }
  560. graph_bundled& operator[](graph_bundle_t)
  561. { return get_property(*this); }
  562. const graph_bundled& operator[](graph_bundle_t) const
  563. { return get_property(*this); }
  564. #endif
  565. //private: if friends worked, these would be private
  566. typename Matrix::const_reference
  567. get_edge(vertex_descriptor u, vertex_descriptor v) const {
  568. if (Directed::is_directed)
  569. return m_matrix[u * m_vertex_set.size() + v];
  570. else {
  571. if (v > u)
  572. std::swap(u, v);
  573. return m_matrix[u * (u + 1)/2 + v];
  574. }
  575. }
  576. typename Matrix::reference
  577. get_edge(vertex_descriptor u, vertex_descriptor v) {
  578. if (Directed::is_directed)
  579. return m_matrix[u * m_vertex_set.size() + v];
  580. else {
  581. if (v > u)
  582. std::swap(u, v);
  583. return m_matrix[u * (u + 1)/2 + v];
  584. }
  585. }
  586. Matrix m_matrix;
  587. VertexList m_vertex_set;
  588. std::vector<vertex_property_type> m_vertex_properties;
  589. size_type m_num_edges;
  590. graph_property_type m_property;
  591. };
  592. //=========================================================================
  593. // Functions required by the AdjacencyMatrix concept
  594. template <typename D, typename VP, typename EP, typename GP, typename A>
  595. std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor,
  596. bool>
  597. edge(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
  598. typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor v,
  599. const adjacency_matrix<D,VP,EP,GP,A>& g)
  600. {
  601. bool exists = detail::get_edge_exists(g.get_edge(u,v), 0);
  602. typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor
  603. e(exists, u, v, &detail::get_edge_property(g.get_edge(u,v)));
  604. return std::make_pair(e, exists);
  605. }
  606. //=========================================================================
  607. // Functions required by the IncidenceGraph concept
  608. // O(1)
  609. template <typename VP, typename EP, typename GP, typename A>
  610. std::pair<typename adjacency_matrix<directedS,VP,EP,GP,A>::out_edge_iterator,
  611. typename adjacency_matrix<directedS,VP,EP,GP,A>::out_edge_iterator>
  612. out_edges
  613. (typename adjacency_matrix<directedS,VP,EP,GP,A>::vertex_descriptor u,
  614. const adjacency_matrix<directedS,VP,EP,GP,A>& g_)
  615. {
  616. typedef adjacency_matrix<directedS,VP,EP,GP,A> Graph;
  617. Graph& g = const_cast<Graph&>(g_);
  618. typename Graph::vertices_size_type offset = u * g.m_vertex_set.size();
  619. typename Graph::MatrixIter f = g.m_matrix.begin() + offset;
  620. typename Graph::MatrixIter l = f + g.m_vertex_set.size();
  621. typename Graph::unfiltered_out_edge_iter
  622. first(f, u, g.m_vertex_set.size())
  623. , last(l, u, g.m_vertex_set.size());
  624. detail::does_edge_exist pred;
  625. typedef typename Graph::out_edge_iterator out_edge_iterator;
  626. return std::make_pair(out_edge_iterator(pred, first, last),
  627. out_edge_iterator(pred, last, last));
  628. }
  629. // O(1)
  630. template <typename VP, typename EP, typename GP, typename A>
  631. std::pair<
  632. typename adjacency_matrix<undirectedS,VP,EP,GP,A>::out_edge_iterator,
  633. typename adjacency_matrix<undirectedS,VP,EP,GP,A>::out_edge_iterator>
  634. out_edges
  635. (typename adjacency_matrix<undirectedS,VP,EP,GP,A>::vertex_descriptor u,
  636. const adjacency_matrix<undirectedS,VP,EP,GP,A>& g_)
  637. {
  638. typedef adjacency_matrix<undirectedS,VP,EP,GP,A> Graph;
  639. Graph& g = const_cast<Graph&>(g_);
  640. typename Graph::vertices_size_type offset = u * (u + 1) / 2;
  641. typename Graph::MatrixIter f = g.m_matrix.begin() + offset;
  642. typename Graph::MatrixIter l = g.m_matrix.end();
  643. typename Graph::unfiltered_out_edge_iter
  644. first(f, u, g.m_vertex_set.size())
  645. , last(l, u, g.m_vertex_set.size());
  646. detail::does_edge_exist pred;
  647. typedef typename Graph::out_edge_iterator out_edge_iterator;
  648. return std::make_pair(out_edge_iterator(pred, first, last),
  649. out_edge_iterator(pred, last, last));
  650. }
  651. // O(N)
  652. template <typename D, typename VP, typename EP, typename GP, typename A>
  653. typename adjacency_matrix<D,VP,EP,GP,A>::degree_size_type
  654. out_degree(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
  655. const adjacency_matrix<D,VP,EP,GP,A>& g)
  656. {
  657. typename adjacency_matrix<D,VP,EP,GP,A>::degree_size_type n = 0;
  658. typename adjacency_matrix<D,VP,EP,GP,A>::out_edge_iterator f, l;
  659. for (boost::tie(f, l) = out_edges(u, g); f != l; ++f)
  660. ++n;
  661. return n;
  662. }
  663. // O(1)
  664. template <typename D, typename VP, typename EP, typename GP, typename A,
  665. typename Dir, typename Vertex>
  666. typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor
  667. source(const detail::matrix_edge_desc_impl<Dir,Vertex>& e,
  668. const adjacency_matrix<D,VP,EP,GP,A>&)
  669. {
  670. return e.m_source;
  671. }
  672. // O(1)
  673. template <typename D, typename VP, typename EP, typename GP, typename A,
  674. typename Dir, typename Vertex>
  675. typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor
  676. target(const detail::matrix_edge_desc_impl<Dir,Vertex>& e,
  677. const adjacency_matrix<D,VP,EP,GP,A>&)
  678. {
  679. return e.m_target;
  680. }
  681. //=========================================================================
  682. // Functions required by the BidirectionalGraph concept
  683. // O(1)
  684. template <typename VP, typename EP, typename GP, typename A>
  685. std::pair<typename adjacency_matrix<directedS,VP,EP,GP,A>::in_edge_iterator,
  686. typename adjacency_matrix<directedS,VP,EP,GP,A>::in_edge_iterator>
  687. in_edges
  688. (typename adjacency_matrix<directedS,VP,EP,GP,A>::vertex_descriptor u,
  689. const adjacency_matrix<directedS,VP,EP,GP,A>& g_)
  690. {
  691. typedef adjacency_matrix<directedS,VP,EP,GP,A> Graph;
  692. Graph& g = const_cast<Graph&>(g_);
  693. typename Graph::MatrixIter f = g.m_matrix.begin() + u;
  694. typename Graph::MatrixIter l = g.m_matrix.end();
  695. typename Graph::unfiltered_in_edge_iter
  696. first(f, l, u, g.m_vertex_set.size())
  697. , last(l, l, u, g.m_vertex_set.size());
  698. detail::does_edge_exist pred;
  699. typedef typename Graph::in_edge_iterator in_edge_iterator;
  700. return std::make_pair(in_edge_iterator(pred, first, last),
  701. in_edge_iterator(pred, last, last));
  702. }
  703. // O(1)
  704. template <typename VP, typename EP, typename GP, typename A>
  705. std::pair<
  706. typename adjacency_matrix<undirectedS,VP,EP,GP,A>::in_edge_iterator,
  707. typename adjacency_matrix<undirectedS,VP,EP,GP,A>::in_edge_iterator>
  708. in_edges
  709. (typename adjacency_matrix<undirectedS,VP,EP,GP,A>::vertex_descriptor u,
  710. const adjacency_matrix<undirectedS,VP,EP,GP,A>& g_)
  711. {
  712. typedef adjacency_matrix<undirectedS,VP,EP,GP,A> Graph;
  713. Graph& g = const_cast<Graph&>(g_);
  714. typename Graph::vertices_size_type offset = u * (u + 1) / 2;
  715. typename Graph::MatrixIter f = g.m_matrix.begin() + offset;
  716. typename Graph::MatrixIter l = g.m_matrix.end();
  717. typename Graph::unfiltered_in_edge_iter
  718. first(f, u, g.m_vertex_set.size())
  719. , last(l, u, g.m_vertex_set.size());
  720. detail::does_edge_exist pred;
  721. typedef typename Graph::in_edge_iterator in_edge_iterator;
  722. return std::make_pair(in_edge_iterator(pred, first, last),
  723. in_edge_iterator(pred, last, last));
  724. }
  725. // O(N)
  726. template <typename D, typename VP, typename EP, typename GP, typename A>
  727. typename adjacency_matrix<D,VP,EP,GP,A>::degree_size_type
  728. in_degree(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
  729. const adjacency_matrix<D,VP,EP,GP,A>& g)
  730. {
  731. typename adjacency_matrix<D,VP,EP,GP,A>::degree_size_type n = 0;
  732. typename adjacency_matrix<D,VP,EP,GP,A>::in_edge_iterator f, l;
  733. for (boost::tie(f, l) = in_edges(u, g); f != l; ++f)
  734. ++n;
  735. return n;
  736. }
  737. //=========================================================================
  738. // Functions required by the AdjacencyGraph concept
  739. template <typename D, typename VP, typename EP, typename GP, typename A>
  740. std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::adjacency_iterator,
  741. typename adjacency_matrix<D,VP,EP,GP,A>::adjacency_iterator>
  742. adjacent_vertices
  743. (typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
  744. const adjacency_matrix<D,VP,EP,GP,A>& g_)
  745. {
  746. typedef adjacency_matrix<D,VP,EP,GP,A> Graph;
  747. const Graph& cg = static_cast<const Graph&>(g_);
  748. Graph& g = const_cast<Graph&>(cg);
  749. typedef typename Graph::adjacency_iterator adjacency_iterator;
  750. typename Graph::out_edge_iterator first, last;
  751. boost::tie(first, last) = out_edges(u, g);
  752. return std::make_pair(adjacency_iterator(first, &g),
  753. adjacency_iterator(last, &g));
  754. }
  755. //=========================================================================
  756. // Functions required by the VertexListGraph concept
  757. template <typename D, typename VP, typename EP, typename GP, typename A>
  758. std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::vertex_iterator,
  759. typename adjacency_matrix<D,VP,EP,GP,A>::vertex_iterator>
  760. vertices(const adjacency_matrix<D,VP,EP,GP,A>& g_) {
  761. typedef adjacency_matrix<D,VP,EP,GP,A> Graph;
  762. Graph& g = const_cast<Graph&>(g_);
  763. return std::make_pair(g.m_vertex_set.begin(), g.m_vertex_set.end());
  764. }
  765. template <typename D, typename VP, typename EP, typename GP, typename A>
  766. typename adjacency_matrix<D,VP,EP,GP,A>::vertices_size_type
  767. num_vertices(const adjacency_matrix<D,VP,EP,GP,A>& g) {
  768. return g.m_vertex_set.size();
  769. }
  770. //=========================================================================
  771. // Functions required by the EdgeListGraph concept
  772. template <typename D, typename VP, typename EP, typename GP, typename A>
  773. std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::edge_iterator,
  774. typename adjacency_matrix<D,VP,EP,GP,A>::edge_iterator>
  775. edges(const adjacency_matrix<D,VP,EP,GP,A>& g_)
  776. {
  777. typedef adjacency_matrix<D,VP,EP,GP,A> Graph;
  778. Graph& g = const_cast<Graph&>(g_);
  779. typename Graph::unfiltered_edge_iter
  780. first(g.m_matrix.begin(), g.m_matrix.begin(),
  781. g.m_vertex_set.size()),
  782. last(g.m_matrix.end(), g.m_matrix.begin(),
  783. g.m_vertex_set.size());
  784. detail::does_edge_exist pred;
  785. typedef typename Graph::edge_iterator edge_iterator;
  786. return std::make_pair(edge_iterator(pred, first, last),
  787. edge_iterator(pred, last, last));
  788. }
  789. // O(1)
  790. template <typename D, typename VP, typename EP, typename GP, typename A>
  791. typename adjacency_matrix<D,VP,EP,GP,A>::edges_size_type
  792. num_edges(const adjacency_matrix<D,VP,EP,GP,A>& g)
  793. {
  794. return g.m_num_edges;
  795. }
  796. //=========================================================================
  797. // Functions required by the MutableGraph concept
  798. // O(1)
  799. template <typename D, typename VP, typename EP, typename GP, typename A,
  800. typename EP2>
  801. std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor, bool>
  802. add_edge(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
  803. typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor v,
  804. const EP2& ep,
  805. adjacency_matrix<D,VP,EP,GP,A>& g)
  806. {
  807. typedef typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor
  808. edge_descriptor;
  809. if (detail::get_edge_exists(g.get_edge(u,v), 0) == false) {
  810. ++(g.m_num_edges);
  811. detail::set_edge_property(g.get_edge(u,v), EP(ep), 0);
  812. detail::set_edge_exists(g.get_edge(u,v), true, 0);
  813. return std::make_pair
  814. (edge_descriptor(true, u, v, &detail::get_edge_property(g.get_edge(u,v))),
  815. true);
  816. } else
  817. return std::make_pair
  818. (edge_descriptor(true, u, v, &detail::get_edge_property(g.get_edge(u,v))),
  819. false);
  820. }
  821. // O(1)
  822. template <typename D, typename VP, typename EP, typename GP, typename A>
  823. std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor, bool>
  824. add_edge(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
  825. typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor v,
  826. adjacency_matrix<D,VP,EP,GP,A>& g)
  827. {
  828. EP ep;
  829. return add_edge(u, v, ep, g);
  830. }
  831. // O(1)
  832. template <typename D, typename VP, typename EP, typename GP, typename A>
  833. void
  834. remove_edge(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u,
  835. typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor v,
  836. adjacency_matrix<D,VP,EP,GP,A>& g)
  837. {
  838. // Don'remove the edge unless it already exists.
  839. if(detail::get_edge_exists(g.get_edge(u,v), 0)) {
  840. --(g.m_num_edges);
  841. detail::set_edge_exists(g.get_edge(u,v), false, 0);
  842. }
  843. }
  844. // O(1)
  845. template <typename D, typename VP, typename EP, typename GP, typename A>
  846. void
  847. remove_edge(typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor e,
  848. adjacency_matrix<D,VP,EP,GP,A>& g)
  849. {
  850. remove_edge(source(e, g), target(e, g), g);
  851. }
  852. template <typename D, typename VP, typename EP, typename GP, typename A>
  853. inline typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor
  854. add_vertex(adjacency_matrix<D,VP,EP,GP,A>& g) {
  855. // UNDER CONSTRUCTION
  856. BOOST_ASSERT(false);
  857. return *vertices(g).first;
  858. }
  859. template <typename D, typename VP, typename EP, typename GP, typename A,
  860. typename VP2>
  861. inline typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor
  862. add_vertex(const VP2& /*vp*/, adjacency_matrix<D,VP,EP,GP,A>& g) {
  863. // UNDER CONSTRUCTION
  864. BOOST_ASSERT(false);
  865. return *vertices(g).first;
  866. }
  867. template <typename D, typename VP, typename EP, typename GP, typename A>
  868. inline void
  869. remove_vertex(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor /*u*/,
  870. adjacency_matrix<D,VP,EP,GP,A>& /*g*/)
  871. {
  872. // UNDER CONSTRUCTION
  873. BOOST_ASSERT(false);
  874. }
  875. // O(V)
  876. template <typename VP, typename EP, typename GP, typename A>
  877. void
  878. clear_vertex
  879. (typename adjacency_matrix<directedS,VP,EP,GP,A>::vertex_descriptor u,
  880. adjacency_matrix<directedS,VP,EP,GP,A>& g)
  881. {
  882. typename adjacency_matrix<directedS,VP,EP,GP,A>::vertex_iterator
  883. vi, vi_end;
  884. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  885. remove_edge(u, *vi, g);
  886. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  887. remove_edge(*vi, u, g);
  888. }
  889. // O(V)
  890. template <typename VP, typename EP, typename GP, typename A>
  891. void
  892. clear_vertex
  893. (typename adjacency_matrix<undirectedS,VP,EP,GP,A>::vertex_descriptor u,
  894. adjacency_matrix<undirectedS,VP,EP,GP,A>& g)
  895. {
  896. typename adjacency_matrix<undirectedS,VP,EP,GP,A>::vertex_iterator
  897. vi, vi_end;
  898. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  899. remove_edge(u, *vi, g);
  900. }
  901. //=========================================================================
  902. // Functions required by the PropertyGraph concept
  903. template <typename D, typename VP, typename EP, typename GP, typename A,
  904. typename Prop, typename Kind>
  905. struct adj_mat_pm_helper;
  906. template <typename D, typename VP, typename EP, typename GP, typename A,
  907. typename Prop>
  908. struct adj_mat_pm_helper<D, VP, EP, GP, A, Prop, vertex_property_tag> {
  909. typedef typename graph_traits<adjacency_matrix<D, VP, EP, GP, A> >::vertex_descriptor arg_type;
  910. typedef typed_identity_property_map<arg_type> vi_map_type;
  911. typedef iterator_property_map<typename std::vector<VP>::iterator, vi_map_type> all_map_type;
  912. typedef iterator_property_map<typename std::vector<VP>::const_iterator, vi_map_type> all_map_const_type;
  913. typedef transform_value_property_map<
  914. detail::lookup_one_property_f<VP, Prop>,
  915. all_map_type>
  916. type;
  917. typedef transform_value_property_map<
  918. detail::lookup_one_property_f<const VP, Prop>,
  919. all_map_const_type>
  920. const_type;
  921. typedef typename property_traits<type>::reference single_nonconst_type;
  922. typedef typename property_traits<const_type>::reference single_const_type;
  923. static type get_nonconst(adjacency_matrix<D, VP, EP, GP, A>& g, Prop prop) {
  924. return type(prop, all_map_type(g.m_vertex_properties.begin(), vi_map_type()));
  925. }
  926. static const_type get_const(const adjacency_matrix<D, VP, EP, GP, A>& g, Prop prop) {
  927. return const_type(prop, all_map_const_type(g.m_vertex_properties.begin(), vi_map_type()));
  928. }
  929. static single_nonconst_type get_nonconst_one(adjacency_matrix<D, VP, EP, GP, A>& g, Prop prop, arg_type v) {
  930. return lookup_one_property<VP, Prop>::lookup(g.m_vertex_properties[v], prop);
  931. }
  932. static single_const_type get_const_one(const adjacency_matrix<D, VP, EP, GP, A>& g, Prop prop, arg_type v) {
  933. return lookup_one_property<const VP, Prop>::lookup(g.m_vertex_properties[v], prop);
  934. }
  935. };
  936. template <typename D, typename VP, typename EP, typename GP, typename A,
  937. typename Tag>
  938. struct adj_mat_pm_helper<D, VP, EP, GP, A, Tag, edge_property_tag> {
  939. typedef typename graph_traits<adjacency_matrix<D, VP, EP, GP, A> >::edge_descriptor edge_descriptor;
  940. template <typename IsConst>
  941. struct lookup_property_from_edge {
  942. Tag tag;
  943. lookup_property_from_edge(Tag tag): tag(tag) {}
  944. typedef typename boost::mpl::if_<IsConst, const EP, EP>::type ep_type_nonref;
  945. typedef ep_type_nonref& ep_type;
  946. typedef typename lookup_one_property<ep_type_nonref, Tag>::type& result_type;
  947. result_type operator()(edge_descriptor e) const {
  948. return lookup_one_property<ep_type_nonref, Tag>::lookup(*static_cast<ep_type_nonref*>(e.get_property()), tag);
  949. }
  950. };
  951. typedef function_property_map<
  952. lookup_property_from_edge<boost::mpl::false_>,
  953. typename graph_traits<adjacency_matrix<D, VP, EP, GP, A> >::edge_descriptor> type;
  954. typedef function_property_map<
  955. lookup_property_from_edge<boost::mpl::true_>,
  956. typename graph_traits<adjacency_matrix<D, VP, EP, GP, A> >::edge_descriptor> const_type;
  957. typedef edge_descriptor arg_type;
  958. typedef typename lookup_property_from_edge<boost::mpl::false_>::result_type single_nonconst_type;
  959. typedef typename lookup_property_from_edge<boost::mpl::true_>::result_type single_const_type;
  960. static type get_nonconst(adjacency_matrix<D, VP, EP, GP, A>& g, Tag tag) {
  961. return type(tag);
  962. }
  963. static const_type get_const(const adjacency_matrix<D, VP, EP, GP, A>& g, Tag tag) {
  964. return const_type(tag);
  965. }
  966. static single_nonconst_type get_nonconst_one(adjacency_matrix<D, VP, EP, GP, A>& g, Tag tag, edge_descriptor e) {
  967. return lookup_one_property<EP, Tag>::lookup(*static_cast<EP*>(e.get_property()), tag);
  968. }
  969. static single_const_type get_const_one(const adjacency_matrix<D, VP, EP, GP, A>& g, Tag tag, edge_descriptor e) {
  970. return lookup_one_property<const EP, Tag>::lookup(*static_cast<const EP*>(e.get_property()), tag);
  971. }
  972. };
  973. template <typename D, typename VP, typename EP, typename GP, typename A,
  974. typename Tag>
  975. struct property_map<adjacency_matrix<D,VP,EP,GP,A>, Tag>
  976. : adj_mat_pm_helper<D, VP, EP, GP, A, Tag,
  977. typename detail::property_kind_from_graph<adjacency_matrix<D, VP, EP, GP, A>, Tag>::type> {};
  978. template <typename D, typename VP, typename EP, typename GP, typename A,
  979. typename Tag>
  980. typename property_map<adjacency_matrix<D, VP, EP, GP, A>, Tag>::type
  981. get(Tag tag, adjacency_matrix<D, VP, EP, GP, A>& g) {
  982. return property_map<adjacency_matrix<D, VP, EP, GP, A>, Tag>::get_nonconst(g, tag);
  983. }
  984. template <typename D, typename VP, typename EP, typename GP, typename A,
  985. typename Tag>
  986. typename property_map<adjacency_matrix<D, VP, EP, GP, A>, Tag>::const_type
  987. get(Tag tag, const adjacency_matrix<D, VP, EP, GP, A>& g) {
  988. return property_map<adjacency_matrix<D, VP, EP, GP, A>, Tag>::get_const(g, tag);
  989. }
  990. template <typename D, typename VP, typename EP, typename GP, typename A,
  991. typename Tag>
  992. typename property_map<adjacency_matrix<D, VP, EP, GP, A>, Tag>::single_nonconst_type
  993. 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) {
  994. return property_map<adjacency_matrix<D, VP, EP, GP, A>, Tag>::get_nonconst_one(g, tag, a);
  995. }
  996. template <typename D, typename VP, typename EP, typename GP, typename A,
  997. typename Tag>
  998. typename property_map<adjacency_matrix<D, VP, EP, GP, A>, Tag>::single_const_type
  999. 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) {
  1000. return property_map<adjacency_matrix<D, VP, EP, GP, A>, Tag>::get_const_one(g, tag, a);
  1001. }
  1002. template <typename D, typename VP, typename EP, typename GP, typename A,
  1003. typename Tag>
  1004. void
  1005. put(Tag tag,
  1006. adjacency_matrix<D, VP, EP, GP, A>& g,
  1007. typename property_map<adjacency_matrix<D, VP, EP, GP, A>, Tag>::arg_type a,
  1008. typename property_map<adjacency_matrix<D, VP, EP, GP, A>, Tag>::single_const_type val) {
  1009. property_map<adjacency_matrix<D, VP, EP, GP, A>, Tag>::get_nonconst_one(g, tag, a) = val;
  1010. }
  1011. // O(1)
  1012. template <typename D, typename VP, typename EP, typename GP, typename A,
  1013. typename Tag, typename Value>
  1014. inline void
  1015. set_property(adjacency_matrix<D,VP,EP,GP,A>& g, Tag tag, const Value& value)
  1016. {
  1017. get_property_value(g.m_property, tag) = value;
  1018. }
  1019. template <typename D, typename VP, typename EP, typename GP, typename A,
  1020. typename Tag>
  1021. inline typename graph_property<adjacency_matrix<D,VP,EP,GP,A>, Tag>::type&
  1022. get_property(adjacency_matrix<D,VP,EP,GP,A>& g, Tag tag)
  1023. {
  1024. return get_property_value(g.m_property, tag);
  1025. }
  1026. template <typename D, typename VP, typename EP, typename GP, typename A,
  1027. typename Tag>
  1028. inline const typename graph_property<adjacency_matrix<D,VP,EP,GP,A>, Tag>::type&
  1029. get_property(const adjacency_matrix<D,VP,EP,GP,A>& g, Tag tag)
  1030. {
  1031. return get_property_value(g.m_property, tag);
  1032. }
  1033. //=========================================================================
  1034. // Vertex Property Map
  1035. template <typename D, typename VP, typename EP, typename GP, typename A>
  1036. struct property_map<adjacency_matrix<D, VP, EP, GP, A>, vertex_index_t> {
  1037. typedef typename adjacency_matrix<D, VP, EP, GP, A>::vertex_descriptor Vertex;
  1038. typedef typed_identity_property_map<Vertex> type;
  1039. typedef type const_type;
  1040. };
  1041. template <typename D, typename VP, typename EP, typename GP, typename A>
  1042. typename property_map<adjacency_matrix<D, VP, EP, GP, A>, vertex_index_t>::const_type
  1043. get(vertex_index_t, adjacency_matrix<D, VP, EP, GP, A>&) {
  1044. return typename property_map<adjacency_matrix<D, VP, EP, GP, A>, vertex_index_t>::const_type();
  1045. }
  1046. template <typename D, typename VP, typename EP, typename GP, typename A>
  1047. typename adjacency_matrix<D, VP, EP, GP, A>::vertex_descriptor
  1048. get(vertex_index_t,
  1049. adjacency_matrix<D, VP, EP, GP, A>&,
  1050. typename adjacency_matrix<D, VP, EP, GP, A>::vertex_descriptor v) {
  1051. return v;
  1052. }
  1053. template <typename D, typename VP, typename EP, typename GP, typename A>
  1054. typename property_map<adjacency_matrix<D, VP, EP, GP, A>, vertex_index_t>::const_type
  1055. get(vertex_index_t, const adjacency_matrix<D, VP, EP, GP, A>&) {
  1056. return typename property_map<adjacency_matrix<D, VP, EP, GP, A>, vertex_index_t>::const_type();
  1057. }
  1058. template <typename D, typename VP, typename EP, typename GP, typename A>
  1059. typename adjacency_matrix<D, VP, EP, GP, A>::vertex_descriptor
  1060. get(vertex_index_t,
  1061. const adjacency_matrix<D, VP, EP, GP, A>&,
  1062. typename adjacency_matrix<D, VP, EP, GP, A>::vertex_descriptor v) {
  1063. return v;
  1064. }
  1065. //=========================================================================
  1066. // Other Functions
  1067. template <typename D, typename VP, typename EP, typename GP, typename A>
  1068. typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor
  1069. vertex(typename adjacency_matrix<D,VP,EP,GP,A>::vertices_size_type n,
  1070. const adjacency_matrix<D,VP,EP,GP,A>&)
  1071. {
  1072. return n;
  1073. }
  1074. template <typename D, typename VP, typename EP, typename GP, typename A>
  1075. struct graph_mutability_traits<adjacency_matrix<D, VP, EP, GP, A> > {
  1076. typedef mutable_edge_property_graph_tag category;
  1077. };
  1078. } // namespace boost
  1079. #endif // BOOST_ADJACENCY_MATRIX_HPP