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