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