annotate DEPENDENCIES/generic/include/boost/graph/detail/adjacency_list.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 // -*- c++ -*-
Chris@16 2 //=======================================================================
Chris@16 3 // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
Chris@16 4 // Copyright 2010 Thomas Claveirole
Chris@16 5 // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Thomas Claveirole
Chris@16 6 //
Chris@16 7 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 8 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 9 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 10 //=======================================================================
Chris@16 11
Chris@16 12 #ifndef BOOST_GRAPH_DETAIL_ADJACENCY_LIST_HPP
Chris@16 13 #define BOOST_GRAPH_DETAIL_ADJACENCY_LIST_HPP
Chris@16 14
Chris@16 15 #include <map> // for vertex_map in copy_impl
Chris@16 16 #include <boost/config.hpp>
Chris@16 17 #include <boost/detail/workaround.hpp>
Chris@16 18 #include <boost/operators.hpp>
Chris@16 19 #include <boost/property_map/property_map.hpp>
Chris@16 20 #include <boost/pending/container_traits.hpp>
Chris@16 21 #include <boost/range/irange.hpp>
Chris@16 22 #include <boost/graph/graph_traits.hpp>
Chris@16 23 #include <memory>
Chris@16 24 #include <algorithm>
Chris@16 25 #include <boost/limits.hpp>
Chris@16 26
Chris@16 27 #include <boost/iterator/iterator_adaptor.hpp>
Chris@16 28
Chris@16 29 #include <boost/mpl/if.hpp>
Chris@16 30 #include <boost/mpl/not.hpp>
Chris@16 31 #include <boost/mpl/and.hpp>
Chris@16 32 #include <boost/graph/graph_concepts.hpp>
Chris@16 33 #include <boost/pending/container_traits.hpp>
Chris@16 34 #include <boost/graph/detail/adj_list_edge_iterator.hpp>
Chris@16 35 #include <boost/graph/properties.hpp>
Chris@16 36 #include <boost/pending/property.hpp>
Chris@16 37 #include <boost/graph/adjacency_iterator.hpp>
Chris@16 38 #include <boost/static_assert.hpp>
Chris@16 39 #include <boost/assert.hpp>
Chris@16 40
Chris@101 41 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@101 42 #define BOOST_GRAPH_MOVE_IF_POSSIBLE(x) (x)
Chris@101 43 #else
Chris@101 44 #include <utility>
Chris@101 45 #define BOOST_GRAPH_MOVE_IF_POSSIBLE(x) (std::move((x)))
Chris@101 46 #endif
Chris@101 47
Chris@16 48 /*
Chris@16 49 Outline for this file:
Chris@16 50
Chris@16 51 out_edge_iterator and in_edge_iterator implementation
Chris@16 52 edge_iterator for undirected graph
Chris@16 53 stored edge types (these object live in the out-edge/in-edge lists)
Chris@16 54 directed edges helper class
Chris@16 55 directed graph helper class
Chris@16 56 undirected graph helper class
Chris@16 57 bidirectional graph helper class
Chris@16 58 bidirectional graph helper class (without edge properties)
Chris@16 59 bidirectional graph helper class (with edge properties)
Chris@16 60 adjacency_list helper class
Chris@16 61 adj_list_impl class
Chris@16 62 vec_adj_list_impl class
Chris@16 63 adj_list_gen class
Chris@16 64 vertex property map
Chris@16 65 edge property map
Chris@16 66
Chris@16 67
Chris@16 68 Note: it would be nice to merge some of the undirected and
Chris@16 69 bidirectional code... it is awful similar.
Chris@16 70 */
Chris@16 71
Chris@16 72
Chris@16 73 namespace boost {
Chris@16 74
Chris@16 75 namespace detail {
Chris@16 76
Chris@16 77 template <typename DirectedS>
Chris@16 78 struct directed_category_traits {
Chris@16 79 typedef directed_tag directed_category;
Chris@16 80 };
Chris@16 81
Chris@16 82 template <>
Chris@16 83 struct directed_category_traits<directedS> {
Chris@16 84 typedef directed_tag directed_category;
Chris@16 85 };
Chris@16 86 template <>
Chris@16 87 struct directed_category_traits<undirectedS> {
Chris@16 88 typedef undirected_tag directed_category;
Chris@16 89 };
Chris@16 90 template <>
Chris@16 91 struct directed_category_traits<bidirectionalS> {
Chris@16 92 typedef bidirectional_tag directed_category;
Chris@16 93 };
Chris@16 94
Chris@16 95 template <class Vertex>
Chris@16 96 struct target_is {
Chris@16 97 target_is(const Vertex& v) : m_target(v) { }
Chris@16 98 template <class StoredEdge>
Chris@16 99 bool operator()(const StoredEdge& e) const {
Chris@16 100 return e.get_target() == m_target;
Chris@16 101 }
Chris@16 102 Vertex m_target;
Chris@16 103 };
Chris@16 104
Chris@16 105 // O(E/V)
Chris@16 106 template <class EdgeList, class vertex_descriptor>
Chris@16 107 void erase_from_incidence_list(EdgeList& el, vertex_descriptor v,
Chris@16 108 allow_parallel_edge_tag)
Chris@16 109 {
Chris@16 110 boost::graph_detail::erase_if(el, detail::target_is<vertex_descriptor>(v));
Chris@16 111 }
Chris@16 112 // O(log(E/V))
Chris@16 113 template <class EdgeList, class vertex_descriptor>
Chris@16 114 void erase_from_incidence_list(EdgeList& el, vertex_descriptor v,
Chris@16 115 disallow_parallel_edge_tag)
Chris@16 116 {
Chris@16 117 typedef typename EdgeList::value_type StoredEdge;
Chris@16 118 el.erase(StoredEdge(v));
Chris@16 119 }
Chris@16 120
Chris@16 121 //=========================================================================
Chris@16 122 // Out-Edge and In-Edge Iterator Implementation
Chris@16 123
Chris@16 124 template <class BaseIter, class VertexDescriptor, class EdgeDescriptor, class Difference>
Chris@16 125 struct out_edge_iter
Chris@16 126 : iterator_adaptor<
Chris@16 127 out_edge_iter<BaseIter, VertexDescriptor, EdgeDescriptor, Difference>
Chris@16 128 , BaseIter
Chris@16 129 , EdgeDescriptor
Chris@16 130 , use_default
Chris@16 131 , EdgeDescriptor
Chris@16 132 , Difference
Chris@16 133 >
Chris@16 134 {
Chris@16 135 typedef iterator_adaptor<
Chris@16 136 out_edge_iter<BaseIter, VertexDescriptor, EdgeDescriptor, Difference>
Chris@16 137 , BaseIter
Chris@16 138 , EdgeDescriptor
Chris@16 139 , use_default
Chris@16 140 , EdgeDescriptor
Chris@16 141 , Difference
Chris@16 142 > super_t;
Chris@16 143
Chris@16 144 inline out_edge_iter() { }
Chris@16 145 inline out_edge_iter(const BaseIter& i, const VertexDescriptor& src)
Chris@16 146 : super_t(i), m_src(src) { }
Chris@16 147
Chris@16 148 inline EdgeDescriptor
Chris@16 149 dereference() const
Chris@16 150 {
Chris@16 151 return EdgeDescriptor(m_src, (*this->base()).get_target(),
Chris@16 152 &(*this->base()).get_property());
Chris@16 153 }
Chris@16 154 VertexDescriptor m_src;
Chris@16 155 };
Chris@16 156
Chris@16 157 template <class BaseIter, class VertexDescriptor, class EdgeDescriptor, class Difference>
Chris@16 158 struct in_edge_iter
Chris@16 159 : iterator_adaptor<
Chris@16 160 in_edge_iter<BaseIter, VertexDescriptor, EdgeDescriptor, Difference>
Chris@16 161 , BaseIter
Chris@16 162 , EdgeDescriptor
Chris@16 163 , use_default
Chris@16 164 , EdgeDescriptor
Chris@16 165 , Difference
Chris@16 166 >
Chris@16 167 {
Chris@16 168 typedef iterator_adaptor<
Chris@16 169 in_edge_iter<BaseIter, VertexDescriptor, EdgeDescriptor, Difference>
Chris@16 170 , BaseIter
Chris@16 171 , EdgeDescriptor
Chris@16 172 , use_default
Chris@16 173 , EdgeDescriptor
Chris@16 174 , Difference
Chris@16 175 > super_t;
Chris@16 176
Chris@16 177 inline in_edge_iter() { }
Chris@16 178 inline in_edge_iter(const BaseIter& i, const VertexDescriptor& src)
Chris@16 179 : super_t(i), m_src(src) { }
Chris@16 180
Chris@16 181 inline EdgeDescriptor
Chris@16 182 dereference() const
Chris@16 183 {
Chris@16 184 return EdgeDescriptor((*this->base()).get_target(), m_src,
Chris@16 185 &this->base()->get_property());
Chris@16 186 }
Chris@16 187 VertexDescriptor m_src;
Chris@16 188 };
Chris@16 189
Chris@16 190 //=========================================================================
Chris@16 191 // Undirected Edge Iterator Implementation
Chris@16 192
Chris@16 193 template <class EdgeIter, class EdgeDescriptor, class Difference>
Chris@16 194 struct undirected_edge_iter
Chris@16 195 : iterator_adaptor<
Chris@16 196 undirected_edge_iter<EdgeIter, EdgeDescriptor, Difference>
Chris@16 197 , EdgeIter
Chris@16 198 , EdgeDescriptor
Chris@16 199 , use_default
Chris@16 200 , EdgeDescriptor
Chris@16 201 , Difference
Chris@16 202 >
Chris@16 203 {
Chris@16 204 typedef iterator_adaptor<
Chris@16 205 undirected_edge_iter<EdgeIter, EdgeDescriptor, Difference>
Chris@16 206 , EdgeIter
Chris@16 207 , EdgeDescriptor
Chris@16 208 , use_default
Chris@16 209 , EdgeDescriptor
Chris@16 210 , Difference
Chris@16 211 > super_t;
Chris@16 212
Chris@16 213 undirected_edge_iter() {}
Chris@16 214
Chris@16 215 explicit undirected_edge_iter(EdgeIter i)
Chris@16 216 : super_t(i) {}
Chris@16 217
Chris@16 218 inline EdgeDescriptor
Chris@16 219 dereference() const {
Chris@16 220 return EdgeDescriptor(
Chris@16 221 (*this->base()).m_source
Chris@16 222 , (*this->base()).m_target
Chris@16 223 , &this->base()->get_property());
Chris@16 224 }
Chris@16 225 };
Chris@16 226
Chris@16 227 //=========================================================================
Chris@16 228 // Edge Storage Types (stored in the out-edge/in-edge lists)
Chris@16 229
Chris@16 230 template <class Vertex>
Chris@16 231 class stored_edge
Chris@16 232 : public boost::equality_comparable1< stored_edge<Vertex>,
Chris@16 233 boost::less_than_comparable1< stored_edge<Vertex> > >
Chris@16 234 {
Chris@16 235 public:
Chris@16 236 typedef no_property property_type;
Chris@16 237 inline stored_edge() { }
Chris@16 238 inline stored_edge(Vertex target, const no_property& = no_property())
Chris@16 239 : m_target(target) { }
Chris@16 240 // Need to write this explicitly so stored_edge_property can
Chris@16 241 // invoke Base::operator= (at least, for SGI MIPSPro compiler)
Chris@16 242 inline stored_edge& operator=(const stored_edge& x) {
Chris@16 243 m_target = x.m_target;
Chris@16 244 return *this;
Chris@16 245 }
Chris@16 246 inline Vertex& get_target() const { return m_target; }
Chris@16 247 inline const no_property& get_property() const { return s_prop; }
Chris@16 248 inline bool operator==(const stored_edge& x) const
Chris@16 249 { return m_target == x.get_target(); }
Chris@16 250 inline bool operator<(const stored_edge& x) const
Chris@16 251 { return m_target < x.get_target(); }
Chris@16 252 //protected: need to add hash<> as a friend
Chris@16 253 static no_property s_prop;
Chris@16 254 // Sometimes target not used as key in the set, and in that case
Chris@16 255 // it is ok to change the target.
Chris@16 256 mutable Vertex m_target;
Chris@16 257 };
Chris@16 258 template <class Vertex>
Chris@16 259 no_property stored_edge<Vertex>::s_prop;
Chris@16 260
Chris@101 261 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
Chris@16 262 template <class Vertex, class Property>
Chris@16 263 class stored_edge_property : public stored_edge<Vertex> {
Chris@16 264 typedef stored_edge_property self;
Chris@16 265 typedef stored_edge<Vertex> Base;
Chris@16 266 public:
Chris@16 267 typedef Property property_type;
Chris@16 268 inline stored_edge_property() { }
Chris@16 269 inline stored_edge_property(Vertex target,
Chris@16 270 const Property& p = Property())
Chris@16 271 : stored_edge<Vertex>(target), m_property(new Property(p)) { }
Chris@16 272 stored_edge_property(const self& x)
Chris@16 273 : Base(x), m_property(const_cast<self&>(x).m_property) { }
Chris@16 274 self& operator=(const self& x) {
Chris@16 275 Base::operator=(x);
Chris@16 276 m_property = const_cast<self&>(x).m_property;
Chris@16 277 return *this;
Chris@16 278 }
Chris@16 279 inline Property& get_property() { return *m_property; }
Chris@16 280 inline const Property& get_property() const { return *m_property; }
Chris@16 281 protected:
Chris@16 282 // Holding the property by-value causes edge-descriptor
Chris@16 283 // invalidation for add_edge() with EdgeList=vecS. Instead we
Chris@16 284 // hold a pointer to the property. std::auto_ptr is not
Chris@16 285 // a perfect fit for the job, but it is darn close.
Chris@16 286 std::auto_ptr<Property> m_property;
Chris@16 287 };
Chris@101 288 #else
Chris@101 289 template <class Vertex, class Property>
Chris@101 290 class stored_edge_property : public stored_edge<Vertex> {
Chris@101 291 typedef stored_edge_property self;
Chris@101 292 typedef stored_edge<Vertex> Base;
Chris@101 293 public:
Chris@101 294 typedef Property property_type;
Chris@101 295 inline stored_edge_property() { }
Chris@101 296 inline stored_edge_property(Vertex target,
Chris@101 297 const Property& p = Property())
Chris@101 298 : stored_edge<Vertex>(target), m_property(new Property(p)) { }
Chris@101 299 #if defined(BOOST_MSVC) || (defined(BOOST_GCC) && (BOOST_GCC / 100) < 406)
Chris@101 300 stored_edge_property(self&& x) : Base(static_cast< Base const& >(x)) {
Chris@101 301 m_property.swap(x.m_property);
Chris@101 302 }
Chris@101 303 stored_edge_property(self const& x) : Base(static_cast< Base const& >(x)) {
Chris@101 304 m_property.swap(const_cast<self&>(x).m_property);
Chris@101 305 }
Chris@101 306 self& operator=(self&& x) {
Chris@101 307 Base::operator=(static_cast< Base const& >(x));
Chris@101 308 m_property = std::move(x.m_property);
Chris@101 309 return *this;
Chris@101 310 }
Chris@101 311 self& operator=(self const& x) {
Chris@101 312 Base::operator=(static_cast< Base const& >(x));
Chris@101 313 m_property = std::move(const_cast<self&>(x).m_property);
Chris@101 314 return *this;
Chris@101 315 }
Chris@101 316 #else
Chris@101 317 stored_edge_property(self&& x) = default;
Chris@101 318 self& operator=(self&& x) = default;
Chris@101 319 #endif
Chris@101 320 inline Property& get_property() { return *m_property; }
Chris@101 321 inline const Property& get_property() const { return *m_property; }
Chris@101 322 protected:
Chris@101 323 std::unique_ptr<Property> m_property;
Chris@101 324 };
Chris@101 325 #endif
Chris@16 326
Chris@16 327
Chris@16 328 template <class Vertex, class Iter, class Property>
Chris@16 329 class stored_edge_iter
Chris@16 330 : public stored_edge<Vertex>
Chris@16 331 {
Chris@16 332 public:
Chris@16 333 typedef Property property_type;
Chris@16 334 inline stored_edge_iter() { }
Chris@16 335 inline stored_edge_iter(Vertex v)
Chris@16 336 : stored_edge<Vertex>(v) { }
Chris@16 337 inline stored_edge_iter(Vertex v, Iter i, void* = 0)
Chris@16 338 : stored_edge<Vertex>(v), m_iter(i) { }
Chris@16 339 inline Property& get_property() { return m_iter->get_property(); }
Chris@16 340 inline const Property& get_property() const {
Chris@16 341 return m_iter->get_property();
Chris@16 342 }
Chris@16 343 inline Iter get_iter() const { return m_iter; }
Chris@16 344 protected:
Chris@16 345 Iter m_iter;
Chris@16 346 };
Chris@16 347
Chris@16 348 // For when the EdgeList is a std::vector.
Chris@16 349 // Want to make the iterator stable, so use an offset
Chris@16 350 // instead of an iterator into a std::vector
Chris@16 351 template <class Vertex, class EdgeVec, class Property>
Chris@16 352 class stored_ra_edge_iter
Chris@16 353 : public stored_edge<Vertex>
Chris@16 354 {
Chris@16 355 typedef typename EdgeVec::iterator Iter;
Chris@16 356 public:
Chris@16 357 typedef Property property_type;
Chris@16 358 inline stored_ra_edge_iter() { }
Chris@16 359 inline explicit stored_ra_edge_iter(Vertex v) // Only used for comparisons
Chris@16 360 : stored_edge<Vertex>(v), m_i(0), m_vec(0){ }
Chris@16 361 inline stored_ra_edge_iter(Vertex v, Iter i, EdgeVec* edge_vec)
Chris@16 362 : stored_edge<Vertex>(v), m_i(i - edge_vec->begin()), m_vec(edge_vec){ }
Chris@16 363 inline Property& get_property() { BOOST_ASSERT ((m_vec != 0)); return (*m_vec)[m_i].get_property(); }
Chris@16 364 inline const Property& get_property() const {
Chris@16 365 BOOST_ASSERT ((m_vec != 0));
Chris@16 366 return (*m_vec)[m_i].get_property();
Chris@16 367 }
Chris@16 368 inline Iter get_iter() const { BOOST_ASSERT ((m_vec != 0)); return m_vec->begin() + m_i; }
Chris@16 369 protected:
Chris@16 370 std::size_t m_i;
Chris@16 371 EdgeVec* m_vec;
Chris@16 372 };
Chris@16 373
Chris@16 374 } // namespace detail
Chris@16 375
Chris@16 376 template <class Tag, class Vertex, class Property>
Chris@16 377 const typename property_value<Property,Tag>::type&
Chris@16 378 get(Tag property_tag,
Chris@16 379 const detail::stored_edge_property<Vertex, Property>& e)
Chris@16 380 {
Chris@16 381 return get_property_value(e.get_property(), property_tag);
Chris@16 382 }
Chris@16 383
Chris@16 384 template <class Tag, class Vertex, class Iter, class Property>
Chris@16 385 const typename property_value<Property,Tag>::type&
Chris@16 386 get(Tag property_tag,
Chris@16 387 const detail::stored_edge_iter<Vertex, Iter, Property>& e)
Chris@16 388 {
Chris@16 389 return get_property_value(e.get_property(), property_tag);
Chris@16 390 }
Chris@16 391
Chris@16 392 template <class Tag, class Vertex, class EdgeVec, class Property>
Chris@16 393 const typename property_value<Property,Tag>::type&
Chris@16 394 get(Tag property_tag,
Chris@16 395 const detail::stored_ra_edge_iter<Vertex, EdgeVec, Property>& e)
Chris@16 396 {
Chris@16 397 return get_property_value(e.get_property(), property_tag);
Chris@16 398 }
Chris@16 399
Chris@16 400 //=========================================================================
Chris@16 401 // Directed Edges Helper Class
Chris@16 402
Chris@16 403 namespace detail {
Chris@16 404
Chris@16 405 // O(E/V)
Chris@16 406 template <class edge_descriptor, class EdgeList, class StoredProperty>
Chris@16 407 inline void
Chris@16 408 remove_directed_edge_dispatch(edge_descriptor, EdgeList& el,
Chris@16 409 StoredProperty& p)
Chris@16 410 {
Chris@16 411 for (typename EdgeList::iterator i = el.begin();
Chris@16 412 i != el.end(); ++i)
Chris@16 413 if (&(*i).get_property() == &p) {
Chris@16 414 el.erase(i);
Chris@16 415 return;
Chris@16 416 }
Chris@16 417 }
Chris@16 418
Chris@16 419 template <class incidence_iterator, class EdgeList, class Predicate>
Chris@16 420 inline void
Chris@16 421 remove_directed_edge_if_dispatch(incidence_iterator first,
Chris@16 422 incidence_iterator last,
Chris@16 423 EdgeList& el, Predicate pred,
Chris@16 424 boost::allow_parallel_edge_tag)
Chris@16 425 {
Chris@16 426 // remove_if
Chris@16 427 while (first != last && !pred(*first))
Chris@16 428 ++first;
Chris@16 429 incidence_iterator i = first;
Chris@16 430 if (first != last)
Chris@16 431 for (++i; i != last; ++i)
Chris@16 432 if (!pred(*i)) {
Chris@101 433 *first.base() = BOOST_GRAPH_MOVE_IF_POSSIBLE(*i.base());
Chris@16 434 ++first;
Chris@16 435 }
Chris@16 436 el.erase(first.base(), el.end());
Chris@16 437 }
Chris@16 438 template <class incidence_iterator, class EdgeList, class Predicate>
Chris@16 439 inline void
Chris@16 440 remove_directed_edge_if_dispatch(incidence_iterator first,
Chris@16 441 incidence_iterator last,
Chris@16 442 EdgeList& el,
Chris@16 443 Predicate pred,
Chris@16 444 boost::disallow_parallel_edge_tag)
Chris@16 445 {
Chris@16 446 for (incidence_iterator next = first;
Chris@16 447 first != last; first = next) {
Chris@16 448 ++next;
Chris@16 449 if (pred(*first))
Chris@16 450 el.erase( first.base() );
Chris@16 451 }
Chris@16 452 }
Chris@16 453
Chris@16 454 template <class PropT, class Graph, class incidence_iterator,
Chris@16 455 class EdgeList, class Predicate>
Chris@16 456 inline void
Chris@16 457 undirected_remove_out_edge_if_dispatch(Graph& g,
Chris@16 458 incidence_iterator first,
Chris@16 459 incidence_iterator last,
Chris@16 460 EdgeList& el, Predicate pred,
Chris@16 461 boost::allow_parallel_edge_tag)
Chris@16 462 {
Chris@16 463 typedef typename Graph::global_edgelist_selector EdgeListS;
Chris@16 464 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 465
Chris@16 466 // remove_if
Chris@16 467 while (first != last && !pred(*first))
Chris@16 468 ++first;
Chris@16 469 incidence_iterator i = first;
Chris@16 470 bool self_loop_removed = false;
Chris@16 471 if (first != last)
Chris@16 472 for (; i != last; ++i) {
Chris@16 473 if (self_loop_removed) {
Chris@16 474 /* With self loops, the descriptor will show up
Chris@16 475 * twice. The first time it will be removed, and now it
Chris@16 476 * will be skipped.
Chris@16 477 */
Chris@16 478 self_loop_removed = false;
Chris@16 479 }
Chris@16 480 else if (!pred(*i)) {
Chris@101 481 *first.base() = BOOST_GRAPH_MOVE_IF_POSSIBLE(*i.base());
Chris@16 482 ++first;
Chris@16 483 } else {
Chris@16 484 if (source(*i, g) == target(*i, g)) self_loop_removed = true;
Chris@16 485 else {
Chris@16 486 // Remove the edge from the target
Chris@16 487 detail::remove_directed_edge_dispatch
Chris@16 488 (*i,
Chris@16 489 g.out_edge_list(target(*i, g)),
Chris@16 490 *(PropT*)(*i).get_property());
Chris@16 491 }
Chris@16 492
Chris@16 493 // Erase the edge property
Chris@16 494 g.m_edges.erase( (*i.base()).get_iter() );
Chris@16 495 }
Chris@16 496 }
Chris@16 497 el.erase(first.base(), el.end());
Chris@16 498 }
Chris@16 499 template <class PropT, class Graph, class incidence_iterator,
Chris@16 500 class EdgeList, class Predicate>
Chris@16 501 inline void
Chris@16 502 undirected_remove_out_edge_if_dispatch(Graph& g,
Chris@16 503 incidence_iterator first,
Chris@16 504 incidence_iterator last,
Chris@16 505 EdgeList& el,
Chris@16 506 Predicate pred,
Chris@16 507 boost::disallow_parallel_edge_tag)
Chris@16 508 {
Chris@16 509 typedef typename Graph::global_edgelist_selector EdgeListS;
Chris@16 510 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 511
Chris@16 512 for (incidence_iterator next = first;
Chris@16 513 first != last; first = next) {
Chris@16 514 ++next;
Chris@16 515 if (pred(*first)) {
Chris@16 516 if (source(*first, g) != target(*first, g)) {
Chris@16 517 // Remove the edge from the target
Chris@16 518 detail::remove_directed_edge_dispatch
Chris@16 519 (*first,
Chris@16 520 g.out_edge_list(target(*first, g)),
Chris@16 521 *(PropT*)(*first).get_property());
Chris@16 522 }
Chris@16 523
Chris@16 524 // Erase the edge property
Chris@16 525 g.m_edges.erase( (*first.base()).get_iter() );
Chris@16 526
Chris@16 527 // Erase the edge in the source
Chris@16 528 el.erase( first.base() );
Chris@16 529 }
Chris@16 530 }
Chris@16 531 }
Chris@16 532
Chris@16 533 // O(E/V)
Chris@16 534 template <class edge_descriptor, class EdgeList, class StoredProperty>
Chris@16 535 inline void
Chris@16 536 remove_directed_edge_dispatch(edge_descriptor e, EdgeList& el,
Chris@16 537 no_property&)
Chris@16 538 {
Chris@16 539 for (typename EdgeList::iterator i = el.begin();
Chris@16 540 i != el.end(); ++i)
Chris@16 541 if ((*i).get_target() == e.m_target) {
Chris@16 542 el.erase(i);
Chris@16 543 return;
Chris@16 544 }
Chris@16 545 }
Chris@16 546
Chris@16 547 } // namespace detail
Chris@16 548
Chris@16 549 template <class Config>
Chris@16 550 struct directed_edges_helper {
Chris@16 551
Chris@16 552 // Placement of these overloaded remove_edge() functions
Chris@16 553 // inside the class avoids a VC++ bug.
Chris@16 554
Chris@16 555 // O(E/V)
Chris@16 556 inline void
Chris@16 557 remove_edge(typename Config::edge_descriptor e)
Chris@16 558 {
Chris@16 559 typedef typename Config::graph_type graph_type;
Chris@16 560 graph_type& g = static_cast<graph_type&>(*this);
Chris@16 561 typename Config::OutEdgeList& el = g.out_edge_list(source(e, g));
Chris@16 562 typedef typename Config::OutEdgeList::value_type::property_type PType;
Chris@16 563 detail::remove_directed_edge_dispatch(e, el,
Chris@16 564 *(PType*)e.get_property());
Chris@16 565 }
Chris@16 566
Chris@16 567 // O(1)
Chris@16 568 inline void
Chris@16 569 remove_edge(typename Config::out_edge_iterator iter)
Chris@16 570 {
Chris@16 571 typedef typename Config::graph_type graph_type;
Chris@16 572 graph_type& g = static_cast<graph_type&>(*this);
Chris@16 573 typename Config::edge_descriptor e = *iter;
Chris@16 574 typename Config::OutEdgeList& el = g.out_edge_list(source(e, g));
Chris@16 575 el.erase(iter.base());
Chris@16 576 }
Chris@16 577
Chris@16 578 };
Chris@16 579
Chris@16 580 // O(1)
Chris@16 581 template <class Config>
Chris@16 582 inline std::pair<typename Config::edge_iterator,
Chris@16 583 typename Config::edge_iterator>
Chris@16 584 edges(const directed_edges_helper<Config>& g_)
Chris@16 585 {
Chris@16 586 typedef typename Config::graph_type graph_type;
Chris@16 587 typedef typename Config::edge_iterator edge_iterator;
Chris@16 588 const graph_type& cg = static_cast<const graph_type&>(g_);
Chris@16 589 graph_type& g = const_cast<graph_type&>(cg);
Chris@16 590 return std::make_pair( edge_iterator(g.vertex_set().begin(),
Chris@16 591 g.vertex_set().begin(),
Chris@16 592 g.vertex_set().end(), g),
Chris@16 593 edge_iterator(g.vertex_set().begin(),
Chris@16 594 g.vertex_set().end(),
Chris@16 595 g.vertex_set().end(), g) );
Chris@16 596 }
Chris@16 597
Chris@16 598 //=========================================================================
Chris@16 599 // Directed Graph Helper Class
Chris@16 600
Chris@16 601 struct adj_list_dir_traversal_tag :
Chris@16 602 public virtual vertex_list_graph_tag,
Chris@16 603 public virtual incidence_graph_tag,
Chris@16 604 public virtual adjacency_graph_tag,
Chris@16 605 public virtual edge_list_graph_tag { };
Chris@16 606
Chris@16 607 template <class Config>
Chris@16 608 struct directed_graph_helper
Chris@16 609 : public directed_edges_helper<Config> {
Chris@16 610 typedef typename Config::edge_descriptor edge_descriptor;
Chris@16 611 typedef adj_list_dir_traversal_tag traversal_category;
Chris@16 612 };
Chris@16 613
Chris@16 614 // O(E/V)
Chris@16 615 template <class Config>
Chris@16 616 inline void
Chris@16 617 remove_edge(typename Config::vertex_descriptor u,
Chris@16 618 typename Config::vertex_descriptor v,
Chris@16 619 directed_graph_helper<Config>& g_)
Chris@16 620 {
Chris@16 621 typedef typename Config::graph_type graph_type;
Chris@16 622 typedef typename Config::edge_parallel_category Cat;
Chris@16 623 graph_type& g = static_cast<graph_type&>(g_);
Chris@16 624 detail::erase_from_incidence_list(g.out_edge_list(u), v, Cat());
Chris@16 625 }
Chris@16 626
Chris@16 627 template <class Config, class Predicate>
Chris@16 628 inline void
Chris@16 629 remove_out_edge_if(typename Config::vertex_descriptor u, Predicate pred,
Chris@16 630 directed_graph_helper<Config>& g_)
Chris@16 631 {
Chris@16 632 typedef typename Config::graph_type graph_type;
Chris@16 633 graph_type& g = static_cast<graph_type&>(g_);
Chris@16 634 typename Config::out_edge_iterator first, last;
Chris@16 635 boost::tie(first, last) = out_edges(u, g);
Chris@16 636 typedef typename Config::edge_parallel_category edge_parallel_category;
Chris@16 637 detail::remove_directed_edge_if_dispatch
Chris@16 638 (first, last, g.out_edge_list(u), pred, edge_parallel_category());
Chris@16 639 }
Chris@16 640
Chris@16 641 template <class Config, class Predicate>
Chris@16 642 inline void
Chris@16 643 remove_edge_if(Predicate pred, directed_graph_helper<Config>& g_)
Chris@16 644 {
Chris@16 645 typedef typename Config::graph_type graph_type;
Chris@16 646 graph_type& g = static_cast<graph_type&>(g_);
Chris@16 647
Chris@16 648 typename Config::vertex_iterator vi, vi_end;
Chris@16 649 for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
Chris@16 650 remove_out_edge_if(*vi, pred, g);
Chris@16 651 }
Chris@16 652
Chris@16 653 template <class EdgeOrIter, class Config>
Chris@16 654 inline void
Chris@16 655 remove_edge(EdgeOrIter e_or_iter, directed_graph_helper<Config>& g_)
Chris@16 656 {
Chris@16 657 g_.remove_edge(e_or_iter);
Chris@16 658 }
Chris@16 659
Chris@16 660 // O(V + E) for allow_parallel_edges
Chris@16 661 // O(V * log(E/V)) for disallow_parallel_edges
Chris@16 662 template <class Config>
Chris@16 663 inline void
Chris@16 664 clear_vertex(typename Config::vertex_descriptor u,
Chris@16 665 directed_graph_helper<Config>& g_)
Chris@16 666 {
Chris@16 667 typedef typename Config::graph_type graph_type;
Chris@16 668 typedef typename Config::edge_parallel_category Cat;
Chris@16 669 graph_type& g = static_cast<graph_type&>(g_);
Chris@16 670 typename Config::vertex_iterator vi, viend;
Chris@16 671 for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi)
Chris@16 672 detail::erase_from_incidence_list(g.out_edge_list(*vi), u, Cat());
Chris@16 673 g.out_edge_list(u).clear();
Chris@16 674 // clear() should be a req of Sequence and AssociativeContainer,
Chris@16 675 // or maybe just Container
Chris@16 676 }
Chris@16 677
Chris@16 678 template <class Config>
Chris@16 679 inline void
Chris@16 680 clear_out_edges(typename Config::vertex_descriptor u,
Chris@16 681 directed_graph_helper<Config>& g_)
Chris@16 682 {
Chris@16 683 typedef typename Config::graph_type graph_type;
Chris@16 684 graph_type& g = static_cast<graph_type&>(g_);
Chris@16 685 g.out_edge_list(u).clear();
Chris@16 686 // clear() should be a req of Sequence and AssociativeContainer,
Chris@16 687 // or maybe just Container
Chris@16 688 }
Chris@16 689
Chris@16 690 // O(V), could do better...
Chris@16 691 template <class Config>
Chris@16 692 inline typename Config::edges_size_type
Chris@16 693 num_edges(const directed_graph_helper<Config>& g_)
Chris@16 694 {
Chris@16 695 typedef typename Config::graph_type graph_type;
Chris@16 696 const graph_type& g = static_cast<const graph_type&>(g_);
Chris@16 697 typename Config::edges_size_type num_e = 0;
Chris@16 698 typename Config::vertex_iterator vi, vi_end;
Chris@16 699 for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
Chris@16 700 num_e += out_degree(*vi, g);
Chris@16 701 return num_e;
Chris@16 702 }
Chris@16 703 // O(1) for allow_parallel_edge_tag
Chris@16 704 // O(log(E/V)) for disallow_parallel_edge_tag
Chris@16 705 template <class Config>
Chris@16 706 inline std::pair<typename directed_graph_helper<Config>::edge_descriptor, bool>
Chris@16 707 add_edge(typename Config::vertex_descriptor u,
Chris@16 708 typename Config::vertex_descriptor v,
Chris@16 709 const typename Config::edge_property_type& p,
Chris@16 710 directed_graph_helper<Config>& g_)
Chris@16 711 {
Chris@16 712 typedef typename Config::edge_descriptor edge_descriptor;
Chris@16 713 typedef typename Config::graph_type graph_type;
Chris@16 714 typedef typename Config::StoredEdge StoredEdge;
Chris@16 715 graph_type& g = static_cast<graph_type&>(g_);
Chris@16 716 typename Config::OutEdgeList::iterator i;
Chris@16 717 bool inserted;
Chris@16 718 boost::tie(i, inserted) = boost::graph_detail::push(g.out_edge_list(u),
Chris@16 719 StoredEdge(v, p));
Chris@16 720 return std::make_pair(edge_descriptor(u, v, &(*i).get_property()),
Chris@16 721 inserted);
Chris@16 722 }
Chris@16 723 // Did not use default argument here because that
Chris@16 724 // causes Visual C++ to get confused.
Chris@16 725 template <class Config>
Chris@16 726 inline std::pair<typename Config::edge_descriptor, bool>
Chris@16 727 add_edge(typename Config::vertex_descriptor u,
Chris@16 728 typename Config::vertex_descriptor v,
Chris@16 729 directed_graph_helper<Config>& g_)
Chris@16 730 {
Chris@16 731 typename Config::edge_property_type p;
Chris@16 732 return add_edge(u, v, p, g_);
Chris@16 733 }
Chris@16 734 //=========================================================================
Chris@16 735 // Undirected Graph Helper Class
Chris@16 736
Chris@16 737 template <class Config>
Chris@16 738 struct undirected_graph_helper;
Chris@16 739
Chris@16 740 struct undir_adj_list_traversal_tag :
Chris@16 741 public virtual vertex_list_graph_tag,
Chris@16 742 public virtual incidence_graph_tag,
Chris@16 743 public virtual adjacency_graph_tag,
Chris@16 744 public virtual edge_list_graph_tag,
Chris@16 745 public virtual bidirectional_graph_tag { };
Chris@16 746
Chris@16 747 namespace detail {
Chris@16 748
Chris@16 749 // using class with specialization for dispatch is a VC++ workaround.
Chris@16 750 template <class StoredProperty>
Chris@16 751 struct remove_undirected_edge_dispatch {
Chris@16 752
Chris@16 753 // O(E/V)
Chris@16 754 template <class edge_descriptor, class Config>
Chris@16 755 static void
Chris@16 756 apply(edge_descriptor e,
Chris@16 757 undirected_graph_helper<Config>& g_,
Chris@16 758 StoredProperty& p)
Chris@16 759 {
Chris@16 760 typedef typename Config::global_edgelist_selector EdgeListS;
Chris@16 761 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 762
Chris@16 763 typedef typename Config::graph_type graph_type;
Chris@16 764 graph_type& g = static_cast<graph_type&>(g_);
Chris@16 765
Chris@16 766 typename Config::OutEdgeList& out_el = g.out_edge_list(source(e, g));
Chris@16 767 typename Config::OutEdgeList::iterator out_i = out_el.begin();
Chris@16 768 typename Config::EdgeIter edge_iter_to_erase;
Chris@16 769 for (; out_i != out_el.end(); ++out_i)
Chris@16 770 if (&(*out_i).get_property() == &p) {
Chris@16 771 edge_iter_to_erase = (*out_i).get_iter();
Chris@16 772 out_el.erase(out_i);
Chris@16 773 break;
Chris@16 774 }
Chris@16 775 typename Config::OutEdgeList& in_el = g.out_edge_list(target(e, g));
Chris@16 776 typename Config::OutEdgeList::iterator in_i = in_el.begin();
Chris@16 777 for (; in_i != in_el.end(); ++in_i)
Chris@16 778 if (&(*in_i).get_property() == &p) {
Chris@16 779 in_el.erase(in_i);
Chris@16 780 break;
Chris@16 781 }
Chris@16 782 g.m_edges.erase(edge_iter_to_erase);
Chris@16 783 }
Chris@16 784 };
Chris@16 785
Chris@16 786 template <>
Chris@16 787 struct remove_undirected_edge_dispatch<no_property> {
Chris@16 788 // O(E/V)
Chris@16 789 template <class edge_descriptor, class Config>
Chris@16 790 static void
Chris@16 791 apply(edge_descriptor e,
Chris@16 792 undirected_graph_helper<Config>& g_,
Chris@16 793 no_property&)
Chris@16 794 {
Chris@16 795 typedef typename Config::global_edgelist_selector EdgeListS;
Chris@16 796 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 797
Chris@16 798 typedef typename Config::graph_type graph_type;
Chris@16 799 graph_type& g = static_cast<graph_type&>(g_);
Chris@16 800 no_property* p = (no_property*)e.get_property();
Chris@16 801 typename Config::OutEdgeList& out_el = g.out_edge_list(source(e, g));
Chris@16 802 typename Config::OutEdgeList::iterator out_i = out_el.begin();
Chris@16 803 typename Config::EdgeIter edge_iter_to_erase;
Chris@16 804 for (; out_i != out_el.end(); ++out_i)
Chris@16 805 if (&(*out_i).get_property() == p) {
Chris@16 806 edge_iter_to_erase = (*out_i).get_iter();
Chris@16 807 out_el.erase(out_i);
Chris@16 808 break;
Chris@16 809 }
Chris@16 810 typename Config::OutEdgeList& in_el = g.out_edge_list(target(e, g));
Chris@16 811 typename Config::OutEdgeList::iterator in_i = in_el.begin();
Chris@16 812 for (; in_i != in_el.end(); ++in_i)
Chris@16 813 if (&(*in_i).get_property() == p) {
Chris@16 814 in_el.erase(in_i);
Chris@16 815 break;
Chris@16 816 }
Chris@16 817 g.m_edges.erase(edge_iter_to_erase);
Chris@16 818 }
Chris@16 819 };
Chris@16 820
Chris@16 821 // O(E/V)
Chris@16 822 template <class Graph, class EdgeList, class Vertex>
Chris@16 823 inline void
Chris@16 824 remove_edge_and_property(Graph& g, EdgeList& el, Vertex v,
Chris@16 825 boost::allow_parallel_edge_tag cat)
Chris@16 826 {
Chris@16 827 typedef typename Graph::global_edgelist_selector EdgeListS;
Chris@16 828 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 829
Chris@16 830 typename EdgeList::iterator i = el.begin(), end = el.end();
Chris@16 831 for (; i != end; ++i) {
Chris@16 832 if ((*i).get_target() == v) {
Chris@16 833 // NOTE: Wihtout this skip, this loop will double-delete properties
Chris@16 834 // of loop edges. This solution is based on the observation that
Chris@16 835 // the incidence edges of a vertex with a loop are adjacent in the
Chris@16 836 // out edge list. This *may* actually hold for multisets also.
Chris@16 837 bool skip = (boost::next(i) != end && i->get_iter() == boost::next(i)->get_iter());
Chris@16 838 g.m_edges.erase((*i).get_iter());
Chris@16 839 if (skip) ++i;
Chris@16 840 }
Chris@16 841 }
Chris@16 842 detail::erase_from_incidence_list(el, v, cat);
Chris@16 843 }
Chris@16 844 // O(log(E/V))
Chris@16 845 template <class Graph, class EdgeList, class Vertex>
Chris@16 846 inline void
Chris@16 847 remove_edge_and_property(Graph& g, EdgeList& el, Vertex v,
Chris@16 848 boost::disallow_parallel_edge_tag)
Chris@16 849 {
Chris@16 850 typedef typename Graph::global_edgelist_selector EdgeListS;
Chris@16 851 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 852
Chris@16 853 typedef typename EdgeList::value_type StoredEdge;
Chris@16 854 typename EdgeList::iterator i = el.find(StoredEdge(v)), end = el.end();
Chris@16 855 if (i != end) {
Chris@16 856 g.m_edges.erase((*i).get_iter());
Chris@16 857 el.erase(i);
Chris@16 858 }
Chris@16 859 }
Chris@16 860
Chris@16 861 } // namespace detail
Chris@16 862
Chris@16 863 template <class Vertex, class EdgeProperty>
Chris@16 864 struct list_edge // short name due to VC++ truncation and linker problems
Chris@16 865 : public boost::detail::edge_base<boost::undirected_tag, Vertex>
Chris@16 866 {
Chris@16 867 typedef EdgeProperty property_type;
Chris@16 868 typedef boost::detail::edge_base<boost::undirected_tag, Vertex> Base;
Chris@16 869 list_edge(Vertex u, Vertex v, const EdgeProperty& p = EdgeProperty())
Chris@16 870 : Base(u, v), m_property(p) { }
Chris@16 871 EdgeProperty& get_property() { return m_property; }
Chris@16 872 const EdgeProperty& get_property() const { return m_property; }
Chris@16 873 // the following methods should never be used, but are needed
Chris@16 874 // to make SGI MIPSpro C++ happy
Chris@16 875 list_edge() { }
Chris@16 876 bool operator==(const list_edge&) const { return false; }
Chris@16 877 bool operator<(const list_edge&) const { return false; }
Chris@16 878 EdgeProperty m_property;
Chris@16 879 };
Chris@16 880
Chris@16 881 template <class Config>
Chris@16 882 struct undirected_graph_helper {
Chris@16 883
Chris@16 884 typedef undir_adj_list_traversal_tag traversal_category;
Chris@16 885
Chris@16 886 // Placement of these overloaded remove_edge() functions
Chris@16 887 // inside the class avoids a VC++ bug.
Chris@16 888
Chris@16 889 // O(E/V)
Chris@16 890 inline void
Chris@16 891 remove_edge(typename Config::edge_descriptor e)
Chris@16 892 {
Chris@16 893 typedef typename Config::global_edgelist_selector EdgeListS;
Chris@16 894 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 895
Chris@16 896 typedef typename Config::OutEdgeList::value_type::property_type PType;
Chris@16 897 detail::remove_undirected_edge_dispatch<PType>::apply
Chris@16 898 (e, *this, *(PType*)e.get_property());
Chris@16 899 }
Chris@16 900 // O(E/V)
Chris@16 901 inline void
Chris@16 902 remove_edge(typename Config::out_edge_iterator iter)
Chris@16 903 {
Chris@16 904 this->remove_edge(*iter);
Chris@16 905 }
Chris@16 906 };
Chris@16 907
Chris@16 908 // Had to make these non-members to avoid accidental instantiation
Chris@16 909 // on SGI MIPSpro C++
Chris@16 910 template <class C>
Chris@16 911 inline typename C::InEdgeList&
Chris@16 912 in_edge_list(undirected_graph_helper<C>&,
Chris@16 913 typename C::vertex_descriptor v)
Chris@16 914 {
Chris@16 915 typename C::stored_vertex* sv = (typename C::stored_vertex*)v;
Chris@16 916 return sv->m_out_edges;
Chris@16 917 }
Chris@16 918 template <class C>
Chris@16 919 inline const typename C::InEdgeList&
Chris@16 920 in_edge_list(const undirected_graph_helper<C>&,
Chris@16 921 typename C::vertex_descriptor v) {
Chris@16 922 typename C::stored_vertex* sv = (typename C::stored_vertex*)v;
Chris@16 923 return sv->m_out_edges;
Chris@16 924 }
Chris@16 925
Chris@16 926 // O(E/V)
Chris@16 927 template <class EdgeOrIter, class Config>
Chris@16 928 inline void
Chris@16 929 remove_edge(EdgeOrIter e, undirected_graph_helper<Config>& g_)
Chris@16 930 {
Chris@16 931 typedef typename Config::global_edgelist_selector EdgeListS;
Chris@16 932 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 933
Chris@16 934 g_.remove_edge(e);
Chris@16 935 }
Chris@16 936
Chris@16 937 // O(E/V) or O(log(E/V))
Chris@16 938 template <class Config>
Chris@16 939 void
Chris@16 940 remove_edge(typename Config::vertex_descriptor u,
Chris@16 941 typename Config::vertex_descriptor v,
Chris@16 942 undirected_graph_helper<Config>& g_)
Chris@16 943 {
Chris@16 944 typedef typename Config::global_edgelist_selector EdgeListS;
Chris@16 945 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 946
Chris@16 947 typedef typename Config::graph_type graph_type;
Chris@16 948 graph_type& g = static_cast<graph_type&>(g_);
Chris@16 949 typedef typename Config::edge_parallel_category Cat;
Chris@16 950 detail::remove_edge_and_property(g, g.out_edge_list(u), v, Cat());
Chris@16 951 detail::erase_from_incidence_list(g.out_edge_list(v), u, Cat());
Chris@16 952 }
Chris@16 953
Chris@16 954 template <class Config, class Predicate>
Chris@16 955 void
Chris@16 956 remove_out_edge_if(typename Config::vertex_descriptor u, Predicate pred,
Chris@16 957 undirected_graph_helper<Config>& g_)
Chris@16 958 {
Chris@16 959 typedef typename Config::global_edgelist_selector EdgeListS;
Chris@16 960 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 961
Chris@16 962 typedef typename Config::graph_type graph_type;
Chris@16 963 typedef typename Config::OutEdgeList::value_type::property_type PropT;
Chris@16 964 graph_type& g = static_cast<graph_type&>(g_);
Chris@16 965 typename Config::out_edge_iterator first, last;
Chris@16 966 boost::tie(first, last) = out_edges(u, g);
Chris@16 967 typedef typename Config::edge_parallel_category Cat;
Chris@16 968 detail::undirected_remove_out_edge_if_dispatch<PropT>
Chris@16 969 (g, first, last, g.out_edge_list(u), pred, Cat());
Chris@16 970 }
Chris@16 971 template <class Config, class Predicate>
Chris@16 972 void
Chris@16 973 remove_in_edge_if(typename Config::vertex_descriptor u, Predicate pred,
Chris@16 974 undirected_graph_helper<Config>& g_)
Chris@16 975 {
Chris@16 976 typedef typename Config::global_edgelist_selector EdgeListS;
Chris@16 977 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 978
Chris@16 979 remove_out_edge_if(u, pred, g_);
Chris@16 980 }
Chris@16 981
Chris@16 982 // O(E/V * E) or O(log(E/V) * E)
Chris@16 983 template <class Predicate, class Config>
Chris@16 984 void
Chris@16 985 remove_edge_if(Predicate pred, undirected_graph_helper<Config>& g_)
Chris@16 986 {
Chris@16 987 typedef typename Config::global_edgelist_selector EdgeListS;
Chris@16 988 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 989
Chris@16 990 typedef typename Config::graph_type graph_type;
Chris@16 991 graph_type& g = static_cast<graph_type&>(g_);
Chris@16 992 typename Config::edge_iterator ei, ei_end, next;
Chris@16 993 boost::tie(ei, ei_end) = edges(g);
Chris@16 994 for (next = ei; ei != ei_end; ei = next) {
Chris@16 995 ++next;
Chris@16 996 if (pred(*ei))
Chris@16 997 remove_edge(*ei, g);
Chris@16 998 }
Chris@16 999 }
Chris@16 1000
Chris@16 1001 // O(1)
Chris@16 1002 template <class Config>
Chris@16 1003 inline std::pair<typename Config::edge_iterator,
Chris@16 1004 typename Config::edge_iterator>
Chris@16 1005 edges(const undirected_graph_helper<Config>& g_)
Chris@16 1006 {
Chris@16 1007 typedef typename Config::graph_type graph_type;
Chris@16 1008 typedef typename Config::edge_iterator edge_iterator;
Chris@16 1009 const graph_type& cg = static_cast<const graph_type&>(g_);
Chris@16 1010 graph_type& g = const_cast<graph_type&>(cg);
Chris@16 1011 return std::make_pair( edge_iterator(g.m_edges.begin()),
Chris@16 1012 edge_iterator(g.m_edges.end()) );
Chris@16 1013 }
Chris@16 1014 // O(1)
Chris@16 1015 template <class Config>
Chris@16 1016 inline typename Config::edges_size_type
Chris@16 1017 num_edges(const undirected_graph_helper<Config>& g_)
Chris@16 1018 {
Chris@16 1019 typedef typename Config::graph_type graph_type;
Chris@16 1020 const graph_type& g = static_cast<const graph_type&>(g_);
Chris@16 1021 return g.m_edges.size();
Chris@16 1022 }
Chris@16 1023 // O(E/V * E/V)
Chris@16 1024 template <class Config>
Chris@16 1025 inline void
Chris@16 1026 clear_vertex(typename Config::vertex_descriptor u,
Chris@16 1027 undirected_graph_helper<Config>& g_)
Chris@16 1028 {
Chris@16 1029 typedef typename Config::global_edgelist_selector EdgeListS;
Chris@16 1030 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 1031
Chris@16 1032 typedef typename Config::graph_type graph_type;
Chris@16 1033 graph_type& g = static_cast<graph_type&>(g_);
Chris@16 1034 while (true) {
Chris@16 1035 typename Config::out_edge_iterator ei, ei_end;
Chris@16 1036 boost::tie(ei, ei_end) = out_edges(u, g);
Chris@16 1037 if (ei == ei_end) break;
Chris@16 1038 remove_edge(*ei, g);
Chris@16 1039 }
Chris@16 1040 }
Chris@16 1041 // O(1) for allow_parallel_edge_tag
Chris@16 1042 // O(log(E/V)) for disallow_parallel_edge_tag
Chris@16 1043 template <class Config>
Chris@16 1044 inline std::pair<typename Config::edge_descriptor, bool>
Chris@16 1045 add_edge(typename Config::vertex_descriptor u,
Chris@16 1046 typename Config::vertex_descriptor v,
Chris@16 1047 const typename Config::edge_property_type& p,
Chris@16 1048 undirected_graph_helper<Config>& g_)
Chris@16 1049 {
Chris@16 1050 typedef typename Config::StoredEdge StoredEdge;
Chris@16 1051 typedef typename Config::edge_descriptor edge_descriptor;
Chris@16 1052 typedef typename Config::graph_type graph_type;
Chris@16 1053 graph_type& g = static_cast<graph_type&>(g_);
Chris@16 1054
Chris@16 1055 bool inserted;
Chris@16 1056 typename Config::EdgeContainer::value_type e(u, v, p);
Chris@16 1057 typename Config::EdgeContainer::iterator p_iter
Chris@16 1058 = graph_detail::push(g.m_edges, e).first;
Chris@16 1059
Chris@16 1060 typename Config::OutEdgeList::iterator i;
Chris@16 1061 boost::tie(i, inserted) = boost::graph_detail::push(g.out_edge_list(u),
Chris@16 1062 StoredEdge(v, p_iter, &g.m_edges));
Chris@16 1063 if (inserted) {
Chris@16 1064 boost::graph_detail::push(g.out_edge_list(v), StoredEdge(u, p_iter, &g.m_edges));
Chris@16 1065 return std::make_pair(edge_descriptor(u, v, &p_iter->get_property()),
Chris@16 1066 true);
Chris@16 1067 } else {
Chris@16 1068 g.m_edges.erase(p_iter);
Chris@16 1069 return std::make_pair
Chris@16 1070 (edge_descriptor(u, v, &i->get_iter()->get_property()), false);
Chris@16 1071 }
Chris@16 1072 }
Chris@16 1073 template <class Config>
Chris@16 1074 inline std::pair<typename Config::edge_descriptor, bool>
Chris@16 1075 add_edge(typename Config::vertex_descriptor u,
Chris@16 1076 typename Config::vertex_descriptor v,
Chris@16 1077 undirected_graph_helper<Config>& g_)
Chris@16 1078 {
Chris@16 1079 typename Config::edge_property_type p;
Chris@16 1080 return add_edge(u, v, p, g_);
Chris@16 1081 }
Chris@16 1082
Chris@16 1083 // O(1)
Chris@16 1084 template <class Config>
Chris@16 1085 inline typename Config::degree_size_type
Chris@16 1086 degree(typename Config::vertex_descriptor u,
Chris@16 1087 const undirected_graph_helper<Config>& g_)
Chris@16 1088 {
Chris@16 1089 typedef typename Config::graph_type Graph;
Chris@16 1090 const Graph& g = static_cast<const Graph&>(g_);
Chris@16 1091 return out_degree(u, g);
Chris@16 1092 }
Chris@16 1093
Chris@16 1094 template <class Config>
Chris@16 1095 inline std::pair<typename Config::in_edge_iterator,
Chris@16 1096 typename Config::in_edge_iterator>
Chris@16 1097 in_edges(typename Config::vertex_descriptor u,
Chris@16 1098 const undirected_graph_helper<Config>& g_)
Chris@16 1099 {
Chris@16 1100 typedef typename Config::graph_type Graph;
Chris@16 1101 const Graph& cg = static_cast<const Graph&>(g_);
Chris@16 1102 Graph& g = const_cast<Graph&>(cg);
Chris@16 1103 typedef typename Config::in_edge_iterator in_edge_iterator;
Chris@16 1104 return
Chris@16 1105 std::make_pair(in_edge_iterator(g.out_edge_list(u).begin(), u),
Chris@16 1106 in_edge_iterator(g.out_edge_list(u).end(), u));
Chris@16 1107 }
Chris@16 1108
Chris@16 1109 template <class Config>
Chris@16 1110 inline typename Config::degree_size_type
Chris@16 1111 in_degree(typename Config::vertex_descriptor u,
Chris@16 1112 const undirected_graph_helper<Config>& g_)
Chris@16 1113 { return degree(u, g_); }
Chris@16 1114
Chris@16 1115 //=========================================================================
Chris@16 1116 // Bidirectional Graph Helper Class
Chris@16 1117
Chris@16 1118 struct bidir_adj_list_traversal_tag :
Chris@16 1119 public virtual vertex_list_graph_tag,
Chris@16 1120 public virtual incidence_graph_tag,
Chris@16 1121 public virtual adjacency_graph_tag,
Chris@16 1122 public virtual edge_list_graph_tag,
Chris@16 1123 public virtual bidirectional_graph_tag { };
Chris@16 1124
Chris@16 1125 template <class Config>
Chris@16 1126 struct bidirectional_graph_helper
Chris@16 1127 : public directed_edges_helper<Config> {
Chris@16 1128 typedef bidir_adj_list_traversal_tag traversal_category;
Chris@16 1129 };
Chris@16 1130
Chris@16 1131 // Had to make these non-members to avoid accidental instantiation
Chris@16 1132 // on SGI MIPSpro C++
Chris@16 1133 template <class C>
Chris@16 1134 inline typename C::InEdgeList&
Chris@16 1135 in_edge_list(bidirectional_graph_helper<C>&,
Chris@16 1136 typename C::vertex_descriptor v)
Chris@16 1137 {
Chris@16 1138 typename C::stored_vertex* sv = (typename C::stored_vertex*)v;
Chris@16 1139 return sv->m_in_edges;
Chris@16 1140 }
Chris@16 1141 template <class C>
Chris@16 1142 inline const typename C::InEdgeList&
Chris@16 1143 in_edge_list(const bidirectional_graph_helper<C>&,
Chris@16 1144 typename C::vertex_descriptor v) {
Chris@16 1145 typename C::stored_vertex* sv = (typename C::stored_vertex*)v;
Chris@16 1146 return sv->m_in_edges;
Chris@16 1147 }
Chris@16 1148
Chris@16 1149 template <class Predicate, class Config>
Chris@16 1150 inline void
Chris@16 1151 remove_edge_if(Predicate pred, bidirectional_graph_helper<Config>& g_)
Chris@16 1152 {
Chris@16 1153 typedef typename Config::global_edgelist_selector EdgeListS;
Chris@16 1154 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 1155
Chris@16 1156 typedef typename Config::graph_type graph_type;
Chris@16 1157 graph_type& g = static_cast<graph_type&>(g_);
Chris@16 1158 typename Config::edge_iterator ei, ei_end, next;
Chris@16 1159 boost::tie(ei, ei_end) = edges(g);
Chris@16 1160 for (next = ei; ei != ei_end; ei = next) {
Chris@16 1161 ++next;
Chris@16 1162 if (pred(*ei))
Chris@16 1163 remove_edge(*ei, g);
Chris@16 1164 }
Chris@16 1165 }
Chris@16 1166
Chris@16 1167 template <class Config>
Chris@16 1168 inline std::pair<typename Config::in_edge_iterator,
Chris@16 1169 typename Config::in_edge_iterator>
Chris@16 1170 in_edges(typename Config::vertex_descriptor u,
Chris@16 1171 const bidirectional_graph_helper<Config>& g_)
Chris@16 1172 {
Chris@16 1173 typedef typename Config::graph_type graph_type;
Chris@16 1174 const graph_type& cg = static_cast<const graph_type&>(g_);
Chris@16 1175 graph_type& g = const_cast<graph_type&>(cg);
Chris@16 1176 typedef typename Config::in_edge_iterator in_edge_iterator;
Chris@16 1177 return
Chris@16 1178 std::make_pair(in_edge_iterator(in_edge_list(g, u).begin(), u),
Chris@16 1179 in_edge_iterator(in_edge_list(g, u).end(), u));
Chris@16 1180 }
Chris@16 1181
Chris@16 1182 // O(1)
Chris@16 1183 template <class Config>
Chris@16 1184 inline std::pair<typename Config::edge_iterator,
Chris@16 1185 typename Config::edge_iterator>
Chris@16 1186 edges(const bidirectional_graph_helper<Config>& g_)
Chris@16 1187 {
Chris@16 1188 typedef typename Config::graph_type graph_type;
Chris@16 1189 typedef typename Config::edge_iterator edge_iterator;
Chris@16 1190 const graph_type& cg = static_cast<const graph_type&>(g_);
Chris@16 1191 graph_type& g = const_cast<graph_type&>(cg);
Chris@16 1192 return std::make_pair( edge_iterator(g.m_edges.begin()),
Chris@16 1193 edge_iterator(g.m_edges.end()) );
Chris@16 1194 }
Chris@16 1195
Chris@16 1196 //=========================================================================
Chris@16 1197 // Bidirectional Graph Helper Class (with edge properties)
Chris@16 1198
Chris@16 1199
Chris@16 1200 template <class Config>
Chris@16 1201 struct bidirectional_graph_helper_with_property
Chris@16 1202 : public bidirectional_graph_helper<Config>
Chris@16 1203 {
Chris@16 1204 typedef typename Config::graph_type graph_type;
Chris@16 1205 typedef typename Config::out_edge_iterator out_edge_iterator;
Chris@16 1206
Chris@16 1207 std::pair<out_edge_iterator, out_edge_iterator>
Chris@16 1208 get_parallel_edge_sublist(typename Config::edge_descriptor e,
Chris@16 1209 const graph_type& g,
Chris@16 1210 void*)
Chris@16 1211 { return out_edges(source(e, g), g); }
Chris@16 1212
Chris@16 1213 std::pair<out_edge_iterator, out_edge_iterator>
Chris@16 1214 get_parallel_edge_sublist(typename Config::edge_descriptor e,
Chris@16 1215 const graph_type& g,
Chris@16 1216 setS*)
Chris@16 1217 { return edge_range(source(e, g), target(e, g), g); }
Chris@16 1218
Chris@16 1219 std::pair<out_edge_iterator, out_edge_iterator>
Chris@16 1220 get_parallel_edge_sublist(typename Config::edge_descriptor e,
Chris@16 1221 const graph_type& g,
Chris@16 1222 multisetS*)
Chris@16 1223 { return edge_range(source(e, g), target(e, g), g); }
Chris@16 1224
Chris@16 1225 std::pair<out_edge_iterator, out_edge_iterator>
Chris@16 1226 get_parallel_edge_sublist(typename Config::edge_descriptor e,
Chris@16 1227 const graph_type& g,
Chris@16 1228 hash_setS*)
Chris@16 1229 { return edge_range(source(e, g), target(e, g), g); }
Chris@16 1230
Chris@16 1231 // Placement of these overloaded remove_edge() functions
Chris@16 1232 // inside the class avoids a VC++ bug.
Chris@16 1233
Chris@16 1234 // O(E/V) or O(log(E/V))
Chris@16 1235 void
Chris@16 1236 remove_edge(typename Config::edge_descriptor e)
Chris@16 1237 {
Chris@16 1238 typedef typename Config::global_edgelist_selector EdgeListS;
Chris@16 1239 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 1240
Chris@16 1241 graph_type& g = static_cast<graph_type&>(*this);
Chris@16 1242
Chris@16 1243 typedef typename Config::edgelist_selector OutEdgeListS;
Chris@16 1244
Chris@16 1245 std::pair<out_edge_iterator, out_edge_iterator> rng =
Chris@16 1246 get_parallel_edge_sublist(e, g, (OutEdgeListS*)(0));
Chris@16 1247 rng.first = std::find(rng.first, rng.second, e);
Chris@16 1248 BOOST_ASSERT(rng.first != rng.second);
Chris@16 1249 remove_edge(rng.first);
Chris@16 1250 }
Chris@16 1251
Chris@16 1252 inline void
Chris@16 1253 remove_edge(typename Config::out_edge_iterator iter)
Chris@16 1254 {
Chris@16 1255 typedef typename Config::global_edgelist_selector EdgeListS;
Chris@16 1256 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 1257
Chris@16 1258 typedef typename Config::graph_type graph_type;
Chris@16 1259 graph_type& g = static_cast<graph_type&>(*this);
Chris@16 1260 typename Config::edge_descriptor e = *iter;
Chris@16 1261 typename Config::OutEdgeList& oel = g.out_edge_list(source(e, g));
Chris@16 1262 typename Config::InEdgeList& iel = in_edge_list(g, target(e, g));
Chris@16 1263 typedef typename Config::OutEdgeList::value_type::property_type PType;
Chris@16 1264 PType& p = *(PType*)e.get_property();
Chris@16 1265 detail::remove_directed_edge_dispatch(*iter, iel, p);
Chris@16 1266 g.m_edges.erase(iter.base()->get_iter());
Chris@16 1267 oel.erase(iter.base());
Chris@16 1268 }
Chris@16 1269 };
Chris@16 1270
Chris@16 1271 // O(E/V) for allow_parallel_edge_tag
Chris@16 1272 // O(log(E/V)) for disallow_parallel_edge_tag
Chris@16 1273 template <class Config>
Chris@16 1274 inline void
Chris@16 1275 remove_edge(typename Config::vertex_descriptor u,
Chris@16 1276 typename Config::vertex_descriptor v,
Chris@16 1277 bidirectional_graph_helper_with_property<Config>& g_)
Chris@16 1278 {
Chris@16 1279 typedef typename Config::global_edgelist_selector EdgeListS;
Chris@16 1280 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 1281
Chris@16 1282 typedef typename Config::graph_type graph_type;
Chris@16 1283 graph_type& g = static_cast<graph_type&>(g_);
Chris@16 1284 typedef typename Config::edge_parallel_category Cat;
Chris@16 1285 detail::remove_edge_and_property(g, g.out_edge_list(u), v, Cat());
Chris@16 1286 detail::erase_from_incidence_list(in_edge_list(g, v), u, Cat());
Chris@16 1287 }
Chris@16 1288
Chris@16 1289 // O(E/V) or O(log(E/V))
Chris@16 1290 template <class EdgeOrIter, class Config>
Chris@16 1291 inline void
Chris@16 1292 remove_edge(EdgeOrIter e,
Chris@16 1293 bidirectional_graph_helper_with_property<Config>& g_)
Chris@16 1294 {
Chris@16 1295 typedef typename Config::global_edgelist_selector EdgeListS;
Chris@16 1296 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 1297
Chris@16 1298 g_.remove_edge(e);
Chris@16 1299 }
Chris@16 1300
Chris@16 1301 template <class Config, class Predicate>
Chris@16 1302 inline void
Chris@16 1303 remove_out_edge_if(typename Config::vertex_descriptor u, Predicate pred,
Chris@16 1304 bidirectional_graph_helper_with_property<Config>& g_)
Chris@16 1305 {
Chris@16 1306 typedef typename Config::global_edgelist_selector EdgeListS;
Chris@16 1307 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 1308
Chris@16 1309 typedef typename Config::graph_type graph_type;
Chris@16 1310 typedef typename Config::OutEdgeList::value_type::property_type PropT;
Chris@16 1311 graph_type& g = static_cast<graph_type&>(g_);
Chris@16 1312
Chris@16 1313 typedef typename Config::EdgeIter EdgeIter;
Chris@16 1314 typedef std::vector<EdgeIter> Garbage;
Chris@16 1315 Garbage garbage;
Chris@16 1316
Chris@16 1317 // First remove the edges from the targets' in-edge lists and
Chris@16 1318 // from the graph's edge set list.
Chris@16 1319 typename Config::out_edge_iterator out_i, out_end;
Chris@16 1320 for (boost::tie(out_i, out_end) = out_edges(u, g); out_i != out_end; ++out_i)
Chris@16 1321 if (pred(*out_i)) {
Chris@16 1322 detail::remove_directed_edge_dispatch
Chris@16 1323 (*out_i, in_edge_list(g, target(*out_i, g)),
Chris@16 1324 *(PropT*)(*out_i).get_property());
Chris@16 1325 // Put in garbage to delete later. Will need the properties
Chris@16 1326 // for the remove_if of the out-edges.
Chris@16 1327 garbage.push_back((*out_i.base()).get_iter());
Chris@16 1328 }
Chris@16 1329
Chris@16 1330 // Now remove the edges from this out-edge list.
Chris@16 1331 typename Config::out_edge_iterator first, last;
Chris@16 1332 boost::tie(first, last) = out_edges(u, g);
Chris@16 1333 typedef typename Config::edge_parallel_category Cat;
Chris@16 1334 detail::remove_directed_edge_if_dispatch
Chris@16 1335 (first, last, g.out_edge_list(u), pred, Cat());
Chris@16 1336
Chris@16 1337 // Now delete the edge properties from the g.m_edges list
Chris@16 1338 for (typename Garbage::iterator i = garbage.begin();
Chris@16 1339 i != garbage.end(); ++i)
Chris@16 1340 g.m_edges.erase(*i);
Chris@16 1341 }
Chris@16 1342 template <class Config, class Predicate>
Chris@16 1343 inline void
Chris@16 1344 remove_in_edge_if(typename Config::vertex_descriptor v, Predicate pred,
Chris@16 1345 bidirectional_graph_helper_with_property<Config>& g_)
Chris@16 1346 {
Chris@16 1347 typedef typename Config::global_edgelist_selector EdgeListS;
Chris@16 1348 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 1349
Chris@16 1350 typedef typename Config::graph_type graph_type;
Chris@16 1351 typedef typename Config::OutEdgeList::value_type::property_type PropT;
Chris@16 1352 graph_type& g = static_cast<graph_type&>(g_);
Chris@16 1353
Chris@16 1354 typedef typename Config::EdgeIter EdgeIter;
Chris@16 1355 typedef std::vector<EdgeIter> Garbage;
Chris@16 1356 Garbage garbage;
Chris@16 1357
Chris@16 1358 // First remove the edges from the sources' out-edge lists and
Chris@16 1359 // from the graph's edge set list.
Chris@16 1360 typename Config::in_edge_iterator in_i, in_end;
Chris@16 1361 for (boost::tie(in_i, in_end) = in_edges(v, g); in_i != in_end; ++in_i)
Chris@16 1362 if (pred(*in_i)) {
Chris@16 1363 typename Config::vertex_descriptor u = source(*in_i, g);
Chris@16 1364 detail::remove_directed_edge_dispatch
Chris@16 1365 (*in_i, g.out_edge_list(u), *(PropT*)(*in_i).get_property());
Chris@16 1366 // Put in garbage to delete later. Will need the properties
Chris@16 1367 // for the remove_if of the out-edges.
Chris@16 1368 garbage.push_back((*in_i.base()).get_iter());
Chris@16 1369 }
Chris@16 1370 // Now remove the edges from this in-edge list.
Chris@16 1371 typename Config::in_edge_iterator first, last;
Chris@16 1372 boost::tie(first, last) = in_edges(v, g);
Chris@16 1373 typedef typename Config::edge_parallel_category Cat;
Chris@16 1374 detail::remove_directed_edge_if_dispatch
Chris@16 1375 (first, last, in_edge_list(g, v), pred, Cat());
Chris@16 1376
Chris@16 1377 // Now delete the edge properties from the g.m_edges list
Chris@16 1378 for (typename Garbage::iterator i = garbage.begin();
Chris@16 1379 i != garbage.end(); ++i)
Chris@16 1380 g.m_edges.erase(*i);
Chris@16 1381 }
Chris@16 1382
Chris@16 1383 // O(1)
Chris@16 1384 template <class Config>
Chris@16 1385 inline typename Config::edges_size_type
Chris@16 1386 num_edges(const bidirectional_graph_helper_with_property<Config>& g_)
Chris@16 1387 {
Chris@16 1388 typedef typename Config::graph_type graph_type;
Chris@16 1389 const graph_type& g = static_cast<const graph_type&>(g_);
Chris@16 1390 return g.m_edges.size();
Chris@16 1391 }
Chris@16 1392 // O(E/V * E/V) for allow_parallel_edge_tag
Chris@16 1393 // O(E/V * log(E/V)) for disallow_parallel_edge_tag
Chris@16 1394 template <class Config>
Chris@16 1395 inline void
Chris@16 1396 clear_vertex(typename Config::vertex_descriptor u,
Chris@16 1397 bidirectional_graph_helper_with_property<Config>& g_)
Chris@16 1398 {
Chris@16 1399 typedef typename Config::global_edgelist_selector EdgeListS;
Chris@16 1400 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 1401
Chris@16 1402 typedef typename Config::graph_type graph_type;
Chris@16 1403 typedef typename Config::edge_parallel_category Cat;
Chris@16 1404 graph_type& g = static_cast<graph_type&>(g_);
Chris@16 1405 typename Config::OutEdgeList& el = g.out_edge_list(u);
Chris@16 1406 typename Config::OutEdgeList::iterator
Chris@16 1407 ei = el.begin(), ei_end = el.end();
Chris@16 1408 for (; ei != ei_end; ++ei) {
Chris@16 1409 detail::erase_from_incidence_list
Chris@16 1410 (in_edge_list(g, (*ei).get_target()), u, Cat());
Chris@16 1411 g.m_edges.erase((*ei).get_iter());
Chris@16 1412 }
Chris@16 1413 typename Config::InEdgeList& in_el = in_edge_list(g, u);
Chris@16 1414 typename Config::InEdgeList::iterator
Chris@16 1415 in_ei = in_el.begin(), in_ei_end = in_el.end();
Chris@16 1416 for (; in_ei != in_ei_end; ++in_ei) {
Chris@16 1417 detail::erase_from_incidence_list
Chris@16 1418 (g.out_edge_list((*in_ei).get_target()), u, Cat());
Chris@16 1419 g.m_edges.erase((*in_ei).get_iter());
Chris@16 1420 }
Chris@16 1421 g.out_edge_list(u).clear();
Chris@16 1422 in_edge_list(g, u).clear();
Chris@16 1423 }
Chris@16 1424
Chris@16 1425 template <class Config>
Chris@16 1426 inline void
Chris@16 1427 clear_out_edges(typename Config::vertex_descriptor u,
Chris@16 1428 bidirectional_graph_helper_with_property<Config>& g_)
Chris@16 1429 {
Chris@16 1430 typedef typename Config::global_edgelist_selector EdgeListS;
Chris@16 1431 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 1432
Chris@16 1433 typedef typename Config::graph_type graph_type;
Chris@16 1434 typedef typename Config::edge_parallel_category Cat;
Chris@16 1435 graph_type& g = static_cast<graph_type&>(g_);
Chris@16 1436 typename Config::OutEdgeList& el = g.out_edge_list(u);
Chris@16 1437 typename Config::OutEdgeList::iterator
Chris@16 1438 ei = el.begin(), ei_end = el.end();
Chris@16 1439 for (; ei != ei_end; ++ei) {
Chris@16 1440 detail::erase_from_incidence_list
Chris@16 1441 (in_edge_list(g, (*ei).get_target()), u, Cat());
Chris@16 1442 g.m_edges.erase((*ei).get_iter());
Chris@16 1443 }
Chris@16 1444 g.out_edge_list(u).clear();
Chris@16 1445 }
Chris@16 1446
Chris@16 1447 template <class Config>
Chris@16 1448 inline void
Chris@16 1449 clear_in_edges(typename Config::vertex_descriptor u,
Chris@16 1450 bidirectional_graph_helper_with_property<Config>& g_)
Chris@16 1451 {
Chris@16 1452 typedef typename Config::global_edgelist_selector EdgeListS;
Chris@16 1453 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 1454
Chris@16 1455 typedef typename Config::graph_type graph_type;
Chris@16 1456 typedef typename Config::edge_parallel_category Cat;
Chris@16 1457 graph_type& g = static_cast<graph_type&>(g_);
Chris@16 1458 typename Config::InEdgeList& in_el = in_edge_list(g, u);
Chris@16 1459 typename Config::InEdgeList::iterator
Chris@16 1460 in_ei = in_el.begin(), in_ei_end = in_el.end();
Chris@16 1461 for (; in_ei != in_ei_end; ++in_ei) {
Chris@16 1462 detail::erase_from_incidence_list
Chris@16 1463 (g.out_edge_list((*in_ei).get_target()), u, Cat());
Chris@16 1464 g.m_edges.erase((*in_ei).get_iter());
Chris@16 1465 }
Chris@16 1466 in_edge_list(g, u).clear();
Chris@16 1467 }
Chris@16 1468
Chris@16 1469 // O(1) for allow_parallel_edge_tag
Chris@16 1470 // O(log(E/V)) for disallow_parallel_edge_tag
Chris@16 1471 template <class Config>
Chris@16 1472 inline std::pair<typename Config::edge_descriptor, bool>
Chris@16 1473 add_edge(typename Config::vertex_descriptor u,
Chris@16 1474 typename Config::vertex_descriptor v,
Chris@16 1475 const typename Config::edge_property_type& p,
Chris@16 1476 bidirectional_graph_helper_with_property<Config>& g_)
Chris@16 1477 {
Chris@16 1478 typedef typename Config::graph_type graph_type;
Chris@16 1479 graph_type& g = static_cast<graph_type&>(g_);
Chris@16 1480 typedef typename Config::edge_descriptor edge_descriptor;
Chris@16 1481 typedef typename Config::StoredEdge StoredEdge;
Chris@16 1482 bool inserted;
Chris@16 1483 typename Config::EdgeContainer::value_type e(u, v, p);
Chris@16 1484 typename Config::EdgeContainer::iterator p_iter
Chris@16 1485 = graph_detail::push(g.m_edges, e).first;
Chris@16 1486 typename Config::OutEdgeList::iterator i;
Chris@16 1487 boost::tie(i, inserted) = boost::graph_detail::push(g.out_edge_list(u),
Chris@16 1488 StoredEdge(v, p_iter, &g.m_edges));
Chris@16 1489 if (inserted) {
Chris@16 1490 boost::graph_detail::push(in_edge_list(g, v), StoredEdge(u, p_iter, &g.m_edges));
Chris@16 1491 return std::make_pair(edge_descriptor(u, v, &p_iter->m_property),
Chris@16 1492 true);
Chris@16 1493 } else {
Chris@16 1494 g.m_edges.erase(p_iter);
Chris@16 1495 return std::make_pair(edge_descriptor(u, v,
Chris@16 1496 &i->get_iter()->get_property()),
Chris@16 1497 false);
Chris@16 1498 }
Chris@16 1499 }
Chris@16 1500
Chris@16 1501 template <class Config>
Chris@16 1502 inline std::pair<typename Config::edge_descriptor, bool>
Chris@16 1503 add_edge(typename Config::vertex_descriptor u,
Chris@16 1504 typename Config::vertex_descriptor v,
Chris@16 1505 bidirectional_graph_helper_with_property<Config>& g_)
Chris@16 1506 {
Chris@16 1507 typename Config::edge_property_type p;
Chris@16 1508 return add_edge(u, v, p, g_);
Chris@16 1509 }
Chris@16 1510 // O(1)
Chris@16 1511 template <class Config>
Chris@16 1512 inline typename Config::degree_size_type
Chris@16 1513 degree(typename Config::vertex_descriptor u,
Chris@16 1514 const bidirectional_graph_helper_with_property<Config>& g_)
Chris@16 1515 {
Chris@16 1516 typedef typename Config::graph_type graph_type;
Chris@16 1517 const graph_type& g = static_cast<const graph_type&>(g_);
Chris@16 1518 return in_degree(u, g) + out_degree(u, g);
Chris@16 1519 }
Chris@16 1520
Chris@16 1521 //=========================================================================
Chris@16 1522 // Adjacency List Helper Class
Chris@16 1523
Chris@16 1524 template <class Config, class Base>
Chris@16 1525 struct adj_list_helper : public Base
Chris@16 1526 {
Chris@16 1527 typedef typename Config::graph_type AdjList;
Chris@16 1528 typedef typename Config::vertex_descriptor vertex_descriptor;
Chris@16 1529 typedef typename Config::edge_descriptor edge_descriptor;
Chris@16 1530 typedef typename Config::out_edge_iterator out_edge_iterator;
Chris@16 1531 typedef typename Config::in_edge_iterator in_edge_iterator;
Chris@16 1532 typedef typename Config::adjacency_iterator adjacency_iterator;
Chris@16 1533 typedef typename Config::inv_adjacency_iterator inv_adjacency_iterator;
Chris@16 1534 typedef typename Config::vertex_iterator vertex_iterator;
Chris@16 1535 typedef typename Config::edge_iterator edge_iterator;
Chris@16 1536 typedef typename Config::directed_category directed_category;
Chris@16 1537 typedef typename Config::edge_parallel_category edge_parallel_category;
Chris@16 1538 typedef typename Config::vertices_size_type vertices_size_type;
Chris@16 1539 typedef typename Config::edges_size_type edges_size_type;
Chris@16 1540 typedef typename Config::degree_size_type degree_size_type;
Chris@16 1541 typedef typename Config::StoredEdge StoredEdge;
Chris@16 1542 typedef typename Config::vertex_property_type vertex_property_type;
Chris@16 1543 typedef typename Config::edge_property_type edge_property_type;
Chris@16 1544 typedef typename Config::graph_property_type graph_property_type;
Chris@16 1545
Chris@16 1546 typedef typename Config::global_edgelist_selector
Chris@16 1547 global_edgelist_selector;
Chris@16 1548
Chris@16 1549 typedef typename lookup_one_property<vertex_property_type, vertex_bundle_t>::type vertex_bundled;
Chris@16 1550 typedef typename lookup_one_property<edge_property_type, edge_bundle_t>::type edge_bundled;
Chris@16 1551 typedef typename lookup_one_property<graph_property_type, graph_bundle_t>::type graph_bundled;
Chris@16 1552 };
Chris@16 1553
Chris@16 1554 template <class Config, class Base>
Chris@16 1555 inline std::pair<typename Config::adjacency_iterator,
Chris@16 1556 typename Config::adjacency_iterator>
Chris@16 1557 adjacent_vertices(typename Config::vertex_descriptor u,
Chris@16 1558 const adj_list_helper<Config, Base>& g_)
Chris@16 1559 {
Chris@16 1560 typedef typename Config::graph_type AdjList;
Chris@16 1561 const AdjList& cg = static_cast<const AdjList&>(g_);
Chris@16 1562 AdjList& g = const_cast<AdjList&>(cg);
Chris@16 1563 typedef typename Config::adjacency_iterator adjacency_iterator;
Chris@16 1564 typename Config::out_edge_iterator first, last;
Chris@16 1565 boost::tie(first, last) = out_edges(u, g);
Chris@16 1566 return std::make_pair(adjacency_iterator(first, &g),
Chris@16 1567 adjacency_iterator(last, &g));
Chris@16 1568 }
Chris@16 1569 template <class Config, class Base>
Chris@16 1570 inline std::pair<typename Config::inv_adjacency_iterator,
Chris@16 1571 typename Config::inv_adjacency_iterator>
Chris@16 1572 inv_adjacent_vertices(typename Config::vertex_descriptor u,
Chris@16 1573 const adj_list_helper<Config, Base>& g_)
Chris@16 1574 {
Chris@16 1575 typedef typename Config::graph_type AdjList;
Chris@16 1576 const AdjList& cg = static_cast<const AdjList&>(g_);
Chris@16 1577 AdjList& g = const_cast<AdjList&>(cg);
Chris@16 1578 typedef typename Config::inv_adjacency_iterator inv_adjacency_iterator;
Chris@16 1579 typename Config::in_edge_iterator first, last;
Chris@16 1580 boost::tie(first, last) = in_edges(u, g);
Chris@16 1581 return std::make_pair(inv_adjacency_iterator(first, &g),
Chris@16 1582 inv_adjacency_iterator(last, &g));
Chris@16 1583 }
Chris@16 1584 template <class Config, class Base>
Chris@16 1585 inline std::pair<typename Config::out_edge_iterator,
Chris@16 1586 typename Config::out_edge_iterator>
Chris@16 1587 out_edges(typename Config::vertex_descriptor u,
Chris@16 1588 const adj_list_helper<Config, Base>& g_)
Chris@16 1589 {
Chris@16 1590 typedef typename Config::graph_type AdjList;
Chris@16 1591 typedef typename Config::out_edge_iterator out_edge_iterator;
Chris@16 1592 const AdjList& cg = static_cast<const AdjList&>(g_);
Chris@16 1593 AdjList& g = const_cast<AdjList&>(cg);
Chris@16 1594 return
Chris@16 1595 std::make_pair(out_edge_iterator(g.out_edge_list(u).begin(), u),
Chris@16 1596 out_edge_iterator(g.out_edge_list(u).end(), u));
Chris@16 1597 }
Chris@16 1598 template <class Config, class Base>
Chris@16 1599 inline std::pair<typename Config::vertex_iterator,
Chris@16 1600 typename Config::vertex_iterator>
Chris@16 1601 vertices(const adj_list_helper<Config, Base>& g_)
Chris@16 1602 {
Chris@16 1603 typedef typename Config::graph_type AdjList;
Chris@16 1604 const AdjList& cg = static_cast<const AdjList&>(g_);
Chris@16 1605 AdjList& g = const_cast<AdjList&>(cg);
Chris@16 1606 return std::make_pair( g.vertex_set().begin(), g.vertex_set().end() );
Chris@16 1607 }
Chris@16 1608 template <class Config, class Base>
Chris@16 1609 inline typename Config::vertices_size_type
Chris@16 1610 num_vertices(const adj_list_helper<Config, Base>& g_)
Chris@16 1611 {
Chris@16 1612 typedef typename Config::graph_type AdjList;
Chris@16 1613 const AdjList& g = static_cast<const AdjList&>(g_);
Chris@16 1614 return g.vertex_set().size();
Chris@16 1615 }
Chris@16 1616 template <class Config, class Base>
Chris@16 1617 inline typename Config::degree_size_type
Chris@16 1618 out_degree(typename Config::vertex_descriptor u,
Chris@16 1619 const adj_list_helper<Config, Base>& g_)
Chris@16 1620 {
Chris@16 1621 typedef typename Config::graph_type AdjList;
Chris@16 1622 const AdjList& g = static_cast<const AdjList&>(g_);
Chris@16 1623 return g.out_edge_list(u).size();
Chris@16 1624 }
Chris@16 1625 template <class Config, class Base>
Chris@16 1626 inline std::pair<typename Config::edge_descriptor, bool>
Chris@16 1627 edge(typename Config::vertex_descriptor u,
Chris@16 1628 typename Config::vertex_descriptor v,
Chris@16 1629 const adj_list_helper<Config, Base>& g_)
Chris@16 1630 {
Chris@16 1631 typedef typename Config::graph_type Graph;
Chris@16 1632 typedef typename Config::StoredEdge StoredEdge;
Chris@16 1633 const Graph& cg = static_cast<const Graph&>(g_);
Chris@16 1634 const typename Config::OutEdgeList& el = cg.out_edge_list(u);
Chris@16 1635 typename Config::OutEdgeList::const_iterator it = graph_detail::
Chris@16 1636 find(el, StoredEdge(v));
Chris@16 1637 return std::make_pair(
Chris@16 1638 typename Config::edge_descriptor
Chris@16 1639 (u, v, (it == el.end() ? 0 : &(*it).get_property())),
Chris@16 1640 (it != el.end()));
Chris@16 1641 }
Chris@16 1642
Chris@16 1643 template <class Config, class Base>
Chris@16 1644 inline std::pair<typename Config::out_edge_iterator,
Chris@16 1645 typename Config::out_edge_iterator>
Chris@16 1646 edge_range(typename Config::vertex_descriptor u,
Chris@16 1647 typename Config::vertex_descriptor v,
Chris@16 1648 const adj_list_helper<Config, Base>& g_)
Chris@16 1649 {
Chris@16 1650 typedef typename Config::graph_type Graph;
Chris@16 1651 typedef typename Config::StoredEdge StoredEdge;
Chris@16 1652 const Graph& cg = static_cast<const Graph&>(g_);
Chris@16 1653 Graph& g = const_cast<Graph&>(cg);
Chris@16 1654 typedef typename Config::out_edge_iterator out_edge_iterator;
Chris@16 1655 typename Config::OutEdgeList& el = g.out_edge_list(u);
Chris@16 1656 typename Config::OutEdgeList::iterator first, last;
Chris@16 1657 typename Config::EdgeContainer fake_edge_container;
Chris@16 1658 boost::tie(first, last) = graph_detail::
Chris@101 1659 equal_range(el, StoredEdge(v));
Chris@16 1660 return std::make_pair(out_edge_iterator(first, u),
Chris@16 1661 out_edge_iterator(last, u));
Chris@16 1662 }
Chris@16 1663
Chris@16 1664 template <class Config>
Chris@16 1665 inline typename Config::degree_size_type
Chris@16 1666 in_degree(typename Config::vertex_descriptor u,
Chris@16 1667 const directed_edges_helper<Config>& g_)
Chris@16 1668 {
Chris@16 1669 typedef typename Config::graph_type Graph;
Chris@16 1670 const Graph& cg = static_cast<const Graph&>(g_);
Chris@16 1671 Graph& g = const_cast<Graph&>(cg);
Chris@16 1672 return in_edge_list(g, u).size();
Chris@16 1673 }
Chris@16 1674
Chris@16 1675 namespace detail {
Chris@16 1676 template <class Config, class Base, class Property>
Chris@16 1677 inline
Chris@16 1678 typename boost::property_map<typename Config::graph_type,
Chris@16 1679 Property>::type
Chris@16 1680 get_dispatch(adj_list_helper<Config,Base>&, Property p,
Chris@16 1681 boost::edge_property_tag) {
Chris@16 1682 typedef typename Config::graph_type Graph;
Chris@16 1683 typedef typename boost::property_map<Graph, Property>::type PA;
Chris@16 1684 return PA(p);
Chris@16 1685 }
Chris@16 1686 template <class Config, class Base, class Property>
Chris@16 1687 inline
Chris@16 1688 typename boost::property_map<typename Config::graph_type,
Chris@16 1689 Property>::const_type
Chris@16 1690 get_dispatch(const adj_list_helper<Config,Base>&, Property p,
Chris@16 1691 boost::edge_property_tag) {
Chris@16 1692 typedef typename Config::graph_type Graph;
Chris@16 1693 typedef typename boost::property_map<Graph, Property>::const_type PA;
Chris@16 1694 return PA(p);
Chris@16 1695 }
Chris@16 1696
Chris@16 1697 template <class Config, class Base, class Property>
Chris@16 1698 inline
Chris@16 1699 typename boost::property_map<typename Config::graph_type,
Chris@16 1700 Property>::type
Chris@16 1701 get_dispatch(adj_list_helper<Config,Base>& g, Property p,
Chris@16 1702 boost::vertex_property_tag) {
Chris@16 1703 typedef typename Config::graph_type Graph;
Chris@16 1704 typedef typename boost::property_map<Graph, Property>::type PA;
Chris@16 1705 return PA(&static_cast<Graph&>(g), p);
Chris@16 1706 }
Chris@16 1707 template <class Config, class Base, class Property>
Chris@16 1708 inline
Chris@16 1709 typename boost::property_map<typename Config::graph_type,
Chris@16 1710 Property>::const_type
Chris@16 1711 get_dispatch(const adj_list_helper<Config, Base>& g, Property p,
Chris@16 1712 boost::vertex_property_tag) {
Chris@16 1713 typedef typename Config::graph_type Graph;
Chris@16 1714 typedef typename boost::property_map<Graph, Property>::const_type PA;
Chris@16 1715 const Graph& cg = static_cast<const Graph&>(g);
Chris@16 1716 return PA(&cg, p);
Chris@16 1717 }
Chris@16 1718
Chris@16 1719 } // namespace detail
Chris@16 1720
Chris@16 1721 // Implementation of the PropertyGraph interface
Chris@16 1722 template <class Config, class Base, class Property>
Chris@16 1723 inline
Chris@16 1724 typename boost::property_map<typename Config::graph_type, Property>::type
Chris@16 1725 get(Property p, adj_list_helper<Config, Base>& g) {
Chris@16 1726 typedef typename detail::property_kind_from_graph<adj_list_helper<Config, Base>, Property>::type Kind;
Chris@16 1727 return detail::get_dispatch(g, p, Kind());
Chris@16 1728 }
Chris@16 1729 template <class Config, class Base, class Property>
Chris@16 1730 inline
Chris@16 1731 typename boost::property_map<typename Config::graph_type,
Chris@16 1732 Property>::const_type
Chris@16 1733 get(Property p, const adj_list_helper<Config, Base>& g) {
Chris@16 1734 typedef typename detail::property_kind_from_graph<adj_list_helper<Config, Base>, Property>::type Kind;
Chris@16 1735 return detail::get_dispatch(g, p, Kind());
Chris@16 1736 }
Chris@16 1737
Chris@16 1738 template <class Config, class Base, class Property, class Key>
Chris@16 1739 inline
Chris@16 1740 typename boost::property_traits<
Chris@16 1741 typename boost::property_map<typename Config::graph_type,
Chris@16 1742 Property>::type
Chris@16 1743 >::reference
Chris@16 1744 get(Property p, adj_list_helper<Config, Base>& g, const Key& key) {
Chris@16 1745 return get(get(p, g), key);
Chris@16 1746 }
Chris@16 1747
Chris@16 1748 template <class Config, class Base, class Property, class Key>
Chris@16 1749 inline
Chris@16 1750 typename boost::property_traits<
Chris@16 1751 typename boost::property_map<typename Config::graph_type,
Chris@16 1752 Property>::const_type
Chris@16 1753 >::reference
Chris@16 1754 get(Property p, const adj_list_helper<Config, Base>& g, const Key& key) {
Chris@16 1755 return get(get(p, g), key);
Chris@16 1756 }
Chris@16 1757
Chris@16 1758 template <class Config, class Base, class Property, class Key,class Value>
Chris@16 1759 inline void
Chris@16 1760 put(Property p, adj_list_helper<Config, Base>& g,
Chris@16 1761 const Key& key, const Value& value)
Chris@16 1762 {
Chris@16 1763 typedef typename Config::graph_type Graph;
Chris@16 1764 typedef typename boost::property_map<Graph, Property>::type Map;
Chris@16 1765 Map pmap = get(p, static_cast<Graph&>(g));
Chris@16 1766 put(pmap, key, value);
Chris@16 1767 }
Chris@16 1768
Chris@16 1769
Chris@16 1770 //=========================================================================
Chris@16 1771 // Generalize Adjacency List Implementation
Chris@16 1772
Chris@16 1773 struct adj_list_tag { };
Chris@16 1774
Chris@16 1775 template <class Derived, class Config, class Base>
Chris@16 1776 class adj_list_impl
Chris@16 1777 : public adj_list_helper<Config, Base>
Chris@16 1778 {
Chris@16 1779 typedef typename Config::OutEdgeList OutEdgeList;
Chris@16 1780 typedef typename Config::InEdgeList InEdgeList;
Chris@16 1781 typedef typename Config::StoredVertexList StoredVertexList;
Chris@16 1782 public:
Chris@16 1783 typedef typename Config::stored_vertex stored_vertex;
Chris@16 1784 typedef typename Config::EdgeContainer EdgeContainer;
Chris@16 1785 typedef typename Config::vertex_descriptor vertex_descriptor;
Chris@16 1786 typedef typename Config::edge_descriptor edge_descriptor;
Chris@16 1787 typedef typename Config::vertex_iterator vertex_iterator;
Chris@16 1788 typedef typename Config::edge_iterator edge_iterator;
Chris@16 1789 typedef typename Config::edge_parallel_category edge_parallel_category;
Chris@16 1790 typedef typename Config::vertices_size_type vertices_size_type;
Chris@16 1791 typedef typename Config::edges_size_type edges_size_type;
Chris@16 1792 typedef typename Config::degree_size_type degree_size_type;
Chris@16 1793 typedef typename Config::edge_property_type edge_property_type;
Chris@16 1794 typedef adj_list_tag graph_tag;
Chris@16 1795
Chris@16 1796 static vertex_descriptor null_vertex()
Chris@16 1797 {
Chris@16 1798 return 0;
Chris@16 1799 }
Chris@16 1800
Chris@16 1801 inline adj_list_impl() { }
Chris@16 1802
Chris@16 1803 inline adj_list_impl(const adj_list_impl& x) {
Chris@16 1804 copy_impl(x);
Chris@16 1805 }
Chris@16 1806 inline adj_list_impl& operator=(const adj_list_impl& x) {
Chris@16 1807 this->clear();
Chris@16 1808 copy_impl(x);
Chris@16 1809 return *this;
Chris@16 1810 }
Chris@16 1811 inline void clear() {
Chris@16 1812 for (typename StoredVertexList::iterator i = m_vertices.begin();
Chris@16 1813 i != m_vertices.end(); ++i)
Chris@16 1814 delete (stored_vertex*)*i;
Chris@16 1815 m_vertices.clear();
Chris@16 1816 m_edges.clear();
Chris@16 1817 }
Chris@16 1818 inline adj_list_impl(vertices_size_type num_vertices) {
Chris@16 1819 for (vertices_size_type i = 0; i < num_vertices; ++i)
Chris@16 1820 add_vertex(static_cast<Derived&>(*this));
Chris@16 1821 }
Chris@16 1822 template <class EdgeIterator>
Chris@16 1823 inline adj_list_impl(vertices_size_type num_vertices,
Chris@16 1824 EdgeIterator first, EdgeIterator last)
Chris@16 1825 {
Chris@16 1826 vertex_descriptor* v = new vertex_descriptor[num_vertices];
Chris@16 1827 for (vertices_size_type i = 0; i < num_vertices; ++i)
Chris@16 1828 v[i] = add_vertex(static_cast<Derived&>(*this));
Chris@16 1829
Chris@16 1830 while (first != last) {
Chris@16 1831 add_edge(v[(*first).first], v[(*first).second], *this);
Chris@16 1832 ++first;
Chris@16 1833 }
Chris@16 1834 delete [] v;
Chris@16 1835 }
Chris@16 1836 template <class EdgeIterator, class EdgePropertyIterator>
Chris@16 1837 inline adj_list_impl(vertices_size_type num_vertices,
Chris@16 1838 EdgeIterator first, EdgeIterator last,
Chris@16 1839 EdgePropertyIterator ep_iter)
Chris@16 1840 {
Chris@16 1841 vertex_descriptor* v = new vertex_descriptor[num_vertices];
Chris@16 1842 for (vertices_size_type i = 0; i < num_vertices; ++i)
Chris@16 1843 v[i] = add_vertex(static_cast<Derived&>(*this));
Chris@16 1844
Chris@16 1845 while (first != last) {
Chris@16 1846 add_edge(v[(*first).first], v[(*first).second], *ep_iter, *this);
Chris@16 1847 ++first;
Chris@16 1848 ++ep_iter;
Chris@16 1849 }
Chris@16 1850 delete [] v;
Chris@16 1851 }
Chris@16 1852 ~adj_list_impl() {
Chris@16 1853 for (typename StoredVertexList::iterator i = m_vertices.begin();
Chris@16 1854 i != m_vertices.end(); ++i)
Chris@16 1855 delete (stored_vertex*)*i;
Chris@16 1856 }
Chris@16 1857 // protected:
Chris@16 1858 inline OutEdgeList& out_edge_list(vertex_descriptor v) {
Chris@16 1859 stored_vertex* sv = (stored_vertex*)v;
Chris@16 1860 return sv->m_out_edges;
Chris@16 1861 }
Chris@16 1862 inline const OutEdgeList& out_edge_list(vertex_descriptor v) const {
Chris@16 1863 stored_vertex* sv = (stored_vertex*)v;
Chris@16 1864 return sv->m_out_edges;
Chris@16 1865 }
Chris@16 1866 inline StoredVertexList& vertex_set() { return m_vertices; }
Chris@16 1867 inline const StoredVertexList& vertex_set() const { return m_vertices; }
Chris@16 1868
Chris@16 1869 inline void copy_impl(const adj_list_impl& x_)
Chris@16 1870 {
Chris@16 1871 const Derived& x = static_cast<const Derived&>(x_);
Chris@16 1872
Chris@16 1873 // Would be better to have a constant time way to get from
Chris@16 1874 // vertices in x to the corresponding vertices in *this.
Chris@16 1875 std::map<stored_vertex*,stored_vertex*> vertex_map;
Chris@16 1876
Chris@16 1877 // Copy the stored vertex objects by adding each vertex
Chris@16 1878 // and copying its property object.
Chris@16 1879 vertex_iterator vi, vi_end;
Chris@16 1880 for (boost::tie(vi, vi_end) = vertices(x); vi != vi_end; ++vi) {
Chris@16 1881 stored_vertex* v = (stored_vertex*)add_vertex(*this);
Chris@16 1882 v->m_property = ((stored_vertex*)*vi)->m_property;
Chris@16 1883 vertex_map[(stored_vertex*)*vi] = v;
Chris@16 1884 }
Chris@16 1885 // Copy the edges by adding each edge and copying its
Chris@16 1886 // property object.
Chris@16 1887 edge_iterator ei, ei_end;
Chris@16 1888 for (boost::tie(ei, ei_end) = edges(x); ei != ei_end; ++ei) {
Chris@16 1889 edge_descriptor e;
Chris@16 1890 bool inserted;
Chris@16 1891 vertex_descriptor s = source(*ei,x), t = target(*ei,x);
Chris@16 1892 boost::tie(e, inserted) = add_edge(vertex_map[(stored_vertex*)s],
Chris@16 1893 vertex_map[(stored_vertex*)t], *this);
Chris@16 1894 *((edge_property_type*)e.m_eproperty)
Chris@16 1895 = *((edge_property_type*)(*ei).m_eproperty);
Chris@16 1896 }
Chris@16 1897 }
Chris@16 1898
Chris@16 1899
Chris@16 1900 typename Config::EdgeContainer m_edges;
Chris@16 1901 StoredVertexList m_vertices;
Chris@16 1902 };
Chris@16 1903
Chris@16 1904 // O(1)
Chris@16 1905 template <class Derived, class Config, class Base>
Chris@16 1906 inline typename Config::vertex_descriptor
Chris@16 1907 add_vertex(adj_list_impl<Derived, Config, Base>& g_)
Chris@16 1908 {
Chris@16 1909 Derived& g = static_cast<Derived&>(g_);
Chris@16 1910 typedef typename Config::stored_vertex stored_vertex;
Chris@16 1911 stored_vertex* v = new stored_vertex;
Chris@16 1912 typename Config::StoredVertexList::iterator pos;
Chris@16 1913 bool inserted;
Chris@16 1914 boost::tie(pos,inserted) = boost::graph_detail::push(g.m_vertices, v);
Chris@16 1915 v->m_position = pos;
Chris@16 1916 g.added_vertex(v);
Chris@16 1917 return v;
Chris@16 1918 }
Chris@16 1919 // O(1)
Chris@16 1920 template <class Derived, class Config, class Base>
Chris@16 1921 inline typename Config::vertex_descriptor
Chris@16 1922 add_vertex(const typename Config::vertex_property_type& p,
Chris@16 1923 adj_list_impl<Derived, Config, Base>& g_)
Chris@16 1924 {
Chris@16 1925 typedef typename Config::vertex_descriptor vertex_descriptor;
Chris@16 1926 Derived& g = static_cast<Derived&>(g_);
Chris@16 1927 if (optional<vertex_descriptor> v
Chris@16 1928 = g.vertex_by_property(get_property_value(p, vertex_bundle)))
Chris@16 1929 return *v;
Chris@16 1930
Chris@16 1931 typedef typename Config::stored_vertex stored_vertex;
Chris@16 1932 stored_vertex* v = new stored_vertex(p);
Chris@16 1933 typename Config::StoredVertexList::iterator pos;
Chris@16 1934 bool inserted;
Chris@16 1935 boost::tie(pos,inserted) = boost::graph_detail::push(g.m_vertices, v);
Chris@16 1936 v->m_position = pos;
Chris@16 1937 g.added_vertex(v);
Chris@16 1938 return v;
Chris@16 1939 }
Chris@16 1940 // O(1)
Chris@16 1941 template <class Derived, class Config, class Base>
Chris@16 1942 inline void remove_vertex(typename Config::vertex_descriptor u,
Chris@16 1943 adj_list_impl<Derived, Config, Base>& g_)
Chris@16 1944 {
Chris@16 1945 typedef typename Config::stored_vertex stored_vertex;
Chris@16 1946 Derived& g = static_cast<Derived&>(g_);
Chris@16 1947 g.removing_vertex(u, boost::graph_detail::iterator_stability(g_.m_vertices));
Chris@16 1948 stored_vertex* su = (stored_vertex*)u;
Chris@16 1949 g.m_vertices.erase(su->m_position);
Chris@16 1950 delete su;
Chris@16 1951 }
Chris@16 1952 // O(V)
Chris@16 1953 template <class Derived, class Config, class Base>
Chris@16 1954 inline typename Config::vertex_descriptor
Chris@16 1955 vertex(typename Config::vertices_size_type n,
Chris@16 1956 const adj_list_impl<Derived, Config, Base>& g_)
Chris@16 1957 {
Chris@16 1958 const Derived& g = static_cast<const Derived&>(g_);
Chris@16 1959 typename Config::vertex_iterator i = vertices(g).first;
Chris@16 1960 while (n--) ++i; // std::advance(i, n); (not VC++ portable)
Chris@16 1961 return *i;
Chris@16 1962 }
Chris@16 1963
Chris@16 1964 //=========================================================================
Chris@16 1965 // Vector-Backbone Adjacency List Implementation
Chris@16 1966
Chris@16 1967 namespace detail {
Chris@16 1968
Chris@16 1969 template <class Graph, class vertex_descriptor>
Chris@16 1970 inline void
Chris@16 1971 remove_vertex_dispatch(Graph& g, vertex_descriptor u,
Chris@16 1972 boost::directed_tag)
Chris@16 1973 {
Chris@16 1974 typedef typename Graph::edge_parallel_category edge_parallel_category;
Chris@16 1975 g.m_vertices.erase(g.m_vertices.begin() + u);
Chris@16 1976 vertex_descriptor V = num_vertices(g);
Chris@16 1977 if (u != V) {
Chris@16 1978 for (vertex_descriptor v = 0; v < V; ++v)
Chris@16 1979 reindex_edge_list(g.out_edge_list(v), u, edge_parallel_category());
Chris@16 1980 }
Chris@16 1981 }
Chris@16 1982
Chris@16 1983 template <class Graph, class vertex_descriptor>
Chris@16 1984 inline void
Chris@16 1985 remove_vertex_dispatch(Graph& g, vertex_descriptor u,
Chris@16 1986 boost::undirected_tag)
Chris@16 1987 {
Chris@16 1988 typedef typename Graph::global_edgelist_selector EdgeListS;
Chris@16 1989 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 1990
Chris@16 1991 typedef typename Graph::edge_parallel_category edge_parallel_category;
Chris@16 1992 g.m_vertices.erase(g.m_vertices.begin() + u);
Chris@16 1993 vertex_descriptor V = num_vertices(g);
Chris@16 1994 for (vertex_descriptor v = 0; v < V; ++v)
Chris@16 1995 reindex_edge_list(g.out_edge_list(v), u,
Chris@16 1996 edge_parallel_category());
Chris@16 1997 typedef typename Graph::EdgeContainer Container;
Chris@16 1998 typedef typename Container::iterator Iter;
Chris@16 1999 Iter ei = g.m_edges.begin(), ei_end = g.m_edges.end();
Chris@16 2000 for (; ei != ei_end; ++ei) {
Chris@16 2001 if (ei->m_source > u)
Chris@16 2002 --ei->m_source;
Chris@16 2003 if (ei->m_target > u)
Chris@16 2004 --ei->m_target;
Chris@16 2005 }
Chris@16 2006 }
Chris@16 2007 template <class Graph, class vertex_descriptor>
Chris@16 2008 inline void
Chris@16 2009 remove_vertex_dispatch(Graph& g, vertex_descriptor u,
Chris@16 2010 boost::bidirectional_tag)
Chris@16 2011 {
Chris@16 2012 typedef typename Graph::global_edgelist_selector EdgeListS;
Chris@16 2013 BOOST_STATIC_ASSERT((!is_same<EdgeListS, vecS>::value));
Chris@16 2014
Chris@16 2015 typedef typename Graph::edge_parallel_category edge_parallel_category;
Chris@16 2016 g.m_vertices.erase(g.m_vertices.begin() + u);
Chris@16 2017 vertex_descriptor V = num_vertices(g);
Chris@16 2018 vertex_descriptor v;
Chris@16 2019 if (u != V) {
Chris@16 2020 for (v = 0; v < V; ++v)
Chris@16 2021 reindex_edge_list(g.out_edge_list(v), u,
Chris@16 2022 edge_parallel_category());
Chris@16 2023 for (v = 0; v < V; ++v)
Chris@16 2024 reindex_edge_list(in_edge_list(g, v), u,
Chris@16 2025 edge_parallel_category());
Chris@16 2026
Chris@16 2027 typedef typename Graph::EdgeContainer Container;
Chris@16 2028 typedef typename Container::iterator Iter;
Chris@16 2029 Iter ei = g.m_edges.begin(), ei_end = g.m_edges.end();
Chris@16 2030 for (; ei != ei_end; ++ei) {
Chris@16 2031 if (ei->m_source > u)
Chris@16 2032 --ei->m_source;
Chris@16 2033 if (ei->m_target > u)
Chris@16 2034 --ei->m_target;
Chris@16 2035 }
Chris@16 2036 }
Chris@16 2037 }
Chris@16 2038
Chris@16 2039 template <class EdgeList, class vertex_descriptor>
Chris@16 2040 inline void
Chris@16 2041 reindex_edge_list(EdgeList& el, vertex_descriptor u,
Chris@16 2042 boost::allow_parallel_edge_tag)
Chris@16 2043 {
Chris@16 2044 typename EdgeList::iterator ei = el.begin(), e_end = el.end();
Chris@16 2045 for (; ei != e_end; ++ei)
Chris@16 2046 if ((*ei).get_target() > u)
Chris@16 2047 --(*ei).get_target();
Chris@16 2048 }
Chris@16 2049 template <class EdgeList, class vertex_descriptor>
Chris@16 2050 inline void
Chris@16 2051 reindex_edge_list(EdgeList& el, vertex_descriptor u,
Chris@16 2052 boost::disallow_parallel_edge_tag)
Chris@16 2053 {
Chris@16 2054 typename EdgeList::iterator ei = el.begin(), e_end = el.end();
Chris@16 2055 while (ei != e_end) {
Chris@16 2056 typename EdgeList::value_type ce = *ei;
Chris@16 2057 ++ei;
Chris@16 2058 if (ce.get_target() > u) {
Chris@16 2059 el.erase(ce);
Chris@16 2060 --ce.get_target();
Chris@16 2061 el.insert(ce);
Chris@16 2062 }
Chris@16 2063 }
Chris@16 2064 }
Chris@16 2065 } // namespace detail
Chris@16 2066
Chris@16 2067 struct vec_adj_list_tag { };
Chris@16 2068
Chris@16 2069 template <class Graph, class Config, class Base>
Chris@16 2070 class vec_adj_list_impl
Chris@16 2071 : public adj_list_helper<Config, Base>
Chris@16 2072 {
Chris@16 2073 typedef typename Config::OutEdgeList OutEdgeList;
Chris@16 2074 typedef typename Config::InEdgeList InEdgeList;
Chris@16 2075 typedef typename Config::StoredVertexList StoredVertexList;
Chris@16 2076 public:
Chris@16 2077 typedef typename Config::vertex_descriptor vertex_descriptor;
Chris@16 2078 typedef typename Config::edge_descriptor edge_descriptor;
Chris@16 2079 typedef typename Config::out_edge_iterator out_edge_iterator;
Chris@16 2080 typedef typename Config::edge_iterator edge_iterator;
Chris@16 2081 typedef typename Config::directed_category directed_category;
Chris@16 2082 typedef typename Config::vertices_size_type vertices_size_type;
Chris@16 2083 typedef typename Config::edges_size_type edges_size_type;
Chris@16 2084 typedef typename Config::degree_size_type degree_size_type;
Chris@16 2085 typedef typename Config::StoredEdge StoredEdge;
Chris@16 2086 typedef typename Config::stored_vertex stored_vertex;
Chris@16 2087 typedef typename Config::EdgeContainer EdgeContainer;
Chris@16 2088 typedef typename Config::edge_property_type edge_property_type;
Chris@16 2089 typedef vec_adj_list_tag graph_tag;
Chris@16 2090
Chris@16 2091 static vertex_descriptor null_vertex()
Chris@16 2092 {
Chris@16 2093 return (std::numeric_limits<vertex_descriptor>::max)();
Chris@16 2094 }
Chris@16 2095
Chris@16 2096 inline vec_adj_list_impl() { }
Chris@16 2097
Chris@16 2098 inline vec_adj_list_impl(const vec_adj_list_impl& x) {
Chris@16 2099 copy_impl(x);
Chris@16 2100 }
Chris@16 2101 inline vec_adj_list_impl& operator=(const vec_adj_list_impl& x) {
Chris@16 2102 this->clear();
Chris@16 2103 copy_impl(x);
Chris@16 2104 return *this;
Chris@16 2105 }
Chris@16 2106 inline void clear() {
Chris@16 2107 m_vertices.clear();
Chris@16 2108 m_edges.clear();
Chris@16 2109 }
Chris@16 2110
Chris@16 2111 inline vec_adj_list_impl(vertices_size_type _num_vertices)
Chris@16 2112 : m_vertices(_num_vertices) { }
Chris@16 2113
Chris@16 2114 template <class EdgeIterator>
Chris@16 2115 inline vec_adj_list_impl(vertices_size_type num_vertices,
Chris@16 2116 EdgeIterator first, EdgeIterator last)
Chris@16 2117 : m_vertices(num_vertices)
Chris@16 2118 {
Chris@16 2119 while (first != last) {
Chris@16 2120 add_edge((*first).first, (*first).second,
Chris@16 2121 static_cast<Graph&>(*this));
Chris@16 2122 ++first;
Chris@16 2123 }
Chris@16 2124 }
Chris@16 2125 template <class EdgeIterator, class EdgePropertyIterator>
Chris@16 2126 inline vec_adj_list_impl(vertices_size_type num_vertices,
Chris@16 2127 EdgeIterator first, EdgeIterator last,
Chris@16 2128 EdgePropertyIterator ep_iter)
Chris@16 2129 : m_vertices(num_vertices)
Chris@16 2130 {
Chris@16 2131 while (first != last) {
Chris@16 2132 add_edge((*first).first, (*first).second, *ep_iter,
Chris@16 2133 static_cast<Graph&>(*this));
Chris@16 2134 ++first;
Chris@16 2135 ++ep_iter;
Chris@16 2136 }
Chris@16 2137 }
Chris@16 2138
Chris@16 2139 // protected:
Chris@16 2140 inline boost::integer_range<vertex_descriptor> vertex_set() const {
Chris@16 2141 return boost::integer_range<vertex_descriptor>(0, m_vertices.size());
Chris@16 2142 }
Chris@16 2143 inline OutEdgeList& out_edge_list(vertex_descriptor v) {
Chris@16 2144 return m_vertices[v].m_out_edges;
Chris@16 2145 }
Chris@16 2146 inline const OutEdgeList& out_edge_list(vertex_descriptor v) const {
Chris@16 2147 return m_vertices[v].m_out_edges;
Chris@16 2148 }
Chris@16 2149 inline void copy_impl(const vec_adj_list_impl& x_)
Chris@16 2150 {
Chris@16 2151 const Graph& x = static_cast<const Graph&>(x_);
Chris@16 2152 // Copy the stored vertex objects by adding each vertex
Chris@16 2153 // and copying its property object.
Chris@16 2154 for (vertices_size_type i = 0; i < num_vertices(x); ++i) {
Chris@16 2155 vertex_descriptor v = add_vertex(*this);
Chris@16 2156 m_vertices[v].m_property = x.m_vertices[i].m_property;
Chris@16 2157 }
Chris@16 2158 // Copy the edges by adding each edge and copying its
Chris@16 2159 // property object.
Chris@16 2160 edge_iterator ei, ei_end;
Chris@16 2161 for (boost::tie(ei, ei_end) = edges(x); ei != ei_end; ++ei) {
Chris@16 2162 edge_descriptor e;
Chris@16 2163 bool inserted;
Chris@16 2164 boost::tie(e, inserted) = add_edge(source(*ei,x), target(*ei,x) , *this);
Chris@16 2165 *((edge_property_type*)e.m_eproperty)
Chris@16 2166 = *((edge_property_type*)(*ei).m_eproperty);
Chris@16 2167 }
Chris@16 2168 }
Chris@16 2169 typename Config::EdgeContainer m_edges;
Chris@16 2170 StoredVertexList m_vertices;
Chris@16 2171 };
Chris@16 2172 // Had to make these non-members to avoid accidental instantiation
Chris@16 2173 // on SGI MIPSpro C++
Chris@16 2174 template <class G, class C, class B>
Chris@16 2175 inline typename C::InEdgeList&
Chris@16 2176 in_edge_list(vec_adj_list_impl<G,C,B>& g,
Chris@16 2177 typename C::vertex_descriptor v) {
Chris@16 2178 return g.m_vertices[v].m_in_edges;
Chris@16 2179 }
Chris@16 2180 template <class G, class C, class B>
Chris@16 2181 inline const typename C::InEdgeList&
Chris@16 2182 in_edge_list(const vec_adj_list_impl<G,C,B>& g,
Chris@16 2183 typename C::vertex_descriptor v) {
Chris@16 2184 return g.m_vertices[v].m_in_edges;
Chris@16 2185 }
Chris@16 2186
Chris@16 2187 // O(1)
Chris@16 2188 template <class Graph, class Config, class Base>
Chris@16 2189 inline typename Config::vertex_descriptor
Chris@16 2190 add_vertex(vec_adj_list_impl<Graph, Config, Base>& g_) {
Chris@16 2191 Graph& g = static_cast<Graph&>(g_);
Chris@16 2192 g.m_vertices.resize(g.m_vertices.size() + 1);
Chris@16 2193 g.added_vertex(g.m_vertices.size() - 1);
Chris@16 2194 return g.m_vertices.size() - 1;
Chris@16 2195 }
Chris@16 2196
Chris@16 2197 template <class Graph, class Config, class Base>
Chris@16 2198 inline typename Config::vertex_descriptor
Chris@16 2199 add_vertex(const typename Config::vertex_property_type& p,
Chris@16 2200 vec_adj_list_impl<Graph, Config, Base>& g_) {
Chris@16 2201 typedef typename Config::vertex_descriptor vertex_descriptor;
Chris@16 2202 Graph& g = static_cast<Graph&>(g_);
Chris@16 2203 if (optional<vertex_descriptor> v
Chris@16 2204 = g.vertex_by_property(get_property_value(p, vertex_bundle)))
Chris@16 2205 return *v;
Chris@16 2206 typedef typename Config::stored_vertex stored_vertex;
Chris@16 2207 g.m_vertices.push_back(stored_vertex(p));
Chris@16 2208 g.added_vertex(g.m_vertices.size() - 1);
Chris@16 2209 return g.m_vertices.size() - 1;
Chris@16 2210 }
Chris@16 2211
Chris@16 2212 // Here we override the directed_graph_helper add_edge() function
Chris@16 2213 // so that the number of vertices is automatically changed if
Chris@16 2214 // either u or v is greater than the number of vertices.
Chris@16 2215 template <class Graph, class Config, class Base>
Chris@16 2216 inline std::pair<typename Config::edge_descriptor, bool>
Chris@16 2217 add_edge(typename Config::vertex_descriptor u,
Chris@16 2218 typename Config::vertex_descriptor v,
Chris@16 2219 const typename Config::edge_property_type& p,
Chris@16 2220 vec_adj_list_impl<Graph, Config, Base>& g_)
Chris@16 2221 {
Chris@16 2222 BOOST_USING_STD_MAX();
Chris@16 2223 typename Config::vertex_descriptor x = max BOOST_PREVENT_MACRO_SUBSTITUTION(u, v);
Chris@16 2224 if (x >= num_vertices(g_))
Chris@16 2225 g_.m_vertices.resize(x + 1);
Chris@16 2226 adj_list_helper<Config, Base>& g = g_;
Chris@16 2227 return add_edge(u, v, p, g);
Chris@16 2228 }
Chris@16 2229 template <class Graph, class Config, class Base>
Chris@16 2230 inline std::pair<typename Config::edge_descriptor, bool>
Chris@16 2231 add_edge(typename Config::vertex_descriptor u,
Chris@16 2232 typename Config::vertex_descriptor v,
Chris@16 2233 vec_adj_list_impl<Graph, Config, Base>& g_)
Chris@16 2234 {
Chris@16 2235 typename Config::edge_property_type p;
Chris@16 2236 return add_edge(u, v, p, g_);
Chris@16 2237 }
Chris@16 2238
Chris@16 2239
Chris@16 2240 // O(V + E)
Chris@16 2241 template <class Graph, class Config, class Base>
Chris@16 2242 inline void remove_vertex(typename Config::vertex_descriptor v,
Chris@16 2243 vec_adj_list_impl<Graph, Config, Base>& g_)
Chris@16 2244 {
Chris@16 2245 typedef typename Config::directed_category Cat;
Chris@16 2246 Graph& g = static_cast<Graph&>(g_);
Chris@16 2247 g.removing_vertex(v, boost::graph_detail::iterator_stability(g_.m_vertices));
Chris@16 2248 detail::remove_vertex_dispatch(g, v, Cat());
Chris@16 2249 }
Chris@16 2250 // O(1)
Chris@16 2251 template <class Graph, class Config, class Base>
Chris@16 2252 inline typename Config::vertex_descriptor
Chris@16 2253 vertex(typename Config::vertices_size_type n,
Chris@16 2254 const vec_adj_list_impl<Graph, Config, Base>&)
Chris@16 2255 {
Chris@16 2256 return n;
Chris@16 2257 }
Chris@16 2258
Chris@16 2259
Chris@16 2260 namespace detail {
Chris@16 2261
Chris@16 2262 //=========================================================================
Chris@16 2263 // Adjacency List Generator
Chris@16 2264
Chris@16 2265 template <class Graph, class VertexListS, class OutEdgeListS,
Chris@16 2266 class DirectedS, class VertexProperty, class EdgeProperty,
Chris@16 2267 class GraphProperty, class EdgeListS>
Chris@16 2268 struct adj_list_gen
Chris@16 2269 {
Chris@16 2270 typedef typename detail::is_random_access<VertexListS>::type
Chris@16 2271 is_rand_access;
Chris@16 2272 typedef typename has_property<EdgeProperty>::type has_edge_property;
Chris@16 2273 typedef typename DirectedS::is_directed_t DirectedT;
Chris@16 2274 typedef typename DirectedS::is_bidir_t BidirectionalT;
Chris@16 2275
Chris@16 2276 struct config
Chris@16 2277 {
Chris@16 2278 typedef OutEdgeListS edgelist_selector;
Chris@16 2279 typedef EdgeListS global_edgelist_selector;
Chris@16 2280
Chris@16 2281 typedef Graph graph_type;
Chris@16 2282 typedef EdgeProperty edge_property_type;
Chris@16 2283 typedef VertexProperty vertex_property_type;
Chris@16 2284 typedef GraphProperty graph_property_type;
Chris@16 2285 typedef std::size_t vertices_size_type;
Chris@16 2286
Chris@16 2287 typedef adjacency_list_traits<OutEdgeListS, VertexListS, DirectedS>
Chris@16 2288 Traits;
Chris@16 2289
Chris@16 2290 typedef typename Traits::directed_category directed_category;
Chris@16 2291 typedef typename Traits::edge_parallel_category edge_parallel_category;
Chris@16 2292 typedef typename Traits::vertex_descriptor vertex_descriptor;
Chris@16 2293 typedef typename Traits::edge_descriptor edge_descriptor;
Chris@16 2294
Chris@16 2295 typedef void* vertex_ptr;
Chris@16 2296
Chris@16 2297 // need to reorganize this to avoid instantiating stuff
Chris@16 2298 // that doesn't get used -JGS
Chris@16 2299
Chris@16 2300 // VertexList and vertex_iterator
Chris@16 2301 typedef typename container_gen<VertexListS,
Chris@16 2302 vertex_ptr>::type SeqVertexList;
Chris@16 2303 typedef boost::integer_range<vertex_descriptor> RandVertexList;
Chris@16 2304 typedef typename mpl::if_<is_rand_access,
Chris@16 2305 RandVertexList, SeqVertexList>::type VertexList;
Chris@16 2306
Chris@16 2307 typedef typename VertexList::iterator vertex_iterator;
Chris@16 2308
Chris@16 2309 // EdgeContainer and StoredEdge
Chris@16 2310
Chris@16 2311 typedef typename container_gen<EdgeListS,
Chris@16 2312 list_edge<vertex_descriptor, EdgeProperty> >::type EdgeContainer;
Chris@16 2313
Chris@16 2314 typedef typename mpl::and_<DirectedT,
Chris@16 2315 typename mpl::not_<BidirectionalT>::type >::type on_edge_storage;
Chris@16 2316
Chris@16 2317 typedef typename mpl::if_<on_edge_storage,
Chris@16 2318 std::size_t, typename EdgeContainer::size_type
Chris@16 2319 >::type edges_size_type;
Chris@16 2320
Chris@16 2321 typedef typename EdgeContainer::iterator EdgeIter;
Chris@16 2322
Chris@16 2323 typedef typename detail::is_random_access<EdgeListS>::type is_edge_ra;
Chris@16 2324
Chris@16 2325 typedef typename mpl::if_<on_edge_storage,
Chris@16 2326 stored_edge_property<vertex_descriptor, EdgeProperty>,
Chris@16 2327 typename mpl::if_<is_edge_ra,
Chris@16 2328 stored_ra_edge_iter<vertex_descriptor, EdgeContainer, EdgeProperty>,
Chris@16 2329 stored_edge_iter<vertex_descriptor, EdgeIter, EdgeProperty>
Chris@16 2330 >::type
Chris@16 2331 >::type StoredEdge;
Chris@16 2332
Chris@16 2333 // Adjacency Types
Chris@16 2334
Chris@16 2335 typedef typename container_gen<OutEdgeListS, StoredEdge>::type
Chris@16 2336 OutEdgeList;
Chris@16 2337 typedef typename OutEdgeList::size_type degree_size_type;
Chris@16 2338 typedef typename OutEdgeList::iterator OutEdgeIter;
Chris@16 2339
Chris@16 2340 typedef boost::detail::iterator_traits<OutEdgeIter> OutEdgeIterTraits;
Chris@16 2341 typedef typename OutEdgeIterTraits::iterator_category OutEdgeIterCat;
Chris@16 2342 typedef typename OutEdgeIterTraits::difference_type OutEdgeIterDiff;
Chris@16 2343
Chris@16 2344 typedef out_edge_iter<
Chris@16 2345 OutEdgeIter, vertex_descriptor, edge_descriptor, OutEdgeIterDiff
Chris@16 2346 > out_edge_iterator;
Chris@16 2347
Chris@16 2348 typedef typename adjacency_iterator_generator<graph_type,
Chris@16 2349 vertex_descriptor, out_edge_iterator>::type adjacency_iterator;
Chris@16 2350
Chris@16 2351 typedef OutEdgeList InEdgeList;
Chris@16 2352 typedef OutEdgeIter InEdgeIter;
Chris@16 2353 typedef OutEdgeIterCat InEdgeIterCat;
Chris@16 2354 typedef OutEdgeIterDiff InEdgeIterDiff;
Chris@16 2355
Chris@16 2356 typedef in_edge_iter<
Chris@16 2357 InEdgeIter, vertex_descriptor, edge_descriptor, InEdgeIterDiff
Chris@16 2358 > in_edge_iterator;
Chris@16 2359
Chris@16 2360 typedef typename inv_adjacency_iterator_generator<graph_type,
Chris@16 2361 vertex_descriptor, in_edge_iterator>::type inv_adjacency_iterator;
Chris@16 2362
Chris@16 2363 // Edge Iterator
Chris@16 2364
Chris@16 2365 typedef boost::detail::iterator_traits<EdgeIter> EdgeIterTraits;
Chris@16 2366 typedef typename EdgeIterTraits::iterator_category EdgeIterCat;
Chris@16 2367 typedef typename EdgeIterTraits::difference_type EdgeIterDiff;
Chris@16 2368
Chris@16 2369 typedef undirected_edge_iter<
Chris@16 2370 EdgeIter
Chris@16 2371 , edge_descriptor
Chris@16 2372 , EdgeIterDiff
Chris@16 2373 > UndirectedEdgeIter; // also used for bidirectional
Chris@16 2374
Chris@16 2375 typedef adj_list_edge_iterator<vertex_iterator, out_edge_iterator,
Chris@16 2376 graph_type> DirectedEdgeIter;
Chris@16 2377
Chris@16 2378 typedef typename mpl::if_<on_edge_storage,
Chris@16 2379 DirectedEdgeIter, UndirectedEdgeIter>::type edge_iterator;
Chris@16 2380
Chris@16 2381 // stored_vertex and StoredVertexList
Chris@16 2382 typedef typename container_gen<VertexListS, vertex_ptr>::type
Chris@16 2383 SeqStoredVertexList;
Chris@16 2384 struct seq_stored_vertex {
Chris@16 2385 seq_stored_vertex() { }
Chris@16 2386 seq_stored_vertex(const VertexProperty& p) : m_property(p) { }
Chris@16 2387 OutEdgeList m_out_edges;
Chris@16 2388 VertexProperty m_property;
Chris@16 2389 typename SeqStoredVertexList::iterator m_position;
Chris@16 2390 };
Chris@16 2391 struct bidir_seq_stored_vertex {
Chris@16 2392 bidir_seq_stored_vertex() { }
Chris@16 2393 bidir_seq_stored_vertex(const VertexProperty& p) : m_property(p) { }
Chris@16 2394 OutEdgeList m_out_edges;
Chris@16 2395 InEdgeList m_in_edges;
Chris@16 2396 VertexProperty m_property;
Chris@16 2397 typename SeqStoredVertexList::iterator m_position;
Chris@16 2398 };
Chris@16 2399 struct rand_stored_vertex {
Chris@16 2400 rand_stored_vertex() { }
Chris@16 2401 rand_stored_vertex(const VertexProperty& p) : m_property(p) { }
Chris@16 2402 OutEdgeList m_out_edges;
Chris@16 2403 VertexProperty m_property;
Chris@16 2404 };
Chris@16 2405 struct bidir_rand_stored_vertex {
Chris@16 2406 bidir_rand_stored_vertex() { }
Chris@16 2407 bidir_rand_stored_vertex(const VertexProperty& p) : m_property(p) { }
Chris@16 2408 OutEdgeList m_out_edges;
Chris@16 2409 InEdgeList m_in_edges;
Chris@16 2410 VertexProperty m_property;
Chris@16 2411 };
Chris@16 2412 typedef typename mpl::if_<is_rand_access,
Chris@16 2413 typename mpl::if_<BidirectionalT,
Chris@16 2414 bidir_rand_stored_vertex, rand_stored_vertex>::type,
Chris@16 2415 typename mpl::if_<BidirectionalT,
Chris@16 2416 bidir_seq_stored_vertex, seq_stored_vertex>::type
Chris@16 2417 >::type StoredVertex;
Chris@16 2418 struct stored_vertex : public StoredVertex {
Chris@16 2419 stored_vertex() { }
Chris@16 2420 stored_vertex(const VertexProperty& p) : StoredVertex(p) { }
Chris@16 2421 };
Chris@16 2422
Chris@16 2423 typedef typename container_gen<VertexListS, stored_vertex>::type
Chris@16 2424 RandStoredVertexList;
Chris@16 2425 typedef typename mpl::if_< is_rand_access,
Chris@16 2426 RandStoredVertexList, SeqStoredVertexList>::type StoredVertexList;
Chris@16 2427 }; // end of config
Chris@16 2428
Chris@16 2429
Chris@16 2430 typedef typename mpl::if_<BidirectionalT,
Chris@16 2431 bidirectional_graph_helper_with_property<config>,
Chris@16 2432 typename mpl::if_<DirectedT,
Chris@16 2433 directed_graph_helper<config>,
Chris@16 2434 undirected_graph_helper<config>
Chris@16 2435 >::type
Chris@16 2436 >::type DirectedHelper;
Chris@16 2437
Chris@16 2438 typedef typename mpl::if_<is_rand_access,
Chris@16 2439 vec_adj_list_impl<Graph, config, DirectedHelper>,
Chris@16 2440 adj_list_impl<Graph, config, DirectedHelper>
Chris@16 2441 >::type type;
Chris@16 2442
Chris@16 2443 };
Chris@16 2444
Chris@16 2445 } // namespace detail
Chris@16 2446
Chris@16 2447 //=========================================================================
Chris@16 2448 // Vertex Property Maps
Chris@16 2449
Chris@16 2450 template <class Graph, class ValueType, class Reference, class Tag>
Chris@16 2451 struct adj_list_vertex_property_map
Chris@16 2452 : public boost::put_get_helper<
Chris@16 2453 Reference,
Chris@16 2454 adj_list_vertex_property_map<Graph, ValueType, Reference, Tag>
Chris@16 2455 >
Chris@16 2456 {
Chris@16 2457 typedef typename Graph::stored_vertex StoredVertex;
Chris@16 2458 typedef ValueType value_type;
Chris@16 2459 typedef Reference reference;
Chris@16 2460 typedef typename Graph::vertex_descriptor key_type;
Chris@16 2461 typedef boost::lvalue_property_map_tag category;
Chris@16 2462 inline adj_list_vertex_property_map(const Graph* = 0, Tag tag = Tag()): m_tag(tag) { }
Chris@16 2463 inline Reference operator[](key_type v) const {
Chris@16 2464 StoredVertex* sv = (StoredVertex*)v;
Chris@16 2465 return get_property_value(sv->m_property, m_tag);
Chris@16 2466 }
Chris@16 2467 inline Reference operator()(key_type v) const {
Chris@16 2468 return this->operator[](v);
Chris@16 2469 }
Chris@16 2470 Tag m_tag;
Chris@16 2471 };
Chris@16 2472
Chris@16 2473 template <class Graph, class Property, class PropRef>
Chris@16 2474 struct adj_list_vertex_all_properties_map
Chris@16 2475 : public boost::put_get_helper<PropRef,
Chris@16 2476 adj_list_vertex_all_properties_map<Graph, Property, PropRef>
Chris@16 2477 >
Chris@16 2478 {
Chris@16 2479 typedef typename Graph::stored_vertex StoredVertex;
Chris@16 2480 typedef Property value_type;
Chris@16 2481 typedef PropRef reference;
Chris@16 2482 typedef typename Graph::vertex_descriptor key_type;
Chris@16 2483 typedef boost::lvalue_property_map_tag category;
Chris@16 2484 inline adj_list_vertex_all_properties_map(const Graph* = 0, vertex_all_t = vertex_all_t()) { }
Chris@16 2485 inline PropRef operator[](key_type v) const {
Chris@16 2486 StoredVertex* sv = (StoredVertex*)v;
Chris@16 2487 return sv->m_property;
Chris@16 2488 }
Chris@16 2489 inline PropRef operator()(key_type v) const {
Chris@16 2490 return this->operator[](v);
Chris@16 2491 }
Chris@16 2492 };
Chris@16 2493
Chris@16 2494 template <class Graph, class GraphPtr, class ValueType, class Reference,
Chris@16 2495 class Tag>
Chris@16 2496 struct vec_adj_list_vertex_property_map
Chris@16 2497 : public boost::put_get_helper<
Chris@16 2498 Reference,
Chris@16 2499 vec_adj_list_vertex_property_map<Graph,GraphPtr,ValueType,Reference,
Chris@16 2500 Tag>
Chris@16 2501 >
Chris@16 2502 {
Chris@16 2503 typedef ValueType value_type;
Chris@16 2504 typedef Reference reference;
Chris@16 2505 typedef typename boost::graph_traits<Graph>::vertex_descriptor key_type;
Chris@16 2506 typedef boost::lvalue_property_map_tag category;
Chris@16 2507 vec_adj_list_vertex_property_map(GraphPtr g = 0, Tag tag = Tag()) : m_g(g), m_tag(tag) { }
Chris@16 2508 inline Reference operator[](key_type v) const {
Chris@16 2509 return get_property_value(m_g->m_vertices[v].m_property, m_tag);
Chris@16 2510 }
Chris@16 2511 inline Reference operator()(key_type v) const {
Chris@16 2512 return this->operator[](v);
Chris@16 2513 }
Chris@16 2514 GraphPtr m_g;
Chris@16 2515 Tag m_tag;
Chris@16 2516 };
Chris@16 2517
Chris@16 2518 template <class Graph, class GraphPtr, class Property, class PropertyRef>
Chris@16 2519 struct vec_adj_list_vertex_all_properties_map
Chris@16 2520 : public boost::put_get_helper<PropertyRef,
Chris@16 2521 vec_adj_list_vertex_all_properties_map<Graph,GraphPtr,Property,
Chris@16 2522 PropertyRef>
Chris@16 2523 >
Chris@16 2524 {
Chris@16 2525 typedef Property value_type;
Chris@16 2526 typedef PropertyRef reference;
Chris@16 2527 typedef typename boost::graph_traits<Graph>::vertex_descriptor key_type;
Chris@16 2528 typedef boost::lvalue_property_map_tag category;
Chris@16 2529 vec_adj_list_vertex_all_properties_map(GraphPtr g = 0, vertex_all_t = vertex_all_t()) : m_g(g) { }
Chris@16 2530 inline PropertyRef operator[](key_type v) const {
Chris@16 2531 return m_g->m_vertices[v].m_property;
Chris@16 2532 }
Chris@16 2533 inline PropertyRef operator()(key_type v) const {
Chris@16 2534 return this->operator[](v);
Chris@16 2535 }
Chris@16 2536 GraphPtr m_g;
Chris@16 2537 };
Chris@16 2538
Chris@16 2539 struct adj_list_any_vertex_pa {
Chris@16 2540 template <class Tag, class Graph, class Property>
Chris@16 2541 struct bind_ {
Chris@16 2542 typedef typename property_value<Property, Tag>::type value_type;
Chris@16 2543 typedef value_type& reference;
Chris@16 2544 typedef const value_type& const_reference;
Chris@16 2545
Chris@16 2546 typedef adj_list_vertex_property_map
Chris@16 2547 <Graph, value_type, reference, Tag> type;
Chris@16 2548 typedef adj_list_vertex_property_map
Chris@16 2549 <Graph, value_type, const_reference, Tag> const_type;
Chris@16 2550 };
Chris@16 2551 };
Chris@16 2552 struct adj_list_all_vertex_pa {
Chris@16 2553 template <class Tag, class Graph, class Property>
Chris@16 2554 struct bind_ {
Chris@16 2555 typedef typename Graph::vertex_descriptor Vertex;
Chris@16 2556 typedef adj_list_vertex_all_properties_map<Graph,Property,
Chris@16 2557 Property&> type;
Chris@16 2558 typedef adj_list_vertex_all_properties_map<Graph,Property,
Chris@16 2559 const Property&> const_type;
Chris@16 2560 };
Chris@16 2561 };
Chris@16 2562
Chris@16 2563 template <class Property, class Vertex>
Chris@16 2564 struct vec_adj_list_vertex_id_map
Chris@16 2565 : public boost::put_get_helper<
Chris@16 2566 Vertex, vec_adj_list_vertex_id_map<Property, Vertex>
Chris@16 2567 >
Chris@16 2568 {
Chris@16 2569 typedef Vertex value_type;
Chris@16 2570 typedef Vertex key_type;
Chris@16 2571 typedef Vertex reference;
Chris@16 2572 typedef boost::readable_property_map_tag category;
Chris@16 2573 inline vec_adj_list_vertex_id_map() { }
Chris@16 2574 template <class Graph>
Chris@16 2575 inline vec_adj_list_vertex_id_map(const Graph&, vertex_index_t) { }
Chris@16 2576 inline value_type operator[](key_type v) const { return v; }
Chris@16 2577 inline value_type operator()(key_type v) const { return v; }
Chris@16 2578 };
Chris@16 2579
Chris@16 2580 struct vec_adj_list_any_vertex_pa {
Chris@16 2581 template <class Tag, class Graph, class Property>
Chris@16 2582 struct bind_ {
Chris@16 2583 typedef typename property_value<Property, Tag>::type value_type;
Chris@16 2584 typedef value_type& reference;
Chris@16 2585 typedef const value_type& const_reference;
Chris@16 2586
Chris@16 2587 typedef vec_adj_list_vertex_property_map
Chris@16 2588 <Graph, Graph*, value_type, reference, Tag> type;
Chris@16 2589 typedef vec_adj_list_vertex_property_map
Chris@16 2590 <Graph, const Graph*, value_type, const_reference, Tag> const_type;
Chris@16 2591 };
Chris@16 2592 };
Chris@16 2593 struct vec_adj_list_id_vertex_pa {
Chris@16 2594 template <class Tag, class Graph, class Property>
Chris@16 2595 struct bind_ {
Chris@16 2596 typedef typename Graph::vertex_descriptor Vertex;
Chris@16 2597 typedef vec_adj_list_vertex_id_map<Property, Vertex> type;
Chris@16 2598 typedef vec_adj_list_vertex_id_map<Property, Vertex> const_type;
Chris@16 2599 };
Chris@16 2600 };
Chris@16 2601 struct vec_adj_list_all_vertex_pa {
Chris@16 2602 template <class Tag, class Graph, class Property>
Chris@16 2603 struct bind_ {
Chris@16 2604 typedef typename Graph::vertex_descriptor Vertex;
Chris@16 2605 typedef vec_adj_list_vertex_all_properties_map
Chris@16 2606 <Graph, Graph*, Property, Property&> type;
Chris@16 2607 typedef vec_adj_list_vertex_all_properties_map
Chris@16 2608 <Graph, const Graph*, Property, const Property&> const_type;
Chris@16 2609 };
Chris@16 2610 };
Chris@16 2611 namespace detail {
Chris@16 2612 template <class Tag, class Graph, class Property>
Chris@16 2613 struct adj_list_choose_vertex_pa
Chris@16 2614 : boost::mpl::if_<
Chris@16 2615 boost::is_same<Tag, vertex_all_t>,
Chris@16 2616 adj_list_all_vertex_pa,
Chris@16 2617 adj_list_any_vertex_pa>::type
Chris@16 2618 ::template bind_<Tag, Graph, Property>
Chris@16 2619 {};
Chris@16 2620
Chris@16 2621
Chris@16 2622 template <class Tag>
Chris@16 2623 struct vec_adj_list_choose_vertex_pa_helper {
Chris@16 2624 typedef vec_adj_list_any_vertex_pa type;
Chris@16 2625 };
Chris@16 2626 template <>
Chris@16 2627 struct vec_adj_list_choose_vertex_pa_helper<vertex_index_t> {
Chris@16 2628 typedef vec_adj_list_id_vertex_pa type;
Chris@16 2629 };
Chris@16 2630 template <>
Chris@16 2631 struct vec_adj_list_choose_vertex_pa_helper<vertex_all_t> {
Chris@16 2632 typedef vec_adj_list_all_vertex_pa type;
Chris@16 2633 };
Chris@16 2634 template <class Tag, class Graph, class Property>
Chris@16 2635 struct vec_adj_list_choose_vertex_pa
Chris@16 2636 : vec_adj_list_choose_vertex_pa_helper<Tag>::type::template bind_<Tag,Graph,Property>
Chris@16 2637 {};
Chris@16 2638 } // namespace detail
Chris@16 2639
Chris@16 2640 //=========================================================================
Chris@16 2641 // Edge Property Map
Chris@16 2642
Chris@16 2643 template <class Directed, class Value, class Ref, class Vertex,
Chris@16 2644 class Property, class Tag>
Chris@16 2645 struct adj_list_edge_property_map
Chris@16 2646 : public put_get_helper<
Chris@16 2647 Ref,
Chris@16 2648 adj_list_edge_property_map<Directed, Value, Ref, Vertex, Property,
Chris@16 2649 Tag>
Chris@16 2650 >
Chris@16 2651 {
Chris@16 2652 Tag tag;
Chris@16 2653 explicit adj_list_edge_property_map(Tag tag = Tag()): tag(tag) {}
Chris@16 2654
Chris@16 2655 typedef Value value_type;
Chris@16 2656 typedef Ref reference;
Chris@16 2657 typedef detail::edge_desc_impl<Directed, Vertex> key_type;
Chris@16 2658 typedef boost::lvalue_property_map_tag category;
Chris@16 2659 inline Ref operator[](key_type e) const {
Chris@16 2660 Property& p = *(Property*)e.get_property();
Chris@16 2661 return get_property_value(p, tag);
Chris@16 2662 }
Chris@16 2663 inline Ref operator()(key_type e) const {
Chris@16 2664 return this->operator[](e);
Chris@16 2665 }
Chris@16 2666 };
Chris@16 2667
Chris@16 2668 template <class Directed, class Property, class PropRef, class PropPtr,
Chris@16 2669 class Vertex>
Chris@16 2670 struct adj_list_edge_all_properties_map
Chris@16 2671 : public put_get_helper<PropRef,
Chris@16 2672 adj_list_edge_all_properties_map<Directed, Property, PropRef,
Chris@16 2673 PropPtr, Vertex>
Chris@16 2674 >
Chris@16 2675 {
Chris@16 2676 explicit adj_list_edge_all_properties_map(edge_all_t = edge_all_t()) {}
Chris@16 2677 typedef Property value_type;
Chris@16 2678 typedef PropRef reference;
Chris@16 2679 typedef detail::edge_desc_impl<Directed, Vertex> key_type;
Chris@16 2680 typedef boost::lvalue_property_map_tag category;
Chris@16 2681 inline PropRef operator[](key_type e) const {
Chris@16 2682 return *(PropPtr)e.get_property();
Chris@16 2683 }
Chris@16 2684 inline PropRef operator()(key_type e) const {
Chris@16 2685 return this->operator[](e);
Chris@16 2686 }
Chris@16 2687 };
Chris@16 2688
Chris@16 2689 // Edge Property Maps
Chris@16 2690
Chris@16 2691 namespace detail {
Chris@16 2692 struct adj_list_any_edge_pmap {
Chris@16 2693 template <class Graph, class Property, class Tag>
Chris@16 2694 struct bind_ {
Chris@16 2695 typedef typename property_value<Property,Tag>::type value_type;
Chris@16 2696 typedef value_type& reference;
Chris@16 2697 typedef const value_type& const_reference;
Chris@16 2698
Chris@16 2699 typedef adj_list_edge_property_map
Chris@16 2700 <typename Graph::directed_category, value_type, reference,
Chris@16 2701 typename Graph::vertex_descriptor,Property,Tag> type;
Chris@16 2702 typedef adj_list_edge_property_map
Chris@16 2703 <typename Graph::directed_category, value_type, const_reference,
Chris@16 2704 typename Graph::vertex_descriptor,const Property, Tag> const_type;
Chris@16 2705 };
Chris@16 2706 };
Chris@16 2707 struct adj_list_all_edge_pmap {
Chris@16 2708 template <class Graph, class Property, class Tag>
Chris@16 2709 struct bind_ {
Chris@16 2710 typedef adj_list_edge_all_properties_map
Chris@16 2711 <typename Graph::directed_category, Property, Property&, Property*,
Chris@16 2712 typename Graph::vertex_descriptor> type;
Chris@16 2713 typedef adj_list_edge_all_properties_map
Chris@16 2714 <typename Graph::directed_category, Property, const Property&,
Chris@16 2715 const Property*, typename Graph::vertex_descriptor> const_type;
Chris@16 2716 };
Chris@16 2717 };
Chris@16 2718
Chris@16 2719 template <class Tag>
Chris@16 2720 struct adj_list_choose_edge_pmap_helper {
Chris@16 2721 typedef adj_list_any_edge_pmap type;
Chris@16 2722 };
Chris@16 2723 template <>
Chris@16 2724 struct adj_list_choose_edge_pmap_helper<edge_all_t> {
Chris@16 2725 typedef adj_list_all_edge_pmap type;
Chris@16 2726 };
Chris@16 2727 template <class Tag, class Graph, class Property>
Chris@16 2728 struct adj_list_choose_edge_pmap
Chris@16 2729 : adj_list_choose_edge_pmap_helper<Tag>::type::template bind_<Graph, Property, Tag>
Chris@16 2730 {};
Chris@16 2731 struct adj_list_edge_property_selector {
Chris@16 2732 template <class Graph, class Property, class Tag>
Chris@16 2733 struct bind_: adj_list_choose_edge_pmap<Tag, Graph, Property> {};
Chris@16 2734 };
Chris@16 2735 } // namespace detail
Chris@16 2736
Chris@16 2737 template <>
Chris@16 2738 struct edge_property_selector<adj_list_tag> {
Chris@16 2739 typedef detail::adj_list_edge_property_selector type;
Chris@16 2740 };
Chris@16 2741 template <>
Chris@16 2742 struct edge_property_selector<vec_adj_list_tag> {
Chris@16 2743 typedef detail::adj_list_edge_property_selector type;
Chris@16 2744 };
Chris@16 2745
Chris@16 2746 // Vertex Property Maps
Chris@16 2747
Chris@16 2748 struct adj_list_vertex_property_selector {
Chris@16 2749 template <class Graph, class Property, class Tag>
Chris@16 2750 struct bind_
Chris@16 2751 : detail::adj_list_choose_vertex_pa<Tag,Graph,Property>
Chris@16 2752 {};
Chris@16 2753 };
Chris@16 2754 template <>
Chris@16 2755 struct vertex_property_selector<adj_list_tag> {
Chris@16 2756 typedef adj_list_vertex_property_selector type;
Chris@16 2757 };
Chris@16 2758
Chris@16 2759 struct vec_adj_list_vertex_property_selector {
Chris@16 2760 template <class Graph, class Property, class Tag>
Chris@16 2761 struct bind_: detail::vec_adj_list_choose_vertex_pa<Tag,Graph,Property> {};
Chris@16 2762 };
Chris@16 2763 template <>
Chris@16 2764 struct vertex_property_selector<vec_adj_list_tag> {
Chris@16 2765 typedef vec_adj_list_vertex_property_selector type;
Chris@16 2766 };
Chris@16 2767
Chris@16 2768 } // namespace boost
Chris@16 2769
Chris@16 2770 namespace boost {
Chris@16 2771
Chris@16 2772 template <typename V>
Chris@16 2773 struct hash< boost::detail::stored_edge<V> >
Chris@16 2774 {
Chris@16 2775 std::size_t
Chris@16 2776 operator()(const boost::detail::stored_edge<V>& e) const
Chris@16 2777 {
Chris@16 2778 return hash<V>()(e.m_target);
Chris@16 2779 }
Chris@16 2780 };
Chris@16 2781
Chris@16 2782 template <typename V, typename P>
Chris@16 2783 struct hash< boost::detail::stored_edge_property <V,P> >
Chris@16 2784 {
Chris@16 2785 std::size_t
Chris@16 2786 operator()(const boost::detail::stored_edge_property<V,P>& e) const
Chris@16 2787 {
Chris@16 2788 return hash<V>()(e.m_target);
Chris@16 2789 }
Chris@16 2790 };
Chris@16 2791
Chris@16 2792 template <typename V, typename I, typename P>
Chris@16 2793 struct hash< boost::detail::stored_edge_iter<V,I, P> >
Chris@16 2794 {
Chris@16 2795 std::size_t
Chris@16 2796 operator()(const boost::detail::stored_edge_iter<V,I,P>& e) const
Chris@16 2797 {
Chris@16 2798 return hash<V>()(e.m_target);
Chris@16 2799 }
Chris@16 2800 };
Chris@16 2801
Chris@16 2802 }
Chris@16 2803
Chris@16 2804
Chris@16 2805 #endif // BOOST_GRAPH_DETAIL_DETAIL_ADJACENCY_LIST_CCT
Chris@16 2806
Chris@16 2807 /*
Chris@16 2808 Implementation Notes:
Chris@16 2809
Chris@16 2810 Many of the public interface functions in this file would have been
Chris@16 2811 more conveniently implemented as inline friend functions.
Chris@16 2812 However there are a few compiler bugs that make that approach
Chris@16 2813 non-portable.
Chris@16 2814
Chris@16 2815 1. g++ inline friend in namespace bug
Chris@16 2816 2. g++ using clause doesn't work with inline friends
Chris@16 2817 3. VC++ doesn't have Koenig lookup
Chris@16 2818
Chris@16 2819 For these reasons, the functions were all written as non-inline free
Chris@16 2820 functions, and static cast was used to convert from the helper
Chris@16 2821 class to the adjacency_list derived class.
Chris@16 2822
Chris@16 2823 Looking back, it might have been better to write out all functions
Chris@16 2824 in terms of the adjacency_list, and then use a tag to dispatch
Chris@16 2825 to the various helpers instead of using inheritance.
Chris@16 2826
Chris@16 2827 */