adjacency_matrix.hpp 44 KB

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