• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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