1 //=======================================================================
2 // Copyright 1997-2001 University of Notre Dame.
3 // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See
6 // accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 //=======================================================================
9 #ifndef BOOST_GRAPH_SGB_GRAPH_HPP
10 #define BOOST_GRAPH_SGB_GRAPH_HPP
11
12 #include <boost/config.hpp>
13 #include <boost/operators.hpp>
14 #include <boost/property_map/property_map.hpp>
15 #include <boost/graph/graph_traits.hpp>
16 #include <boost/graph/properties.hpp>
17
18 // Thanks to Andreas Scherer for numerous suggestions and fixes!
19
20 // This file adapts a Stanford GraphBase (SGB) Graph pointer into a
21 // VertexListGraph. Note that a graph adaptor class is not needed,
22 // SGB's Graph* is used as is. The VertexListGraph concept is fulfilled by
23 // defining the appropriate non-member functions for Graph*.
24 //
25 // The PROTOTYPES change file extensions to SGB must be applied so
26 // that the SGB functions have real prototypes which are necessary for
27 // the C++ compiler. To apply the PROTOTYPES extensions, before you do
28 // "make tests install" for SGB do "ln -s PROTOTYPES/* ." to the SGB
29 // root directory (or just copy all the files from the PROTOTYPES
30 // directory to the SGB root directory).
31 //
32 extern "C"
33 {
34 // We include all global definitions for the general stuff
35 // of The Stanford GraphBase and its various graph generator
36 // functions by reading all SGB headerfiles as in section 2 of
37 // the "test_sample" program.
38 #include <gb_graph.h> /* SGB data structures */
39 #include <gb_io.h> /* SGB input/output routines */
40 #include <gb_flip.h> /* random number generator */
41 #include <gb_dijk.h> /* routines for shortest paths */
42 #include <gb_basic.h> /* the basic graph operations */
43 #undef empty /* avoid name clash with C++ standard library */
empty(long n)44 inline Graph* empty(long n) /* and provide workaround */
45 {
46 return board(n, 0L, 0L, 0L, 2L, 0L, 0L);
47 }
48 #include <gb_books.h> /* graphs based on literature */
49 #include <gb_econ.h> /* graphs based on economic data */
50 #include <gb_games.h> /* graphs based on football scores */
51 #undef ap /* avoid name clash with BGL parameter */
52 // ap ==> Vertex::u.I
53 #include <gb_gates.h> /* graphs based on logic circuits */
54 #undef val /* avoid name clash with g++ headerfile stl_tempbuf.h */
55 // val ==> Vertex::x.I
56 #include <gb_lisa.h> /* graphs based on Mona Lisa */
57 #include <gb_miles.h> /* graphs based on mileage data */
58 #include <gb_plane.h> /* planar graphs */
59 #include <gb_raman.h> /* Ramanujan graphs */
60 #include <gb_rand.h> /* random graphs */
61 #include <gb_roget.h> /* graphs based on Roget's Thesaurus */
62 #include <gb_save.h> /* we save results in ASCII format */
63 #include <gb_words.h> /* five-letter-word graphs */
64 #undef weight /* avoid name clash with BGL parameter */
65 // weight ==> Vertex::u.I
66 }
67
68 namespace boost
69 {
70 class sgb_edge;
71 }
72
73 class sgb_out_edge_iterator;
74 class sgb_adj_iterator;
75 class sgb_vertex_iterator;
76
77 namespace boost
78 {
79 typedef Graph* sgb_graph_ptr;
80 typedef const Graph* sgb_const_graph_ptr;
81
82 struct sgb_traversal_tag : public virtual vertex_list_graph_tag,
83 public virtual incidence_graph_tag,
84 public virtual adjacency_graph_tag
85 {
86 };
87
88 template <> struct graph_traits< sgb_graph_ptr >
89 {
90 typedef Vertex* vertex_descriptor;
91 typedef boost::sgb_edge edge_descriptor;
92 typedef sgb_out_edge_iterator out_edge_iterator;
93 typedef void in_edge_iterator;
94 typedef sgb_adj_iterator adjacency_iterator;
95 typedef sgb_vertex_iterator vertex_iterator;
96 typedef void edge_iterator;
97 typedef long vertices_size_type;
98 typedef long edge_size_type;
99 typedef long degree_size_type;
100 typedef directed_tag directed_category;
101 typedef sgb_traversal_tag traversal_category;
102 typedef allow_parallel_edge_tag edge_parallel_category;
103 /** Return a null descriptor */
null_vertexboost::graph_traits104 static vertex_descriptor null_vertex() { return NULL; }
105 };
106 template <> struct graph_traits< sgb_const_graph_ptr >
107 {
108 typedef Vertex* vertex_descriptor;
109 typedef boost::sgb_edge edge_descriptor;
110 typedef sgb_out_edge_iterator out_edge_iterator;
111 typedef void in_edge_iterator;
112 typedef sgb_adj_iterator adjacency_iterator;
113 typedef sgb_vertex_iterator vertex_iterator;
114 typedef void edge_iterator;
115 typedef long vertices_size_type;
116 typedef long edge_size_type;
117 typedef long degree_size_type;
118 typedef directed_tag directed_category;
119 typedef sgb_traversal_tag traversal_category;
120 typedef allow_parallel_edge_tag edge_parallel_category;
121 /** Return a null descriptor */
null_vertexboost::graph_traits122 static vertex_descriptor null_vertex() { return NULL; }
123 };
124 }
125
126 namespace boost
127 {
128
129 struct edge_length_t
130 {
131 typedef edge_property_tag kind;
132 };
133
134 // We could just use Arc* as the edge descriptor type, but
135 // we want to add the source(e,g) function which requires
136 // that we carry along a pointer to the source vertex.
137 class sgb_edge
138 {
139 typedef sgb_edge self;
140
141 public:
sgb_edge()142 sgb_edge() : _arc(0), _src(0) {}
sgb_edge(Arc * a,Vertex * s)143 sgb_edge(Arc* a, Vertex* s) : _arc(a), _src(s) {}
source(self e,sgb_const_graph_ptr)144 friend Vertex* source(self e, sgb_const_graph_ptr) { return e._src; }
target(self e,sgb_const_graph_ptr)145 friend Vertex* target(self e, sgb_const_graph_ptr) { return e._arc->tip; }
operator ==(const self & a,const self & b)146 friend bool operator==(const self& a, const self& b)
147 {
148 return a._arc == b._arc;
149 }
operator !=(const self & a,const self & b)150 friend bool operator!=(const self& a, const self& b)
151 {
152 return a._arc != b._arc;
153 }
154 #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
155 template < class Ref > friend class sgb_edge_length_map;
156 template < class Tag, class Ref > friend class sgb_edge_util_map;
157 friend long get(edge_length_t, const sgb_graph_ptr&, const sgb_edge& key);
158 friend long get(
159 edge_length_t, const sgb_const_graph_ptr&, const sgb_edge& key);
160 friend void put(
161 edge_length_t, sgb_graph_ptr&, const sgb_edge& key, long value);
162
163 protected:
164 #endif
165 Arc* _arc;
166 Vertex* _src;
167 };
168 } // namespace boost
169
170 class sgb_out_edge_iterator
171 : public boost::forward_iterator_helper< sgb_out_edge_iterator, boost::sgb_edge,
172 std::ptrdiff_t, boost::sgb_edge*, boost::sgb_edge >
173 {
174 typedef sgb_out_edge_iterator self;
175
176 public:
sgb_out_edge_iterator()177 sgb_out_edge_iterator() : _src(0), _arc(0) {}
sgb_out_edge_iterator(Vertex * s,Arc * d)178 sgb_out_edge_iterator(Vertex* s, Arc* d) : _src(s), _arc(d) {}
operator *()179 boost::sgb_edge operator*() { return boost::sgb_edge(_arc, _src); }
operator ++()180 self& operator++()
181 {
182 _arc = _arc->next;
183 return *this;
184 }
operator ==(const self & x,const self & y)185 friend bool operator==(const self& x, const self& y)
186 {
187 return x._arc == y._arc;
188 }
189
190 protected:
191 Vertex* _src;
192 Arc* _arc;
193 };
194
195 class sgb_adj_iterator
196 : public boost::forward_iterator_helper< sgb_adj_iterator, Vertex*,
197 std::ptrdiff_t, Vertex**, Vertex* >
198 {
199 typedef sgb_adj_iterator self;
200
201 public:
sgb_adj_iterator()202 sgb_adj_iterator() : _arc(0) {}
sgb_adj_iterator(Arc * d)203 sgb_adj_iterator(Arc* d) : _arc(d) {}
operator *()204 Vertex* operator*() { return _arc->tip; }
operator ++()205 self& operator++()
206 {
207 _arc = _arc->next;
208 return *this;
209 }
operator ==(const self & x,const self & y)210 friend bool operator==(const self& x, const self& y)
211 {
212 return x._arc == y._arc;
213 }
214
215 protected:
216 Arc* _arc;
217 };
218
219 // The reason we have this instead of just using Vertex* is that we
220 // want to use Vertex* as the vertex_descriptor instead of just
221 // Vertex, which avoids problems with boost passing vertex descriptors
222 // by value and how that interacts with the sgb_vertex_id_map.
223 class sgb_vertex_iterator
224 : public boost::forward_iterator_helper< sgb_vertex_iterator, Vertex*,
225 std::ptrdiff_t, Vertex**, Vertex* >
226 {
227 typedef sgb_vertex_iterator self;
228
229 public:
sgb_vertex_iterator()230 sgb_vertex_iterator() : _v(0) {}
sgb_vertex_iterator(Vertex * v)231 sgb_vertex_iterator(Vertex* v) : _v(v) {}
operator *()232 Vertex* operator*() { return _v; }
operator ++()233 self& operator++()
234 {
235 ++_v;
236 return *this;
237 }
operator ==(const self & x,const self & y)238 friend bool operator==(const self& x, const self& y)
239 {
240 return x._v == y._v;
241 }
242
243 protected:
244 Vertex* _v;
245 };
246
247 namespace boost
248 {
249
vertices(sgb_const_graph_ptr g)250 inline std::pair< sgb_vertex_iterator, sgb_vertex_iterator > vertices(
251 sgb_const_graph_ptr g)
252 {
253 return std::make_pair(sgb_vertex_iterator(g->vertices),
254 sgb_vertex_iterator(g->vertices + g->n));
255 }
256
out_edges(Vertex * u,sgb_const_graph_ptr)257 inline std::pair< sgb_out_edge_iterator, sgb_out_edge_iterator > out_edges(
258 Vertex* u, sgb_const_graph_ptr)
259 {
260 return std::make_pair(
261 sgb_out_edge_iterator(u, u->arcs), sgb_out_edge_iterator(u, 0));
262 }
263
out_degree(Vertex * u,sgb_const_graph_ptr g)264 inline boost::graph_traits< sgb_graph_ptr >::degree_size_type out_degree(
265 Vertex* u, sgb_const_graph_ptr g)
266 {
267 boost::graph_traits< sgb_graph_ptr >::out_edge_iterator i, i_end;
268 boost::tie(i, i_end) = out_edges(u, g);
269 return std::distance(i, i_end);
270 }
271
272 // in_edges?
273
adjacent_vertices(Vertex * u,sgb_const_graph_ptr)274 inline std::pair< sgb_adj_iterator, sgb_adj_iterator > adjacent_vertices(
275 Vertex* u, sgb_const_graph_ptr)
276 {
277 return std::make_pair(sgb_adj_iterator(u->arcs), sgb_adj_iterator(0));
278 }
279
num_vertices(sgb_const_graph_ptr g)280 inline long num_vertices(sgb_const_graph_ptr g) { return g->n; }
num_edges(sgb_const_graph_ptr g)281 inline long num_edges(sgb_const_graph_ptr g) { return g->m; }
282
vertex(long v,sgb_const_graph_ptr g)283 inline Vertex* vertex(long v, sgb_const_graph_ptr g) { return g->vertices + v; }
284
285 // Various Property Maps
286
287 // Vertex ID
288 class sgb_vertex_id_map
289 : public boost::put_get_helper< long, sgb_vertex_id_map >
290 {
291 public:
292 typedef boost::readable_property_map_tag category;
293 typedef long value_type;
294 typedef long reference;
295 typedef Vertex* key_type;
sgb_vertex_id_map()296 sgb_vertex_id_map() : _g(0) {}
sgb_vertex_id_map(sgb_graph_ptr g)297 sgb_vertex_id_map(sgb_graph_ptr g) : _g(g) {}
operator [](Vertex * v) const298 long operator[](Vertex* v) const { return v - _g->vertices; }
299
300 protected:
301 sgb_graph_ptr _g;
302 };
get(vertex_index_t,sgb_graph_ptr g)303 inline sgb_vertex_id_map get(vertex_index_t, sgb_graph_ptr g)
304 {
305 return sgb_vertex_id_map(g);
306 }
307
308 // Vertex Name
309 class sgb_vertex_name_map
310 : public boost::put_get_helper< char*, sgb_vertex_name_map >
311 {
312 public:
313 typedef boost::readable_property_map_tag category;
314 typedef char* value_type;
315 typedef char* reference;
316 typedef Vertex* key_type;
operator [](Vertex * v) const317 char* operator[](Vertex* v) const { return v->name; }
318 };
get(vertex_name_t,sgb_graph_ptr)319 inline sgb_vertex_name_map get(vertex_name_t, sgb_graph_ptr)
320 {
321 return sgb_vertex_name_map();
322 }
323
324 // Vertex Property Tags
325 #define SGB_PROPERTY_TAG(KIND, TAG) \
326 template < class T > struct TAG##_property \
327 { \
328 typedef KIND##_property_tag kind; \
329 typedef T type; \
330 };
SGB_PROPERTY_TAG(vertex,u)331 SGB_PROPERTY_TAG(vertex, u)
332 SGB_PROPERTY_TAG(vertex, v)
333 SGB_PROPERTY_TAG(vertex, w)
334 SGB_PROPERTY_TAG(vertex, x)
335 SGB_PROPERTY_TAG(vertex, y)
336 SGB_PROPERTY_TAG(vertex, z)
337
338 // Edge Property Tags
339 SGB_PROPERTY_TAG(edge, a)
340 SGB_PROPERTY_TAG(edge, b)
341
342 // Various Utility Maps
343
344 // helpers
345 inline Vertex*& get_util(util& u, Vertex*) { return u.V; }
get_util(util & u,Arc *)346 inline Arc*& get_util(util& u, Arc*) { return u.A; }
get_util(util & u,sgb_graph_ptr)347 inline sgb_graph_ptr& get_util(util& u, sgb_graph_ptr) { return u.G; }
get_util(util & u,char *)348 inline char*& get_util(util& u, char*) { return u.S; }
get_util(util & u,long)349 inline long& get_util(util& u, long) { return u.I; }
350
351 #define SGB_GET_UTIL_FIELD(KIND, X) \
352 template < class T > inline T& get_util_field(KIND* k, X##_property< T >) \
353 { \
354 return get_util(k->X, T()); \
355 }
356
357 SGB_GET_UTIL_FIELD(Vertex, u)
358 SGB_GET_UTIL_FIELD(Vertex, v)
359 SGB_GET_UTIL_FIELD(Vertex, w)
360 SGB_GET_UTIL_FIELD(Vertex, x)
361 SGB_GET_UTIL_FIELD(Vertex, y)
362 SGB_GET_UTIL_FIELD(Vertex, z)
363
364 SGB_GET_UTIL_FIELD(Arc, a)
365 SGB_GET_UTIL_FIELD(Arc, b)
366
367 // Vertex Utility Map
368 template < class Tag, class Ref >
369 class sgb_vertex_util_map
370 : public boost::put_get_helper< Ref, sgb_vertex_util_map< Tag, Ref > >
371 {
372 Tag tag;
373
374 public:
sgb_vertex_util_map(Tag tag=Tag ())375 explicit sgb_vertex_util_map(Tag tag = Tag()) : tag(tag) {}
376 typedef boost::lvalue_property_map_tag category;
377 typedef typename Tag::type value_type;
378 typedef Vertex* key_type;
379 typedef Ref reference;
operator [](Vertex * v) const380 reference operator[](Vertex* v) const { return get_util_field(v, tag); }
381 };
382
383 // Edge Utility Map
384 template < class Tag, class Ref >
385 class sgb_edge_util_map
386 : public boost::put_get_helper< Ref, sgb_edge_util_map< Tag, Ref > >
387 {
388 Tag tag;
389
390 public:
sgb_edge_util_map(Tag tag=Tag ())391 explicit sgb_edge_util_map(Tag tag = Tag()) : tag(tag) {}
392 typedef boost::lvalue_property_map_tag category;
393 typedef typename Tag::type value_type;
394 typedef Vertex* key_type;
395 typedef Ref reference;
operator [](const sgb_edge & e) const396 reference operator[](const sgb_edge& e) const
397 {
398 return get_util_field(e._arc, tag);
399 }
400 };
401
402 template < class Tag >
get_property_map(Tag,const sgb_graph_ptr & g,vertex_property_tag)403 inline sgb_vertex_util_map< Tag, const typename Tag::type& > get_property_map(
404 Tag, const sgb_graph_ptr& g, vertex_property_tag)
405 {
406 return sgb_vertex_util_map< Tag, const typename Tag::type& >();
407 }
408 template < class Tag >
get_property_map(Tag,sgb_graph_ptr & g,vertex_property_tag)409 inline sgb_vertex_util_map< Tag, typename Tag::type& > get_property_map(
410 Tag, sgb_graph_ptr& g, vertex_property_tag)
411 {
412 return sgb_vertex_util_map< Tag, typename Tag::type& >();
413 }
414
415 template < class Tag >
get_property_map(Tag,const sgb_graph_ptr & g,edge_property_tag)416 inline sgb_edge_util_map< Tag, const typename Tag::type& > get_property_map(
417 Tag, const sgb_graph_ptr& g, edge_property_tag)
418 {
419 return sgb_edge_util_map< Tag, const typename Tag::type& >();
420 }
421 template < class Tag >
get_property_map(Tag,sgb_graph_ptr & g,edge_property_tag)422 inline sgb_edge_util_map< Tag, typename Tag::type& > get_property_map(
423 Tag, sgb_graph_ptr& g, edge_property_tag)
424 {
425 return sgb_edge_util_map< Tag, typename Tag::type& >();
426 }
427
428 // Edge Length Access
429 template < class Ref >
430 class sgb_edge_length_map
431 : public boost::put_get_helper< Ref, sgb_edge_length_map< Ref > >
432 {
433 public:
434 typedef boost::lvalue_property_map_tag category;
435 typedef long value_type;
436 typedef sgb_edge key_type;
437 typedef Ref reference;
operator [](const sgb_edge & e) const438 reference operator[](const sgb_edge& e) const { return e._arc->len; }
439 };
440
get(edge_length_t,const sgb_graph_ptr &)441 inline sgb_edge_length_map< const long& > get(
442 edge_length_t, const sgb_graph_ptr&)
443 {
444 return sgb_edge_length_map< const long& >();
445 }
get(edge_length_t,const sgb_const_graph_ptr &)446 inline sgb_edge_length_map< const long& > get(
447 edge_length_t, const sgb_const_graph_ptr&)
448 {
449 return sgb_edge_length_map< const long& >();
450 }
get(edge_length_t,sgb_graph_ptr &)451 inline sgb_edge_length_map< long& > get(edge_length_t, sgb_graph_ptr&)
452 {
453 return sgb_edge_length_map< long& >();
454 }
get(edge_length_t,const sgb_graph_ptr &,const sgb_edge & key)455 inline long get(edge_length_t, const sgb_graph_ptr&, const sgb_edge& key)
456 {
457 return key._arc->len;
458 }
get(edge_length_t,const sgb_const_graph_ptr &,const sgb_edge & key)459 inline long get(edge_length_t, const sgb_const_graph_ptr&, const sgb_edge& key)
460 {
461 return key._arc->len;
462 }
put(edge_length_t,sgb_graph_ptr &,const sgb_edge & key,long value)463 inline void put(edge_length_t, sgb_graph_ptr&, const sgb_edge& key, long value)
464 {
465 key._arc->len = value;
466 }
467
468 // Property Map Traits Classes
469 template <> struct property_map< sgb_graph_ptr, edge_length_t >
470 {
471 typedef sgb_edge_length_map< long& > type;
472 typedef sgb_edge_length_map< const long& > const_type;
473 };
474 template <> struct property_map< sgb_graph_ptr, vertex_index_t >
475 {
476 typedef sgb_vertex_id_map type;
477 typedef sgb_vertex_id_map const_type;
478 };
479 template <> struct property_map< sgb_graph_ptr, vertex_name_t >
480 {
481 typedef sgb_vertex_name_map type;
482 typedef sgb_vertex_name_map const_type;
483 };
484
485 template <> struct property_map< sgb_const_graph_ptr, edge_length_t >
486 {
487 typedef sgb_edge_length_map< const long& > const_type;
488 };
489 template <> struct property_map< sgb_const_graph_ptr, vertex_index_t >
490 {
491 typedef sgb_vertex_id_map const_type;
492 };
493 template <> struct property_map< sgb_const_graph_ptr, vertex_name_t >
494 {
495 typedef sgb_vertex_name_map const_type;
496 };
497
498 namespace detail
499 {
500 template < class Kind, class PropertyTag > struct sgb_choose_property_map
501 {
502 };
503 template < class PropertyTag >
504 struct sgb_choose_property_map< vertex_property_tag, PropertyTag >
505 {
506 typedef typename PropertyTag::type value_type;
507 typedef sgb_vertex_util_map< PropertyTag, value_type& > type;
508 typedef sgb_vertex_util_map< PropertyTag, const value_type& >
509 const_type;
510 };
511 template < class PropertyTag >
512 struct sgb_choose_property_map< edge_property_tag, PropertyTag >
513 {
514 typedef typename PropertyTag::type value_type;
515 typedef sgb_edge_util_map< PropertyTag, value_type& > type;
516 typedef sgb_edge_util_map< PropertyTag, const value_type& > const_type;
517 };
518 } // namespace detail
519 template < class PropertyTag > struct property_map< sgb_graph_ptr, PropertyTag >
520 {
521 typedef typename property_kind< PropertyTag >::type Kind;
522 typedef detail::sgb_choose_property_map< Kind, PropertyTag > Choice;
523 typedef typename Choice::type type;
524 typedef typename Choice::const_type const_type;
525 };
526 template < class PropertyTag >
527 struct property_map< sgb_const_graph_ptr, PropertyTag >
528 {
529 typedef typename property_kind< PropertyTag >::type Kind;
530 typedef detail::sgb_choose_property_map< Kind, PropertyTag > Choice;
531 typedef typename Choice::const_type const_type;
532 };
533
534 #define SGB_UTIL_ACCESSOR(KIND, X) \
535 template < class T > \
536 inline sgb_##KIND##_util_map< X##_property< T >, T& > get( \
537 X##_property< T >, sgb_graph_ptr&) \
538 { \
539 return sgb_##KIND##_util_map< X##_property< T >, T& >(); \
540 } \
541 template < class T > \
542 inline sgb_##KIND##_util_map< X##_property< T >, const T& > get( \
543 X##_property< T >, const sgb_graph_ptr&) \
544 { \
545 return sgb_##KIND##_util_map< X##_property< T >, const T& >(); \
546 } \
547 template < class T > \
548 inline sgb_##KIND##_util_map< X##_property< T >, const T& > get( \
549 X##_property< T >, const sgb_const_graph_ptr&) \
550 { \
551 return sgb_##KIND##_util_map< X##_property< T >, const T& >(); \
552 } \
553 template < class T, class Key > \
554 inline typename sgb_##KIND##_util_map< X##_property< T >, \
555 const T& >::value_type \
556 get(X##_property< T >, const sgb_graph_ptr&, const Key& key) \
557 { \
558 return sgb_##KIND##_util_map< X##_property< T >, const T& >()[key]; \
559 } \
560 template < class T, class Key > \
561 inline typename sgb_##KIND##_util_map< X##_property< T >, \
562 const T& >::value_type \
563 get(X##_property< T >, const sgb_const_graph_ptr&, const Key& key) \
564 { \
565 return sgb_##KIND##_util_map< X##_property< T >, const T& >()[key]; \
566 } \
567 template < class T, class Key, class Value > \
568 inline void put( \
569 X##_property< T >, sgb_graph_ptr&, const Key& key, const Value& value) \
570 { \
571 sgb_##KIND##_util_map< X##_property< T >, T& >()[key] = value; \
572 }
573
574 SGB_UTIL_ACCESSOR(vertex, u)
575 SGB_UTIL_ACCESSOR(vertex, v)
576 SGB_UTIL_ACCESSOR(vertex, w)
577 SGB_UTIL_ACCESSOR(vertex, x)
578 SGB_UTIL_ACCESSOR(vertex, y)
579 SGB_UTIL_ACCESSOR(vertex, z)
580
581 SGB_UTIL_ACCESSOR(edge, a)
582 SGB_UTIL_ACCESSOR(edge, b)
583
584 } // namespace boost
585
586 #endif // BOOST_GRAPH_SGB_GRAPH_HPP
587