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