Chris@16
|
1 //=======================================================================
|
Chris@16
|
2 // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
|
Chris@16
|
3 // Copyright 2010 Thomas Claveirole
|
Chris@16
|
4 // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Thomas Claveirole
|
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_GRAPH_ADJACENCY_LIST_HPP
|
Chris@16
|
12 #define BOOST_GRAPH_ADJACENCY_LIST_HPP
|
Chris@16
|
13
|
Chris@16
|
14
|
Chris@16
|
15 #include <boost/config.hpp>
|
Chris@16
|
16
|
Chris@16
|
17 #include <vector>
|
Chris@16
|
18 #include <list>
|
Chris@16
|
19 #include <set>
|
Chris@16
|
20
|
Chris@16
|
21 #include <boost/unordered_set.hpp>
|
Chris@16
|
22
|
Chris@16
|
23 #if !defined BOOST_NO_SLIST
|
Chris@16
|
24 # ifdef BOOST_SLIST_HEADER
|
Chris@16
|
25 # include BOOST_SLIST_HEADER
|
Chris@16
|
26 # else
|
Chris@16
|
27 # include <slist>
|
Chris@16
|
28 # endif
|
Chris@16
|
29 #endif
|
Chris@16
|
30
|
Chris@16
|
31 #include <boost/scoped_ptr.hpp>
|
Chris@16
|
32
|
Chris@16
|
33 #include <boost/graph/graph_traits.hpp>
|
Chris@16
|
34 #include <boost/graph/graph_mutability_traits.hpp>
|
Chris@16
|
35 #include <boost/graph/graph_selectors.hpp>
|
Chris@16
|
36 #include <boost/property_map/property_map.hpp>
|
Chris@16
|
37 #include <boost/mpl/if.hpp>
|
Chris@16
|
38 #include <boost/mpl/and.hpp>
|
Chris@16
|
39 #include <boost/mpl/not.hpp>
|
Chris@16
|
40 #include <boost/mpl/bool.hpp>
|
Chris@16
|
41 #include <boost/graph/detail/edge.hpp>
|
Chris@16
|
42 #include <boost/type_traits/is_same.hpp>
|
Chris@16
|
43 #include <boost/detail/workaround.hpp>
|
Chris@16
|
44 #include <boost/graph/properties.hpp>
|
Chris@16
|
45 #include <boost/graph/named_graph.hpp>
|
Chris@16
|
46
|
Chris@16
|
47 namespace boost {
|
Chris@16
|
48
|
Chris@16
|
49 //===========================================================================
|
Chris@16
|
50 // Selectors for the VertexList and EdgeList template parameters of
|
Chris@16
|
51 // adjacency_list, and the container_gen traits class which is used
|
Chris@16
|
52 // to map the selectors to the container type used to implement the
|
Chris@16
|
53 // graph.
|
Chris@16
|
54
|
Chris@16
|
55 #if !defined BOOST_NO_SLIST
|
Chris@16
|
56 struct slistS {};
|
Chris@16
|
57 #endif
|
Chris@16
|
58
|
Chris@16
|
59 struct vecS { };
|
Chris@16
|
60 struct listS { };
|
Chris@16
|
61 struct setS { };
|
Chris@16
|
62 struct mapS { };
|
Chris@16
|
63 struct multisetS { };
|
Chris@16
|
64 struct multimapS { };
|
Chris@16
|
65 struct hash_setS { };
|
Chris@16
|
66 struct hash_mapS { };
|
Chris@16
|
67 struct hash_multisetS { };
|
Chris@16
|
68 struct hash_multimapS { };
|
Chris@16
|
69
|
Chris@16
|
70 template <class Selector, class ValueType>
|
Chris@16
|
71 struct container_gen { };
|
Chris@16
|
72
|
Chris@16
|
73 template <class ValueType>
|
Chris@16
|
74 struct container_gen<listS, ValueType> {
|
Chris@16
|
75 typedef std::list<ValueType> type;
|
Chris@16
|
76 };
|
Chris@16
|
77 #if !defined BOOST_NO_SLIST
|
Chris@16
|
78 template <class ValueType>
|
Chris@16
|
79 struct container_gen<slistS, ValueType> {
|
Chris@16
|
80 typedef BOOST_STD_EXTENSION_NAMESPACE::slist<ValueType> type;
|
Chris@16
|
81 };
|
Chris@16
|
82 #endif
|
Chris@16
|
83 template <class ValueType>
|
Chris@16
|
84 struct container_gen<vecS, ValueType> {
|
Chris@16
|
85 typedef std::vector<ValueType> type;
|
Chris@16
|
86 };
|
Chris@16
|
87
|
Chris@16
|
88 template <class ValueType>
|
Chris@16
|
89 struct container_gen<mapS, ValueType> {
|
Chris@16
|
90 typedef std::set<ValueType> type;
|
Chris@16
|
91 };
|
Chris@16
|
92
|
Chris@16
|
93 template <class ValueType>
|
Chris@16
|
94 struct container_gen<setS, ValueType> {
|
Chris@16
|
95 typedef std::set<ValueType> type;
|
Chris@16
|
96 };
|
Chris@16
|
97
|
Chris@16
|
98 template <class ValueType>
|
Chris@16
|
99 struct container_gen<multisetS, ValueType> {
|
Chris@16
|
100 typedef std::multiset<ValueType> type;
|
Chris@16
|
101 };
|
Chris@16
|
102
|
Chris@16
|
103 template <class ValueType>
|
Chris@16
|
104 struct container_gen<multimapS, ValueType> {
|
Chris@16
|
105 typedef std::multiset<ValueType> type;
|
Chris@16
|
106 };
|
Chris@16
|
107
|
Chris@16
|
108 template <class ValueType>
|
Chris@16
|
109 struct container_gen<hash_setS, ValueType> {
|
Chris@16
|
110 typedef boost::unordered_set<ValueType> type;
|
Chris@16
|
111 };
|
Chris@16
|
112
|
Chris@16
|
113 template <class ValueType>
|
Chris@16
|
114 struct container_gen<hash_mapS, ValueType> {
|
Chris@16
|
115 typedef boost::unordered_set<ValueType> type;
|
Chris@16
|
116 };
|
Chris@16
|
117
|
Chris@16
|
118 template <class ValueType>
|
Chris@16
|
119 struct container_gen<hash_multisetS, ValueType> {
|
Chris@16
|
120 typedef boost::unordered_multiset<ValueType> type;
|
Chris@16
|
121 };
|
Chris@16
|
122
|
Chris@16
|
123 template <class ValueType>
|
Chris@16
|
124 struct container_gen<hash_multimapS, ValueType> {
|
Chris@16
|
125 typedef boost::unordered_multiset<ValueType> type;
|
Chris@16
|
126 };
|
Chris@16
|
127
|
Chris@16
|
128 template <class StorageSelector>
|
Chris@16
|
129 struct parallel_edge_traits { };
|
Chris@16
|
130
|
Chris@16
|
131 template <>
|
Chris@16
|
132 struct parallel_edge_traits<vecS> {
|
Chris@16
|
133 typedef allow_parallel_edge_tag type; };
|
Chris@16
|
134
|
Chris@16
|
135 template <>
|
Chris@16
|
136 struct parallel_edge_traits<listS> {
|
Chris@16
|
137 typedef allow_parallel_edge_tag type; };
|
Chris@16
|
138
|
Chris@16
|
139 #if !defined BOOST_NO_SLIST
|
Chris@16
|
140 template <>
|
Chris@16
|
141 struct parallel_edge_traits<slistS> {
|
Chris@16
|
142 typedef allow_parallel_edge_tag type; };
|
Chris@16
|
143 #endif
|
Chris@16
|
144
|
Chris@16
|
145 template <>
|
Chris@16
|
146 struct parallel_edge_traits<setS> {
|
Chris@16
|
147 typedef disallow_parallel_edge_tag type; };
|
Chris@16
|
148
|
Chris@16
|
149 template <>
|
Chris@16
|
150 struct parallel_edge_traits<multisetS> {
|
Chris@16
|
151 typedef allow_parallel_edge_tag type; };
|
Chris@16
|
152
|
Chris@16
|
153 template <>
|
Chris@16
|
154 struct parallel_edge_traits<hash_setS> {
|
Chris@16
|
155 typedef disallow_parallel_edge_tag type;
|
Chris@16
|
156 };
|
Chris@16
|
157
|
Chris@16
|
158 // mapS is obsolete, replaced with setS
|
Chris@16
|
159 template <>
|
Chris@16
|
160 struct parallel_edge_traits<mapS> {
|
Chris@16
|
161 typedef disallow_parallel_edge_tag type; };
|
Chris@16
|
162
|
Chris@16
|
163 template <>
|
Chris@16
|
164 struct parallel_edge_traits<hash_mapS> {
|
Chris@16
|
165 typedef disallow_parallel_edge_tag type;
|
Chris@16
|
166 };
|
Chris@16
|
167
|
Chris@16
|
168 template <>
|
Chris@16
|
169 struct parallel_edge_traits<hash_multisetS> {
|
Chris@16
|
170 typedef allow_parallel_edge_tag type;
|
Chris@16
|
171 };
|
Chris@16
|
172
|
Chris@16
|
173 template <>
|
Chris@16
|
174 struct parallel_edge_traits<hash_multimapS> {
|
Chris@16
|
175 typedef allow_parallel_edge_tag type;
|
Chris@16
|
176 };
|
Chris@16
|
177
|
Chris@16
|
178 namespace detail {
|
Chris@16
|
179 template <class Directed> struct is_random_access {
|
Chris@16
|
180 enum { value = false};
|
Chris@16
|
181 typedef mpl::false_ type;
|
Chris@16
|
182 };
|
Chris@16
|
183 template <>
|
Chris@16
|
184 struct is_random_access<vecS> {
|
Chris@16
|
185 enum { value = true };
|
Chris@16
|
186 typedef mpl::true_ type;
|
Chris@16
|
187 };
|
Chris@16
|
188
|
Chris@16
|
189 } // namespace detail
|
Chris@16
|
190
|
Chris@16
|
191 template <typename Selector> struct is_distributed_selector: mpl::false_ {};
|
Chris@16
|
192
|
Chris@16
|
193
|
Chris@16
|
194 //===========================================================================
|
Chris@16
|
195 // The adjacency_list_traits class, which provides a way to access
|
Chris@16
|
196 // some of the associated types of an adjacency_list type without
|
Chris@16
|
197 // having to first create the adjacency_list type. This is useful
|
Chris@16
|
198 // when trying to create interior vertex or edge properties who's
|
Chris@16
|
199 // value type is a vertex or edge descriptor.
|
Chris@16
|
200
|
Chris@16
|
201 template <class OutEdgeListS = vecS,
|
Chris@16
|
202 class VertexListS = vecS,
|
Chris@16
|
203 class DirectedS = directedS,
|
Chris@16
|
204 class EdgeListS = listS>
|
Chris@16
|
205 struct adjacency_list_traits
|
Chris@16
|
206 {
|
Chris@16
|
207 typedef typename detail::is_random_access<VertexListS>::type
|
Chris@16
|
208 is_rand_access;
|
Chris@16
|
209 typedef typename DirectedS::is_bidir_t is_bidir;
|
Chris@16
|
210 typedef typename DirectedS::is_directed_t is_directed;
|
Chris@16
|
211
|
Chris@16
|
212 typedef typename mpl::if_<is_bidir,
|
Chris@16
|
213 bidirectional_tag,
|
Chris@16
|
214 typename mpl::if_<is_directed,
|
Chris@16
|
215 directed_tag, undirected_tag
|
Chris@16
|
216 >::type
|
Chris@16
|
217 >::type directed_category;
|
Chris@16
|
218
|
Chris@16
|
219 typedef typename parallel_edge_traits<OutEdgeListS>::type
|
Chris@16
|
220 edge_parallel_category;
|
Chris@16
|
221
|
Chris@16
|
222 typedef std::size_t vertices_size_type;
|
Chris@16
|
223 typedef void* vertex_ptr;
|
Chris@16
|
224 typedef typename mpl::if_<is_rand_access,
|
Chris@16
|
225 vertices_size_type, vertex_ptr>::type vertex_descriptor;
|
Chris@16
|
226 typedef detail::edge_desc_impl<directed_category, vertex_descriptor>
|
Chris@16
|
227 edge_descriptor;
|
Chris@16
|
228
|
Chris@16
|
229 private:
|
Chris@16
|
230 // Logic to figure out the edges_size_type
|
Chris@16
|
231 struct dummy {};
|
Chris@16
|
232 typedef typename container_gen<EdgeListS, dummy>::type EdgeContainer;
|
Chris@16
|
233 typedef typename DirectedS::is_bidir_t BidirectionalT;
|
Chris@16
|
234 typedef typename DirectedS::is_directed_t DirectedT;
|
Chris@16
|
235 typedef typename mpl::and_<DirectedT,
|
Chris@16
|
236 typename mpl::not_<BidirectionalT>::type >::type on_edge_storage;
|
Chris@16
|
237 public:
|
Chris@16
|
238 typedef typename mpl::if_<on_edge_storage,
|
Chris@16
|
239 std::size_t, typename EdgeContainer::size_type
|
Chris@16
|
240 >::type edges_size_type;
|
Chris@16
|
241
|
Chris@16
|
242 };
|
Chris@16
|
243
|
Chris@16
|
244 } // namespace boost
|
Chris@16
|
245
|
Chris@16
|
246 #include <boost/graph/detail/adjacency_list.hpp>
|
Chris@16
|
247
|
Chris@16
|
248 namespace boost {
|
Chris@16
|
249
|
Chris@16
|
250 //===========================================================================
|
Chris@16
|
251 // The adjacency_list class.
|
Chris@16
|
252 //
|
Chris@16
|
253
|
Chris@16
|
254 template <class OutEdgeListS = vecS, // a Sequence or an AssociativeContainer
|
Chris@16
|
255 class VertexListS = vecS, // a Sequence or a RandomAccessContainer
|
Chris@16
|
256 class DirectedS = directedS,
|
Chris@16
|
257 class VertexProperty = no_property,
|
Chris@16
|
258 class EdgeProperty = no_property,
|
Chris@16
|
259 class GraphProperty = no_property,
|
Chris@16
|
260 class EdgeListS = listS>
|
Chris@16
|
261 class adjacency_list
|
Chris@16
|
262 : public detail::adj_list_gen<
|
Chris@16
|
263 adjacency_list<OutEdgeListS,VertexListS,DirectedS,
|
Chris@16
|
264 VertexProperty,EdgeProperty,GraphProperty,EdgeListS>,
|
Chris@16
|
265 VertexListS, OutEdgeListS, DirectedS,
|
Chris@16
|
266 VertexProperty, EdgeProperty,
|
Chris@16
|
267 GraphProperty, EdgeListS>::type,
|
Chris@16
|
268 // Support for named vertices
|
Chris@16
|
269 public graph::maybe_named_graph<
|
Chris@16
|
270 adjacency_list<OutEdgeListS,VertexListS,DirectedS,
|
Chris@16
|
271 VertexProperty,EdgeProperty,GraphProperty,EdgeListS>,
|
Chris@16
|
272 typename adjacency_list_traits<OutEdgeListS, VertexListS, DirectedS,
|
Chris@16
|
273 EdgeListS>::vertex_descriptor,
|
Chris@16
|
274 VertexProperty>
|
Chris@16
|
275 {
|
Chris@16
|
276 public:
|
Chris@16
|
277 typedef GraphProperty graph_property_type;
|
Chris@16
|
278 typedef typename lookup_one_property<GraphProperty, graph_bundle_t>::type graph_bundled;
|
Chris@16
|
279
|
Chris@16
|
280 typedef VertexProperty vertex_property_type;
|
Chris@16
|
281 typedef typename lookup_one_property<VertexProperty, vertex_bundle_t>::type vertex_bundled;
|
Chris@16
|
282
|
Chris@16
|
283 typedef EdgeProperty edge_property_type;
|
Chris@16
|
284 typedef typename lookup_one_property<EdgeProperty, edge_bundle_t>::type edge_bundled;
|
Chris@16
|
285
|
Chris@16
|
286 private:
|
Chris@16
|
287 typedef adjacency_list self;
|
Chris@16
|
288 typedef typename detail::adj_list_gen<
|
Chris@16
|
289 self, VertexListS, OutEdgeListS, DirectedS,
|
Chris@16
|
290 vertex_property_type, edge_property_type, GraphProperty, EdgeListS
|
Chris@16
|
291 >::type Base;
|
Chris@16
|
292
|
Chris@16
|
293 public:
|
Chris@16
|
294 typedef typename Base::stored_vertex stored_vertex;
|
Chris@16
|
295 typedef typename Base::vertices_size_type vertices_size_type;
|
Chris@16
|
296 typedef typename Base::edges_size_type edges_size_type;
|
Chris@16
|
297 typedef typename Base::degree_size_type degree_size_type;
|
Chris@16
|
298 typedef typename Base::vertex_descriptor vertex_descriptor;
|
Chris@16
|
299 typedef typename Base::edge_descriptor edge_descriptor;
|
Chris@16
|
300 typedef OutEdgeListS out_edge_list_selector;
|
Chris@16
|
301 typedef VertexListS vertex_list_selector;
|
Chris@16
|
302 typedef DirectedS directed_selector;
|
Chris@16
|
303 typedef EdgeListS edge_list_selector;
|
Chris@16
|
304
|
Chris@16
|
305
|
Chris@16
|
306 adjacency_list(const GraphProperty& p = GraphProperty())
|
Chris@16
|
307 : m_property(new graph_property_type(p))
|
Chris@16
|
308 { }
|
Chris@16
|
309
|
Chris@16
|
310 adjacency_list(const adjacency_list& x)
|
Chris@16
|
311 : Base(x), m_property(new graph_property_type(*x.m_property))
|
Chris@16
|
312 { }
|
Chris@16
|
313
|
Chris@16
|
314 adjacency_list& operator=(const adjacency_list& x) {
|
Chris@16
|
315 // TBD: probably should give the strong guarantee
|
Chris@16
|
316 if (&x != this) {
|
Chris@16
|
317 Base::operator=(x);
|
Chris@16
|
318
|
Chris@16
|
319 // Copy/swap the ptr since we can't just assign it...
|
Chris@16
|
320 property_ptr p(new graph_property_type(*x.m_property));
|
Chris@16
|
321 m_property.swap(p);
|
Chris@16
|
322 }
|
Chris@16
|
323 return *this;
|
Chris@16
|
324 }
|
Chris@16
|
325
|
Chris@16
|
326 // Required by Mutable Graph
|
Chris@16
|
327 adjacency_list(vertices_size_type num_vertices,
|
Chris@16
|
328 const GraphProperty& p = GraphProperty())
|
Chris@16
|
329 : Base(num_vertices), m_property(new graph_property_type(p))
|
Chris@16
|
330 { }
|
Chris@16
|
331
|
Chris@16
|
332 // Required by Iterator Constructible Graph
|
Chris@16
|
333 template <class EdgeIterator>
|
Chris@16
|
334 adjacency_list(EdgeIterator first, EdgeIterator last,
|
Chris@16
|
335 vertices_size_type n,
|
Chris@16
|
336 edges_size_type = 0,
|
Chris@16
|
337 const GraphProperty& p = GraphProperty())
|
Chris@16
|
338 : Base(n, first, last), m_property(new graph_property_type(p))
|
Chris@16
|
339 { }
|
Chris@16
|
340
|
Chris@16
|
341 template <class EdgeIterator, class EdgePropertyIterator>
|
Chris@16
|
342 adjacency_list(EdgeIterator first, EdgeIterator last,
|
Chris@16
|
343 EdgePropertyIterator ep_iter,
|
Chris@16
|
344 vertices_size_type n,
|
Chris@16
|
345 edges_size_type = 0,
|
Chris@16
|
346 const GraphProperty& p = GraphProperty())
|
Chris@16
|
347 : Base(n, first, last, ep_iter), m_property(new graph_property_type(p))
|
Chris@16
|
348 { }
|
Chris@16
|
349
|
Chris@16
|
350 void swap(adjacency_list& x) {
|
Chris@16
|
351 // Is there a more efficient way to do this?
|
Chris@16
|
352 adjacency_list tmp(x);
|
Chris@16
|
353 x = *this;
|
Chris@16
|
354 *this = tmp;
|
Chris@16
|
355 }
|
Chris@16
|
356
|
Chris@16
|
357 void clear()
|
Chris@16
|
358 {
|
Chris@16
|
359 this->clearing_graph();
|
Chris@16
|
360 Base::clear();
|
Chris@16
|
361 }
|
Chris@16
|
362
|
Chris@16
|
363 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
|
Chris@16
|
364 // Directly access a vertex or edge bundle
|
Chris@16
|
365 vertex_bundled& operator[](vertex_descriptor v)
|
Chris@16
|
366 { return get(vertex_bundle, *this)[v]; }
|
Chris@16
|
367
|
Chris@16
|
368 const vertex_bundled& operator[](vertex_descriptor v) const
|
Chris@16
|
369 { return get(vertex_bundle, *this)[v]; }
|
Chris@16
|
370
|
Chris@16
|
371 edge_bundled& operator[](edge_descriptor e)
|
Chris@16
|
372 { return get(edge_bundle, *this)[e]; }
|
Chris@16
|
373
|
Chris@16
|
374 const edge_bundled& operator[](edge_descriptor e) const
|
Chris@16
|
375 { return get(edge_bundle, *this)[e]; }
|
Chris@16
|
376
|
Chris@16
|
377 graph_bundled& operator[](graph_bundle_t)
|
Chris@16
|
378 { return get_property(*this); }
|
Chris@16
|
379
|
Chris@16
|
380 graph_bundled const& operator[](graph_bundle_t) const
|
Chris@16
|
381 { return get_property(*this); }
|
Chris@16
|
382 #endif
|
Chris@16
|
383
|
Chris@16
|
384 // protected: (would be protected if friends were more portable)
|
Chris@16
|
385 typedef scoped_ptr<graph_property_type> property_ptr;
|
Chris@16
|
386 property_ptr m_property;
|
Chris@16
|
387 };
|
Chris@16
|
388
|
Chris@16
|
389 #define ADJLIST_PARAMS \
|
Chris@16
|
390 typename OEL, typename VL, typename D, typename VP, typename EP, \
|
Chris@16
|
391 typename GP, typename EL
|
Chris@16
|
392 #define ADJLIST adjacency_list<OEL,VL,D,VP,EP,GP,EL>
|
Chris@16
|
393
|
Chris@16
|
394 template<ADJLIST_PARAMS, typename Tag, typename Value>
|
Chris@16
|
395 inline void set_property(ADJLIST& g, Tag tag, Value const& value) {
|
Chris@16
|
396 get_property_value(*g.m_property, tag) = value;
|
Chris@16
|
397 }
|
Chris@16
|
398
|
Chris@16
|
399 template<ADJLIST_PARAMS, typename Tag>
|
Chris@16
|
400 inline typename graph_property<ADJLIST, Tag>::type&
|
Chris@16
|
401 get_property(ADJLIST& g, Tag tag) {
|
Chris@16
|
402 return get_property_value(*g.m_property, tag);
|
Chris@16
|
403 }
|
Chris@16
|
404
|
Chris@16
|
405 template<ADJLIST_PARAMS, typename Tag>
|
Chris@16
|
406 inline typename graph_property<ADJLIST, Tag>::type const&
|
Chris@16
|
407 get_property(ADJLIST const& g, Tag tag) {
|
Chris@16
|
408 return get_property_value(*g.m_property, tag);
|
Chris@16
|
409 }
|
Chris@16
|
410
|
Chris@16
|
411 // dwa 09/25/00 - needed to be more explicit so reverse_graph would work.
|
Chris@16
|
412 template <class Directed, class Vertex,
|
Chris@16
|
413 class OutEdgeListS,
|
Chris@16
|
414 class VertexListS,
|
Chris@16
|
415 class DirectedS,
|
Chris@16
|
416 class VertexProperty,
|
Chris@16
|
417 class EdgeProperty,
|
Chris@16
|
418 class GraphProperty, class EdgeListS>
|
Chris@16
|
419 inline Vertex
|
Chris@16
|
420 source(const detail::edge_base<Directed,Vertex>& e,
|
Chris@16
|
421 const adjacency_list<OutEdgeListS, VertexListS, DirectedS,
|
Chris@16
|
422 VertexProperty, EdgeProperty, GraphProperty, EdgeListS>&)
|
Chris@16
|
423 {
|
Chris@16
|
424 return e.m_source;
|
Chris@16
|
425 }
|
Chris@16
|
426
|
Chris@16
|
427 template <class Directed, class Vertex, class OutEdgeListS,
|
Chris@16
|
428 class VertexListS, class DirectedS, class VertexProperty,
|
Chris@16
|
429 class EdgeProperty, class GraphProperty, class EdgeListS>
|
Chris@16
|
430 inline Vertex
|
Chris@16
|
431 target(const detail::edge_base<Directed,Vertex>& e,
|
Chris@16
|
432 const adjacency_list<OutEdgeListS, VertexListS, DirectedS,
|
Chris@16
|
433 VertexProperty, EdgeProperty, GraphProperty, EdgeListS>&)
|
Chris@16
|
434 {
|
Chris@16
|
435 return e.m_target;
|
Chris@16
|
436 }
|
Chris@16
|
437
|
Chris@16
|
438 // Mutability Traits
|
Chris@16
|
439 template <ADJLIST_PARAMS>
|
Chris@16
|
440 struct graph_mutability_traits<ADJLIST> {
|
Chris@16
|
441 typedef mutable_property_graph_tag category;
|
Chris@16
|
442 };
|
Chris@16
|
443
|
Chris@16
|
444 // Can't remove vertices from adjacency lists with VL==vecS
|
Chris@16
|
445 template <typename OEL, typename D, typename VP, typename EP, typename GP, typename EL>
|
Chris@16
|
446 struct graph_mutability_traits< adjacency_list<OEL,vecS,D,VP,EP,GP,EL> > {
|
Chris@16
|
447 typedef add_only_property_graph_tag category;
|
Chris@16
|
448 };
|
Chris@16
|
449 #undef ADJLIST_PARAMS
|
Chris@16
|
450 #undef ADJLIST
|
Chris@16
|
451
|
Chris@16
|
452
|
Chris@16
|
453 } // namespace boost
|
Chris@16
|
454
|
Chris@16
|
455
|
Chris@16
|
456 #endif // BOOST_GRAPH_ADJACENCY_LIST_HPP
|