File indexing completed on 2025-01-18 09:37:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_GRAPH_DETAIL_ADJACENCY_LIST_HPP
0013 #define BOOST_GRAPH_DETAIL_ADJACENCY_LIST_HPP
0014
0015 #include <map> // for vertex_map in copy_impl
0016 #include <boost/config.hpp>
0017 #include <boost/detail/workaround.hpp>
0018 #include <boost/operators.hpp>
0019 #include <boost/property_map/property_map.hpp>
0020 #include <boost/pending/container_traits.hpp>
0021 #include <boost/range/irange.hpp>
0022 #include <boost/graph/graph_traits.hpp>
0023 #include <memory>
0024 #include <iterator>
0025 #include <algorithm>
0026 #include <boost/limits.hpp>
0027
0028 #include <boost/iterator/iterator_adaptor.hpp>
0029
0030 #include <boost/mpl/if.hpp>
0031 #include <boost/mpl/not.hpp>
0032 #include <boost/mpl/and.hpp>
0033 #include <boost/graph/graph_concepts.hpp>
0034 #include <boost/pending/container_traits.hpp>
0035 #include <boost/graph/detail/adj_list_edge_iterator.hpp>
0036 #include <boost/graph/properties.hpp>
0037 #include <boost/pending/property.hpp>
0038 #include <boost/graph/adjacency_iterator.hpp>
0039 #include <boost/static_assert.hpp>
0040 #include <boost/assert.hpp>
0041
0042 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
0043 #define BOOST_GRAPH_MOVE_IF_POSSIBLE(x) (x)
0044 #else
0045 #include <utility>
0046 #define BOOST_GRAPH_MOVE_IF_POSSIBLE(x) (std::move((x)))
0047 #endif
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 namespace boost
0074 {
0075
0076 namespace detail
0077 {
0078
0079 template < typename DirectedS > struct directed_category_traits
0080 {
0081 typedef directed_tag directed_category;
0082 };
0083
0084 template <> struct directed_category_traits< directedS >
0085 {
0086 typedef directed_tag directed_category;
0087 };
0088 template <> struct directed_category_traits< undirectedS >
0089 {
0090 typedef undirected_tag directed_category;
0091 };
0092 template <> struct directed_category_traits< bidirectionalS >
0093 {
0094 typedef bidirectional_tag directed_category;
0095 };
0096
0097 template < class Vertex > struct target_is
0098 {
0099 target_is(const Vertex& v) : m_target(v) {}
0100 template < class StoredEdge > bool operator()(const StoredEdge& e) const
0101 {
0102 return e.get_target() == m_target;
0103 }
0104 Vertex m_target;
0105 };
0106
0107
0108 template < class EdgeList, class vertex_descriptor >
0109 void erase_from_incidence_list(
0110 EdgeList& el, vertex_descriptor v, allow_parallel_edge_tag)
0111 {
0112 boost::graph_detail::erase_if(
0113 el, detail::target_is< vertex_descriptor >(v));
0114 }
0115
0116 template < class EdgeList, class vertex_descriptor >
0117 void erase_from_incidence_list(
0118 EdgeList& el, vertex_descriptor v, disallow_parallel_edge_tag)
0119 {
0120 typedef typename EdgeList::value_type StoredEdge;
0121 el.erase(StoredEdge(v));
0122 }
0123
0124
0125
0126
0127 template < class BaseIter, class VertexDescriptor, class EdgeDescriptor,
0128 class Difference >
0129 struct out_edge_iter
0130 : iterator_adaptor< out_edge_iter< BaseIter, VertexDescriptor,
0131 EdgeDescriptor, Difference >,
0132 BaseIter, EdgeDescriptor, use_default, EdgeDescriptor, Difference >
0133 {
0134 typedef iterator_adaptor< out_edge_iter< BaseIter, VertexDescriptor,
0135 EdgeDescriptor, Difference >,
0136 BaseIter, EdgeDescriptor, use_default, EdgeDescriptor, Difference >
0137 super_t;
0138
0139 inline out_edge_iter() {}
0140 inline out_edge_iter(const BaseIter& i, const VertexDescriptor& src)
0141 : super_t(i), m_src(src)
0142 {
0143 }
0144
0145 inline EdgeDescriptor dereference() const
0146 {
0147 return EdgeDescriptor(m_src, (*this->base()).get_target(),
0148 &(*this->base()).get_property());
0149 }
0150 VertexDescriptor m_src;
0151 };
0152
0153 template < class BaseIter, class VertexDescriptor, class EdgeDescriptor,
0154 class Difference >
0155 struct in_edge_iter
0156 : iterator_adaptor< in_edge_iter< BaseIter, VertexDescriptor,
0157 EdgeDescriptor, Difference >,
0158 BaseIter, EdgeDescriptor, use_default, EdgeDescriptor, Difference >
0159 {
0160 typedef iterator_adaptor< in_edge_iter< BaseIter, VertexDescriptor,
0161 EdgeDescriptor, Difference >,
0162 BaseIter, EdgeDescriptor, use_default, EdgeDescriptor, Difference >
0163 super_t;
0164
0165 inline in_edge_iter() {}
0166 inline in_edge_iter(const BaseIter& i, const VertexDescriptor& src)
0167 : super_t(i), m_src(src)
0168 {
0169 }
0170
0171 inline EdgeDescriptor dereference() const
0172 {
0173 return EdgeDescriptor((*this->base()).get_target(), m_src,
0174 &this->base()->get_property());
0175 }
0176 VertexDescriptor m_src;
0177 };
0178
0179
0180
0181
0182 template < class EdgeIter, class EdgeDescriptor, class Difference >
0183 struct undirected_edge_iter
0184 : iterator_adaptor<
0185 undirected_edge_iter< EdgeIter, EdgeDescriptor, Difference >,
0186 EdgeIter, EdgeDescriptor, use_default, EdgeDescriptor, Difference >
0187 {
0188 typedef iterator_adaptor<
0189 undirected_edge_iter< EdgeIter, EdgeDescriptor, Difference >,
0190 EdgeIter, EdgeDescriptor, use_default, EdgeDescriptor, Difference >
0191 super_t;
0192
0193 undirected_edge_iter() {}
0194
0195 explicit undirected_edge_iter(EdgeIter i) : super_t(i) {}
0196
0197 inline EdgeDescriptor dereference() const
0198 {
0199 return EdgeDescriptor((*this->base()).m_source,
0200 (*this->base()).m_target, &this->base()->get_property());
0201 }
0202 };
0203
0204
0205
0206
0207 template < class Vertex >
0208 class stored_edge
0209 : public boost::equality_comparable1< stored_edge< Vertex >,
0210 boost::less_than_comparable1< stored_edge< Vertex > > >
0211 {
0212 public:
0213 typedef no_property property_type;
0214 inline stored_edge() {}
0215 inline stored_edge(Vertex target, const no_property& = no_property())
0216 : m_target(target)
0217 {
0218 }
0219 inline Vertex& get_target() const { return m_target; }
0220 inline const no_property& get_property() const { return s_prop; }
0221 inline bool operator==(const stored_edge& x) const
0222 {
0223 return m_target == x.get_target();
0224 }
0225 inline bool operator<(const stored_edge& x) const
0226 {
0227 return m_target < x.get_target();
0228 }
0229
0230 static no_property s_prop;
0231
0232
0233 mutable Vertex m_target;
0234 };
0235 template < class Vertex > no_property stored_edge< Vertex >::s_prop;
0236
0237 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) \
0238 || defined(BOOST_NO_CXX11_SMART_PTR)
0239 template < class Vertex, class Property >
0240 class stored_edge_property : public stored_edge< Vertex >
0241 {
0242 typedef stored_edge_property self;
0243 typedef stored_edge< Vertex > Base;
0244
0245 public:
0246 typedef Property property_type;
0247 inline stored_edge_property() {}
0248 inline stored_edge_property(
0249 Vertex target, const Property& p = Property())
0250 : stored_edge< Vertex >(target), m_property(new Property(p))
0251 {
0252 }
0253 stored_edge_property(const self& x)
0254 : Base(static_cast< Base const& >(x))
0255 , m_property(const_cast< self& >(x).m_property)
0256 {
0257 }
0258 self& operator=(const self& x)
0259 {
0260
0261
0262 static_cast< Base& >(*this) = static_cast< Base const& >(x);
0263 m_property = const_cast< self& >(x).m_property;
0264 return *this;
0265 }
0266 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0267
0268
0269 stored_edge_property(self&& x)
0270 : Base(static_cast< Base&& >(x)), m_property(std::move(x.m_property))
0271 {
0272 }
0273 self& operator=(self&& x)
0274 {
0275
0276
0277 static_cast< Base& >(*this) = static_cast< Base&& >(x);
0278 m_property = std::move(x.m_property);
0279 return *this;
0280 }
0281 #endif
0282 inline Property& get_property() { return *m_property; }
0283 inline const Property& get_property() const { return *m_property; }
0284
0285 protected:
0286
0287
0288
0289
0290 #ifdef BOOST_NO_AUTO_PTR
0291 std::unique_ptr< Property > m_property;
0292 #else
0293 std::auto_ptr< Property > m_property;
0294 #endif
0295 };
0296 #else
0297 template < class Vertex, class Property >
0298 class stored_edge_property : public stored_edge< Vertex >
0299 {
0300 typedef stored_edge_property self;
0301 typedef stored_edge< Vertex > Base;
0302
0303 public:
0304 typedef Property property_type;
0305 inline stored_edge_property() {}
0306 inline stored_edge_property(
0307 Vertex target, const Property& p = Property())
0308 : stored_edge< Vertex >(target), m_property(new Property(p))
0309 {
0310 }
0311 stored_edge_property(self&& x)
0312 : Base(static_cast< Base&& >(x)), m_property(std::move(x.m_property))
0313 {
0314 }
0315 stored_edge_property(self const& x)
0316 : Base(static_cast< Base const& >(x))
0317 , m_property(std::move(const_cast< self& >(x).m_property))
0318 {
0319 }
0320 self& operator=(self&& x)
0321 {
0322
0323
0324 static_cast< Base& >(*this) = static_cast< Base&& >(x);
0325 m_property = std::move(x.m_property);
0326 return *this;
0327 }
0328 self& operator=(self const& x)
0329 {
0330
0331
0332 static_cast< Base& >(*this) = static_cast< Base const& >(x);
0333 m_property = std::move(const_cast< self& >(x).m_property);
0334 return *this;
0335 }
0336 inline Property& get_property() { return *m_property; }
0337 inline const Property& get_property() const { return *m_property; }
0338
0339 protected:
0340 std::unique_ptr< Property > m_property;
0341 };
0342 #endif
0343
0344 template < class Vertex, class Iter, class Property >
0345 class stored_edge_iter : public stored_edge< Vertex >
0346 {
0347 public:
0348 typedef Property property_type;
0349 inline stored_edge_iter() {}
0350 inline stored_edge_iter(Vertex v) : stored_edge< Vertex >(v) {}
0351 inline stored_edge_iter(Vertex v, Iter i, void* = 0)
0352 : stored_edge< Vertex >(v), m_iter(i)
0353 {
0354 }
0355 inline Property& get_property() { return m_iter->get_property(); }
0356 inline const Property& get_property() const
0357 {
0358 return m_iter->get_property();
0359 }
0360 inline Iter get_iter() const { return m_iter; }
0361
0362 protected:
0363 Iter m_iter;
0364 };
0365
0366
0367
0368
0369 template < class Vertex, class EdgeVec, class Property >
0370 class stored_ra_edge_iter : public stored_edge< Vertex >
0371 {
0372 typedef typename EdgeVec::iterator Iter;
0373
0374 public:
0375 typedef Property property_type;
0376 inline stored_ra_edge_iter() {}
0377 inline explicit stored_ra_edge_iter(
0378 Vertex v)
0379 : stored_edge< Vertex >(v), m_i(0), m_vec(0)
0380 {
0381 }
0382 inline stored_ra_edge_iter(Vertex v, Iter i, EdgeVec* edge_vec)
0383 : stored_edge< Vertex >(v), m_i(i - edge_vec->begin()), m_vec(edge_vec)
0384 {
0385 }
0386 inline Property& get_property()
0387 {
0388 BOOST_ASSERT((m_vec != 0));
0389 return (*m_vec)[m_i].get_property();
0390 }
0391 inline const Property& get_property() const
0392 {
0393 BOOST_ASSERT((m_vec != 0));
0394 return (*m_vec)[m_i].get_property();
0395 }
0396 inline Iter get_iter() const
0397 {
0398 BOOST_ASSERT((m_vec != 0));
0399 return m_vec->begin() + m_i;
0400 }
0401
0402 protected:
0403 std::size_t m_i;
0404 EdgeVec* m_vec;
0405 };
0406
0407 }
0408
0409 template < class Tag, class Vertex, class Property >
0410 const typename property_value< Property, Tag >::type& get(
0411 Tag property_tag, const detail::stored_edge_property< Vertex, Property >& e)
0412 {
0413 return get_property_value(e.get_property(), property_tag);
0414 }
0415
0416 template < class Tag, class Vertex, class Iter, class Property >
0417 const typename property_value< Property, Tag >::type& get(Tag property_tag,
0418 const detail::stored_edge_iter< Vertex, Iter, Property >& e)
0419 {
0420 return get_property_value(e.get_property(), property_tag);
0421 }
0422
0423 template < class Tag, class Vertex, class EdgeVec, class Property >
0424 const typename property_value< Property, Tag >::type& get(Tag property_tag,
0425 const detail::stored_ra_edge_iter< Vertex, EdgeVec, Property >& e)
0426 {
0427 return get_property_value(e.get_property(), property_tag);
0428 }
0429
0430
0431
0432
0433 namespace detail
0434 {
0435
0436
0437 template < class edge_descriptor, class EdgeList, class StoredProperty >
0438 inline void remove_directed_edge_dispatch(
0439 edge_descriptor, EdgeList& el, StoredProperty& p)
0440 {
0441 for (typename EdgeList::iterator i = el.begin(); i != el.end(); ++i)
0442 if (&(*i).get_property() == &p)
0443 {
0444 el.erase(i);
0445 return;
0446 }
0447 }
0448
0449 template < class incidence_iterator, class EdgeList, class Predicate >
0450 inline void remove_directed_edge_if_dispatch(incidence_iterator first,
0451 incidence_iterator last, EdgeList& el, Predicate pred,
0452 boost::allow_parallel_edge_tag)
0453 {
0454
0455 while (first != last && !pred(*first))
0456 ++first;
0457 incidence_iterator i = first;
0458 if (first != last)
0459 for (++i; i != last; ++i)
0460 if (!pred(*i))
0461 {
0462 *first.base() = BOOST_GRAPH_MOVE_IF_POSSIBLE(*i.base());
0463 ++first;
0464 }
0465 el.erase(first.base(), el.end());
0466 }
0467 template < class incidence_iterator, class EdgeList, class Predicate >
0468 inline void remove_directed_edge_if_dispatch(incidence_iterator first,
0469 incidence_iterator last, EdgeList& el, Predicate pred,
0470 boost::disallow_parallel_edge_tag)
0471 {
0472 for (incidence_iterator next = first; first != last; first = next)
0473 {
0474 ++next;
0475 if (pred(*first))
0476 el.erase(first.base());
0477 }
0478 }
0479
0480 template < class PropT, class Graph, class incidence_iterator,
0481 class EdgeList, class Predicate >
0482 inline void undirected_remove_out_edge_if_dispatch(Graph& g,
0483 incidence_iterator first, incidence_iterator last, EdgeList& el,
0484 Predicate pred, boost::allow_parallel_edge_tag)
0485 {
0486 typedef typename Graph::global_edgelist_selector EdgeListS;
0487 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
0488
0489
0490 while (first != last && !pred(*first))
0491 ++first;
0492 incidence_iterator i = first;
0493 bool self_loop_removed = false;
0494 if (first != last)
0495 for (; i != last; ++i)
0496 {
0497 if (self_loop_removed)
0498 {
0499
0500
0501
0502
0503 self_loop_removed = false;
0504 }
0505 else if (!pred(*i))
0506 {
0507 *first.base() = BOOST_GRAPH_MOVE_IF_POSSIBLE(*i.base());
0508 ++first;
0509 }
0510 else
0511 {
0512 if (source(*i, g) == target(*i, g))
0513 self_loop_removed = true;
0514 else
0515 {
0516
0517 detail::remove_directed_edge_dispatch(*i,
0518 g.out_edge_list(target(*i, g)),
0519 *(PropT*)(*i).get_property());
0520 }
0521
0522
0523 g.m_edges.erase((*i.base()).get_iter());
0524 }
0525 }
0526 el.erase(first.base(), el.end());
0527 }
0528 template < class PropT, class Graph, class incidence_iterator,
0529 class EdgeList, class Predicate >
0530 inline void undirected_remove_out_edge_if_dispatch(Graph& g,
0531 incidence_iterator first, incidence_iterator last, EdgeList& el,
0532 Predicate pred, boost::disallow_parallel_edge_tag)
0533 {
0534 typedef typename Graph::global_edgelist_selector EdgeListS;
0535 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
0536
0537 for (incidence_iterator next = first; first != last; first = next)
0538 {
0539 ++next;
0540 if (pred(*first))
0541 {
0542 if (source(*first, g) != target(*first, g))
0543 {
0544
0545 detail::remove_directed_edge_dispatch(*first,
0546 g.out_edge_list(target(*first, g)),
0547 *(PropT*)(*first).get_property());
0548 }
0549
0550
0551 g.m_edges.erase((*first.base()).get_iter());
0552
0553
0554 el.erase(first.base());
0555 }
0556 }
0557 }
0558
0559
0560 template < class edge_descriptor, class EdgeList, class StoredProperty >
0561 inline void remove_directed_edge_dispatch(
0562 edge_descriptor e, EdgeList& el, no_property&)
0563 {
0564 for (typename EdgeList::iterator i = el.begin(); i != el.end(); ++i)
0565 if ((*i).get_target() == e.m_target)
0566 {
0567 el.erase(i);
0568 return;
0569 }
0570 }
0571
0572 }
0573
0574 template < class Config > struct directed_edges_helper
0575 {
0576
0577
0578
0579
0580
0581 inline void remove_edge(typename Config::edge_descriptor e)
0582 {
0583 typedef typename Config::graph_type graph_type;
0584 graph_type& g = static_cast< graph_type& >(*this);
0585 typename Config::OutEdgeList& el = g.out_edge_list(source(e, g));
0586 typedef typename Config::OutEdgeList::value_type::property_type PType;
0587 detail::remove_directed_edge_dispatch(e, el, *(PType*)e.get_property());
0588 }
0589
0590
0591 inline void remove_edge(typename Config::out_edge_iterator iter)
0592 {
0593 typedef typename Config::graph_type graph_type;
0594 graph_type& g = static_cast< graph_type& >(*this);
0595 typename Config::edge_descriptor e = *iter;
0596 typename Config::OutEdgeList& el = g.out_edge_list(source(e, g));
0597 el.erase(iter.base());
0598 }
0599 };
0600
0601
0602 template < class Config >
0603 inline std::pair< typename Config::edge_iterator,
0604 typename Config::edge_iterator >
0605 edges(const directed_edges_helper< Config >& g_)
0606 {
0607 typedef typename Config::graph_type graph_type;
0608 typedef typename Config::edge_iterator edge_iterator;
0609 const graph_type& cg = static_cast< const graph_type& >(g_);
0610 graph_type& g = const_cast< graph_type& >(cg);
0611 return std::make_pair(edge_iterator(g.vertex_set().begin(),
0612 g.vertex_set().begin(), g.vertex_set().end(), g),
0613 edge_iterator(g.vertex_set().begin(), g.vertex_set().end(),
0614 g.vertex_set().end(), g));
0615 }
0616
0617
0618
0619
0620 struct adj_list_dir_traversal_tag : public virtual vertex_list_graph_tag,
0621 public virtual incidence_graph_tag,
0622 public virtual adjacency_graph_tag,
0623 public virtual edge_list_graph_tag
0624 {
0625 };
0626
0627 template < class Config >
0628 struct directed_graph_helper : public directed_edges_helper< Config >
0629 {
0630 typedef typename Config::edge_descriptor edge_descriptor;
0631 typedef adj_list_dir_traversal_tag traversal_category;
0632 };
0633
0634
0635 template < class Config >
0636 inline void remove_edge(typename Config::vertex_descriptor u,
0637 typename Config::vertex_descriptor v, directed_graph_helper< Config >& g_)
0638 {
0639 typedef typename Config::graph_type graph_type;
0640 typedef typename Config::edge_parallel_category Cat;
0641 graph_type& g = static_cast< graph_type& >(g_);
0642 detail::erase_from_incidence_list(g.out_edge_list(u), v, Cat());
0643 }
0644
0645 template < class Config, class Predicate >
0646 inline void remove_out_edge_if(typename Config::vertex_descriptor u,
0647 Predicate pred, directed_graph_helper< Config >& g_)
0648 {
0649 typedef typename Config::graph_type graph_type;
0650 graph_type& g = static_cast< graph_type& >(g_);
0651 typename Config::out_edge_iterator first, last;
0652 boost::tie(first, last) = out_edges(u, g);
0653 typedef typename Config::edge_parallel_category edge_parallel_category;
0654 detail::remove_directed_edge_if_dispatch(
0655 first, last, g.out_edge_list(u), pred, edge_parallel_category());
0656 }
0657
0658 template < class Config, class Predicate >
0659 inline void remove_edge_if(Predicate pred, directed_graph_helper< Config >& g_)
0660 {
0661 typedef typename Config::graph_type graph_type;
0662 graph_type& g = static_cast< graph_type& >(g_);
0663
0664 typename Config::vertex_iterator vi, vi_end;
0665 for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
0666 remove_out_edge_if(*vi, pred, g);
0667 }
0668
0669 template < class EdgeOrIter, class Config >
0670 inline void remove_edge(
0671 EdgeOrIter e_or_iter, directed_graph_helper< Config >& g_)
0672 {
0673 g_.remove_edge(e_or_iter);
0674 }
0675
0676
0677
0678 template < class Config >
0679 inline void clear_vertex(
0680 typename Config::vertex_descriptor u, directed_graph_helper< Config >& g_)
0681 {
0682 typedef typename Config::graph_type graph_type;
0683 typedef typename Config::edge_parallel_category Cat;
0684 graph_type& g = static_cast< graph_type& >(g_);
0685 typename Config::vertex_iterator vi, viend;
0686 for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi)
0687 detail::erase_from_incidence_list(g.out_edge_list(*vi), u, Cat());
0688 g.out_edge_list(u).clear();
0689
0690
0691 }
0692
0693 template < class Config >
0694 inline void clear_out_edges(
0695 typename Config::vertex_descriptor u, directed_graph_helper< Config >& g_)
0696 {
0697 typedef typename Config::graph_type graph_type;
0698 graph_type& g = static_cast< graph_type& >(g_);
0699 g.out_edge_list(u).clear();
0700
0701
0702 }
0703
0704
0705 template < class Config >
0706 inline typename Config::edges_size_type num_edges(
0707 const directed_graph_helper< Config >& g_)
0708 {
0709 typedef typename Config::graph_type graph_type;
0710 const graph_type& g = static_cast< const graph_type& >(g_);
0711 typename Config::edges_size_type num_e = 0;
0712 typename Config::vertex_iterator vi, vi_end;
0713 for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
0714 num_e += out_degree(*vi, g);
0715 return num_e;
0716 }
0717
0718
0719 template < class Config >
0720 inline std::pair< typename directed_graph_helper< Config >::edge_descriptor,
0721 bool >
0722 add_edge(typename Config::vertex_descriptor u,
0723 typename Config::vertex_descriptor v,
0724 const typename Config::edge_property_type& p,
0725 directed_graph_helper< Config >& g_)
0726 {
0727 typedef typename Config::edge_descriptor edge_descriptor;
0728 typedef typename Config::graph_type graph_type;
0729 typedef typename Config::StoredEdge StoredEdge;
0730 graph_type& g = static_cast< graph_type& >(g_);
0731 typename Config::OutEdgeList::iterator i;
0732 bool inserted;
0733 boost::tie(i, inserted)
0734 = boost::graph_detail::push(g.out_edge_list(u), StoredEdge(v, p));
0735 return std::make_pair(
0736 edge_descriptor(u, v, &(*i).get_property()), inserted);
0737 }
0738
0739
0740 template < class Config >
0741 inline std::pair< typename Config::edge_descriptor, bool > add_edge(
0742 typename Config::vertex_descriptor u, typename Config::vertex_descriptor v,
0743 directed_graph_helper< Config >& g_)
0744 {
0745 typename Config::edge_property_type p;
0746 return add_edge(u, v, p, g_);
0747 }
0748
0749
0750
0751 template < class Config > struct undirected_graph_helper;
0752
0753 struct undir_adj_list_traversal_tag : public virtual vertex_list_graph_tag,
0754 public virtual incidence_graph_tag,
0755 public virtual adjacency_graph_tag,
0756 public virtual edge_list_graph_tag,
0757 public virtual bidirectional_graph_tag
0758 {
0759 };
0760
0761 namespace detail
0762 {
0763
0764
0765 template < class StoredProperty > struct remove_undirected_edge_dispatch
0766 {
0767
0768
0769 template < class edge_descriptor, class Config >
0770 static void apply(edge_descriptor e,
0771 undirected_graph_helper< Config >& g_, StoredProperty& p)
0772 {
0773 typedef typename Config::global_edgelist_selector EdgeListS;
0774 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
0775
0776 typedef typename Config::graph_type graph_type;
0777 graph_type& g = static_cast< graph_type& >(g_);
0778
0779 typename Config::OutEdgeList& out_el
0780 = g.out_edge_list(source(e, g));
0781 typename Config::OutEdgeList::iterator out_i = out_el.begin();
0782 typename Config::EdgeIter edge_iter_to_erase;
0783 for (; out_i != out_el.end(); ++out_i)
0784 if (&(*out_i).get_property() == &p)
0785 {
0786 edge_iter_to_erase = (*out_i).get_iter();
0787 out_el.erase(out_i);
0788 break;
0789 }
0790 typename Config::OutEdgeList& in_el = g.out_edge_list(target(e, g));
0791 typename Config::OutEdgeList::iterator in_i = in_el.begin();
0792 for (; in_i != in_el.end(); ++in_i)
0793 if (&(*in_i).get_property() == &p)
0794 {
0795 in_el.erase(in_i);
0796 break;
0797 }
0798 g.m_edges.erase(edge_iter_to_erase);
0799 }
0800 };
0801
0802 template <> struct remove_undirected_edge_dispatch< no_property >
0803 {
0804
0805 template < class edge_descriptor, class Config >
0806 static void apply(edge_descriptor e,
0807 undirected_graph_helper< Config >& g_, no_property&)
0808 {
0809 typedef typename Config::global_edgelist_selector EdgeListS;
0810 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
0811
0812 typedef typename Config::graph_type graph_type;
0813 graph_type& g = static_cast< graph_type& >(g_);
0814 no_property* p = (no_property*)e.get_property();
0815 typename Config::OutEdgeList& out_el
0816 = g.out_edge_list(source(e, g));
0817 typename Config::OutEdgeList::iterator out_i = out_el.begin();
0818 typename Config::EdgeIter edge_iter_to_erase;
0819 for (; out_i != out_el.end(); ++out_i)
0820 if (&(*out_i).get_property() == p)
0821 {
0822 edge_iter_to_erase = (*out_i).get_iter();
0823 out_el.erase(out_i);
0824 break;
0825 }
0826 typename Config::OutEdgeList& in_el = g.out_edge_list(target(e, g));
0827 typename Config::OutEdgeList::iterator in_i = in_el.begin();
0828 for (; in_i != in_el.end(); ++in_i)
0829 if (&(*in_i).get_property() == p)
0830 {
0831 in_el.erase(in_i);
0832 break;
0833 }
0834 g.m_edges.erase(edge_iter_to_erase);
0835 }
0836 };
0837
0838
0839 template < class Graph, class EdgeList, class Vertex >
0840 inline void remove_edge_and_property(
0841 Graph& g, EdgeList& el, Vertex v, boost::allow_parallel_edge_tag cat)
0842 {
0843 typedef typename Graph::global_edgelist_selector EdgeListS;
0844 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
0845
0846 typename EdgeList::iterator i = el.begin(), end = el.end();
0847 for (; i != end; ++i)
0848 {
0849 if ((*i).get_target() == v)
0850 {
0851
0852
0853
0854
0855
0856 bool skip = (boost::next(i) != end
0857 && i->get_iter() == boost::next(i)->get_iter());
0858 g.m_edges.erase((*i).get_iter());
0859 if (skip)
0860 ++i;
0861 }
0862 }
0863 detail::erase_from_incidence_list(el, v, cat);
0864 }
0865
0866 template < class Graph, class EdgeList, class Vertex >
0867 inline void remove_edge_and_property(
0868 Graph& g, EdgeList& el, Vertex v, boost::disallow_parallel_edge_tag)
0869 {
0870 typedef typename Graph::global_edgelist_selector EdgeListS;
0871 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
0872
0873 typedef typename EdgeList::value_type StoredEdge;
0874 typename EdgeList::iterator i = el.find(StoredEdge(v)), end = el.end();
0875 if (i != end)
0876 {
0877 g.m_edges.erase((*i).get_iter());
0878 el.erase(i);
0879 }
0880 }
0881
0882 }
0883
0884 template < class Vertex, class EdgeProperty >
0885 struct list_edge
0886 : public boost::detail::edge_base< boost::undirected_tag, Vertex >
0887 {
0888 typedef EdgeProperty property_type;
0889 typedef boost::detail::edge_base< boost::undirected_tag, Vertex > Base;
0890 list_edge(Vertex u, Vertex v, const EdgeProperty& p = EdgeProperty())
0891 : Base(u, v), m_property(p)
0892 {
0893 }
0894 EdgeProperty& get_property() { return m_property; }
0895 const EdgeProperty& get_property() const { return m_property; }
0896
0897
0898 list_edge() {}
0899 bool operator==(const list_edge&) const { return false; }
0900 bool operator<(const list_edge&) const { return false; }
0901 EdgeProperty m_property;
0902 };
0903
0904 template < class Config > struct undirected_graph_helper
0905 {
0906
0907 typedef undir_adj_list_traversal_tag traversal_category;
0908
0909
0910
0911
0912
0913 inline void remove_edge(typename Config::edge_descriptor e)
0914 {
0915 typedef typename Config::global_edgelist_selector EdgeListS;
0916 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
0917
0918 typedef typename Config::OutEdgeList::value_type::property_type PType;
0919 detail::remove_undirected_edge_dispatch< PType >::apply(
0920 e, *this, *(PType*)e.get_property());
0921 }
0922
0923 inline void remove_edge(typename Config::out_edge_iterator iter)
0924 {
0925 this->remove_edge(*iter);
0926 }
0927 };
0928
0929
0930
0931 template < class C >
0932 inline typename C::InEdgeList& in_edge_list(
0933 undirected_graph_helper< C >&, typename C::vertex_descriptor v)
0934 {
0935 typename C::stored_vertex* sv = (typename C::stored_vertex*)v;
0936 return sv->m_out_edges;
0937 }
0938 template < class C >
0939 inline const typename C::InEdgeList& in_edge_list(
0940 const undirected_graph_helper< C >&, typename C::vertex_descriptor v)
0941 {
0942 typename C::stored_vertex* sv = (typename C::stored_vertex*)v;
0943 return sv->m_out_edges;
0944 }
0945
0946
0947 template < class EdgeOrIter, class Config >
0948 inline void remove_edge(EdgeOrIter e, undirected_graph_helper< Config >& g_)
0949 {
0950 typedef typename Config::global_edgelist_selector EdgeListS;
0951 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
0952
0953 g_.remove_edge(e);
0954 }
0955
0956
0957 template < class Config >
0958 void remove_edge(typename Config::vertex_descriptor u,
0959 typename Config::vertex_descriptor v, undirected_graph_helper< Config >& g_)
0960 {
0961 typedef typename Config::global_edgelist_selector EdgeListS;
0962 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
0963
0964 typedef typename Config::graph_type graph_type;
0965 graph_type& g = static_cast< graph_type& >(g_);
0966 typedef typename Config::edge_parallel_category Cat;
0967 detail::remove_edge_and_property(g, g.out_edge_list(u), v, Cat());
0968 detail::erase_from_incidence_list(g.out_edge_list(v), u, Cat());
0969 }
0970
0971 template < class Config, class Predicate >
0972 void remove_out_edge_if(typename Config::vertex_descriptor u, Predicate pred,
0973 undirected_graph_helper< Config >& g_)
0974 {
0975 typedef typename Config::global_edgelist_selector EdgeListS;
0976 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
0977
0978 typedef typename Config::graph_type graph_type;
0979 typedef typename Config::OutEdgeList::value_type::property_type PropT;
0980 graph_type& g = static_cast< graph_type& >(g_);
0981 typename Config::out_edge_iterator first, last;
0982 boost::tie(first, last) = out_edges(u, g);
0983 typedef typename Config::edge_parallel_category Cat;
0984 detail::undirected_remove_out_edge_if_dispatch< PropT >(
0985 g, first, last, g.out_edge_list(u), pred, Cat());
0986 }
0987 template < class Config, class Predicate >
0988 void remove_in_edge_if(typename Config::vertex_descriptor u, Predicate pred,
0989 undirected_graph_helper< Config >& g_)
0990 {
0991 typedef typename Config::global_edgelist_selector EdgeListS;
0992 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
0993
0994 remove_out_edge_if(u, pred, g_);
0995 }
0996
0997
0998 template < class Predicate, class Config >
0999 void remove_edge_if(Predicate pred, undirected_graph_helper< Config >& g_)
1000 {
1001 typedef typename Config::global_edgelist_selector EdgeListS;
1002 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
1003
1004 typedef typename Config::graph_type graph_type;
1005 graph_type& g = static_cast< graph_type& >(g_);
1006 typename Config::edge_iterator ei, ei_end, next;
1007 boost::tie(ei, ei_end) = edges(g);
1008 for (next = ei; ei != ei_end; ei = next)
1009 {
1010 ++next;
1011 if (pred(*ei))
1012 remove_edge(*ei, g);
1013 }
1014 }
1015
1016
1017 template < class Config >
1018 inline std::pair< typename Config::edge_iterator,
1019 typename Config::edge_iterator >
1020 edges(const undirected_graph_helper< Config >& g_)
1021 {
1022 typedef typename Config::graph_type graph_type;
1023 typedef typename Config::edge_iterator edge_iterator;
1024 const graph_type& cg = static_cast< const graph_type& >(g_);
1025 graph_type& g = const_cast< graph_type& >(cg);
1026 return std::make_pair(
1027 edge_iterator(g.m_edges.begin()), edge_iterator(g.m_edges.end()));
1028 }
1029
1030 template < class Config >
1031 inline typename Config::edges_size_type num_edges(
1032 const undirected_graph_helper< Config >& g_)
1033 {
1034 typedef typename Config::graph_type graph_type;
1035 const graph_type& g = static_cast< const graph_type& >(g_);
1036 return g.m_edges.size();
1037 }
1038
1039 template < class Config >
1040 inline void clear_vertex(
1041 typename Config::vertex_descriptor u, undirected_graph_helper< Config >& g_)
1042 {
1043 typedef typename Config::global_edgelist_selector EdgeListS;
1044 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
1045
1046 typedef typename Config::graph_type graph_type;
1047 graph_type& g = static_cast< graph_type& >(g_);
1048 while (true)
1049 {
1050 typename Config::out_edge_iterator ei, ei_end;
1051 boost::tie(ei, ei_end) = out_edges(u, g);
1052 if (ei == ei_end)
1053 break;
1054 remove_edge(*ei, g);
1055 }
1056 }
1057
1058
1059 template < class Config >
1060 inline std::pair< typename Config::edge_descriptor, bool > add_edge(
1061 typename Config::vertex_descriptor u, typename Config::vertex_descriptor v,
1062 const typename Config::edge_property_type& p,
1063 undirected_graph_helper< Config >& g_)
1064 {
1065 typedef typename Config::StoredEdge StoredEdge;
1066 typedef typename Config::edge_descriptor edge_descriptor;
1067 typedef typename Config::graph_type graph_type;
1068 graph_type& g = static_cast< graph_type& >(g_);
1069
1070 bool inserted;
1071 typename Config::EdgeContainer::value_type e(u, v, p);
1072 typename Config::EdgeContainer::iterator p_iter
1073 = graph_detail::push(g.m_edges, e).first;
1074
1075 typename Config::OutEdgeList::iterator i;
1076 boost::tie(i, inserted) = boost::graph_detail::push(
1077 g.out_edge_list(u), StoredEdge(v, p_iter, &g.m_edges));
1078 if (inserted)
1079 {
1080 boost::graph_detail::push(
1081 g.out_edge_list(v), StoredEdge(u, p_iter, &g.m_edges));
1082 return std::make_pair(
1083 edge_descriptor(u, v, &p_iter->get_property()), true);
1084 }
1085 else
1086 {
1087 g.m_edges.erase(p_iter);
1088 return std::make_pair(
1089 edge_descriptor(u, v, &i->get_iter()->get_property()), false);
1090 }
1091 }
1092 template < class Config >
1093 inline std::pair< typename Config::edge_descriptor, bool > add_edge(
1094 typename Config::vertex_descriptor u, typename Config::vertex_descriptor v,
1095 undirected_graph_helper< Config >& g_)
1096 {
1097 typename Config::edge_property_type p;
1098 return add_edge(u, v, p, g_);
1099 }
1100
1101
1102 template < class Config >
1103 inline typename Config::degree_size_type degree(
1104 typename Config::vertex_descriptor u,
1105 const undirected_graph_helper< Config >& g_)
1106 {
1107 typedef typename Config::graph_type Graph;
1108 const Graph& g = static_cast< const Graph& >(g_);
1109 return out_degree(u, g);
1110 }
1111
1112 template < class Config >
1113 inline std::pair< typename Config::in_edge_iterator,
1114 typename Config::in_edge_iterator >
1115 in_edges(typename Config::vertex_descriptor u,
1116 const undirected_graph_helper< Config >& g_)
1117 {
1118 typedef typename Config::graph_type Graph;
1119 const Graph& cg = static_cast< const Graph& >(g_);
1120 Graph& g = const_cast< Graph& >(cg);
1121 typedef typename Config::in_edge_iterator in_edge_iterator;
1122 return std::make_pair(in_edge_iterator(g.out_edge_list(u).begin(), u),
1123 in_edge_iterator(g.out_edge_list(u).end(), u));
1124 }
1125
1126 template < class Config >
1127 inline typename Config::degree_size_type in_degree(
1128 typename Config::vertex_descriptor u,
1129 const undirected_graph_helper< Config >& g_)
1130 {
1131 return degree(u, g_);
1132 }
1133
1134
1135
1136
1137 struct bidir_adj_list_traversal_tag : public virtual vertex_list_graph_tag,
1138 public virtual incidence_graph_tag,
1139 public virtual adjacency_graph_tag,
1140 public virtual edge_list_graph_tag,
1141 public virtual bidirectional_graph_tag
1142 {
1143 };
1144
1145 template < class Config >
1146 struct bidirectional_graph_helper : public directed_edges_helper< Config >
1147 {
1148 typedef bidir_adj_list_traversal_tag traversal_category;
1149 };
1150
1151
1152
1153 template < class C >
1154 inline typename C::InEdgeList& in_edge_list(
1155 bidirectional_graph_helper< C >&, typename C::vertex_descriptor v)
1156 {
1157 typename C::stored_vertex* sv = (typename C::stored_vertex*)v;
1158 return sv->m_in_edges;
1159 }
1160 template < class C >
1161 inline const typename C::InEdgeList& in_edge_list(
1162 const bidirectional_graph_helper< C >&, typename C::vertex_descriptor v)
1163 {
1164 typename C::stored_vertex* sv = (typename C::stored_vertex*)v;
1165 return sv->m_in_edges;
1166 }
1167
1168 template < class Predicate, class Config >
1169 inline void remove_edge_if(
1170 Predicate pred, bidirectional_graph_helper< Config >& g_)
1171 {
1172 typedef typename Config::global_edgelist_selector EdgeListS;
1173 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
1174
1175 typedef typename Config::graph_type graph_type;
1176 graph_type& g = static_cast< graph_type& >(g_);
1177 typename Config::edge_iterator ei, ei_end, next;
1178 boost::tie(ei, ei_end) = edges(g);
1179 for (next = ei; ei != ei_end; ei = next)
1180 {
1181 ++next;
1182 if (pred(*ei))
1183 remove_edge(*ei, g);
1184 }
1185 }
1186
1187 template < class Config >
1188 inline std::pair< typename Config::in_edge_iterator,
1189 typename Config::in_edge_iterator >
1190 in_edges(typename Config::vertex_descriptor u,
1191 const bidirectional_graph_helper< Config >& g_)
1192 {
1193 typedef typename Config::graph_type graph_type;
1194 const graph_type& cg = static_cast< const graph_type& >(g_);
1195 graph_type& g = const_cast< graph_type& >(cg);
1196 typedef typename Config::in_edge_iterator in_edge_iterator;
1197 return std::make_pair(in_edge_iterator(in_edge_list(g, u).begin(), u),
1198 in_edge_iterator(in_edge_list(g, u).end(), u));
1199 }
1200
1201
1202 template < class Config >
1203 inline std::pair< typename Config::edge_iterator,
1204 typename Config::edge_iterator >
1205 edges(const bidirectional_graph_helper< Config >& g_)
1206 {
1207 typedef typename Config::graph_type graph_type;
1208 typedef typename Config::edge_iterator edge_iterator;
1209 const graph_type& cg = static_cast< const graph_type& >(g_);
1210 graph_type& g = const_cast< graph_type& >(cg);
1211 return std::make_pair(
1212 edge_iterator(g.m_edges.begin()), edge_iterator(g.m_edges.end()));
1213 }
1214
1215
1216
1217
1218 template < class Config >
1219 struct bidirectional_graph_helper_with_property
1220 : public bidirectional_graph_helper< Config >
1221 {
1222 typedef typename Config::graph_type graph_type;
1223 typedef typename Config::out_edge_iterator out_edge_iterator;
1224
1225 std::pair< out_edge_iterator, out_edge_iterator > get_parallel_edge_sublist(
1226 typename Config::edge_descriptor e, const graph_type& g, void*)
1227 {
1228 return out_edges(source(e, g), g);
1229 }
1230
1231 std::pair< out_edge_iterator, out_edge_iterator > get_parallel_edge_sublist(
1232 typename Config::edge_descriptor e, const graph_type& g, setS*)
1233 {
1234 return edge_range(source(e, g), target(e, g), g);
1235 }
1236
1237 std::pair< out_edge_iterator, out_edge_iterator > get_parallel_edge_sublist(
1238 typename Config::edge_descriptor e, const graph_type& g, multisetS*)
1239 {
1240 return edge_range(source(e, g), target(e, g), g);
1241 }
1242
1243 std::pair< out_edge_iterator, out_edge_iterator > get_parallel_edge_sublist(
1244 typename Config::edge_descriptor e, const graph_type& g, hash_setS*)
1245 {
1246 return edge_range(source(e, g), target(e, g), g);
1247 }
1248
1249
1250
1251
1252
1253 void remove_edge(typename Config::edge_descriptor e)
1254 {
1255 typedef typename Config::global_edgelist_selector EdgeListS;
1256 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
1257
1258 graph_type& g = static_cast< graph_type& >(*this);
1259
1260 typedef typename Config::edgelist_selector OutEdgeListS;
1261
1262 std::pair< out_edge_iterator, out_edge_iterator > rng
1263 = get_parallel_edge_sublist(e, g, (OutEdgeListS*)(0));
1264 rng.first = std::find(rng.first, rng.second, e);
1265 BOOST_ASSERT(rng.first != rng.second);
1266 remove_edge(rng.first);
1267 }
1268
1269 inline void remove_edge(typename Config::out_edge_iterator iter)
1270 {
1271 typedef typename Config::global_edgelist_selector EdgeListS;
1272 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
1273
1274 typedef typename Config::graph_type graph_type;
1275 graph_type& g = static_cast< graph_type& >(*this);
1276 typename Config::edge_descriptor e = *iter;
1277 typename Config::OutEdgeList& oel = g.out_edge_list(source(e, g));
1278 typename Config::InEdgeList& iel = in_edge_list(g, target(e, g));
1279 typedef typename Config::OutEdgeList::value_type::property_type PType;
1280 PType& p = *(PType*)e.get_property();
1281 detail::remove_directed_edge_dispatch(*iter, iel, p);
1282 g.m_edges.erase(iter.base()->get_iter());
1283 oel.erase(iter.base());
1284 }
1285 };
1286
1287
1288
1289 template < class Config >
1290 inline void remove_edge(typename Config::vertex_descriptor u,
1291 typename Config::vertex_descriptor v,
1292 bidirectional_graph_helper_with_property< Config >& g_)
1293 {
1294 typedef typename Config::global_edgelist_selector EdgeListS;
1295 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
1296
1297 typedef typename Config::graph_type graph_type;
1298 graph_type& g = static_cast< graph_type& >(g_);
1299 typedef typename Config::edge_parallel_category Cat;
1300 detail::remove_edge_and_property(g, g.out_edge_list(u), v, Cat());
1301 detail::erase_from_incidence_list(in_edge_list(g, v), u, Cat());
1302 }
1303
1304
1305 template < class EdgeOrIter, class Config >
1306 inline void remove_edge(
1307 EdgeOrIter e, bidirectional_graph_helper_with_property< Config >& g_)
1308 {
1309 typedef typename Config::global_edgelist_selector EdgeListS;
1310 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
1311
1312 g_.remove_edge(e);
1313 }
1314
1315 template < class Config, class Predicate >
1316 inline void remove_out_edge_if(typename Config::vertex_descriptor u,
1317 Predicate pred, bidirectional_graph_helper_with_property< Config >& g_)
1318 {
1319 typedef typename Config::global_edgelist_selector EdgeListS;
1320 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
1321
1322 typedef typename Config::graph_type graph_type;
1323 typedef typename Config::OutEdgeList::value_type::property_type PropT;
1324 graph_type& g = static_cast< graph_type& >(g_);
1325
1326 typedef typename Config::EdgeIter EdgeIter;
1327 typedef std::vector< EdgeIter > Garbage;
1328 Garbage garbage;
1329
1330
1331
1332 typename Config::out_edge_iterator out_i, out_end;
1333 for (boost::tie(out_i, out_end) = out_edges(u, g); out_i != out_end;
1334 ++out_i)
1335 if (pred(*out_i))
1336 {
1337 detail::remove_directed_edge_dispatch(*out_i,
1338 in_edge_list(g, target(*out_i, g)),
1339 *(PropT*)(*out_i).get_property());
1340
1341
1342 garbage.push_back((*out_i.base()).get_iter());
1343 }
1344
1345
1346 typename Config::out_edge_iterator first, last;
1347 boost::tie(first, last) = out_edges(u, g);
1348 typedef typename Config::edge_parallel_category Cat;
1349 detail::remove_directed_edge_if_dispatch(
1350 first, last, g.out_edge_list(u), pred, Cat());
1351
1352
1353 for (typename Garbage::iterator i = garbage.begin(); i != garbage.end();
1354 ++i)
1355 g.m_edges.erase(*i);
1356 }
1357 template < class Config, class Predicate >
1358 inline void remove_in_edge_if(typename Config::vertex_descriptor v,
1359 Predicate pred, bidirectional_graph_helper_with_property< Config >& g_)
1360 {
1361 typedef typename Config::global_edgelist_selector EdgeListS;
1362 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
1363
1364 typedef typename Config::graph_type graph_type;
1365 typedef typename Config::OutEdgeList::value_type::property_type PropT;
1366 graph_type& g = static_cast< graph_type& >(g_);
1367
1368 typedef typename Config::EdgeIter EdgeIter;
1369 typedef std::vector< EdgeIter > Garbage;
1370 Garbage garbage;
1371
1372
1373
1374 typename Config::in_edge_iterator in_i, in_end;
1375 for (boost::tie(in_i, in_end) = in_edges(v, g); in_i != in_end; ++in_i)
1376 if (pred(*in_i))
1377 {
1378 typename Config::vertex_descriptor u = source(*in_i, g);
1379 detail::remove_directed_edge_dispatch(
1380 *in_i, g.out_edge_list(u), *(PropT*)(*in_i).get_property());
1381
1382
1383 garbage.push_back((*in_i.base()).get_iter());
1384 }
1385
1386 typename Config::in_edge_iterator first, last;
1387 boost::tie(first, last) = in_edges(v, g);
1388 typedef typename Config::edge_parallel_category Cat;
1389 detail::remove_directed_edge_if_dispatch(
1390 first, last, in_edge_list(g, v), pred, Cat());
1391
1392
1393 for (typename Garbage::iterator i = garbage.begin(); i != garbage.end();
1394 ++i)
1395 g.m_edges.erase(*i);
1396 }
1397
1398
1399 template < class Config >
1400 inline typename Config::edges_size_type num_edges(
1401 const bidirectional_graph_helper_with_property< Config >& g_)
1402 {
1403 typedef typename Config::graph_type graph_type;
1404 const graph_type& g = static_cast< const graph_type& >(g_);
1405 return g.m_edges.size();
1406 }
1407
1408
1409 template < class Config >
1410 inline void clear_vertex(typename Config::vertex_descriptor u,
1411 bidirectional_graph_helper_with_property< Config >& g_)
1412 {
1413 typedef typename Config::global_edgelist_selector EdgeListS;
1414 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
1415
1416 typedef typename Config::graph_type graph_type;
1417 typedef typename Config::edge_parallel_category Cat;
1418 graph_type& g = static_cast< graph_type& >(g_);
1419 typename Config::OutEdgeList& el = g.out_edge_list(u);
1420 typename Config::OutEdgeList::iterator ei = el.begin(), ei_end = el.end();
1421 for (; ei != ei_end; ++ei)
1422 {
1423 detail::erase_from_incidence_list(
1424 in_edge_list(g, (*ei).get_target()), u, Cat());
1425 g.m_edges.erase((*ei).get_iter());
1426 }
1427 typename Config::InEdgeList& in_el = in_edge_list(g, u);
1428 typename Config::InEdgeList::iterator in_ei = in_el.begin(),
1429 in_ei_end = in_el.end();
1430 for (; in_ei != in_ei_end; ++in_ei)
1431 {
1432 detail::erase_from_incidence_list(
1433 g.out_edge_list((*in_ei).get_target()), u, Cat());
1434 g.m_edges.erase((*in_ei).get_iter());
1435 }
1436 g.out_edge_list(u).clear();
1437 in_edge_list(g, u).clear();
1438 }
1439
1440 template < class Config >
1441 inline void clear_out_edges(typename Config::vertex_descriptor u,
1442 bidirectional_graph_helper_with_property< Config >& g_)
1443 {
1444 typedef typename Config::global_edgelist_selector EdgeListS;
1445 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
1446
1447 typedef typename Config::graph_type graph_type;
1448 typedef typename Config::edge_parallel_category Cat;
1449 graph_type& g = static_cast< graph_type& >(g_);
1450 typename Config::OutEdgeList& el = g.out_edge_list(u);
1451 typename Config::OutEdgeList::iterator ei = el.begin(), ei_end = el.end();
1452 for (; ei != ei_end; ++ei)
1453 {
1454 detail::erase_from_incidence_list(
1455 in_edge_list(g, (*ei).get_target()), u, Cat());
1456 g.m_edges.erase((*ei).get_iter());
1457 }
1458 g.out_edge_list(u).clear();
1459 }
1460
1461 template < class Config >
1462 inline void clear_in_edges(typename Config::vertex_descriptor u,
1463 bidirectional_graph_helper_with_property< Config >& g_)
1464 {
1465 typedef typename Config::global_edgelist_selector EdgeListS;
1466 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
1467
1468 typedef typename Config::graph_type graph_type;
1469 typedef typename Config::edge_parallel_category Cat;
1470 graph_type& g = static_cast< graph_type& >(g_);
1471 typename Config::InEdgeList& in_el = in_edge_list(g, u);
1472 typename Config::InEdgeList::iterator in_ei = in_el.begin(),
1473 in_ei_end = in_el.end();
1474 for (; in_ei != in_ei_end; ++in_ei)
1475 {
1476 detail::erase_from_incidence_list(
1477 g.out_edge_list((*in_ei).get_target()), u, Cat());
1478 g.m_edges.erase((*in_ei).get_iter());
1479 }
1480 in_edge_list(g, u).clear();
1481 }
1482
1483
1484
1485 template < class Config >
1486 inline std::pair< typename Config::edge_descriptor, bool > add_edge(
1487 typename Config::vertex_descriptor u, typename Config::vertex_descriptor v,
1488 const typename Config::edge_property_type& p,
1489 bidirectional_graph_helper_with_property< Config >& g_)
1490 {
1491 typedef typename Config::graph_type graph_type;
1492 graph_type& g = static_cast< graph_type& >(g_);
1493 typedef typename Config::edge_descriptor edge_descriptor;
1494 typedef typename Config::StoredEdge StoredEdge;
1495 bool inserted;
1496 typename Config::EdgeContainer::value_type e(u, v, p);
1497 typename Config::EdgeContainer::iterator p_iter
1498 = graph_detail::push(g.m_edges, e).first;
1499 typename Config::OutEdgeList::iterator i;
1500 boost::tie(i, inserted) = boost::graph_detail::push(
1501 g.out_edge_list(u), StoredEdge(v, p_iter, &g.m_edges));
1502 if (inserted)
1503 {
1504 boost::graph_detail::push(
1505 in_edge_list(g, v), StoredEdge(u, p_iter, &g.m_edges));
1506 return std::make_pair(edge_descriptor(u, v, &p_iter->m_property), true);
1507 }
1508 else
1509 {
1510 g.m_edges.erase(p_iter);
1511 return std::make_pair(
1512 edge_descriptor(u, v, &i->get_iter()->get_property()), false);
1513 }
1514 }
1515
1516 template < class Config >
1517 inline std::pair< typename Config::edge_descriptor, bool > add_edge(
1518 typename Config::vertex_descriptor u, typename Config::vertex_descriptor v,
1519 bidirectional_graph_helper_with_property< Config >& g_)
1520 {
1521 typename Config::edge_property_type p;
1522 return add_edge(u, v, p, g_);
1523 }
1524
1525 template < class Config >
1526 inline typename Config::degree_size_type degree(
1527 typename Config::vertex_descriptor u,
1528 const bidirectional_graph_helper_with_property< Config >& g_)
1529 {
1530 typedef typename Config::graph_type graph_type;
1531 const graph_type& g = static_cast< const graph_type& >(g_);
1532 return in_degree(u, g) + out_degree(u, g);
1533 }
1534
1535
1536
1537
1538 template < class Config, class Base > struct adj_list_helper : public Base
1539 {
1540 typedef typename Config::graph_type AdjList;
1541 typedef typename Config::vertex_descriptor vertex_descriptor;
1542 typedef typename Config::edge_descriptor edge_descriptor;
1543 typedef typename Config::out_edge_iterator out_edge_iterator;
1544 typedef typename Config::in_edge_iterator in_edge_iterator;
1545 typedef typename Config::adjacency_iterator adjacency_iterator;
1546 typedef typename Config::inv_adjacency_iterator inv_adjacency_iterator;
1547 typedef typename Config::vertex_iterator vertex_iterator;
1548 typedef typename Config::edge_iterator edge_iterator;
1549 typedef typename Config::directed_category directed_category;
1550 typedef typename Config::edge_parallel_category edge_parallel_category;
1551 typedef typename Config::vertices_size_type vertices_size_type;
1552 typedef typename Config::edges_size_type edges_size_type;
1553 typedef typename Config::degree_size_type degree_size_type;
1554 typedef typename Config::StoredEdge StoredEdge;
1555 typedef typename Config::vertex_property_type vertex_property_type;
1556 typedef typename Config::edge_property_type edge_property_type;
1557 typedef typename Config::graph_property_type graph_property_type;
1558
1559 typedef typename Config::global_edgelist_selector global_edgelist_selector;
1560
1561 typedef typename lookup_one_property< vertex_property_type,
1562 vertex_bundle_t >::type vertex_bundled;
1563 typedef
1564 typename lookup_one_property< edge_property_type, edge_bundle_t >::type
1565 edge_bundled;
1566 typedef typename lookup_one_property< graph_property_type,
1567 graph_bundle_t >::type graph_bundled;
1568 };
1569
1570 template < class Config, class Base >
1571 inline std::pair< typename Config::adjacency_iterator,
1572 typename Config::adjacency_iterator >
1573 adjacent_vertices(typename Config::vertex_descriptor u,
1574 const adj_list_helper< Config, Base >& g_)
1575 {
1576 typedef typename Config::graph_type AdjList;
1577 const AdjList& cg = static_cast< const AdjList& >(g_);
1578 AdjList& g = const_cast< AdjList& >(cg);
1579 typedef typename Config::adjacency_iterator adjacency_iterator;
1580 typename Config::out_edge_iterator first, last;
1581 boost::tie(first, last) = out_edges(u, g);
1582 return std::make_pair(
1583 adjacency_iterator(first, &g), adjacency_iterator(last, &g));
1584 }
1585 template < class Config, class Base >
1586 inline std::pair< typename Config::inv_adjacency_iterator,
1587 typename Config::inv_adjacency_iterator >
1588 inv_adjacent_vertices(typename Config::vertex_descriptor u,
1589 const adj_list_helper< Config, Base >& g_)
1590 {
1591 typedef typename Config::graph_type AdjList;
1592 const AdjList& cg = static_cast< const AdjList& >(g_);
1593 AdjList& g = const_cast< AdjList& >(cg);
1594 typedef typename Config::inv_adjacency_iterator inv_adjacency_iterator;
1595 typename Config::in_edge_iterator first, last;
1596 boost::tie(first, last) = in_edges(u, g);
1597 return std::make_pair(
1598 inv_adjacency_iterator(first, &g), inv_adjacency_iterator(last, &g));
1599 }
1600 template < class Config, class Base >
1601 inline std::pair< typename Config::out_edge_iterator,
1602 typename Config::out_edge_iterator >
1603 out_edges(typename Config::vertex_descriptor u,
1604 const adj_list_helper< Config, Base >& g_)
1605 {
1606 typedef typename Config::graph_type AdjList;
1607 typedef typename Config::out_edge_iterator out_edge_iterator;
1608 const AdjList& cg = static_cast< const AdjList& >(g_);
1609 AdjList& g = const_cast< AdjList& >(cg);
1610 return std::make_pair(out_edge_iterator(g.out_edge_list(u).begin(), u),
1611 out_edge_iterator(g.out_edge_list(u).end(), u));
1612 }
1613 template < class Config, class Base >
1614 inline std::pair< typename Config::vertex_iterator,
1615 typename Config::vertex_iterator >
1616 vertices(const adj_list_helper< Config, Base >& g_)
1617 {
1618 typedef typename Config::graph_type AdjList;
1619 const AdjList& cg = static_cast< const AdjList& >(g_);
1620 AdjList& g = const_cast< AdjList& >(cg);
1621 return std::make_pair(g.vertex_set().begin(), g.vertex_set().end());
1622 }
1623 template < class Config, class Base >
1624 inline typename Config::vertices_size_type num_vertices(
1625 const adj_list_helper< Config, Base >& g_)
1626 {
1627 typedef typename Config::graph_type AdjList;
1628 const AdjList& g = static_cast< const AdjList& >(g_);
1629 return g.vertex_set().size();
1630 }
1631 template < class Config, class Base >
1632 inline typename Config::degree_size_type out_degree(
1633 typename Config::vertex_descriptor u,
1634 const adj_list_helper< Config, Base >& g_)
1635 {
1636 typedef typename Config::graph_type AdjList;
1637 const AdjList& g = static_cast< const AdjList& >(g_);
1638 return g.out_edge_list(u).size();
1639 }
1640 template < class Config, class Base >
1641 inline std::pair< typename Config::edge_descriptor, bool > edge(
1642 typename Config::vertex_descriptor u, typename Config::vertex_descriptor v,
1643 const adj_list_helper< Config, Base >& g_)
1644 {
1645 typedef typename Config::graph_type Graph;
1646 typedef typename Config::StoredEdge StoredEdge;
1647 const Graph& cg = static_cast< const Graph& >(g_);
1648 const typename Config::OutEdgeList& el = cg.out_edge_list(u);
1649 typename Config::OutEdgeList::const_iterator it
1650 = graph_detail::find(el, StoredEdge(v));
1651 return std::make_pair(typename Config::edge_descriptor(u, v,
1652 (it == el.end() ? 0 : &(*it).get_property())),
1653 (it != el.end()));
1654 }
1655
1656 template < class Config, class Base >
1657 inline std::pair< typename Config::out_edge_iterator,
1658 typename Config::out_edge_iterator >
1659 edge_range(typename Config::vertex_descriptor u,
1660 typename Config::vertex_descriptor v,
1661 const adj_list_helper< Config, Base >& g_)
1662 {
1663 typedef typename Config::graph_type Graph;
1664 typedef typename Config::StoredEdge StoredEdge;
1665 const Graph& cg = static_cast< const Graph& >(g_);
1666 Graph& g = const_cast< Graph& >(cg);
1667 typedef typename Config::out_edge_iterator out_edge_iterator;
1668 typename Config::OutEdgeList& el = g.out_edge_list(u);
1669 typename Config::OutEdgeList::iterator first, last;
1670 typename Config::EdgeContainer fake_edge_container;
1671 boost::tie(first, last) = graph_detail::equal_range(el, StoredEdge(v));
1672 return std::make_pair(
1673 out_edge_iterator(first, u), out_edge_iterator(last, u));
1674 }
1675
1676 template < class Config >
1677 inline typename Config::degree_size_type in_degree(
1678 typename Config::vertex_descriptor u,
1679 const directed_edges_helper< Config >& g_)
1680 {
1681 typedef typename Config::graph_type Graph;
1682 const Graph& cg = static_cast< const Graph& >(g_);
1683 Graph& g = const_cast< Graph& >(cg);
1684 return in_edge_list(g, u).size();
1685 }
1686
1687 namespace detail
1688 {
1689 template < class Config, class Base, class Property >
1690 inline typename boost::property_map< typename Config::graph_type,
1691 Property >::type
1692 get_dispatch(
1693 adj_list_helper< Config, Base >&, Property p, boost::edge_property_tag)
1694 {
1695 typedef typename Config::graph_type Graph;
1696 typedef typename boost::property_map< Graph, Property >::type PA;
1697 return PA(p);
1698 }
1699 template < class Config, class Base, class Property >
1700 inline typename boost::property_map< typename Config::graph_type,
1701 Property >::const_type
1702 get_dispatch(const adj_list_helper< Config, Base >&, Property p,
1703 boost::edge_property_tag)
1704 {
1705 typedef typename Config::graph_type Graph;
1706 typedef typename boost::property_map< Graph, Property >::const_type PA;
1707 return PA(p);
1708 }
1709
1710 template < class Config, class Base, class Property >
1711 inline typename boost::property_map< typename Config::graph_type,
1712 Property >::type
1713 get_dispatch(adj_list_helper< Config, Base >& g, Property p,
1714 boost::vertex_property_tag)
1715 {
1716 typedef typename Config::graph_type Graph;
1717 typedef typename boost::property_map< Graph, Property >::type PA;
1718 return PA(&static_cast< Graph& >(g), p);
1719 }
1720 template < class Config, class Base, class Property >
1721 inline typename boost::property_map< typename Config::graph_type,
1722 Property >::const_type
1723 get_dispatch(const adj_list_helper< Config, Base >& g, Property p,
1724 boost::vertex_property_tag)
1725 {
1726 typedef typename Config::graph_type Graph;
1727 typedef typename boost::property_map< Graph, Property >::const_type PA;
1728 const Graph& cg = static_cast< const Graph& >(g);
1729 return PA(&cg, p);
1730 }
1731
1732 }
1733
1734
1735 template < class Config, class Base, class Property >
1736 inline
1737 typename boost::property_map< typename Config::graph_type, Property >::type
1738 get(Property p, adj_list_helper< Config, Base >& g)
1739 {
1740 typedef typename detail::property_kind_from_graph<
1741 adj_list_helper< Config, Base >, Property >::type Kind;
1742 return detail::get_dispatch(g, p, Kind());
1743 }
1744 template < class Config, class Base, class Property >
1745 inline typename boost::property_map< typename Config::graph_type,
1746 Property >::const_type
1747 get(Property p, const adj_list_helper< Config, Base >& g)
1748 {
1749 typedef typename detail::property_kind_from_graph<
1750 adj_list_helper< Config, Base >, Property >::type Kind;
1751 return detail::get_dispatch(g, p, Kind());
1752 }
1753
1754 template < class Config, class Base, class Property, class Key >
1755 inline typename boost::property_traits< typename boost::property_map<
1756 typename Config::graph_type, Property >::type >::reference
1757 get(Property p, adj_list_helper< Config, Base >& g, const Key& key)
1758 {
1759 return get(get(p, g), key);
1760 }
1761
1762 template < class Config, class Base, class Property, class Key >
1763 inline typename boost::property_traits< typename boost::property_map<
1764 typename Config::graph_type, Property >::const_type >::reference
1765 get(Property p, const adj_list_helper< Config, Base >& g, const Key& key)
1766 {
1767 return get(get(p, g), key);
1768 }
1769
1770 template < class Config, class Base, class Property, class Key, class Value >
1771 inline void put(Property p, adj_list_helper< Config, Base >& g, const Key& key,
1772 const Value& value)
1773 {
1774 typedef typename Config::graph_type Graph;
1775 typedef typename boost::property_map< Graph, Property >::type Map;
1776 Map pmap = get(p, static_cast< Graph& >(g));
1777 put(pmap, key, value);
1778 }
1779
1780
1781
1782
1783 struct adj_list_tag
1784 {
1785 };
1786
1787 template < class Derived, class Config, class Base >
1788 class adj_list_impl : public adj_list_helper< Config, Base >
1789 {
1790 typedef typename Config::OutEdgeList OutEdgeList;
1791 typedef typename Config::InEdgeList InEdgeList;
1792 typedef typename Config::StoredVertexList StoredVertexList;
1793
1794 public:
1795 typedef typename Config::stored_vertex stored_vertex;
1796 typedef typename Config::EdgeContainer EdgeContainer;
1797 typedef typename Config::vertex_descriptor vertex_descriptor;
1798 typedef typename Config::edge_descriptor edge_descriptor;
1799 typedef typename Config::vertex_iterator vertex_iterator;
1800 typedef typename Config::edge_iterator edge_iterator;
1801 typedef typename Config::edge_parallel_category edge_parallel_category;
1802 typedef typename Config::vertices_size_type vertices_size_type;
1803 typedef typename Config::edges_size_type edges_size_type;
1804 typedef typename Config::degree_size_type degree_size_type;
1805 typedef typename Config::edge_property_type edge_property_type;
1806 typedef adj_list_tag graph_tag;
1807
1808 static vertex_descriptor null_vertex() { return 0; }
1809
1810 inline adj_list_impl() {}
1811
1812 inline adj_list_impl(const adj_list_impl& x) { copy_impl(x); }
1813 inline adj_list_impl& operator=(const adj_list_impl& x)
1814 {
1815 this->clear();
1816 copy_impl(x);
1817 return *this;
1818 }
1819 inline void clear()
1820 {
1821 for (typename StoredVertexList::iterator i = m_vertices.begin();
1822 i != m_vertices.end(); ++i)
1823 delete (stored_vertex*)*i;
1824 m_vertices.clear();
1825 m_edges.clear();
1826 }
1827 inline adj_list_impl(vertices_size_type num_vertices)
1828 {
1829 for (vertices_size_type i = 0; i < num_vertices; ++i)
1830 add_vertex(static_cast< Derived& >(*this));
1831 }
1832 template < class EdgeIterator >
1833 inline adj_list_impl(
1834 vertices_size_type num_vertices, EdgeIterator first, EdgeIterator last)
1835 {
1836 vertex_descriptor* v = new vertex_descriptor[num_vertices];
1837 for (vertices_size_type i = 0; i < num_vertices; ++i)
1838 v[i] = add_vertex(static_cast< Derived& >(*this));
1839
1840 while (first != last)
1841 {
1842 add_edge(v[(*first).first], v[(*first).second], *this);
1843 ++first;
1844 }
1845 delete[] v;
1846 }
1847 template < class EdgeIterator, class EdgePropertyIterator >
1848 inline adj_list_impl(vertices_size_type num_vertices, EdgeIterator first,
1849 EdgeIterator last, EdgePropertyIterator ep_iter)
1850 {
1851 vertex_descriptor* v = new vertex_descriptor[num_vertices];
1852 for (vertices_size_type i = 0; i < num_vertices; ++i)
1853 v[i] = add_vertex(static_cast< Derived& >(*this));
1854
1855 while (first != last)
1856 {
1857 add_edge(v[(*first).first], v[(*first).second], *ep_iter, *this);
1858 ++first;
1859 ++ep_iter;
1860 }
1861 delete[] v;
1862 }
1863 ~adj_list_impl()
1864 {
1865 for (typename StoredVertexList::iterator i = m_vertices.begin();
1866 i != m_vertices.end(); ++i)
1867 delete (stored_vertex*)*i;
1868 }
1869
1870 inline OutEdgeList& out_edge_list(vertex_descriptor v)
1871 {
1872 stored_vertex* sv = (stored_vertex*)v;
1873 return sv->m_out_edges;
1874 }
1875 inline const OutEdgeList& out_edge_list(vertex_descriptor v) const
1876 {
1877 stored_vertex* sv = (stored_vertex*)v;
1878 return sv->m_out_edges;
1879 }
1880 inline StoredVertexList& vertex_set() { return m_vertices; }
1881 inline const StoredVertexList& vertex_set() const { return m_vertices; }
1882
1883 inline void copy_impl(const adj_list_impl& x_)
1884 {
1885 const Derived& x = static_cast< const Derived& >(x_);
1886
1887
1888
1889 std::map< stored_vertex*, stored_vertex* > vertex_map;
1890
1891
1892
1893 vertex_iterator vi, vi_end;
1894 for (boost::tie(vi, vi_end) = vertices(x); vi != vi_end; ++vi)
1895 {
1896 stored_vertex* v = (stored_vertex*)add_vertex(*this);
1897 v->m_property = ((stored_vertex*)*vi)->m_property;
1898 vertex_map[(stored_vertex*)*vi] = v;
1899 }
1900
1901
1902 edge_iterator ei, ei_end;
1903 for (boost::tie(ei, ei_end) = edges(x); ei != ei_end; ++ei)
1904 {
1905 edge_descriptor e;
1906 bool inserted;
1907 vertex_descriptor s = source(*ei, x), t = target(*ei, x);
1908 boost::tie(e, inserted) = add_edge(vertex_map[(stored_vertex*)s],
1909 vertex_map[(stored_vertex*)t], *this);
1910 *((edge_property_type*)e.m_eproperty)
1911 = *((edge_property_type*)(*ei).m_eproperty);
1912 }
1913 }
1914
1915 typename Config::EdgeContainer m_edges;
1916 StoredVertexList m_vertices;
1917 };
1918
1919
1920 template < class Derived, class Config, class Base >
1921 inline typename Config::vertex_descriptor add_vertex(
1922 adj_list_impl< Derived, Config, Base >& g_)
1923 {
1924 Derived& g = static_cast< Derived& >(g_);
1925 typedef typename Config::stored_vertex stored_vertex;
1926 stored_vertex* v = new stored_vertex;
1927 typename Config::StoredVertexList::iterator pos;
1928 bool inserted;
1929 boost::tie(pos, inserted) = boost::graph_detail::push(g.m_vertices, v);
1930 v->m_position = pos;
1931 g.added_vertex(v);
1932 return v;
1933 }
1934
1935 template < class Derived, class Config, class Base >
1936 inline typename Config::vertex_descriptor add_vertex(
1937 const typename Config::vertex_property_type& p,
1938 adj_list_impl< Derived, Config, Base >& g_)
1939 {
1940 typedef typename Config::vertex_descriptor vertex_descriptor;
1941 Derived& g = static_cast< Derived& >(g_);
1942 if (optional< vertex_descriptor > v
1943 = g.vertex_by_property(get_property_value(p, vertex_bundle)))
1944 return *v;
1945
1946 typedef typename Config::stored_vertex stored_vertex;
1947 stored_vertex* v = new stored_vertex(p);
1948 typename Config::StoredVertexList::iterator pos;
1949 bool inserted;
1950 boost::tie(pos, inserted) = boost::graph_detail::push(g.m_vertices, v);
1951 v->m_position = pos;
1952 g.added_vertex(v);
1953 return v;
1954 }
1955
1956 template < class Derived, class Config, class Base >
1957 inline void remove_vertex(typename Config::vertex_descriptor u,
1958 adj_list_impl< Derived, Config, Base >& g_)
1959 {
1960 typedef typename Config::stored_vertex stored_vertex;
1961 Derived& g = static_cast< Derived& >(g_);
1962 g.removing_vertex(
1963 u, boost::graph_detail::iterator_stability(g_.m_vertices));
1964 stored_vertex* su = (stored_vertex*)u;
1965 g.m_vertices.erase(su->m_position);
1966 delete su;
1967 }
1968
1969 template < class Derived, class Config, class Base >
1970 inline typename Config::vertex_descriptor vertex(
1971 typename Config::vertices_size_type n,
1972 const adj_list_impl< Derived, Config, Base >& g_)
1973 {
1974 const Derived& g = static_cast< const Derived& >(g_);
1975 typename Config::vertex_iterator i = vertices(g).first;
1976 while (n--)
1977 ++i;
1978 return *i;
1979 }
1980
1981
1982
1983
1984 namespace detail
1985 {
1986
1987 template < class Graph, class vertex_descriptor >
1988 inline void remove_vertex_dispatch(
1989 Graph& g, vertex_descriptor u, boost::directed_tag)
1990 {
1991 typedef typename Graph::edge_parallel_category edge_parallel_category;
1992 g.m_vertices.erase(g.m_vertices.begin() + u);
1993 vertex_descriptor V = num_vertices(g);
1994 if (u != V)
1995 {
1996 for (vertex_descriptor v = 0; v < V; ++v)
1997 reindex_edge_list(
1998 g.out_edge_list(v), u, edge_parallel_category());
1999 }
2000 }
2001
2002 template < class Graph, class vertex_descriptor >
2003 inline void remove_vertex_dispatch(
2004 Graph& g, vertex_descriptor u, boost::undirected_tag)
2005 {
2006 typedef typename Graph::global_edgelist_selector EdgeListS;
2007 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
2008
2009 typedef typename Graph::edge_parallel_category edge_parallel_category;
2010 g.m_vertices.erase(g.m_vertices.begin() + u);
2011 vertex_descriptor V = num_vertices(g);
2012 for (vertex_descriptor v = 0; v < V; ++v)
2013 reindex_edge_list(g.out_edge_list(v), u, edge_parallel_category());
2014 typedef typename Graph::EdgeContainer Container;
2015 typedef typename Container::iterator Iter;
2016 Iter ei = g.m_edges.begin(), ei_end = g.m_edges.end();
2017 for (; ei != ei_end; ++ei)
2018 {
2019 if (ei->m_source > u)
2020 --ei->m_source;
2021 if (ei->m_target > u)
2022 --ei->m_target;
2023 }
2024 }
2025 template < class Graph, class vertex_descriptor >
2026 inline void remove_vertex_dispatch(
2027 Graph& g, vertex_descriptor u, boost::bidirectional_tag)
2028 {
2029 typedef typename Graph::global_edgelist_selector EdgeListS;
2030 BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
2031
2032 typedef typename Graph::edge_parallel_category edge_parallel_category;
2033 g.m_vertices.erase(g.m_vertices.begin() + u);
2034 vertex_descriptor V = num_vertices(g);
2035 vertex_descriptor v;
2036 if (u != V)
2037 {
2038 for (v = 0; v < V; ++v)
2039 reindex_edge_list(
2040 g.out_edge_list(v), u, edge_parallel_category());
2041 for (v = 0; v < V; ++v)
2042 reindex_edge_list(
2043 in_edge_list(g, v), u, edge_parallel_category());
2044
2045 typedef typename Graph::EdgeContainer Container;
2046 typedef typename Container::iterator Iter;
2047 Iter ei = g.m_edges.begin(), ei_end = g.m_edges.end();
2048 for (; ei != ei_end; ++ei)
2049 {
2050 if (ei->m_source > u)
2051 --ei->m_source;
2052 if (ei->m_target > u)
2053 --ei->m_target;
2054 }
2055 }
2056 }
2057
2058 template < class EdgeList, class vertex_descriptor >
2059 inline void reindex_edge_list(
2060 EdgeList& el, vertex_descriptor u, boost::allow_parallel_edge_tag)
2061 {
2062 typename EdgeList::iterator ei = el.begin(), e_end = el.end();
2063 for (; ei != e_end; ++ei)
2064 if ((*ei).get_target() > u)
2065 --(*ei).get_target();
2066 }
2067
2068 template < class EdgeList, class vertex_descriptor >
2069 inline void reindex_edge_list(
2070 EdgeList& el, vertex_descriptor u, boost::disallow_parallel_edge_tag)
2071 {
2072 typename EdgeList::iterator ei = el.begin(), e_end = el.end();
2073 while (ei != e_end)
2074 {
2075 if (ei->get_target() > u)
2076 {
2077 typename EdgeList::value_type ce = *ei;
2078 ++ei;
2079 el.erase(ce);
2080 --ce.get_target();
2081 el.insert(ce);
2082 }
2083 else {
2084 ++ei;
2085 }
2086 }
2087 }
2088 }
2089
2090 struct vec_adj_list_tag
2091 {
2092 };
2093
2094 template < class Graph, class Config, class Base >
2095 class vec_adj_list_impl : public adj_list_helper< Config, Base >
2096 {
2097 typedef typename Config::OutEdgeList OutEdgeList;
2098 typedef typename Config::InEdgeList InEdgeList;
2099 typedef typename Config::StoredVertexList StoredVertexList;
2100
2101 public:
2102 typedef typename Config::vertex_descriptor vertex_descriptor;
2103 typedef typename Config::edge_descriptor edge_descriptor;
2104 typedef typename Config::out_edge_iterator out_edge_iterator;
2105 typedef typename Config::edge_iterator edge_iterator;
2106 typedef typename Config::directed_category directed_category;
2107 typedef typename Config::vertices_size_type vertices_size_type;
2108 typedef typename Config::edges_size_type edges_size_type;
2109 typedef typename Config::degree_size_type degree_size_type;
2110 typedef typename Config::StoredEdge StoredEdge;
2111 typedef typename Config::stored_vertex stored_vertex;
2112 typedef typename Config::EdgeContainer EdgeContainer;
2113 typedef typename Config::edge_property_type edge_property_type;
2114 typedef vec_adj_list_tag graph_tag;
2115
2116 static vertex_descriptor null_vertex()
2117 {
2118 return (std::numeric_limits< vertex_descriptor >::max)();
2119 }
2120
2121 inline vec_adj_list_impl() {}
2122
2123 inline vec_adj_list_impl(const vec_adj_list_impl& x) { copy_impl(x); }
2124 inline vec_adj_list_impl& operator=(const vec_adj_list_impl& x)
2125 {
2126 this->clear();
2127 copy_impl(x);
2128 return *this;
2129 }
2130 inline void clear()
2131 {
2132 m_vertices.clear();
2133 m_edges.clear();
2134 }
2135
2136 inline vec_adj_list_impl(vertices_size_type _num_vertices)
2137 : m_vertices(_num_vertices)
2138 {
2139 }
2140
2141 template < class EdgeIterator >
2142 inline vec_adj_list_impl(
2143 vertices_size_type num_vertices, EdgeIterator first, EdgeIterator last)
2144 : m_vertices(num_vertices)
2145 {
2146 while (first != last)
2147 {
2148 add_edge(
2149 (*first).first, (*first).second, static_cast< Graph& >(*this));
2150 ++first;
2151 }
2152 }
2153 template < class EdgeIterator, class EdgePropertyIterator >
2154 inline vec_adj_list_impl(vertices_size_type num_vertices,
2155 EdgeIterator first, EdgeIterator last, EdgePropertyIterator ep_iter)
2156 : m_vertices(num_vertices)
2157 {
2158 while (first != last)
2159 {
2160 add_edge((*first).first, (*first).second, *ep_iter,
2161 static_cast< Graph& >(*this));
2162 ++first;
2163 ++ep_iter;
2164 }
2165 }
2166
2167
2168 inline boost::integer_range< vertex_descriptor > vertex_set() const
2169 {
2170 return boost::integer_range< vertex_descriptor >(0, m_vertices.size());
2171 }
2172 inline OutEdgeList& out_edge_list(vertex_descriptor v)
2173 {
2174 return m_vertices[v].m_out_edges;
2175 }
2176 inline const OutEdgeList& out_edge_list(vertex_descriptor v) const
2177 {
2178 return m_vertices[v].m_out_edges;
2179 }
2180 inline void copy_impl(const vec_adj_list_impl& x_)
2181 {
2182 const Graph& x = static_cast< const Graph& >(x_);
2183
2184
2185 for (vertices_size_type i = 0; i < num_vertices(x); ++i)
2186 {
2187 vertex_descriptor v = add_vertex(*this);
2188 m_vertices[v].m_property = x.m_vertices[i].m_property;
2189 }
2190
2191
2192 edge_iterator ei, ei_end;
2193 for (boost::tie(ei, ei_end) = edges(x); ei != ei_end; ++ei)
2194 {
2195 edge_descriptor e;
2196 bool inserted;
2197 boost::tie(e, inserted)
2198 = add_edge(source(*ei, x), target(*ei, x), *this);
2199 *((edge_property_type*)e.m_eproperty)
2200 = *((edge_property_type*)(*ei).m_eproperty);
2201 }
2202 }
2203 typename Config::EdgeContainer m_edges;
2204 StoredVertexList m_vertices;
2205 };
2206
2207
2208 template < class G, class C, class B >
2209 inline typename C::InEdgeList& in_edge_list(
2210 vec_adj_list_impl< G, C, B >& g, typename C::vertex_descriptor v)
2211 {
2212 return g.m_vertices[v].m_in_edges;
2213 }
2214 template < class G, class C, class B >
2215 inline const typename C::InEdgeList& in_edge_list(
2216 const vec_adj_list_impl< G, C, B >& g, typename C::vertex_descriptor v)
2217 {
2218 return g.m_vertices[v].m_in_edges;
2219 }
2220
2221
2222 template < class Graph, class Config, class Base >
2223 inline typename Config::vertex_descriptor add_vertex(
2224 vec_adj_list_impl< Graph, Config, Base >& g_)
2225 {
2226 Graph& g = static_cast< Graph& >(g_);
2227 g.m_vertices.resize(g.m_vertices.size() + 1);
2228 g.added_vertex(g.m_vertices.size() - 1);
2229 return g.m_vertices.size() - 1;
2230 }
2231
2232 template < class Graph, class Config, class Base >
2233 inline typename Config::vertex_descriptor add_vertex(
2234 const typename Config::vertex_property_type& p,
2235 vec_adj_list_impl< Graph, Config, Base >& g_)
2236 {
2237 typedef typename Config::vertex_descriptor vertex_descriptor;
2238 Graph& g = static_cast< Graph& >(g_);
2239 if (optional< vertex_descriptor > v
2240 = g.vertex_by_property(get_property_value(p, vertex_bundle)))
2241 return *v;
2242 typedef typename Config::stored_vertex stored_vertex;
2243 g.m_vertices.push_back(stored_vertex(p));
2244 g.added_vertex(g.m_vertices.size() - 1);
2245 return g.m_vertices.size() - 1;
2246 }
2247
2248
2249
2250
2251 template < class Graph, class Config, class Base >
2252 inline std::pair< typename Config::edge_descriptor, bool > add_edge(
2253 typename Config::vertex_descriptor u, typename Config::vertex_descriptor v,
2254 const typename Config::edge_property_type& p,
2255 vec_adj_list_impl< Graph, Config, Base >& g_)
2256 {
2257 BOOST_USING_STD_MAX();
2258 typename Config::vertex_descriptor x
2259 = max BOOST_PREVENT_MACRO_SUBSTITUTION(u, v);
2260 if (x >= num_vertices(g_))
2261 g_.m_vertices.resize(x + 1);
2262 adj_list_helper< Config, Base >& g = g_;
2263 return add_edge(u, v, p, g);
2264 }
2265 template < class Graph, class Config, class Base >
2266 inline std::pair< typename Config::edge_descriptor, bool > add_edge(
2267 typename Config::vertex_descriptor u, typename Config::vertex_descriptor v,
2268 vec_adj_list_impl< Graph, Config, Base >& g_)
2269 {
2270 typename Config::edge_property_type p;
2271 return add_edge(u, v, p, g_);
2272 }
2273
2274
2275 template < class Graph, class Config, class Base >
2276 inline void remove_vertex(typename Config::vertex_descriptor v,
2277 vec_adj_list_impl< Graph, Config, Base >& g_)
2278 {
2279 typedef typename Config::directed_category Cat;
2280 Graph& g = static_cast< Graph& >(g_);
2281 g.removing_vertex(
2282 v, boost::graph_detail::iterator_stability(g_.m_vertices));
2283 detail::remove_vertex_dispatch(g, v, Cat());
2284 }
2285
2286 template < class Graph, class Config, class Base >
2287 inline typename Config::vertex_descriptor vertex(
2288 typename Config::vertices_size_type n,
2289 const vec_adj_list_impl< Graph, Config, Base >&)
2290 {
2291 return n;
2292 }
2293
2294 namespace detail
2295 {
2296
2297
2298
2299
2300 template < class Graph, class VertexListS, class OutEdgeListS,
2301 class DirectedS, class VertexProperty, class EdgeProperty,
2302 class GraphProperty, class EdgeListS >
2303 struct adj_list_gen
2304 {
2305 typedef typename detail::is_random_access< VertexListS >::type
2306 is_rand_access;
2307 typedef typename has_property< EdgeProperty >::type has_edge_property;
2308 typedef typename DirectedS::is_directed_t DirectedT;
2309 typedef typename DirectedS::is_bidir_t BidirectionalT;
2310
2311 struct config
2312 {
2313 typedef OutEdgeListS edgelist_selector;
2314 typedef EdgeListS global_edgelist_selector;
2315
2316 typedef Graph graph_type;
2317 typedef EdgeProperty edge_property_type;
2318 typedef VertexProperty vertex_property_type;
2319 typedef GraphProperty graph_property_type;
2320 typedef std::size_t vertices_size_type;
2321
2322 typedef adjacency_list_traits< OutEdgeListS, VertexListS,
2323 DirectedS >
2324 Traits;
2325
2326 typedef typename Traits::directed_category directed_category;
2327 typedef
2328 typename Traits::edge_parallel_category edge_parallel_category;
2329 typedef typename Traits::vertex_descriptor vertex_descriptor;
2330 typedef typename Traits::edge_descriptor edge_descriptor;
2331
2332 typedef void* vertex_ptr;
2333
2334
2335
2336
2337
2338 typedef typename container_gen< VertexListS, vertex_ptr >::type
2339 SeqVertexList;
2340 typedef boost::integer_range< vertex_descriptor > RandVertexList;
2341 typedef typename mpl::if_< is_rand_access, RandVertexList,
2342 SeqVertexList >::type VertexList;
2343
2344 typedef typename VertexList::iterator vertex_iterator;
2345
2346
2347
2348 typedef typename container_gen< EdgeListS,
2349 list_edge< vertex_descriptor, EdgeProperty > >::type
2350 EdgeContainer;
2351
2352 typedef typename mpl::and_< DirectedT,
2353 typename mpl::not_< BidirectionalT >::type >::type
2354 on_edge_storage;
2355
2356 typedef typename mpl::if_< on_edge_storage, std::size_t,
2357 typename EdgeContainer::size_type >::type edges_size_type;
2358
2359 typedef typename EdgeContainer::iterator EdgeIter;
2360
2361 typedef
2362 typename detail::is_random_access< EdgeListS >::type is_edge_ra;
2363
2364 typedef typename mpl::if_< on_edge_storage,
2365 stored_edge_property< vertex_descriptor, EdgeProperty >,
2366 typename mpl::if_< is_edge_ra,
2367 stored_ra_edge_iter< vertex_descriptor, EdgeContainer,
2368 EdgeProperty >,
2369 stored_edge_iter< vertex_descriptor, EdgeIter,
2370 EdgeProperty > >::type >::type StoredEdge;
2371
2372
2373
2374 typedef typename container_gen< OutEdgeListS, StoredEdge >::type
2375 OutEdgeList;
2376 typedef typename OutEdgeList::size_type degree_size_type;
2377 typedef typename OutEdgeList::iterator OutEdgeIter;
2378
2379 typedef std::iterator_traits< OutEdgeIter >
2380 OutEdgeIterTraits;
2381 typedef
2382 typename OutEdgeIterTraits::iterator_category OutEdgeIterCat;
2383 typedef typename OutEdgeIterTraits::difference_type OutEdgeIterDiff;
2384
2385 typedef out_edge_iter< OutEdgeIter, vertex_descriptor,
2386 edge_descriptor, OutEdgeIterDiff >
2387 out_edge_iterator;
2388
2389 typedef typename adjacency_iterator_generator< graph_type,
2390 vertex_descriptor, out_edge_iterator >::type adjacency_iterator;
2391
2392 typedef OutEdgeList InEdgeList;
2393 typedef OutEdgeIter InEdgeIter;
2394 typedef OutEdgeIterCat InEdgeIterCat;
2395 typedef OutEdgeIterDiff InEdgeIterDiff;
2396
2397 typedef in_edge_iter< InEdgeIter, vertex_descriptor,
2398 edge_descriptor, InEdgeIterDiff >
2399 in_edge_iterator;
2400
2401 typedef typename inv_adjacency_iterator_generator< graph_type,
2402 vertex_descriptor, in_edge_iterator >::type
2403 inv_adjacency_iterator;
2404
2405
2406
2407 typedef std::iterator_traits< EdgeIter > EdgeIterTraits;
2408 typedef typename EdgeIterTraits::iterator_category EdgeIterCat;
2409 typedef typename EdgeIterTraits::difference_type EdgeIterDiff;
2410
2411 typedef undirected_edge_iter< EdgeIter, edge_descriptor,
2412 EdgeIterDiff >
2413 UndirectedEdgeIter;
2414
2415 typedef adj_list_edge_iterator< vertex_iterator, out_edge_iterator,
2416 graph_type >
2417 DirectedEdgeIter;
2418
2419 typedef typename mpl::if_< on_edge_storage, DirectedEdgeIter,
2420 UndirectedEdgeIter >::type edge_iterator;
2421
2422
2423 typedef typename container_gen< VertexListS, vertex_ptr >::type
2424 SeqStoredVertexList;
2425 struct seq_stored_vertex
2426 {
2427 seq_stored_vertex() {}
2428 seq_stored_vertex(const VertexProperty& p) : m_property(p) {}
2429 OutEdgeList m_out_edges;
2430 VertexProperty m_property;
2431 typename SeqStoredVertexList::iterator m_position;
2432 };
2433 struct bidir_seq_stored_vertex
2434 {
2435 bidir_seq_stored_vertex() {}
2436 bidir_seq_stored_vertex(const VertexProperty& p) : m_property(p)
2437 {
2438 }
2439 OutEdgeList m_out_edges;
2440 InEdgeList m_in_edges;
2441 VertexProperty m_property;
2442 typename SeqStoredVertexList::iterator m_position;
2443 };
2444 struct rand_stored_vertex
2445 {
2446 rand_stored_vertex() {}
2447 rand_stored_vertex(const VertexProperty& p) : m_property(p) {}
2448 OutEdgeList m_out_edges;
2449 VertexProperty m_property;
2450 };
2451 struct bidir_rand_stored_vertex
2452 {
2453 bidir_rand_stored_vertex() {}
2454 bidir_rand_stored_vertex(const VertexProperty& p)
2455 : m_property(p)
2456 {
2457 }
2458 OutEdgeList m_out_edges;
2459 InEdgeList m_in_edges;
2460 VertexProperty m_property;
2461 };
2462 typedef typename mpl::if_< is_rand_access,
2463 typename mpl::if_< BidirectionalT, bidir_rand_stored_vertex,
2464 rand_stored_vertex >::type,
2465 typename mpl::if_< BidirectionalT, bidir_seq_stored_vertex,
2466 seq_stored_vertex >::type >::type StoredVertex;
2467 struct stored_vertex : public StoredVertex
2468 {
2469 stored_vertex() {}
2470 stored_vertex(const VertexProperty& p) : StoredVertex(p) {}
2471 };
2472
2473 typedef typename container_gen< VertexListS, stored_vertex >::type
2474 RandStoredVertexList;
2475 typedef typename mpl::if_< is_rand_access, RandStoredVertexList,
2476 SeqStoredVertexList >::type StoredVertexList;
2477 };
2478
2479 typedef typename mpl::if_< BidirectionalT,
2480 bidirectional_graph_helper_with_property< config >,
2481 typename mpl::if_< DirectedT, directed_graph_helper< config >,
2482 undirected_graph_helper< config > >::type >::type
2483 DirectedHelper;
2484
2485 typedef typename mpl::if_< is_rand_access,
2486 vec_adj_list_impl< Graph, config, DirectedHelper >,
2487 adj_list_impl< Graph, config, DirectedHelper > >::type type;
2488 };
2489
2490 }
2491
2492
2493
2494
2495 template < class Graph, class ValueType, class Reference, class Tag >
2496 struct adj_list_vertex_property_map
2497 : public boost::put_get_helper< Reference,
2498 adj_list_vertex_property_map< Graph, ValueType, Reference, Tag > >
2499 {
2500 typedef typename Graph::stored_vertex StoredVertex;
2501 typedef ValueType value_type;
2502 typedef Reference reference;
2503 typedef typename Graph::vertex_descriptor key_type;
2504 typedef boost::lvalue_property_map_tag category;
2505 inline adj_list_vertex_property_map(const Graph* = 0, Tag tag = Tag())
2506 : m_tag(tag)
2507 {
2508 }
2509 inline Reference operator[](key_type v) const
2510 {
2511 StoredVertex* sv = (StoredVertex*)v;
2512 return get_property_value(sv->m_property, m_tag);
2513 }
2514 inline Reference operator()(key_type v) const
2515 {
2516 return this->operator[](v);
2517 }
2518 Tag m_tag;
2519 };
2520
2521 template < class Graph, class Property, class PropRef >
2522 struct adj_list_vertex_all_properties_map
2523 : public boost::put_get_helper< PropRef,
2524 adj_list_vertex_all_properties_map< Graph, Property, PropRef > >
2525 {
2526 typedef typename Graph::stored_vertex StoredVertex;
2527 typedef Property value_type;
2528 typedef PropRef reference;
2529 typedef typename Graph::vertex_descriptor key_type;
2530 typedef boost::lvalue_property_map_tag category;
2531 inline adj_list_vertex_all_properties_map(
2532 const Graph* = 0, vertex_all_t = vertex_all_t())
2533 {
2534 }
2535 inline PropRef operator[](key_type v) const
2536 {
2537 StoredVertex* sv = (StoredVertex*)v;
2538 return sv->m_property;
2539 }
2540 inline PropRef operator()(key_type v) const { return this->operator[](v); }
2541 };
2542
2543 template < class Graph, class GraphPtr, class ValueType, class Reference,
2544 class Tag >
2545 struct vec_adj_list_vertex_property_map
2546 : public boost::put_get_helper< Reference,
2547 vec_adj_list_vertex_property_map< Graph, GraphPtr, ValueType, Reference,
2548 Tag > >
2549 {
2550 typedef ValueType value_type;
2551 typedef Reference reference;
2552 typedef typename boost::graph_traits< Graph >::vertex_descriptor key_type;
2553 typedef boost::lvalue_property_map_tag category;
2554 vec_adj_list_vertex_property_map(GraphPtr g = 0, Tag tag = Tag())
2555 : m_g(g), m_tag(tag)
2556 {
2557 }
2558 inline Reference operator[](key_type v) const
2559 {
2560 return get_property_value(m_g->m_vertices[v].m_property, m_tag);
2561 }
2562 inline Reference operator()(key_type v) const
2563 {
2564 return this->operator[](v);
2565 }
2566 GraphPtr m_g;
2567 Tag m_tag;
2568 };
2569
2570 template < class Graph, class GraphPtr, class Property, class PropertyRef >
2571 struct vec_adj_list_vertex_all_properties_map
2572 : public boost::put_get_helper< PropertyRef,
2573 vec_adj_list_vertex_all_properties_map< Graph, GraphPtr, Property,
2574 PropertyRef > >
2575 {
2576 typedef Property value_type;
2577 typedef PropertyRef reference;
2578 typedef typename boost::graph_traits< Graph >::vertex_descriptor key_type;
2579 typedef boost::lvalue_property_map_tag category;
2580 vec_adj_list_vertex_all_properties_map(
2581 GraphPtr g = 0, vertex_all_t = vertex_all_t())
2582 : m_g(g)
2583 {
2584 }
2585 inline PropertyRef operator[](key_type v) const
2586 {
2587 return m_g->m_vertices[v].m_property;
2588 }
2589 inline PropertyRef operator()(key_type v) const
2590 {
2591 return this->operator[](v);
2592 }
2593 GraphPtr m_g;
2594 };
2595
2596 struct adj_list_any_vertex_pa
2597 {
2598 template < class Tag, class Graph, class Property > struct bind_
2599 {
2600 typedef typename property_value< Property, Tag >::type value_type;
2601 typedef value_type& reference;
2602 typedef const value_type& const_reference;
2603
2604 typedef adj_list_vertex_property_map< Graph, value_type, reference,
2605 Tag >
2606 type;
2607 typedef adj_list_vertex_property_map< Graph, value_type,
2608 const_reference, Tag >
2609 const_type;
2610 };
2611 };
2612 struct adj_list_all_vertex_pa
2613 {
2614 template < class Tag, class Graph, class Property > struct bind_
2615 {
2616 typedef typename Graph::vertex_descriptor Vertex;
2617 typedef adj_list_vertex_all_properties_map< Graph, Property, Property& >
2618 type;
2619 typedef adj_list_vertex_all_properties_map< Graph, Property,
2620 const Property& >
2621 const_type;
2622 };
2623 };
2624
2625 template < class Property, class Vertex >
2626 struct vec_adj_list_vertex_id_map
2627 : public boost::put_get_helper< Vertex,
2628 vec_adj_list_vertex_id_map< Property, Vertex > >
2629 {
2630 typedef Vertex value_type;
2631 typedef Vertex key_type;
2632 typedef Vertex reference;
2633 typedef boost::readable_property_map_tag category;
2634 inline vec_adj_list_vertex_id_map() {}
2635 template < class Graph >
2636 inline vec_adj_list_vertex_id_map(const Graph&, vertex_index_t)
2637 {
2638 }
2639 inline value_type operator[](key_type v) const { return v; }
2640 inline value_type operator()(key_type v) const { return v; }
2641 };
2642
2643 struct vec_adj_list_any_vertex_pa
2644 {
2645 template < class Tag, class Graph, class Property > struct bind_
2646 {
2647 typedef typename property_value< Property, Tag >::type value_type;
2648 typedef value_type& reference;
2649 typedef const value_type& const_reference;
2650
2651 typedef vec_adj_list_vertex_property_map< Graph, Graph*, value_type,
2652 reference, Tag >
2653 type;
2654 typedef vec_adj_list_vertex_property_map< Graph, const Graph*,
2655 value_type, const_reference, Tag >
2656 const_type;
2657 };
2658 };
2659 struct vec_adj_list_id_vertex_pa
2660 {
2661 template < class Tag, class Graph, class Property > struct bind_
2662 {
2663 typedef typename Graph::vertex_descriptor Vertex;
2664 typedef vec_adj_list_vertex_id_map< Property, Vertex > type;
2665 typedef vec_adj_list_vertex_id_map< Property, Vertex > const_type;
2666 };
2667 };
2668 struct vec_adj_list_all_vertex_pa
2669 {
2670 template < class Tag, class Graph, class Property > struct bind_
2671 {
2672 typedef typename Graph::vertex_descriptor Vertex;
2673 typedef vec_adj_list_vertex_all_properties_map< Graph, Graph*, Property,
2674 Property& >
2675 type;
2676 typedef vec_adj_list_vertex_all_properties_map< Graph, const Graph*,
2677 Property, const Property& >
2678 const_type;
2679 };
2680 };
2681 namespace detail
2682 {
2683 template < class Tag, class Graph, class Property >
2684 struct adj_list_choose_vertex_pa
2685 : boost::mpl::if_< boost::is_same< Tag, vertex_all_t >,
2686 adj_list_all_vertex_pa, adj_list_any_vertex_pa >::type ::
2687 template bind_< Tag, Graph, Property >
2688 {
2689 };
2690
2691 template < class Tag > struct vec_adj_list_choose_vertex_pa_helper
2692 {
2693 typedef vec_adj_list_any_vertex_pa type;
2694 };
2695 template <> struct vec_adj_list_choose_vertex_pa_helper< vertex_index_t >
2696 {
2697 typedef vec_adj_list_id_vertex_pa type;
2698 };
2699 template <> struct vec_adj_list_choose_vertex_pa_helper< vertex_all_t >
2700 {
2701 typedef vec_adj_list_all_vertex_pa type;
2702 };
2703 template < class Tag, class Graph, class Property >
2704 struct vec_adj_list_choose_vertex_pa
2705 : vec_adj_list_choose_vertex_pa_helper< Tag >::type::template bind_< Tag,
2706 Graph, Property >
2707 {
2708 };
2709 }
2710
2711
2712
2713
2714 template < class Directed, class Value, class Ref, class Vertex, class Property,
2715 class Tag >
2716 struct adj_list_edge_property_map
2717 : public put_get_helper< Ref,
2718 adj_list_edge_property_map< Directed, Value, Ref, Vertex, Property,
2719 Tag > >
2720 {
2721 Tag tag;
2722 explicit adj_list_edge_property_map(Tag tag = Tag()) : tag(tag) {}
2723
2724 typedef Value value_type;
2725 typedef Ref reference;
2726 typedef detail::edge_desc_impl< Directed, Vertex > key_type;
2727 typedef boost::lvalue_property_map_tag category;
2728 inline Ref operator[](key_type e) const
2729 {
2730 Property& p = *(Property*)e.get_property();
2731 return get_property_value(p, tag);
2732 }
2733 inline Ref operator()(key_type e) const { return this->operator[](e); }
2734 };
2735
2736 template < class Directed, class Property, class PropRef, class PropPtr,
2737 class Vertex >
2738 struct adj_list_edge_all_properties_map
2739 : public put_get_helper< PropRef,
2740 adj_list_edge_all_properties_map< Directed, Property, PropRef, PropPtr,
2741 Vertex > >
2742 {
2743 explicit adj_list_edge_all_properties_map(edge_all_t = edge_all_t()) {}
2744 typedef Property value_type;
2745 typedef PropRef reference;
2746 typedef detail::edge_desc_impl< Directed, Vertex > key_type;
2747 typedef boost::lvalue_property_map_tag category;
2748 inline PropRef operator[](key_type e) const
2749 {
2750 return *(PropPtr)e.get_property();
2751 }
2752 inline PropRef operator()(key_type e) const { return this->operator[](e); }
2753 };
2754
2755
2756
2757 namespace detail
2758 {
2759 struct adj_list_any_edge_pmap
2760 {
2761 template < class Graph, class Property, class Tag > struct bind_
2762 {
2763 typedef typename property_value< Property, Tag >::type value_type;
2764 typedef value_type& reference;
2765 typedef const value_type& const_reference;
2766
2767 typedef adj_list_edge_property_map<
2768 typename Graph::directed_category, value_type, reference,
2769 typename Graph::vertex_descriptor, Property, Tag >
2770 type;
2771 typedef adj_list_edge_property_map<
2772 typename Graph::directed_category, value_type, const_reference,
2773 typename Graph::vertex_descriptor, const Property, Tag >
2774 const_type;
2775 };
2776 };
2777 struct adj_list_all_edge_pmap
2778 {
2779 template < class Graph, class Property, class Tag > struct bind_
2780 {
2781 typedef adj_list_edge_all_properties_map<
2782 typename Graph::directed_category, Property, Property&,
2783 Property*, typename Graph::vertex_descriptor >
2784 type;
2785 typedef adj_list_edge_all_properties_map<
2786 typename Graph::directed_category, Property, const Property&,
2787 const Property*, typename Graph::vertex_descriptor >
2788 const_type;
2789 };
2790 };
2791
2792 template < class Tag > struct adj_list_choose_edge_pmap_helper
2793 {
2794 typedef adj_list_any_edge_pmap type;
2795 };
2796 template <> struct adj_list_choose_edge_pmap_helper< edge_all_t >
2797 {
2798 typedef adj_list_all_edge_pmap type;
2799 };
2800 template < class Tag, class Graph, class Property >
2801 struct adj_list_choose_edge_pmap
2802 : adj_list_choose_edge_pmap_helper< Tag >::type::template bind_< Graph,
2803 Property, Tag >
2804 {
2805 };
2806 struct adj_list_edge_property_selector
2807 {
2808 template < class Graph, class Property, class Tag >
2809 struct bind_ : adj_list_choose_edge_pmap< Tag, Graph, Property >
2810 {
2811 };
2812 };
2813 }
2814
2815 template <> struct edge_property_selector< adj_list_tag >
2816 {
2817 typedef detail::adj_list_edge_property_selector type;
2818 };
2819 template <> struct edge_property_selector< vec_adj_list_tag >
2820 {
2821 typedef detail::adj_list_edge_property_selector type;
2822 };
2823
2824
2825
2826 struct adj_list_vertex_property_selector
2827 {
2828 template < class Graph, class Property, class Tag >
2829 struct bind_ : detail::adj_list_choose_vertex_pa< Tag, Graph, Property >
2830 {
2831 };
2832 };
2833 template <> struct vertex_property_selector< adj_list_tag >
2834 {
2835 typedef adj_list_vertex_property_selector type;
2836 };
2837
2838 struct vec_adj_list_vertex_property_selector
2839 {
2840 template < class Graph, class Property, class Tag >
2841 struct bind_ : detail::vec_adj_list_choose_vertex_pa< Tag, Graph, Property >
2842 {
2843 };
2844 };
2845 template <> struct vertex_property_selector< vec_adj_list_tag >
2846 {
2847 typedef vec_adj_list_vertex_property_selector type;
2848 };
2849
2850 }
2851
2852 namespace boost
2853 {
2854
2855 template < typename V > struct hash< boost::detail::stored_edge< V > >
2856 {
2857 std::size_t operator()(const boost::detail::stored_edge< V >& e) const
2858 {
2859 return hash< V >()(e.m_target);
2860 }
2861 };
2862
2863 template < typename V, typename P >
2864 struct hash< boost::detail::stored_edge_property< V, P > >
2865 {
2866 std::size_t operator()(
2867 const boost::detail::stored_edge_property< V, P >& e) const
2868 {
2869 return hash< V >()(e.m_target);
2870 }
2871 };
2872
2873 template < typename V, typename I, typename P >
2874 struct hash< boost::detail::stored_edge_iter< V, I, P > >
2875 {
2876 std::size_t operator()(
2877 const boost::detail::stored_edge_iter< V, I, P >& e) const
2878 {
2879 return hash< V >()(e.m_target);
2880 }
2881 };
2882
2883 }
2884
2885 #endif
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907