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