00001 #ifndef GRAPH_VVBIGRAPH_H
00002 #define GRAPH_VVBIGRAPH_H
00003
00010 #include <config.h>
00011 #include <graph/vertex.h>
00012 #include <graph/edge.h>
00013 #include <graph/vvgraph.h>
00014
00015 #include <util/tie.h>
00016 #include <util/member_iterator.h>
00017 #include <util/circ_iterator.h>
00018 #include <util/set_vector.h>
00019
00020 #include <storage/fwd.h>
00021
00022 #include <utility>
00023 #include <memory>
00024 #include <algorithm>
00025 #include <iterator>
00026
00027 #include <list>
00028 #include <set>
00029 #include <map>
00030
00031 #include <iostream>
00032
00033 #ifdef VVBIGRAPH_NO_CACHE
00034 # define VVBIGRAPH_NO_EDGE_CACHE
00035 # define VVBIGRAPH_NO_VERTEX_CACHE
00036 #endif
00037
00038 #ifdef VVBIGRAPH_NO_VERTEX_CACHE
00039 # define VVBIGRAPH_COMPACT_VERTEX true
00040 #else
00041 # define VVBIGRAPH_COMPACT_VERTEX compact
00042 #endif
00043
00044 #ifdef VVBIGRAPH_NO_EDGE_CACHE
00045 # define VVBIGRAPH_COMPACT_EDGE true
00046 #else
00047 # define VVBIGRAPH_COMPACT_EDGE compact
00048 #endif
00049
00050 #ifdef USE_ALLOCATOR
00051 # define BIGRAPH_TEMPLATE typename Vertex1Content, typename Vertex2Content, typename Edge1Content, typename Edge2Content, bool compact, typename Alloc
00052 # define BIGRAPH_ARGS Vertex1Content,Vertex2Content,Edge1Content,Edge2Content,compact,Alloc
00053 #else // USE_ALLOCATOR
00054 # define BIGRAPH_TEMPLATE typename Vertex1Content, typename Vertex2Content, typename Edge1Content, typename Edge2Content, bool compact
00055 # define BIGRAPH_ARGS Vertex1Content,Vertex2Content,Edge1Content,Edge2Content,compact
00056 #endif // USE_ALLOCATOR
00057
00058 namespace graph
00059 {
00060
00061 template <bool compact, typename T>
00062 struct __vvbigraph_set
00063 { };
00064
00065 template <typename T>
00066 struct __vvbigraph_set<true,T>
00067 {
00068 typedef util::set_vector<T> type;
00069 };
00070
00071 template <typename T>
00072 struct __vvbigraph_set<false,T>
00073 {
00074 typedef std::set<T> type;
00075 };
00076
00077 template <bool compact, typename EdgeContent, typename VVBiGraph, typename single_neighborhood_t, typename edge_list_t, typename vertex_tgt_t>
00078 struct __vvbigraph_EdgeCache
00079 {
00080 };
00081
00082 template <typename EdgeContent, typename VVBiGraph, typename single_neighborhood_t, typename edge_list_t, typename vertex_tgt_t>
00083 struct __vvbigraph_EdgeCache<false, EdgeContent, VVBiGraph, single_neighborhood_t, edge_list_t, vertex_tgt_t>
00084 : public EdgeContent
00085 {
00089 __vvbigraph_EdgeCache(const EdgeContent& copy,
00090 single_neighborhood_t *n,
00091 intptr_t _gid)
00092 : EdgeContent(copy)
00093 , _neighborhood(n)
00094 , gid(_gid)
00095 { }
00096
00097 __vvbigraph_EdgeCache(const __vvbigraph_EdgeCache& copy)
00098 : EdgeContent(copy)
00099 , _neighborhood(copy._neighborhood)
00100 , gid(copy.gid)
00101 {}
00102
00103 #ifdef USE_CXX0X
00104 __vvbigraph_EdgeCache(__vvbigraph_EdgeCache&& ) = default;
00105 #endif
00106
00107 __vvbigraph_EdgeCache& operator=(const __vvbigraph_EdgeCache& copy)
00108 {
00109 _neighborhood = copy._neighborhood;
00110 gid = copy.gid;
00111 static_cast<EdgeContent&>(*this) = static_cast<const EdgeContent&>(copy);
00112 return *this;
00113 }
00114
00115 void setIt(const typename edge_list_t::iterator& i)
00116 {
00117 _it = i;
00118 }
00119
00120 bool eraseEdge()
00121 {
00122 if(_neighborhood->flagged && *_neighborhood->flagged == _it->target) _neighborhood->flagged = 0;
00123 _neighborhood->edges.erase(_it);
00124 return true;
00125 }
00126
00127 void set(single_neighborhood_t* n, intptr_t id)
00128 {
00129 _neighborhood = n;
00130 gid = id;
00131 }
00132
00133 single_neighborhood_t* neighborhood() { return _neighborhood; }
00134
00135 typename edge_list_t::iterator it() { return _it; }
00136
00140 single_neighborhood_t* _neighborhood;
00144 typename edge_list_t::iterator _it;
00145
00149 intptr_t gid;
00150
00151 intptr_t graph_id() { return gid; }
00152 };
00153
00154 template <typename EdgeContent, typename VVBiGraph, typename single_neighborhood_t, typename edge_list_t, typename vertex_tgt_t>
00155 struct __vvbigraph_EdgeCache<true, EdgeContent, VVBiGraph, single_neighborhood_t, edge_list_t, vertex_tgt_t>
00156 : public EdgeContent
00157 {
00161 __vvbigraph_EdgeCache(const EdgeContent& copy,
00162 single_neighborhood_t *,
00163 intptr_t)
00164 : EdgeContent(copy)
00165 { }
00166
00170 __vvbigraph_EdgeCache(const EdgeContent& copy,
00171 single_neighborhood_t *,
00172 const vertex_tgt_t&,
00173 intptr_t)
00174 : EdgeContent(copy)
00175 { }
00176
00177 __vvbigraph_EdgeCache(const __vvbigraph_EdgeCache& copy)
00178 : EdgeContent(copy)
00179 {}
00180
00181 #ifdef USE_CXX0X
00182 __vvbigraph_EdgeCache(__vvbigraph_EdgeCache&& ) = default;
00183 #endif
00184
00185 void setIt(const typename edge_list_t::iterator&)
00186 {
00187 }
00188
00189 bool eraseEdge()
00190 {
00191 return false;
00192 }
00193
00194 intptr_t graph_id() { return 0; }
00195
00196 single_neighborhood_t* neighborhood() { return 0; }
00197
00198 typename edge_list_t::iterator it() { return typename edge_list_t::iterator(); }
00199
00200 void set(single_neighborhood_t*, intptr_t ) {}
00201
00202 __vvbigraph_EdgeCache& operator=(const __vvbigraph_EdgeCache& copy)
00203 {
00204 static_cast<EdgeContent&>(*this) = static_cast<const EdgeContent&>(copy);
00205 return *this;
00206 }
00207 };
00208
00209 template <bool compact, typename VVBiGraph, typename single_neighborhood_t, typename vertex_src_t>
00210 struct __vvbigraph_VertexCache
00211 {
00212 typedef typename std::list<std::pair<vertex_src_t,single_neighborhood_t> >::iterator iterator;
00213 intptr_t graph_id() { return 0; }
00214 void update(intptr_t, const vertex_src_t& , iterator ) {}
00215 iterator neighborhood() { return iterator(); }
00216 };
00217
00218 template <typename VVBiGraph, typename single_neighborhood_t, typename vertex_src_t>
00219 struct __vvbigraph_VertexCache<false,VVBiGraph,single_neighborhood_t,vertex_src_t>
00220 {
00221 typedef typename std::list<std::pair<vertex_src_t,single_neighborhood_t> >::iterator iterator;
00222
00223 __vvbigraph_VertexCache() : gid(0) {}
00224 __vvbigraph_VertexCache(const __vvbigraph_VertexCache& copy ) : gid(copy.gid), _neighborhood(copy._neighborhood) {}
00225
00226 #ifdef USE_CXX0X
00227 __vvbigraph_VertexCache(__vvbigraph_VertexCache&& ) = default;
00228 #endif
00229
00230 intptr_t graph_id() { return gid; }
00231 iterator neighborhood() { return _neighborhood; }
00232
00233 void update(intptr_t id, const vertex_src_t& v, iterator it)
00234 {
00235 gid = id;
00236 _neighborhood = it;
00237 v.cache = reinterpret_cast<void*>(this);
00238 v.cache_source = 0;
00239 }
00240
00247 intptr_t gid;
00248
00254 iterator _neighborhood;
00255 };
00256
00257 template <typename Base>
00258 struct _EmptyDeriv : public Base
00259 {
00260 _EmptyDeriv() : Base() {}
00261 _EmptyDeriv(const _EmptyDeriv& copy) : Base(copy) {}
00262 _EmptyDeriv(const Base& copy) : Base(copy) {}
00263
00264 #ifdef USE_CXX0X
00265 _EmptyDeriv(_EmptyDeriv&& ) = default;
00266 #endif
00267
00268 bool operator==(const _EmptyDeriv& other) const { return *static_cast<const Base*>(this) == other; }
00269 };
00270
00271 struct _EmptyBiEdgeContent
00272 {
00273 _EmptyBiEdgeContent& operator=(const _EmptyBiEdgeContent& ) { return *this; }
00274 bool serialize(storage::VVEStorage&) { return true; }
00275 };
00276
00330 template <typename Vertex1Content, typename Vertex2Content,
00331 typename Edge1Content = _EmptyBiEdgeContent, typename Edge2Content_ = Edge1Content, bool compact = false
00332 #ifdef USE_ALLOCATOR
00333 , typename Alloc = DEFAULT_ALLOC(Vertex1Content)
00334 #endif
00335 >
00336 class VVBiGraph
00337 {
00342 typedef _EmptyDeriv<Edge2Content_> Edge2Content;
00343
00344 public:
00345 #ifdef USE_ALLOCATOR
00346 typedef Alloc Vertex1Alloc;
00347 typedef typename Alloc::template rebind<Vertex2Content>::other Vertex2Alloc;
00348 #endif
00349
00351
00352
00355 #ifdef USE_ALLOCATOR
00356 typedef Vertex<Vertex1Content, Vertex1Alloc> vertex1_t;
00357 #else // USE_ALLOCATOR
00358 typedef Vertex<Vertex1Content> vertex1_t;
00359 #endif // USE_ALLOCATOR
00360
00363 #ifdef USE_ALLOCATOR
00364 typedef Vertex<Vertex2Content, Vertex2Alloc> vertex2_t;
00365 #else // USE_ALLOCATOR
00366 typedef Vertex<Vertex2Content> vertex2_t;
00367 #endif // USE_ALLOCATOR
00368
00372 typedef Edge<Edge1Content> edge1_t;
00376 typedef Edge<Edge2Content> edge2_t;
00377
00382 typedef Edge<const Edge1Content> const_edge1_t;
00387 typedef Edge<const Edge2Content> const_edge2_t;
00389
00395 VVBiGraph() : graph_id(graph::getNextGraphId()) {}
00396
00402 VVBiGraph(const VVBiGraph& copy);
00403
00404 #ifdef USE_CXX0X
00405
00408 VVBiGraph(VVBiGraph&& copy);
00409 #endif
00410
00411 protected:
00412
00413 template <typename VertexSrcContent, typename VertexTgtContent, typename EdgeSrcContent>
00414 struct single_neighborhood_t;
00415
00416 template <typename VertexSrcContent, typename VertexTgtContent, typename EdgeSrcContent>
00417 struct neighbor_t : public __vvbigraph_EdgeCache<VVBIGRAPH_COMPACT_EDGE,
00418 EdgeSrcContent,
00419 VVBiGraph,
00420 single_neighborhood_t<VertexSrcContent,VertexTgtContent,EdgeSrcContent>,
00421 std::list<neighbor_t<VertexSrcContent,VertexTgtContent,EdgeSrcContent> >,
00422 graph::Vertex<VertexTgtContent> >
00423 {
00424 typedef single_neighborhood_t<VertexSrcContent,VertexTgtContent,EdgeSrcContent> _single_neighborhood_t;
00425
00426 typedef graph::Vertex<VertexTgtContent> vertex_tgt_t;
00430 typedef std::list<neighbor_t> edge_list_t;
00431
00432 typedef __vvbigraph_EdgeCache<VVBIGRAPH_COMPACT_EDGE,EdgeSrcContent,VVBiGraph,_single_neighborhood_t,edge_list_t,vertex_tgt_t> base;
00433
00434 #ifdef USE_ALLOCATOR
00435 typedef typename Alloc::template rebind<EdgeSrcContent>::other EdgeAlloc;
00436 static EdgeAlloc edge_alloc;
00437 #endif
00438
00442 neighbor_t(const vertex_tgt_t& tgt, const EdgeSrcContent &e,
00443 _single_neighborhood_t& n,
00444 intptr_t gid)
00445 : base(e, &n, gid)
00446 , target(tgt)
00447 {
00448 }
00449
00450 neighbor_t(const neighbor_t& copy)
00451 : base(copy)
00452 , target(copy.target)
00453 {
00454 }
00455
00456 ~neighbor_t()
00457 {
00458 }
00459
00460 void clear_edge()
00461 {
00462 static_cast<EdgeSrcContent&>(*this) = EdgeSrcContent();
00463 }
00464
00465 neighbor_t& operator=(const neighbor_t& copy)
00466 {
00467 target = copy.target;
00468 static_cast<base&>(*this) = static_cast<const base&>(copy);
00469 return *this;
00470 }
00471
00477 vertex_tgt_t target;
00478
00485 bool operator==(const neighbor_t& other) const
00486 {
00487 return (target == other.target) &&
00488 (static_cast<const EdgeSrcContent&>(*this) == static_cast<EdgeSrcContent>(other));
00489 }
00490
00491 };
00492
00496 typedef neighbor_t<Vertex1Content, Vertex2Content, Edge1Content> neighbor1_t;
00497
00498 typedef typename neighbor1_t::base EdgeCache1;
00499
00503 typedef neighbor_t<Vertex2Content, Vertex1Content, Edge2Content> neighbor2_t;
00504
00505 typedef typename neighbor2_t::base EdgeCache2;
00506
00510 typedef typename neighbor1_t::edge_list_t edge_list1_t;
00514 typedef typename neighbor2_t::edge_list_t edge_list2_t;
00515
00519 typedef typename __vvbigraph_set<compact,vertex2_t>::type in_edges1_t;
00523 typedef typename __vvbigraph_set<compact,vertex1_t>::type in_edges2_t;
00524
00528 template <typename VertexSrcContent, typename VertexTgtContent, typename EdgeSrcContent>
00529 struct single_neighborhood_t : public __vvbigraph_VertexCache<VVBIGRAPH_COMPACT_VERTEX,
00530 VVBiGraph,
00531 single_neighborhood_t<VertexSrcContent,VertexTgtContent,EdgeSrcContent>,
00532 graph::Vertex<VertexSrcContent> >
00533 {
00534 typedef __vvbigraph_VertexCache<VVBIGRAPH_COMPACT_VERTEX,VVBiGraph,single_neighborhood_t,graph::Vertex<VertexSrcContent> > base;
00535
00536 typedef neighbor_t<VertexSrcContent, VertexTgtContent,EdgeSrcContent> _neighbor_t;
00537
00541 typename _neighbor_t::edge_list_t edges;
00542
00543 typedef graph::Vertex<VertexSrcContent> vertex_src_t;
00544 typedef graph::Vertex<VertexTgtContent> vertex_tgt_t;
00545
00546 single_neighborhood_t()
00547 : base()
00548 , flagged(0)
00549 {}
00550
00551 single_neighborhood_t(const single_neighborhood_t& copy)
00552 : base(copy)
00553 , edges(copy.edges)
00554 , in_edges(copy.in_edges)
00555 , flagged(copy.flagged)
00556 {
00557 if(flagged)
00558 {
00559 for(typename _neighbor_t::edge_list_t::iterator it = edges.begin() ; it != edges.end() ; ++it)
00560 {
00561 if(it->target == *flagged)
00562 {
00563 flagged = &it->target;
00564 return;
00565 }
00566 }
00567 }
00568 }
00569
00573 typename __vvbigraph_set<compact,vertex_tgt_t>::type in_edges;
00574
00578 const vertex_tgt_t* flagged;
00579
00585 bool operator==(const single_neighborhood_t& other) const
00586 {
00587 return edges == other.edges;
00588 }
00589 };
00590
00594 typedef single_neighborhood_t<Vertex1Content, Vertex2Content, Edge1Content> single_neighborhood1_t;
00598 typedef single_neighborhood_t<Vertex2Content, Vertex1Content, Edge2Content> single_neighborhood2_t;
00599
00600 typedef typename single_neighborhood1_t::base VertexCache1;
00601 typedef typename single_neighborhood2_t::base VertexCache2;
00602
00603 public:
00604
00609 typedef std::list<std::pair<vertex1_t, single_neighborhood1_t> > neighborhood1_t;
00614 typedef std::list<std::pair<vertex2_t, single_neighborhood2_t> > neighborhood2_t;
00615
00619 typedef std::unordered_map<vertex1_t, typename neighborhood1_t::iterator> lookup1_t;
00620
00624 typedef std::unordered_map<vertex2_t, typename neighborhood2_t::iterator> lookup2_t;
00625
00629 typedef typename neighborhood1_t::value_type neighborhood1_value_type;
00633 typedef typename neighborhood2_t::value_type neighborhood2_value_type;
00634
00638 typedef typename neighborhood1_t::size_type size_type;
00639
00641
00642
00645 typedef util::SelectMemberIterator<typename neighborhood1_t::iterator, const vertex1_t,
00646 &neighborhood1_value_type::first> iterator1;
00650 typedef util::SelectMemberIterator<typename neighborhood2_t::iterator, const vertex2_t,
00651 &neighborhood2_value_type::first> iterator2;
00655 typedef util::SelectMemberIterator<typename neighborhood1_t::const_iterator, const vertex1_t,
00656 &neighborhood1_value_type::first> const_iterator1;
00660 typedef util::SelectMemberIterator<typename neighborhood2_t::const_iterator, const vertex2_t,
00661 &neighborhood2_value_type::first> const_iterator2;
00662
00666 typedef util::SelectMemberIterator<typename edge_list1_t::iterator, vertex2_t,
00667 &neighbor1_t::target> neighbor_iterator1;
00671 typedef util::SelectMemberIterator<typename edge_list2_t::iterator, vertex1_t,
00672 &neighbor2_t::target> neighbor_iterator2;
00678 typedef util::range<neighbor_iterator1> neighbor_iterator1_range;
00684 typedef util::range<neighbor_iterator2> neighbor_iterator2_range;
00685
00690 typedef util::CircIterator<neighbor_iterator1> circ_neighbor_iterator1;
00695 typedef util::CircIterator<neighbor_iterator2> circ_neighbor_iterator2;
00696
00700 typedef util::range<circ_neighbor_iterator1> circ_neighbor_iterator1_range;
00704 typedef util::range<circ_neighbor_iterator2> circ_neighbor_iterator2_range;
00705
00712 typedef typename in_edges1_t::const_iterator ineighbor_iterator1;
00719 typedef typename in_edges2_t::const_iterator ineighbor_iterator2;
00720
00729 typedef util::range<ineighbor_iterator1> ineighbor_iterator1_range;
00738 typedef util::range<ineighbor_iterator2> ineighbor_iterator2_range;
00739
00743 typedef util::SelectMemberIterator<typename edge_list1_t::const_iterator,
00744 const vertex2_t, &neighbor1_t::target> const_neighbor_iterator1;
00748 typedef util::SelectMemberIterator<typename edge_list2_t::const_iterator,
00749 const vertex1_t, &neighbor2_t::target> const_neighbor_iterator2;
00750
00758 typedef util::range<const_neighbor_iterator1> const_neighbor_iterator1_range;
00766 typedef util::range<const_neighbor_iterator2> const_neighbor_iterator2_range;
00767
00772 typedef util::CircIterator<const_neighbor_iterator1> const_circ_neighbor_iterator1;
00777 typedef util::CircIterator<const_neighbor_iterator2> const_circ_neighbor_iterator2;
00778
00782 typedef util::range<const_circ_neighbor_iterator1> const_circ_neighbor_iterator1_range;
00786 typedef util::range<const_circ_neighbor_iterator2> const_circ_neighbor_iterator2_range;
00787
00791 typedef util::range<const_iterator1> const_range_vertex1;
00795 typedef util::range<const_iterator2> const_range_vertex2;
00796
00800 typedef util::range<iterator1> range_vertex1;
00804 typedef util::range<iterator2> range_vertex2;
00805
00807
00809
00810
00818 size_type erase( const vertex1_t& v );
00826 size_type erase( const vertex2_t& v );
00827
00833 iterator1 insert( const vertex1_t& v );
00839 iterator2 insert( const vertex2_t& v );
00841
00843
00844
00850 const vertex1_t& any_vertex1() const;
00851
00857 const vertex2_t& any_vertex2() const;
00858
00867 const vertex1_t& get_vertex1(size_type idx) const;
00876 const vertex2_t& get_vertex2(size_type idx) const;
00877
00883 bool contains( const vertex1_t& v ) const;
00889 bool contains( const vertex2_t& v ) const;
00890
00897 const vertex1_t& reference( vertex1_t v ) const
00898 {
00899 typename neighborhood1_t::const_iterator found = this->findVertex(v);
00900 if(found != neighborhood1.end())
00901 return found->first;
00902 return vertex1_t::null;
00903 }
00910 const vertex2_t& reference( vertex2_t v ) const
00911 {
00912 typename neighborhood2_t::const_iterator found = this->findVertex(v);
00913 if(found != neighborhood2.end())
00914 return found->first;
00915 return vertex2_t::null;
00916 }
00917
00921 size_type nb_vertices1() const { return neighborhood1.size(); }
00925 size_type nb_vertices2() const { return neighborhood2.size(); }
00929 size_type size() const { return this->nb_vertices1() + this->nb_vertices2(); }
00930
00934 bool no_vertex1() const { return neighborhood1.empty(); }
00938 bool no_vertex2() const { return neighborhood2.empty(); }
00942 bool empty() const { return this->no_vertex1() and this->no_vertex2(); }
00943
00945
00947
00948
00955 const vertex2_t& anyIn( const vertex1_t& v ) const;
00962 const vertex1_t& anyIn( const vertex2_t& v ) const;
00963
00969 size_type valence( const vertex1_t& v ) const;
00975 size_type valence( const vertex2_t& v ) const;
00976
00984 bool empty( const vertex1_t& v ) const;
00992 bool empty( const vertex2_t& v ) const;
00993
01000 const vertex2_t& iAnyIn(const vertex1_t& v) const;
01007 const vertex1_t& iAnyIn(const vertex2_t& v) const;
01008
01015 size_type iValence( const vertex1_t& v ) const;
01022 size_type iValence( const vertex2_t& v ) const;
01023
01031 bool iEmpty( const vertex1_t& v ) const;
01039 bool iEmpty( const vertex2_t& v ) const;
01040
01046 const vertex2_t& nextTo( const vertex1_t& v, const vertex2_t& neighbor, unsigned int n = 1 ) const;
01052 const vertex1_t& nextTo( const vertex2_t& v, const vertex1_t& neighbor, unsigned int n = 1 ) const;
01053
01059 const vertex2_t& prevTo( const vertex1_t& v, const vertex2_t& ref, unsigned int n = 1 ) const;
01065 const vertex1_t& prevTo( const vertex2_t& v, const vertex1_t& ref, unsigned int n = 1 ) const;
01066
01072 edge1_t edge( const vertex1_t& src, const vertex2_t& tgt );
01078 edge2_t edge( const vertex2_t& src, const vertex1_t& tgt );
01079
01085 const_edge1_t edge( const vertex1_t& src, const vertex2_t& tgt ) const;
01091 const_edge2_t edge( const vertex2_t& src, const vertex1_t& tgt ) const;
01092
01096 bool flag(const vertex1_t& src, const vertex2_t& neighbor);
01100 bool flag(const vertex2_t& src, const vertex1_t& neighbor);
01101
01105 const vertex2_t& flagged(const vertex1_t& src) const;
01109 const vertex1_t& flagged(const vertex2_t& src) const;
01110
01114 const_neighbor_iterator1_range neighbors(const vertex1_t& v) const;
01118 const_neighbor_iterator2_range neighbors(const vertex2_t& v) const;
01119
01123 neighbor_iterator1_range neighbors(const vertex1_t& v);
01127 neighbor_iterator2_range neighbors(const vertex2_t& v);
01128
01129
01133 const_circ_neighbor_iterator1_range neighbors(const vertex1_t& v, const vertex2_t& n) const;
01137 const_circ_neighbor_iterator2_range neighbors(const vertex2_t& v, const vertex1_t& n) const;
01138
01142 circ_neighbor_iterator1_range neighbors(const vertex1_t& v, const vertex2_t& n);
01146 circ_neighbor_iterator2_range neighbors(const vertex2_t& v, const vertex1_t& n);
01147
01154 ineighbor_iterator1_range iNeighbors(const vertex1_t& v) const;
01161 ineighbor_iterator2_range iNeighbors(const vertex2_t& v) const;
01162
01166 const vertex1_t& source( const edge1_t& edge ) const
01167 {
01168 typename neighborhood1_t::const_iterator found = this->findVertex(vertex1_t(edge.source()));
01169 if(found != neighborhood1.end())
01170 return found->first;
01171 return vertex1_t::null;
01172 }
01173
01177 const vertex2_t& source( const edge2_t& edge ) const
01178 {
01179 typename neighborhood2_t::const_iterator found = this->findVertex(vertex2_t(edge.source()));
01180 if(found != neighborhood2.end())
01181 return found->first;
01182 return vertex2_t::null;
01183 }
01184
01188 const vertex2_t& target( const edge1_t& edge ) const
01189 {
01190 typename neighborhood2_t::const_iterator found = this->findVertex(vertex2_t(edge.target()));
01191 if(found != neighborhood2.end())
01192 return found->first;
01193 return vertex2_t::null;
01194 }
01195
01199 const vertex1_t& target( const edge2_t& edge ) const
01200 {
01201 typename neighborhood1_t::const_iterator found = this->findVertex(vertex1_t(edge.target()));
01202 if(found != neighborhood1.end())
01203 return found->first;
01204 return vertex1_t::null;
01205 }
01206
01208
01210
01211
01216 size_type eraseEdge( const vertex1_t& src, const vertex2_t& tgt);
01222 size_type eraseEdge( const vertex2_t& src, const vertex1_t& tgt);
01223
01237 edge1_t replace( const vertex1_t& v, const vertex2_t& neighbor, const vertex2_t& new_neighbor );
01251 edge2_t replace( const vertex2_t& v, const vertex1_t& neighbor, const vertex1_t& new_neighbor );
01252
01261 edge1_t spliceAfter( const vertex1_t& v, const vertex2_t& neighbor, const vertex2_t& new_neighbor );
01270 edge2_t spliceAfter( const vertex2_t& v, const vertex1_t& neighbor, const vertex1_t& new_neighbor );
01271
01280 edge1_t spliceBefore( const vertex1_t& v, const vertex2_t& neighbor, const vertex2_t& new_neighbor );
01289 edge2_t spliceBefore( const vertex2_t& v, const vertex1_t& neighbor, const vertex1_t& new_neighbor );
01290
01299 edge1_t insertEdge( const vertex1_t& src, const vertex2_t& tgt );
01308 edge2_t insertEdge( const vertex2_t& src, const vertex1_t& tgt );
01309
01315 bool eraseAllEdges( const vertex1_t& v );
01321 bool eraseAllEdges( const vertex2_t& v );
01322
01328 bool clear( const vertex1_t& v );
01334 bool clear( const vertex2_t& v );
01335
01337
01339
01340
01343 VVBiGraph& operator=( const VVBiGraph& other );
01344
01348 void swap(VVBiGraph& other);
01349
01359 bool operator==(const VVBiGraph& other) const;
01360
01364 void clear() { neighborhood1.clear(); neighborhood2.clear(); lookup1.clear(); lookup2.clear(); }
01365
01386 void eraseAllEdges();
01387
01388
01389
01390
01391
01392
01393
01394 template <typename Vertex1Container, typename Vertex2Container>
01395 VVBiGraph subgraph( const Vertex1Container& vertices1, const Vertex2Container& vertices2 ) const;
01397
01399
01400
01407 iterator1 erase(iterator1 pos);
01414 iterator2 erase(iterator2 pos);
01415
01419 neighbor_iterator1 eraseEdge(const vertex1_t& v, neighbor_iterator1 pos);
01420
01424 circ_neighbor_iterator1 eraseEdge(const vertex1_t& v, circ_neighbor_iterator1 pos);
01425
01429 neighbor_iterator2 eraseEdge(const vertex2_t& v, neighbor_iterator2 pos);
01430
01434 circ_neighbor_iterator2 eraseEdge(const vertex2_t& v, circ_neighbor_iterator2 pos);
01435
01441 iterator1 insert( iterator1 pos, const vertex1_t& v );
01447 iterator2 insert( iterator2 pos, const vertex2_t& v );
01448
01452 void insert( iterator1 first, iterator1 last );
01456 void insert( iterator2 first, iterator2 last );
01457
01461 iterator1 begin_vertex1() { return neighborhood1.begin(); }
01465 iterator2 begin_vertex2() { return neighborhood2.begin(); }
01466
01470 iterator1 end_vertex1() { return neighborhood1.end(); }
01474 iterator2 end_vertex2() { return neighborhood2.end(); }
01475
01479 const_range_vertex1 vertices1() const { return util::make_range(begin_vertex1(), end_vertex1()); }
01483 const_range_vertex2 vertices2() const { return util::make_range(begin_vertex2(), end_vertex2()); }
01484
01488 range_vertex1 vertices1() { return util::make_range(begin_vertex1(), end_vertex1()); }
01492 range_vertex2 vertices2() { return util::make_range(begin_vertex2(), end_vertex2()); }
01493
01497 const_iterator1 begin_vertex1() const { return neighborhood1.begin(); }
01501 const_iterator2 begin_vertex2() const { return neighborhood2.begin(); }
01502
01506 const_iterator1 end_vertex1() const { return neighborhood1.end(); }
01510 const_iterator2 end_vertex2() const { return neighborhood2.end(); }
01511
01517 iterator1 find(const vertex1_t& v) { return this->findVertex(v); }
01523 iterator2 find(const vertex2_t& v) { return this->findVertex(v); }
01524
01530 const_iterator1 find(const vertex1_t& v) const { return this->findVertex(v); }
01536 const_iterator2 find(const vertex2_t& v) const { return this->findVertex(v); }
01537
01541 size_type count( const vertex1_t& v ) const;
01545 size_type count( const vertex2_t& v ) const;
01546
01556 neighbor_iterator1 findIn(const vertex1_t& v, const vertex2_t& n);
01566 neighbor_iterator2 findIn(const vertex2_t& v, const vertex1_t& n);
01567
01577 const_neighbor_iterator1 findIn(const vertex1_t& v, const vertex2_t& n) const;
01587 const_neighbor_iterator2 findIn(const vertex2_t& v, const vertex1_t& n) const;
01588
01594 void eraseAllEdges( iterator1 it );
01600 void eraseAllEdges( iterator2 it );
01601
01607 void clear( iterator1 it );
01613 void clear( iterator2 it );
01614
01616
01617 protected:
01624 template <class Neighborhood, class Iterator>
01625 struct search_result_t
01626 {
01632 search_result_t()
01633 : found(false)
01634 , neighborhood(0) {}
01635
01639 search_result_t( Iterator i,
01640 Neighborhood* n,
01641 bool ok = true)
01642 : found(ok)
01643 , it(i)
01644 , neighborhood(n)
01645 {}
01646
01650 search_result_t(const search_result_t& copy)
01651 : found(copy.found)
01652 , it(copy.it)
01653 , neighborhood(copy.neighborhood)
01654 {}
01655
01659 operator bool() { return found; }
01660
01664 bool found;
01668 Iterator it;
01672 Neighborhood* neighborhood;
01673 };
01674
01678 typedef typename edge_list1_t::iterator int_neighbor_iterator1;
01682 typedef typename edge_list2_t::iterator int_neighbor_iterator2;
01683
01687 typedef typename edge_list1_t::const_iterator int_const_neighbor_iterator1;
01691 typedef typename edge_list2_t::const_iterator int_const_neighbor_iterator2;
01692
01696 typedef search_result_t<single_neighborhood1_t, int_neighbor_iterator1> neighbor1_found_t;
01700 typedef search_result_t<single_neighborhood2_t, int_neighbor_iterator2> neighbor2_found_t;
01701
01705 typedef search_result_t<const single_neighborhood1_t, int_const_neighbor_iterator1> const_neighbor1_found_t;
01709 typedef search_result_t<const single_neighborhood2_t, int_const_neighbor_iterator2> const_neighbor2_found_t;
01710
01718 typename neighborhood1_t::iterator findVertex(const vertex1_t& v);
01726 typename neighborhood2_t::iterator findVertex(const vertex2_t& v);
01727
01731 typename neighborhood1_t::const_iterator findVertex(const vertex1_t& v) const;
01735 typename neighborhood2_t::const_iterator findVertex(const vertex2_t& v) const;
01736
01751 neighbor1_found_t findInVertex( const vertex1_t& v, const vertex2_t& neighbor);
01766 neighbor2_found_t findInVertex( const vertex2_t& v, const vertex1_t& neighbor);
01767
01771 const_neighbor1_found_t findInVertex( const vertex1_t& v, const vertex2_t& neighbor) const;
01775 const_neighbor2_found_t findInVertex( const vertex2_t& v, const vertex1_t& neighbor) const;
01776
01781 std::pair<ineighbor_iterator2,bool> insertInEdge(const vertex1_t& v, const vertex2_t& new_neighbor);
01786 std::pair<ineighbor_iterator1,bool> insertInEdge(const vertex2_t& v, const vertex1_t& new_neighbor);
01787
01792 void undoInEdge(const vertex1_t& new_neighbor, ineighbor_iterator1& it);
01793
01798 void undoInEdge(const vertex2_t& new_neighbor, ineighbor_iterator2& it);
01799
01804 void updateEdgeCache(const vertex1_t& v,
01805 typename edge_list1_t::iterator new_edge_it,
01806 const vertex1_t& in_edge);
01811 void updateEdgeCache(const vertex2_t& v,
01812 typename edge_list2_t::iterator new_edge_it,
01813 const vertex2_t& in_edge);
01814
01818 void updateVertexCache(const vertex1_t& v,
01819 typename neighborhood1_t::iterator it);
01823 void updateVertexCache(const vertex2_t& v,
01824 typename neighborhood2_t::iterator it);
01825
01829 neighborhood1_t neighborhood1;
01833 neighborhood2_t neighborhood2;
01834
01838 lookup1_t lookup1;
01842 lookup2_t lookup2;
01843
01847 intptr_t graph_id;
01848
01849 };
01850
01851
01852 #ifdef USE_ALLOCATOR
01853 template <BIGRAPH_TEMPLATE> template <typename V1, typename V2, typename E>
01854 typename VVBiGraph<BIGRAPH_ARGS>::template neighbor_t<V1,V2,E>::EdgeAlloc
01855 VVBiGraph<BIGRAPH_ARGS>::neighbor_t<V1,V2,E>::edge_alloc;
01856 #endif
01857
01858 template <BIGRAPH_TEMPLATE>
01859 typename VVBiGraph<BIGRAPH_ARGS>::iterator1
01860 VVBiGraph<BIGRAPH_ARGS>::erase( iterator1 it )
01861 {
01862 eraseAllEdges(it);
01863 lookup1.erase(*it);
01864 return neighborhood1.erase(it.base());
01865 }
01866
01867 template <BIGRAPH_TEMPLATE>
01868 typename VVBiGraph<BIGRAPH_ARGS>::iterator2
01869 VVBiGraph<BIGRAPH_ARGS>::erase( iterator2 it )
01870 {
01871 eraseAllEdges(it);
01872 lookup2.erase(*it);
01873 return neighborhood2.erase(it.base());
01874 }
01875
01876 template <BIGRAPH_TEMPLATE>
01877 typename VVBiGraph<BIGRAPH_ARGS>::size_type
01878 VVBiGraph<BIGRAPH_ARGS>::erase( const vertex1_t& v )
01879 {
01880 if(eraseAllEdges(v))
01881 {
01882 typename lookup1_t::iterator it_found = lookup1.find(v);
01883 if(it_found == lookup1.end()) return 0;
01884 typename neighborhood1_t::iterator it = it_found->second;
01885 neighborhood1.erase(it);
01886 lookup1.erase(v);
01887 return 1;
01888 }
01889 return 0;
01890 }
01891
01892 template <BIGRAPH_TEMPLATE>
01893 typename VVBiGraph<BIGRAPH_ARGS>::size_type
01894 VVBiGraph<BIGRAPH_ARGS>::erase( const vertex2_t& v )
01895 {
01896 if(eraseAllEdges(v))
01897 {
01898 typename lookup2_t::iterator it_found = lookup2.find(v);
01899 if(it_found == lookup2.end()) return 0;
01900 typename neighborhood2_t::iterator it = it_found->second;
01901 neighborhood2.erase(it);
01902 lookup2.erase(v);
01903 return 1;
01904 }
01905 return 0;
01906 }
01907
01908 template <BIGRAPH_TEMPLATE>
01909 bool VVBiGraph<BIGRAPH_ARGS>::eraseAllEdges( const vertex1_t& v )
01910 {
01911 typename neighborhood1_t::iterator it_found = this->findVertex(v);
01912 if(it_found != neighborhood1.end() )
01913 {
01914 eraseAllEdges(it_found);
01915 return true;
01916 }
01917 return false;
01918 }
01919
01920 template <BIGRAPH_TEMPLATE>
01921 bool VVBiGraph<BIGRAPH_ARGS>::eraseAllEdges( const vertex2_t& v )
01922 {
01923 typename neighborhood2_t::iterator it_found = this->findVertex(v);
01924 if(it_found != neighborhood2.end() )
01925 {
01926 eraseAllEdges(it_found);
01927 return true;
01928 }
01929 return false;
01930 }
01931
01932 template <BIGRAPH_TEMPLATE>
01933 void VVBiGraph<BIGRAPH_ARGS>::eraseAllEdges( iterator1 it_found )
01934 {
01935 const vertex1_t& v = *it_found;
01936
01937 for(typename edge_list1_t::iterator it_el = it_found.base()->second.edges.begin() ;
01938 it_el != it_found.base()->second.edges.end() ; ++it_el)
01939 {
01940 typename lookup2_t::iterator it_found = lookup2.find(it_el->target);
01941 if(it_found != lookup2.end())
01942 it_found->second->second.in_edges.erase(v);
01943 }
01944 it_found.base()->second.edges.clear();
01945 it_found.base()->second.flagged = 0;
01946
01947 in_edges1_t &in_edges = it_found.base()->second.in_edges;
01948 for( typename in_edges1_t::iterator it = in_edges.begin() ;
01949 it != in_edges.end() ; ++it )
01950 {
01951 #ifndef VVBIGRAPH_NO_EDGE_CACHE
01952 EdgeCache2 *cache = reinterpret_cast<EdgeCache2*>(it->cache);
01953 if(!cache or !cache->eraseEdge())
01954 {
01955 #endif
01956 neighbor2_found_t found = findInVertex(*it, v);
01957 found.neighborhood->edges.erase(found.it);
01958 if(found.neighborhood->flagged && *found.neighborhood->flagged == v) found.neighborhood->flagged = 0;
01959 #ifndef VVBIGRAPH_NO_EDGE_CACHE
01960 }
01961 #endif
01962 }
01963 in_edges.clear();
01964 }
01965
01966 template <BIGRAPH_TEMPLATE>
01967 void VVBiGraph<BIGRAPH_ARGS>::eraseAllEdges( iterator2 it_found )
01968 {
01969 const vertex2_t& v = *it_found;
01970 for(typename edge_list2_t::iterator it_el = it_found.base()->second.edges.begin() ;
01971 it_el != it_found.base()->second.edges.end() ; ++it_el)
01972 {
01973 typename lookup1_t::iterator it_found = lookup1.find(it_el->target);
01974 if(it_found != lookup1.end())
01975 it_found->second->second.in_edges.erase(v);
01976 }
01977 it_found.base()->second.edges.clear();
01978
01979 in_edges2_t &in_edges = it_found.base()->second.in_edges;
01980 for( typename in_edges2_t::iterator it = in_edges.begin() ;
01981 it != in_edges.end() ; ++it )
01982 {
01983 #ifndef VVBIGRAPH_NO_EDGE_CACHE
01984 EdgeCache1 *cache = reinterpret_cast<EdgeCache1*>(it->cache);
01985 if(!cache or !cache->eraseEdge())
01986 {
01987 #endif
01988 neighbor1_found_t found = findInVertex(*it, v);
01989 found.neighborhood->edges.erase(found.it);
01990 if(found.neighborhood->flagged && *found.neighborhood->flagged == v) found.neighborhood->flagged = 0;
01991 #ifndef VVBIGRAPH_NO_EDGE_CACHE
01992 }
01993 #endif
01994 }
01995 in_edges.clear();
01996 }
01997
01998
01999 template <BIGRAPH_TEMPLATE>
02000 bool VVBiGraph<BIGRAPH_ARGS>::clear( const vertex1_t& v )
02001 {
02002 typename neighborhood1_t::iterator it_found = this->findVertex(v);
02003 if(it_found != neighborhood1.end() )
02004 {
02005 clear(it_found);
02006 return true;
02007 }
02008 return false;
02009 }
02010
02011 template <BIGRAPH_TEMPLATE>
02012 bool VVBiGraph<BIGRAPH_ARGS>::clear( const vertex2_t& v )
02013 {
02014 typename neighborhood2_t::iterator it_found = this->findVertex(v);
02015 if(it_found != neighborhood2.end() )
02016 {
02017 clear(it_found);
02018 return true;
02019 }
02020 return false;
02021 }
02022
02023 template <BIGRAPH_TEMPLATE>
02024 void VVBiGraph<BIGRAPH_ARGS>::clear( iterator1 it_found )
02025 {
02026 const vertex1_t& v = *it_found;
02027 for(typename edge_list1_t::iterator it_el = it_found.base()->second.edges.begin() ;
02028 it_el != it_found.base()->second.edges.end() ; ++it_el)
02029 {
02030 typename neighborhood2_t::iterator it_found = this->findVertex(it_el->target);
02031 it_found->second.in_edges.erase(v);
02032 }
02033 it_found.base()->second.edges.clear();
02034 }
02035
02036 template <BIGRAPH_TEMPLATE>
02037 void VVBiGraph<BIGRAPH_ARGS>::clear( iterator2 it_found )
02038 {
02039 const vertex2_t& v = *it_found;
02040 for(typename edge_list2_t::iterator it_el = it_found.base()->second.edges.begin() ;
02041 it_el != it_found.base()->second.edges.end() ; ++it_el)
02042 {
02043 typename neighborhood1_t::iterator it_found = this->findVertex(it_el->target);
02044 it_found->second.in_edges.erase(v);
02045 }
02046 it_found.base()->second.edges.clear();
02047 }
02048
02049 template <BIGRAPH_TEMPLATE>
02050 void VVBiGraph<BIGRAPH_ARGS>::eraseAllEdges()
02051 {
02052 for(typename neighborhood1_t::iterator it = neighborhood1.begin() ;
02053 it != neighborhood1.end() ; ++it)
02054 {
02055 it->second.edges.clear();
02056 it->second.in_edges.clear();
02057 it->second.flagged = 0;
02058 }
02059 for(typename neighborhood2_t::iterator it = neighborhood2.begin() ;
02060 it != neighborhood2.end() ; ++it)
02061 {
02062 it->second.edges.clear();
02063 it->second.in_edges.clear();
02064 it->second.flagged = 0;
02065 }
02066 }
02067
02068 template <BIGRAPH_TEMPLATE>
02069 typename VVBiGraph<BIGRAPH_ARGS>::size_type
02070 VVBiGraph<BIGRAPH_ARGS>::count( const vertex1_t& v ) const
02071 {
02072 return lookup1.count(v);
02073 }
02074
02075 template <BIGRAPH_TEMPLATE>
02076 typename VVBiGraph<BIGRAPH_ARGS>::size_type
02077 VVBiGraph<BIGRAPH_ARGS>::count( const vertex2_t& v ) const
02078 {
02079 return lookup2.count(v);
02080 }
02081
02082 template <BIGRAPH_TEMPLATE>
02083 typename VVBiGraph<BIGRAPH_ARGS>::iterator1
02084 VVBiGraph<BIGRAPH_ARGS>::insert( const vertex1_t& v )
02085 {
02086 typename lookup1_t::iterator it_found;
02087 bool inserted;
02088 util::tie(it_found, inserted) = lookup1.insert(std::make_pair(v, typename neighborhood1_t::iterator()));
02089 if(inserted)
02090 {
02091 neighborhood1.push_front(std::make_pair(v,single_neighborhood1_t()));
02092 typename neighborhood1_t::iterator it = neighborhood1.begin();
02093 it_found->second = it;
02094 updateVertexCache(it->first, it);
02095 return it;
02096 }
02097 return it_found->second;
02098
02099
02100
02101
02102
02103
02104 }
02105
02106 template <BIGRAPH_TEMPLATE>
02107 typename VVBiGraph<BIGRAPH_ARGS>::iterator2
02108 VVBiGraph<BIGRAPH_ARGS>::insert( const vertex2_t& v )
02109 {
02110 typename lookup2_t::iterator it_found;
02111 bool inserted;
02112 util::tie(it_found, inserted) = lookup2.insert(std::make_pair(v, typename neighborhood2_t::iterator()));
02113 if(inserted)
02114 {
02115 neighborhood2.push_front(std::make_pair(v,single_neighborhood2_t()));
02116 typename neighborhood2_t::iterator it = neighborhood2.begin();
02117 it_found->second = it;
02118 updateVertexCache(it->first, it);
02119 return it;
02120 }
02121 return it_found->second;
02122
02123
02124
02125
02126
02127
02128 }
02129
02130 template <BIGRAPH_TEMPLATE>
02131 void VVBiGraph<BIGRAPH_ARGS>::updateVertexCache(const vertex1_t& v,
02132 typename neighborhood1_t::iterator it)
02133 {
02134 #ifndef VVBIGRAPH_NO_VERTEX_CACHE
02135 it->second.update(graph_id, v, it);
02136 #endif
02137 }
02138
02139 template <BIGRAPH_TEMPLATE>
02140 void VVBiGraph<BIGRAPH_ARGS>::updateVertexCache(const vertex2_t& v,
02141 typename neighborhood2_t::iterator it)
02142 {
02143 #ifndef VVBIGRAPH_NO_VERTEX_CACHE
02144 it->second.update(graph_id, v, it);
02145 #endif
02146 }
02147
02148 template <BIGRAPH_TEMPLATE>
02149 typename VVBiGraph<BIGRAPH_ARGS>::iterator1
02150 VVBiGraph<BIGRAPH_ARGS>::insert( iterator1 , const vertex1_t& v )
02151 {
02152 return this->insert(v);
02153 }
02154
02155 template <BIGRAPH_TEMPLATE>
02156 typename VVBiGraph<BIGRAPH_ARGS>::iterator2
02157 VVBiGraph<BIGRAPH_ARGS>::insert( iterator2 , const vertex2_t& v )
02158 {
02159 return this->insert(v);
02160 }
02161
02162 template <BIGRAPH_TEMPLATE>
02163 void VVBiGraph<BIGRAPH_ARGS>::insert( iterator1 first, iterator1 last )
02164 {
02165 for(iterator1 it = first ; it != last ; ++it)
02166 {
02167 insert(*it);
02168 }
02169 }
02170
02171 template <BIGRAPH_TEMPLATE>
02172 void VVBiGraph<BIGRAPH_ARGS>::insert( iterator2 first, iterator2 last )
02173 {
02174 for(iterator2 it = first ; it != last ; ++it)
02175 {
02176 insert(*it);
02177 }
02178 }
02179
02180 template <BIGRAPH_TEMPLATE>
02181 const typename VVBiGraph<BIGRAPH_ARGS>::vertex1_t&
02182 VVBiGraph<BIGRAPH_ARGS>::any_vertex1() const
02183 {
02184 if(neighborhood1.empty())
02185 return vertex1_t::null;
02186 return *begin_vertex1();
02187 }
02188
02189 template <BIGRAPH_TEMPLATE>
02190 const typename VVBiGraph<BIGRAPH_ARGS>::vertex2_t&
02191 VVBiGraph<BIGRAPH_ARGS>::any_vertex2() const
02192 {
02193 if(neighborhood2.empty())
02194 return vertex2_t::null;
02195 return *begin_vertex2();
02196 }
02197
02198 template <BIGRAPH_TEMPLATE>
02199 const typename VVBiGraph<BIGRAPH_ARGS>::vertex1_t&
02200 VVBiGraph<BIGRAPH_ARGS>::get_vertex1(size_type idx) const
02201 {
02202 typename neighborhood1_t::const_iterator it = neighborhood1.begin();
02203 std::advance(it, idx);
02204 return it->first;
02205 }
02206
02207 template <BIGRAPH_TEMPLATE>
02208 const typename VVBiGraph<BIGRAPH_ARGS>::vertex2_t&
02209 VVBiGraph<BIGRAPH_ARGS>::get_vertex2(size_type idx) const
02210 {
02211 typename neighborhood2_t::const_iterator it = neighborhood2.begin();
02212 std::advance(it, idx);
02213 return it->first;
02214 }
02215
02216 template <BIGRAPH_TEMPLATE>
02217 const typename VVBiGraph<BIGRAPH_ARGS>::vertex2_t&
02218 VVBiGraph<BIGRAPH_ARGS>::anyIn( const vertex1_t& v ) const
02219 {
02220 if(v.isNull())
02221 return vertex2_t::null;
02222 typename neighborhood1_t::const_iterator it_found = this->findVertex(v);
02223 if(it_found == neighborhood1.end() || it_found->second.edges.empty())
02224 return vertex2_t::null;
02225 const edge_list1_t& lst = it_found->second.edges;
02226 return lst.front().target;
02227 }
02228
02229 template <BIGRAPH_TEMPLATE>
02230 const typename VVBiGraph<BIGRAPH_ARGS>::vertex1_t&
02231 VVBiGraph<BIGRAPH_ARGS>::anyIn( const vertex2_t& v ) const
02232 {
02233 if(v.isNull())
02234 return vertex1_t::null;
02235 typename neighborhood2_t::const_iterator it_found = this->findVertex(v);
02236 if(it_found == neighborhood2.end() || it_found->second.edges.empty())
02237 return vertex1_t::null;
02238 const edge_list2_t& lst = it_found->second.edges;
02239 return lst.front().target;
02240 }
02241
02242 template <BIGRAPH_TEMPLATE>
02243 typename VVBiGraph<BIGRAPH_ARGS>::size_type
02244 VVBiGraph<BIGRAPH_ARGS>::valence( const vertex1_t& v ) const
02245 {
02246 if(v.isNull())
02247 return 0;
02248 typename neighborhood1_t::const_iterator it_found = this->findVertex(v);
02249 if(it_found == neighborhood1.end())
02250 return 0;
02251 return it_found->second.edges.size();
02252 }
02253
02254 template <BIGRAPH_TEMPLATE>
02255 typename VVBiGraph<BIGRAPH_ARGS>::size_type
02256 VVBiGraph<BIGRAPH_ARGS>::valence( const vertex2_t& v ) const
02257 {
02258 if(v.isNull())
02259 return 0;
02260 typename neighborhood2_t::const_iterator it_found = this->findVertex(v);
02261 if(it_found == neighborhood2.end())
02262 return 0;
02263 return it_found->second.edges.size();
02264 }
02265
02266 template <BIGRAPH_TEMPLATE>
02267 bool VVBiGraph<BIGRAPH_ARGS>::empty( const vertex1_t& v ) const
02268 {
02269 if(v.isNull())
02270 return true;
02271 typename neighborhood1_t::const_iterator it_found = this->findVertex(v);
02272 if(it_found == neighborhood1.end())
02273 return true;
02274 return it_found->second.edges.empty();
02275 }
02276
02277 template <BIGRAPH_TEMPLATE>
02278 bool VVBiGraph<BIGRAPH_ARGS>::empty( const vertex2_t& v ) const
02279 {
02280 if(v.isNull())
02281 return true;
02282 typename neighborhood2_t::const_iterator it_found = this->findVertex(v);
02283 if(it_found == neighborhood2.end())
02284 return true;
02285 return it_found->second.edges.empty();
02286 }
02287
02288 template <BIGRAPH_TEMPLATE>
02289 const typename VVBiGraph<BIGRAPH_ARGS>::vertex2_t&
02290 VVBiGraph<BIGRAPH_ARGS>::iAnyIn( const vertex1_t& v ) const
02291 {
02292 if(v.isNull())
02293 return vertex2_t::null;
02294 typename neighborhood1_t::const_iterator it_found = this->findVertex(v);
02295 if(it_found == neighborhood1.end() || it_found->second.in_edges.empty())
02296 return vertex2_t::null;
02297 const in_edges1_t& lst = it_found->second.in_edges;
02298 return *lst.begin();
02299 }
02300
02301 template <BIGRAPH_TEMPLATE>
02302 const typename VVBiGraph<BIGRAPH_ARGS>::vertex1_t&
02303 VVBiGraph<BIGRAPH_ARGS>::iAnyIn( const vertex2_t& v ) const
02304 {
02305 if(v.isNull())
02306 return vertex1_t::null;
02307 typename neighborhood2_t::const_iterator it_found = this->findVertex(v);
02308 if(it_found == neighborhood2.end() || it_found->second.in_edges.empty())
02309 return vertex1_t::null;
02310 const in_edges2_t& lst = it_found->second.in_edges;
02311 return *lst.begin();
02312 }
02313
02314 template <BIGRAPH_TEMPLATE>
02315 typename VVBiGraph<BIGRAPH_ARGS>::size_type
02316 VVBiGraph<BIGRAPH_ARGS>::iValence( const vertex1_t& v ) const
02317 {
02318 if(v.isNull())
02319 return 0;
02320 typename neighborhood1_t::const_iterator it_found = this->findVertex(v);
02321 if(it_found == neighborhood1.end())
02322 return 0;
02323 return it_found->second.in_edges.size();
02324 }
02325
02326 template <BIGRAPH_TEMPLATE>
02327 typename VVBiGraph<BIGRAPH_ARGS>::size_type
02328 VVBiGraph<BIGRAPH_ARGS>::iValence( const vertex2_t& v ) const
02329 {
02330 if(v.isNull())
02331 return 0;
02332 typename neighborhood2_t::const_iterator it_found = this->findVertex(v);
02333 if(it_found == neighborhood2.end())
02334 return 0;
02335 return it_found->second.in_edges.size();
02336 }
02337
02338 template <BIGRAPH_TEMPLATE>
02339 bool VVBiGraph<BIGRAPH_ARGS>::iEmpty( const vertex1_t& v ) const
02340 {
02341 if(v.isNull())
02342 return true;
02343 typename neighborhood1_t::const_iterator it_found = this->findVertex(v);
02344 if(it_found == neighborhood1.end())
02345 return true;
02346 return it_found->second.in_edges.empty();
02347 }
02348
02349 template <BIGRAPH_TEMPLATE>
02350 bool VVBiGraph<BIGRAPH_ARGS>::iEmpty( const vertex2_t& v ) const
02351 {
02352 if(v.isNull())
02353 return true;
02354 typename neighborhood2_t::const_iterator it_found = this->findVertex(v);
02355 if(it_found == neighborhood2.end())
02356 return true;
02357 return it_found->second.in_edges.empty();
02358 }
02359
02360 template <BIGRAPH_TEMPLATE>
02361 typename VVBiGraph<BIGRAPH_ARGS>::neighborhood1_t::iterator
02362 VVBiGraph<BIGRAPH_ARGS>::findVertex( const vertex1_t& v )
02363 {
02364 #ifndef VVBIGRAPH_NO_VERTEX_CACHE
02365 if(v.cache)
02366 {
02367 if(v.cache_source == 0)
02368 {
02369 VertexCache1* cache = reinterpret_cast<VertexCache1*>(v.cache);
02370 if(cache->graph_id() == graph_id)
02371 {
02372 return cache->neighborhood();
02373 }
02374 }
02375 }
02376 #endif // VVBIGRAPH_NO_VERTEX_CACHE
02377 typename lookup1_t::const_iterator it_found = lookup1.find(v);
02378 if(it_found != lookup1.end())
02379 return it_found->second;
02380 return neighborhood1.end();
02381 }
02382
02383 template <BIGRAPH_TEMPLATE>
02384 typename VVBiGraph<BIGRAPH_ARGS>::neighborhood2_t::iterator
02385 VVBiGraph<BIGRAPH_ARGS>::findVertex( const vertex2_t& v )
02386 {
02387 #ifndef VVBIGRAPH_NO_VERTEX_CACHE
02388 if(v.cache)
02389 {
02390 if(v.cache_source == 0)
02391 {
02392 VertexCache2* cache = reinterpret_cast<VertexCache2*>(v.cache);
02393 if(cache->graph_id() == graph_id)
02394 {
02395 return cache->neighborhood();
02396 }
02397 }
02398 }
02399 #endif // VVBIGRAPH_NO_VERTEX_CACHE
02400 typename lookup2_t::const_iterator it_found = lookup2.find(v);
02401 if(it_found != lookup2.end())
02402 return it_found->second;
02403 return neighborhood2.end();
02404 }
02405
02406 template <BIGRAPH_TEMPLATE>
02407 typename VVBiGraph<BIGRAPH_ARGS>::neighborhood1_t::const_iterator
02408 VVBiGraph<BIGRAPH_ARGS>::findVertex( const vertex1_t& v ) const
02409 {
02410 #ifndef VVBIGRAPH_NO_VERTEX_CACHE
02411 if(v.cache)
02412 {
02413 if(v.cache_source == 0)
02414 {
02415 VertexCache1* cache = reinterpret_cast<VertexCache1*>(v.cache);
02416 if(cache->graph_id() == graph_id)
02417 {
02418 return cache->neighborhood();
02419 }
02420 }
02421 }
02422 #endif // VVBIGRAPH_NO_VERTEX_CACHE
02423 typename lookup1_t::const_iterator it_found = lookup1.find(v);
02424 if(it_found != lookup1.end())
02425 return it_found->second;
02426 return neighborhood1.end();
02427 }
02428
02429 template <BIGRAPH_TEMPLATE>
02430 typename VVBiGraph<BIGRAPH_ARGS>::neighborhood2_t::const_iterator
02431 VVBiGraph<BIGRAPH_ARGS>::findVertex( const vertex2_t& v ) const
02432 {
02433 #ifndef VVBIGRAPH_NO_VERTEX_CACHE
02434 if(v.cache)
02435 {
02436 if(v.cache_source == 0)
02437 {
02438 VertexCache2* cache = reinterpret_cast<VertexCache2*>(v.cache);
02439 if(cache->graph_id() == graph_id)
02440 {
02441 return cache->neighborhood();
02442 }
02443 }
02444 }
02445 #endif // VVBIGRAPH_NO_VERTEX_CACHE
02446 typename lookup2_t::const_iterator it_found = lookup2.find(v);
02447 if(it_found != lookup2.end())
02448 return it_found->second;
02449 return neighborhood2.end();
02450 }
02451
02452 template <BIGRAPH_TEMPLATE>
02453 typename VVBiGraph<BIGRAPH_ARGS>::neighbor1_found_t
02454 VVBiGraph<BIGRAPH_ARGS>::findInVertex( const vertex1_t& v, const vertex2_t& n)
02455 {
02456 if(v.isNull() || n.isNull())
02457 return neighbor1_found_t();
02458 #ifndef VVBIGRAPH_NO_EDGE_CACHE
02459 if(n.cache_source == v.id())
02460 {
02461 EdgeCache1 *cache = reinterpret_cast<EdgeCache1*>(n.cache);
02462 if(cache->graph_id() == graph_id)
02463 {
02464 return neighbor1_found_t(cache->it(), cache->neighborhood());
02465 }
02466 }
02467 #endif // VVBIGRAPH_NO_EDGE_CACHE
02468 typename neighborhood1_t::iterator it_found = this->findVertex(v);
02469 if(it_found == neighborhood1.end())
02470 return neighbor1_found_t();
02471 edge_list1_t &lst = it_found->second.edges;
02472 for(typename edge_list1_t::iterator it = lst.begin() ;
02473 it != lst.end() ; ++it)
02474 {
02475 if(it->target == n)
02476 {
02477 return neighbor1_found_t(it, &it_found->second);
02478 }
02479 }
02480 return neighbor1_found_t(lst.end(), &it_found->second, false);
02481 }
02482
02483 template <BIGRAPH_TEMPLATE>
02484 typename VVBiGraph<BIGRAPH_ARGS>::neighbor2_found_t
02485 VVBiGraph<BIGRAPH_ARGS>::findInVertex( const vertex2_t& v, const vertex1_t& n)
02486 {
02487 if(v.isNull() || n.isNull())
02488 return neighbor2_found_t();
02489 #ifndef VVBIGRAPH_NO_EDGE_CACHE
02490 if(n.cache_source == v.id())
02491 {
02492 EdgeCache2 *cache = reinterpret_cast<EdgeCache2*>(n.cache);
02493 if(cache->graph_id() == graph_id)
02494 {
02495 return neighbor2_found_t(cache->it(), cache->neighborhood());
02496 }
02497 }
02498 #endif // VVBIGRAPH_NO_EDGE_CACHE
02499 typename neighborhood2_t::iterator it_found = this->findVertex(v);
02500 if(it_found == neighborhood2.end())
02501 return neighbor2_found_t();
02502 edge_list2_t &lst = it_found->second.edges;
02503 for(typename edge_list2_t::iterator it = lst.begin() ;
02504 it != lst.end() ; ++it)
02505 {
02506 if(it->target == n)
02507 {
02508 return neighbor2_found_t(it, &it_found->second);
02509 }
02510 }
02511 return neighbor2_found_t(lst.end(), &it_found->second, false);
02512 }
02513
02514 template <BIGRAPH_TEMPLATE>
02515 typename VVBiGraph<BIGRAPH_ARGS>::const_neighbor1_found_t
02516 VVBiGraph<BIGRAPH_ARGS>::findInVertex( const vertex1_t& v, const vertex2_t& n) const
02517 {
02518 if(v.isNull() || n.isNull())
02519 return const_neighbor1_found_t();
02520 #ifndef VVBIGRAPH_NO_EDGE_CACHE
02521 if(n.cache_source == v.id())
02522 {
02523 EdgeCache1 *cache = reinterpret_cast<EdgeCache1*>(n.cache);
02524 if(cache->graph_id() == graph_id)
02525 {
02526 return const_neighbor1_found_t(cache->it(), cache->neighborhood());
02527 }
02528 }
02529 #endif // VVBIGRAPH_NO_EDGE_CACHE
02530 typename neighborhood1_t::const_iterator it_found = this->findVertex(v);
02531 if(it_found == neighborhood1.end())
02532 return const_neighbor1_found_t();
02533 const edge_list1_t &lst = it_found->second.edges;
02534 for(typename edge_list1_t::const_iterator it = lst.begin() ;
02535 it != lst.end() ; ++it)
02536 {
02537 if(it->target == n)
02538 {
02539 return const_neighbor1_found_t(it, &it_found->second);
02540 }
02541 }
02542 return const_neighbor1_found_t(lst.end(), &it_found->second, false);
02543 }
02544
02545 template <BIGRAPH_TEMPLATE>
02546 typename VVBiGraph<BIGRAPH_ARGS>::const_neighbor2_found_t
02547 VVBiGraph<BIGRAPH_ARGS>::findInVertex( const vertex2_t& v, const vertex1_t& n) const
02548 {
02549 if(v.isNull() || n.isNull())
02550 return const_neighbor2_found_t();
02551 #ifndef VVBIGRAPH_NO_EDGE_CACHE
02552 if(n.cache_source == v.id())
02553 {
02554 EdgeCache2 *cache = reinterpret_cast<EdgeCache2*>(n.cache);
02555 if(cache->graph_id() == graph_id)
02556 {
02557 return const_neighbor2_found_t(cache->it(), cache->neighborhood());
02558 }
02559 }
02560 #endif // VVBIGRAPH_NO_EDGE_CACHE
02561 typename neighborhood2_t::const_iterator it_found = this->findVertex(v);
02562 if(it_found == neighborhood2.end())
02563 return const_neighbor2_found_t();
02564 const edge_list2_t &lst = it_found->second.edges;
02565 for(typename edge_list2_t::const_iterator it = lst.begin() ;
02566 it != lst.end() ; ++it)
02567 {
02568 if(it->target == n)
02569 {
02570 return const_neighbor2_found_t(it, &it_found->second);
02571 }
02572 }
02573 return const_neighbor2_found_t(lst.end(), &it_found->second, false);
02574 }
02575
02576 template <BIGRAPH_TEMPLATE>
02577 typename VVBiGraph<BIGRAPH_ARGS>::neighbor_iterator1
02578 VVBiGraph<BIGRAPH_ARGS>::findIn(const vertex1_t& v, const vertex2_t& n)
02579 {
02580 neighbor1_found_t found = findInVertex(v, n);
02581 if(found.neighborhood)
02582 return neighbor_iterator1(found.it);
02583 return neighbor_iterator1();
02584 }
02585
02586 template <BIGRAPH_TEMPLATE>
02587 typename VVBiGraph<BIGRAPH_ARGS>::neighbor_iterator2
02588 VVBiGraph<BIGRAPH_ARGS>::findIn(const vertex2_t& v, const vertex1_t& n)
02589 {
02590 neighbor2_found_t found = findInVertex(v, n);
02591 if(found.neighborhood)
02592 return neighbor_iterator2(found.it);
02593 return neighbor_iterator2();
02594 }
02595
02596 template <BIGRAPH_TEMPLATE>
02597 typename VVBiGraph<BIGRAPH_ARGS>::const_neighbor_iterator1
02598 VVBiGraph<BIGRAPH_ARGS>::findIn(const vertex1_t& v, const vertex2_t& n) const
02599 {
02600 const_neighbor1_found_t found = findInVertex(v, n);
02601 if(found.neighborhood)
02602 return const_neighbor_iterator1(found.it);
02603 return const_neighbor_iterator1(found.it);
02604 }
02605
02606 template <BIGRAPH_TEMPLATE>
02607 typename VVBiGraph<BIGRAPH_ARGS>::const_neighbor_iterator2
02608 VVBiGraph<BIGRAPH_ARGS>::findIn(const vertex2_t& v, const vertex1_t& n) const
02609 {
02610 const_neighbor2_found_t found = findInVertex(v, n);
02611 if(found.neighborhood)
02612 return const_neighbor_iterator2(found.it);
02613 return const_neighbor_iterator2(found.it);
02614 }
02615
02616 template <BIGRAPH_TEMPLATE>
02617 typename VVBiGraph<BIGRAPH_ARGS>::neighbor_iterator1
02618 VVBiGraph<BIGRAPH_ARGS>::eraseEdge(const vertex1_t& v, neighbor_iterator1 pos)
02619 {
02620 typename neighborhood1_t::iterator it_found = this->findVertex(v);
02621 if(it_found == neighborhood1.end())
02622 return neighbor_iterator1();
02623 const vertex2_t& n = *pos;
02624 typename neighborhood2_t::iterator it_found2 = this->findVertex(n);
02625 if(it_found2 == neighborhood2.end())
02626 return neighbor_iterator1();
02627 size_type result = it_found2->second.in_edges.erase(v);
02628 if(result)
02629 {
02630 typename edge_list1_t::iterator it = pos.base();
02631 return it_found->second.edges.erase(it);
02632 }
02633 return neighbor_iterator1();
02634 }
02635
02636 template <BIGRAPH_TEMPLATE>
02637 typename VVBiGraph<BIGRAPH_ARGS>::neighbor_iterator2
02638 VVBiGraph<BIGRAPH_ARGS>::eraseEdge(const vertex2_t& v, neighbor_iterator2 pos)
02639 {
02640 typename neighborhood2_t::iterator it_found = this->findVertex(v);
02641 if(it_found == neighborhood2.end())
02642 return neighbor_iterator2();
02643 const vertex1_t& n = *pos;
02644 typename neighborhood1_t::iterator it_found2 = this->findVertex(n);
02645 if(it_found2 == neighborhood1.end())
02646 return neighbor_iterator2();
02647 size_type result = it_found2->second.in_edges.erase(v);
02648 if(result)
02649 {
02650 typename edge_list2_t::iterator it = pos.base();
02651 return it_found->second.edges.erase(it);
02652 }
02653 return neighbor_iterator2();
02654 }
02655
02656 template <BIGRAPH_TEMPLATE>
02657 typename VVBiGraph<BIGRAPH_ARGS>::circ_neighbor_iterator1
02658 VVBiGraph<BIGRAPH_ARGS>::eraseEdge(const vertex1_t& v, circ_neighbor_iterator1 pos)
02659 {
02660 neighbor_iterator1 nit = eraseEdge(v, pos.base());
02661 if(pos.isInitIterator(nit))
02662 return pos.end();
02663 return circ_neighbor_iterator1(pos, nit);
02664 }
02665
02666 template <BIGRAPH_TEMPLATE>
02667 typename VVBiGraph<BIGRAPH_ARGS>::circ_neighbor_iterator2
02668 VVBiGraph<BIGRAPH_ARGS>::eraseEdge(const vertex2_t& v, circ_neighbor_iterator2 pos)
02669 {
02670 neighbor_iterator2 nit = eraseEdge(v, pos.base());
02671 if(pos.isInitIterator(nit))
02672 return pos.end();
02673 return circ_neighbor_iterator2(pos, nit);
02674 }
02675
02676 template <BIGRAPH_TEMPLATE>
02677 typename VVBiGraph<BIGRAPH_ARGS>::size_type
02678 VVBiGraph<BIGRAPH_ARGS>::eraseEdge( const vertex1_t& v, const vertex2_t& n )
02679 {
02680 neighbor1_found_t found = this->findInVertex(v, n);
02681 if(!found)
02682 return false;
02683 if(found.neighborhood->flagged && *found.neighborhood->flagged == n) found.neighborhood->flagged = 0;
02684 found.neighborhood->edges.erase(found.it);
02685 typename lookup2_t::iterator it_found = lookup2.find(n);
02686 if(it_found != lookup2.end())
02687 it_found->second->second.in_edges.erase(v);
02688 return true;
02689 }
02690
02691 template <BIGRAPH_TEMPLATE>
02692 typename VVBiGraph<BIGRAPH_ARGS>::size_type
02693 VVBiGraph<BIGRAPH_ARGS>::eraseEdge( const vertex2_t& v, const vertex1_t& n )
02694 {
02695 neighbor2_found_t found = findInVertex(v, n);
02696 if(!found)
02697 return false;
02698 if(found.neighborhood->flagged && *found.neighborhood->flagged == n) found.neighborhood->flagged = 0;
02699 found.neighborhood->edges.erase(found.it);
02700 typename lookup1_t::iterator it_found = lookup1.find(n);
02701 if(it_found != lookup1.end())
02702 it_found->second->second.in_edges.erase(v);
02703 return true;
02704 }
02705
02706 template <BIGRAPH_TEMPLATE>
02707 bool VVBiGraph<BIGRAPH_ARGS>::contains( const vertex1_t& v ) const
02708 {
02709 return this->findVertex(v) != neighborhood1.end();
02710 }
02711
02712 template <BIGRAPH_TEMPLATE>
02713 bool VVBiGraph<BIGRAPH_ARGS>::contains( const vertex2_t& v ) const
02714 {
02715 return this->findVertex(v) != neighborhood2.end();
02716 }
02717
02718 template <BIGRAPH_TEMPLATE>
02719 std::pair<typename VVBiGraph<BIGRAPH_ARGS>::ineighbor_iterator2,bool>
02720 VVBiGraph<BIGRAPH_ARGS>::insertInEdge(const vertex1_t& v, const vertex2_t& new_neighbor)
02721 {
02722 typename lookup2_t::iterator found = lookup2.find(new_neighbor);
02723 if(found == lookup2.end())
02724 return std::make_pair(ineighbor_iterator2(), false);
02725 return found->second->second.in_edges.insert(v);
02726 }
02727
02728 template <BIGRAPH_TEMPLATE>
02729 std::pair<typename VVBiGraph<BIGRAPH_ARGS>::ineighbor_iterator1,bool>
02730 VVBiGraph<BIGRAPH_ARGS>::insertInEdge(const vertex2_t& v, const vertex1_t& new_neighbor)
02731 {
02732 typename lookup1_t::iterator found = lookup1.find(new_neighbor);
02733 if(found == lookup1.end())
02734 return std::make_pair(ineighbor_iterator1(), false);
02735 return found->second->second.in_edges.insert(v);
02736 }
02737
02738 template <BIGRAPH_TEMPLATE>
02739 void VVBiGraph<BIGRAPH_ARGS>::undoInEdge(const vertex2_t& new_neighbor,
02740 ineighbor_iterator2& it)
02741 {
02742 typename lookup2_t::iterator found = lookup2.find(new_neighbor);
02743 if(found == lookup2.end())
02744 return;
02745 found->second->second.in_edges.erase(it);
02746 }
02747
02748 template <BIGRAPH_TEMPLATE>
02749 void VVBiGraph<BIGRAPH_ARGS>::undoInEdge(const vertex1_t& new_neighbor,
02750 ineighbor_iterator1& it)
02751 {
02752 typename lookup1_t::iterator found = lookup1.find(new_neighbor);
02753 if(found == lookup1.end())
02754 return;
02755 found->second->second.in_edges.erase(it);
02756 }
02757
02758 template <BIGRAPH_TEMPLATE>
02759 void VVBiGraph<BIGRAPH_ARGS>::updateEdgeCache(const vertex1_t& v,
02760 typename edge_list1_t::iterator new_edge_it,
02761 const vertex1_t& in_edge)
02762 {
02763 #ifndef VVBIGRAPH_NO_EDGE_CACHE
02764
02765 neighbor1_t& neighbor = *new_edge_it;
02766 neighbor.setIt(new_edge_it);
02767 neighbor.target.cache_source = v.id();
02768 neighbor.target.cache = reinterpret_cast<void*>(&neighbor);
02769
02770
02771 in_edge.cache_source = v.id();
02772 in_edge.cache = reinterpret_cast<void*>(&neighbor);
02773 #endif // VVBIGRAPH_NO_EDGE_CACHE
02774 }
02775
02776 template <BIGRAPH_TEMPLATE>
02777 void VVBiGraph<BIGRAPH_ARGS>::updateEdgeCache(const vertex2_t& v,
02778 typename edge_list2_t::iterator new_edge_it,
02779 const vertex2_t& in_edge)
02780 {
02781 #ifndef VVBIGRAPH_NO_EDGE_CACHE
02782
02783 neighbor2_t& neighbor = *new_edge_it;
02784 neighbor.setIt(new_edge_it);
02785 neighbor.target.cache_source = v.id();
02786 neighbor.target.cache = reinterpret_cast<void*>(&neighbor);
02787
02788
02789 in_edge.cache_source = v.id();
02790 in_edge.cache = reinterpret_cast<void*>(&neighbor);
02791 #endif // VVBIGRAPH_NO_EDGE_CACHE
02792 }
02793
02794 template <BIGRAPH_TEMPLATE>
02795 typename VVBiGraph<BIGRAPH_ARGS>::edge1_t
02796 VVBiGraph<BIGRAPH_ARGS>::replace( const vertex1_t& v,
02797 const vertex2_t& neighbor,
02798 const vertex2_t& new_neighbor )
02799 {
02800 if(new_neighbor.isNull() || (neighbor == new_neighbor))
02801 return edge1_t();
02802 neighbor1_found_t found = findInVertex(v, neighbor);
02803 if(!found)
02804 return edge1_t();
02805 typename neighborhood2_t::iterator n_found = this->findVertex(neighbor);
02806 ineighbor_iterator2 it_in;
02807 bool inserted;
02808 util::tie(it_in, inserted) = insertInEdge(v, new_neighbor);
02809 if(!inserted)
02810 return edge1_t();
02811 n_found->second.in_edges.erase(v);
02812 found.it->target = new_neighbor;
02813 found.it->clear_edge();
02814 updateEdgeCache(v, found.it, *it_in);
02815 if(n_found->second.flagged and *n_found->second.flagged == neighbor) n_found->second.flagged = 0;
02816 return edge1_t(v.id(), new_neighbor.id(), &*found.it);
02817 }
02818
02819 template <BIGRAPH_TEMPLATE>
02820 typename VVBiGraph<BIGRAPH_ARGS>::edge2_t
02821 VVBiGraph<BIGRAPH_ARGS>::replace( const vertex2_t& v,
02822 const vertex1_t& neighbor,
02823 const vertex1_t& new_neighbor )
02824 {
02825 if(new_neighbor.isNull() || (neighbor == new_neighbor))
02826 return edge2_t();
02827 neighbor2_found_t found = findInVertex(v, neighbor);
02828 if(!found)
02829 return edge2_t();
02830 typename neighborhood1_t::iterator n_found = this->findVertex(neighbor);
02831 ineighbor_iterator1 it_in;
02832 bool inserted;
02833 util::tie(it_in, inserted) = insertInEdge(v, new_neighbor);
02834 if(!inserted)
02835 return edge2_t();
02836 n_found->second.in_edges.erase(v);
02837 found.it->target = new_neighbor;
02838 found.it->clear_edge();
02839 updateEdgeCache(v, found.it, *it_in);
02840 if(n_found->second.flagged and *n_found->second.flagged == neighbor) n_found->second.flagged = 0;
02841 return edge2_t(v.id(), new_neighbor.id(), &*found.it);
02842 }
02843
02844 template <BIGRAPH_TEMPLATE>
02845 const typename VVBiGraph<BIGRAPH_ARGS>::vertex2_t&
02846 VVBiGraph<BIGRAPH_ARGS>::nextTo( const vertex1_t& v,
02847 const vertex2_t& ref,
02848 unsigned int n ) const
02849 {
02850 const_neighbor1_found_t found = findInVertex(v, ref);
02851 if(!found)
02852 return vertex2_t::null;
02853 typename edge_list1_t::const_iterator it = found.it;
02854 const edge_list1_t& lst = found.neighborhood->edges;
02855 for(unsigned int i = 0 ; i < n ; ++i)
02856 {
02857 ++it;
02858 if(it == lst.end())
02859 it = lst.begin();
02860 }
02861 return it->target;
02862 }
02863
02864 template <BIGRAPH_TEMPLATE>
02865 const typename VVBiGraph<BIGRAPH_ARGS>::vertex1_t&
02866 VVBiGraph<BIGRAPH_ARGS>::nextTo( const vertex2_t& v,
02867 const vertex1_t& ref,
02868 unsigned int n ) const
02869 {
02870 const_neighbor2_found_t found = findInVertex(v, ref);
02871 if(!found)
02872 return vertex1_t::null;
02873 typename edge_list2_t::const_iterator it = found.it;
02874 const edge_list2_t& lst = found.neighborhood->edges;
02875 for(unsigned int i = 0 ; i < n ; ++i)
02876 {
02877 ++it;
02878 if(it == lst.end())
02879 it = lst.begin();
02880 }
02881 return it->target;
02882 }
02883
02884 template <BIGRAPH_TEMPLATE>
02885 const typename VVBiGraph<BIGRAPH_ARGS>::vertex2_t&
02886 VVBiGraph<BIGRAPH_ARGS>::prevTo( const vertex1_t& v,
02887 const vertex2_t& ref,
02888 unsigned int n ) const
02889 {
02890 const_neighbor1_found_t found = findInVertex(v, ref);
02891 if(!found)
02892 return vertex2_t::null;
02893 typename edge_list1_t::const_iterator it = found.it;
02894 const edge_list1_t& lst = found.neighborhood->edges;
02895 for(unsigned int i = 0 ; i < n ; ++i)
02896 {
02897 if(it == lst.begin())
02898 it = lst.end();
02899 --it;
02900 }
02901 return it->target;
02902 }
02903
02904 template <BIGRAPH_TEMPLATE>
02905 const typename VVBiGraph<BIGRAPH_ARGS>::vertex1_t&
02906 VVBiGraph<BIGRAPH_ARGS>::prevTo( const vertex2_t& v,
02907 const vertex1_t& ref,
02908 unsigned int n ) const
02909 {
02910 const_neighbor2_found_t found = findInVertex(v, ref);
02911 if(!found)
02912 return vertex1_t::null;
02913 typename edge_list2_t::const_iterator it = found.it;
02914 const edge_list2_t& lst = found.neighborhood->edges;
02915 for(unsigned int i = 0 ; i < n ; ++i)
02916 {
02917 if(it == lst.begin())
02918 it = lst.end();
02919 --it;
02920 }
02921 return it->target;
02922 }
02923
02924 template <BIGRAPH_TEMPLATE>
02925 typename VVBiGraph<BIGRAPH_ARGS>::edge1_t
02926 VVBiGraph<BIGRAPH_ARGS>::edge( const vertex1_t& src,
02927 const vertex2_t& tgt )
02928 {
02929 neighbor1_found_t found = findInVertex(src, tgt);
02930 if(!found)
02931 return edge1_t();
02932 return edge1_t(src.id(), tgt.id(), &*found.it);
02933 }
02934
02935 template <BIGRAPH_TEMPLATE>
02936 typename VVBiGraph<BIGRAPH_ARGS>::edge2_t
02937 VVBiGraph<BIGRAPH_ARGS>::edge( const vertex2_t& src,
02938 const vertex1_t& tgt )
02939 {
02940 neighbor2_found_t found = findInVertex(src, tgt);
02941 if(!found)
02942 return edge2_t();
02943 return edge2_t(src.id(), tgt.id(), &*found.it);
02944 }
02945
02946 template <BIGRAPH_TEMPLATE>
02947 typename VVBiGraph<BIGRAPH_ARGS>::const_edge1_t
02948 VVBiGraph<BIGRAPH_ARGS>::edge( const vertex1_t& src,
02949 const vertex2_t& tgt ) const
02950 {
02951 const_neighbor1_found_t found = findInVertex(src, tgt);
02952 if(!found)
02953 return const_edge1_t();
02954 return const_edge1_t(src.id(), tgt.id(), &*found.it);
02955 }
02956
02957 template <BIGRAPH_TEMPLATE>
02958 typename VVBiGraph<BIGRAPH_ARGS>::const_edge2_t
02959 VVBiGraph<BIGRAPH_ARGS>::edge( const vertex2_t& src,
02960 const vertex1_t& tgt ) const
02961 {
02962 const_neighbor2_found_t found = findInVertex(src, tgt);
02963 if(!found)
02964 return const_edge2_t();
02965 return const_edge2_t(src.id(), tgt.id(), &*found.it);
02966 }
02967
02968 template <BIGRAPH_TEMPLATE>
02969 bool VVBiGraph<BIGRAPH_ARGS>::flag(const vertex1_t& src, const vertex2_t& neighbor)
02970 {
02971 neighbor1_found_t found = findInVertex(src, neighbor);
02972 if(!found)
02973 return false;
02974 found.neighborhood->flagged = &(found.it->target);
02975 return true;
02976 }
02977
02978 template <BIGRAPH_TEMPLATE>
02979 bool VVBiGraph<BIGRAPH_ARGS>::flag(const vertex2_t& src, const vertex1_t& neighbor)
02980 {
02981 neighbor2_found_t found = findInVertex(src, neighbor);
02982 if(!found)
02983 return false;
02984 found.neighborhood->flagged = &(found.it->target);
02985 return true;
02986 }
02987
02988 template <BIGRAPH_TEMPLATE>
02989 const typename VVBiGraph<BIGRAPH_ARGS>::vertex2_t&
02990 VVBiGraph<BIGRAPH_ARGS>::flagged(const vertex1_t& src) const
02991 {
02992 typename neighborhood1_t::const_iterator it_found = this->findVertex(src);
02993 if(it_found == neighborhood1.end() or it_found->second.flagged == 0)
02994 return vertex2_t::null;
02995 return *it_found->second.flagged;
02996 }
02997
02998 template <BIGRAPH_TEMPLATE>
02999 const typename VVBiGraph<BIGRAPH_ARGS>::vertex1_t&
03000 VVBiGraph<BIGRAPH_ARGS>::flagged(const vertex2_t& src) const
03001 {
03002 typename neighborhood2_t::const_iterator it_found = this->findVertex(src);
03003 if(it_found == neighborhood2.end() or it_found->second.flagged == 0)
03004 return vertex1_t::null;
03005 return *it_found->second.flagged;
03006 }
03007
03008 template <BIGRAPH_TEMPLATE>
03009 typename VVBiGraph<BIGRAPH_ARGS>::edge1_t
03010 VVBiGraph<BIGRAPH_ARGS>::spliceAfter( const vertex1_t& v,
03011 const vertex2_t& neighbor,
03012 const vertex2_t& new_neighbor )
03013 {
03014 if(new_neighbor.isNull())
03015 return edge1_t();
03016 neighbor1_found_t found = findInVertex(v, neighbor);
03017 if(!found)
03018 return edge1_t();
03019 ineighbor_iterator2 it_in;
03020 bool inserted;
03021 util::tie(it_in, inserted) = insertInEdge(v, new_neighbor);
03022 if(!inserted)
03023 return edge1_t();
03024 ++found.it;
03025 typename edge_list1_t::iterator new_edge_it = found.neighborhood->edges.insert(found.it, neighbor1_t(new_neighbor, Edge1Content(), *found.neighborhood, graph_id));
03026 updateEdgeCache(v, new_edge_it, *it_in);
03027 return edge1_t(v.id(), new_neighbor.id(), &*new_edge_it);
03028 }
03029
03030 template <BIGRAPH_TEMPLATE>
03031 typename VVBiGraph<BIGRAPH_ARGS>::edge2_t
03032 VVBiGraph<BIGRAPH_ARGS>::spliceAfter( const vertex2_t& v,
03033 const vertex1_t& neighbor,
03034 const vertex1_t& new_neighbor )
03035 {
03036 if(new_neighbor.isNull())
03037 return edge2_t();
03038 neighbor2_found_t found = findInVertex(v, neighbor);
03039 if(!found)
03040 return edge2_t();
03041 ineighbor_iterator1 it_in;
03042 bool inserted;
03043 util::tie(it_in, inserted) = insertInEdge(v, new_neighbor);
03044 if(!inserted)
03045 return edge2_t();
03046 ++found.it;
03047 typename edge_list2_t::iterator new_edge_it = found.neighborhood->edges.insert(found.it, neighbor2_t(new_neighbor, Edge2Content(), *found.neighborhood, graph_id));
03048 updateEdgeCache(v, new_edge_it, *it_in);
03049 return edge2_t(v.id(), new_neighbor.id(), &*new_edge_it);
03050 }
03051
03052 template <BIGRAPH_TEMPLATE>
03053 typename VVBiGraph<BIGRAPH_ARGS>::edge1_t
03054 VVBiGraph<BIGRAPH_ARGS>::spliceBefore( const vertex1_t& v,
03055 const vertex2_t& neighbor,
03056 const vertex2_t& new_neighbor )
03057 {
03058 if(new_neighbor.isNull())
03059 return edge1_t();
03060 neighbor1_found_t found = findInVertex(v, neighbor);
03061 if(!found)
03062 return edge1_t();
03063 ineighbor_iterator2 it_in;
03064 bool inserted;
03065 util::tie(it_in, inserted) = insertInEdge(v, new_neighbor);
03066 if(!inserted)
03067 return edge1_t();
03068 typename edge_list1_t::iterator new_edge_it = found.neighborhood->edges.insert(found.it, neighbor1_t(new_neighbor, Edge1Content(), *found.neighborhood, graph_id));
03069 updateEdgeCache(v, new_edge_it, *it_in);
03070 return edge1_t(v.id(), new_neighbor.id(), &*new_edge_it);
03071 }
03072
03073 template <BIGRAPH_TEMPLATE>
03074 typename VVBiGraph<BIGRAPH_ARGS>::edge2_t
03075 VVBiGraph<BIGRAPH_ARGS>::spliceBefore( const vertex2_t& v,
03076 const vertex1_t& neighbor,
03077 const vertex1_t& new_neighbor )
03078 {
03079 if(new_neighbor.isNull())
03080 return edge2_t();
03081 neighbor2_found_t found = findInVertex(v, neighbor);
03082 if(!found)
03083 return edge2_t();
03084 ineighbor_iterator1 it_in;
03085 bool inserted;
03086 util::tie(it_in, inserted) = insertInEdge(v, new_neighbor);
03087 if(!inserted)
03088 return edge2_t();
03089 typename edge_list2_t::iterator new_edge_it = found.neighborhood->edges.insert(found.it, neighbor2_t(new_neighbor, Edge2Content(), *found.neighborhood, graph_id));
03090 updateEdgeCache(v, new_edge_it, *it_in);
03091 return edge2_t(v.id(), new_neighbor.id(), &*new_edge_it);
03092 }
03093
03094 template <BIGRAPH_TEMPLATE>
03095 typename VVBiGraph<BIGRAPH_ARGS>::edge1_t
03096 VVBiGraph<BIGRAPH_ARGS>::insertEdge( const vertex1_t& v,
03097 const vertex2_t& new_neighbor )
03098 {
03099 if(v.isNull() || new_neighbor.isNull())
03100 return edge1_t();
03101 typename neighborhood1_t::iterator it_found = this->findVertex(v);
03102 if(it_found == neighborhood1.end())
03103 return edge1_t();
03104 ineighbor_iterator2 it_in;
03105 bool inserted;
03106 util::tie(it_in, inserted) = insertInEdge(v, new_neighbor);
03107 if(!inserted)
03108 return edge1_t();
03109 edge_list1_t &lst = it_found->second.edges;
03110 lst.push_front(neighbor1_t(new_neighbor, Edge1Content(), it_found->second, graph_id));
03111 typename edge_list1_t::iterator it = lst.begin();
03112 updateEdgeCache(v, it, *it_in);
03113 return edge1_t(v.id(), new_neighbor.id(), &*it);
03114 }
03115
03116 template <BIGRAPH_TEMPLATE>
03117 typename VVBiGraph<BIGRAPH_ARGS>::edge2_t
03118 VVBiGraph<BIGRAPH_ARGS>::insertEdge( const vertex2_t& v,
03119 const vertex1_t& new_neighbor )
03120 {
03121 if(v.isNull() || new_neighbor.isNull())
03122 return edge2_t();
03123 typename neighborhood2_t::iterator it_found = this->findVertex(v);
03124 if(it_found == neighborhood2.end())
03125 return edge2_t();
03126 ineighbor_iterator1 it_in;
03127 bool inserted;
03128 util::tie(it_in, inserted) = insertInEdge(v, new_neighbor);
03129 if(!inserted)
03130 return edge2_t();
03131 edge_list2_t &lst = it_found->second.edges;
03132 lst.push_front(neighbor2_t(new_neighbor, Edge2Content(), it_found->second, graph_id));
03133 typename edge_list2_t::iterator it = lst.begin();
03134 updateEdgeCache(v, it, *it_in);
03135 return edge2_t(v.id(), new_neighbor.id(), &*it);
03136 }
03137
03138 template <BIGRAPH_TEMPLATE>
03139 typename VVBiGraph<BIGRAPH_ARGS>::const_neighbor_iterator1_range
03140 VVBiGraph<BIGRAPH_ARGS>::neighbors(const vertex1_t& v) const
03141 {
03142 const_neighbor_iterator1_range result;
03143 if(v.isNull())
03144 return result;
03145 typename neighborhood1_t::const_iterator it_found = this->findVertex(v);
03146 if(it_found == neighborhood1.end())
03147 return result;
03148 const edge_list1_t &lst = it_found->second.edges;
03149 result = util::make_range(const_neighbor_iterator1(lst.begin()),
03150 const_neighbor_iterator1(lst.end()));
03151 return result;
03152 }
03153
03154 template <BIGRAPH_TEMPLATE>
03155 typename VVBiGraph<BIGRAPH_ARGS>::const_neighbor_iterator2_range
03156 VVBiGraph<BIGRAPH_ARGS>::neighbors(const vertex2_t& v) const
03157 {
03158 const_neighbor_iterator2_range result;
03159 if(v.isNull())
03160 return result;
03161 typename neighborhood2_t::const_iterator it_found = this->findVertex(v);
03162 if(it_found == neighborhood2.end())
03163 return result;
03164 const edge_list2_t &lst = it_found->second.edges;
03165 result = util::make_range(const_neighbor_iterator2(lst.begin()), const_neighbor_iterator2(lst.end()));
03166 return result;
03167 }
03168
03169 template <BIGRAPH_TEMPLATE>
03170 typename VVBiGraph<BIGRAPH_ARGS>::neighbor_iterator1_range
03171 VVBiGraph<BIGRAPH_ARGS>::neighbors(const vertex1_t& v)
03172 {
03173 neighbor_iterator1_range result;
03174 if(v.isNull())
03175 return result;
03176 typename neighborhood1_t::iterator it_found = this->findVertex(v);
03177 if(it_found == neighborhood1.end())
03178 return result;
03179 edge_list1_t &lst = it_found->second.edges;
03180 result = util::make_range(neighbor_iterator1(lst.begin()), neighbor_iterator1(lst.end()));
03181 return result;
03182 }
03183
03184 template <BIGRAPH_TEMPLATE>
03185 typename VVBiGraph<BIGRAPH_ARGS>::neighbor_iterator2_range
03186 VVBiGraph<BIGRAPH_ARGS>::neighbors(const vertex2_t& v)
03187 {
03188 neighbor_iterator2_range result;
03189 if(v.isNull())
03190 return result;
03191 typename neighborhood2_t::iterator it_found = this->findVertex(v);
03192 if(it_found == neighborhood2.end())
03193 return result;
03194 edge_list2_t &lst = it_found->second.edges;
03195 result = util::make_range(neighbor_iterator2(lst.begin()), neighbor_iterator2(lst.end()));
03196 return result;
03197 }
03198
03199 template <BIGRAPH_TEMPLATE>
03200 typename VVBiGraph<BIGRAPH_ARGS>::const_circ_neighbor_iterator1_range
03201 VVBiGraph<BIGRAPH_ARGS>::neighbors(const vertex1_t& v, const vertex2_t& n) const
03202 {
03203 const_circ_neighbor_iterator1_range result;
03204 if(v.isNull())
03205 return result;
03206 const_neighbor1_found_t found = findInVertex(v, n);
03207 if(!found)
03208 return result;
03209 const edge_list1_t &lst = found.neighborhood->edges;
03210 result = util::make_range(const_circ_neighbor_iterator1(lst.begin(), lst.end(), found.it),
03211 const_circ_neighbor_iterator1(lst.begin(), lst.end()));
03212 return result;
03213 }
03214
03215 template <BIGRAPH_TEMPLATE>
03216 typename VVBiGraph<BIGRAPH_ARGS>::const_circ_neighbor_iterator2_range
03217 VVBiGraph<BIGRAPH_ARGS>::neighbors(const vertex2_t& v, const vertex1_t& n) const
03218 {
03219 const_circ_neighbor_iterator2_range result;
03220 if(v.isNull())
03221 return result;
03222 const_neighbor2_found_t found = findInVertex(v, n);
03223 if(!found)
03224 return result;
03225 const edge_list2_t &lst = found.neighborhood->edges;
03226 result = util::make_range(const_circ_neighbor_iterator2(lst.begin(), lst.end(), found.it),
03227 const_circ_neighbor_iterator2(lst.begin(), lst.end()));
03228 return result;
03229 }
03230
03231 template <BIGRAPH_TEMPLATE>
03232 typename VVBiGraph<BIGRAPH_ARGS>::circ_neighbor_iterator1_range
03233 VVBiGraph<BIGRAPH_ARGS>::neighbors(const vertex1_t& v, const vertex2_t& n)
03234 {
03235 circ_neighbor_iterator1_range result;
03236 if(v.isNull())
03237 return result;
03238 neighbor1_found_t found = findInVertex(v, n);
03239 if(!found)
03240 return result;
03241 edge_list1_t &lst = found.neighborhood->edges;
03242 result = util::make_range(circ_neighbor_iterator1(lst.begin(), lst.end(), found.it),
03243 circ_neighbor_iterator1(lst.begin(), lst.end()));
03244 return result;
03245 }
03246
03247 template <BIGRAPH_TEMPLATE>
03248 typename VVBiGraph<BIGRAPH_ARGS>::circ_neighbor_iterator2_range
03249 VVBiGraph<BIGRAPH_ARGS>::neighbors(const vertex2_t& v, const vertex1_t& n)
03250 {
03251 circ_neighbor_iterator2_range result;
03252 if(v.isNull())
03253 return result;
03254 neighbor2_found_t found = findInVertex(v, n);
03255 if(!found)
03256 return result;
03257 edge_list2_t &lst = found.neighborhood->edges;
03258 result = util::make_range(circ_neighbor_iterator2(lst.begin(), lst.end(), found.it),
03259 circ_neighbor_iterator2(lst.begin(), lst.end()));
03260 return result;
03261 }
03262
03263 template <BIGRAPH_TEMPLATE>
03264 typename VVBiGraph<BIGRAPH_ARGS>::ineighbor_iterator1_range
03265 VVBiGraph<BIGRAPH_ARGS>::iNeighbors(const vertex1_t& v) const
03266 {
03267 ineighbor_iterator1_range result;
03268 if(v.isNull())
03269 return result;
03270 typename neighborhood1_t::const_iterator it_found = this->findVertex(v);
03271 if(it_found == neighborhood1.end())
03272 return result;
03273 const in_edges1_t &lst = it_found->second.in_edges;
03274 result = util::make_range(ineighbor_iterator1(lst.begin()),
03275 ineighbor_iterator1(lst.end()));
03276 return result;
03277 }
03278
03279 template <BIGRAPH_TEMPLATE>
03280 typename VVBiGraph<BIGRAPH_ARGS>::ineighbor_iterator2_range
03281 VVBiGraph<BIGRAPH_ARGS>::iNeighbors(const vertex2_t& v) const
03282 {
03283 ineighbor_iterator2_range result;
03284 if(v.isNull())
03285 return result;
03286 typename neighborhood2_t::const_iterator it_found = this->findVertex(v);
03287 if(it_found == neighborhood2.end())
03288 return result;
03289 const in_edges2_t &lst = it_found->second.in_edges;
03290 result = util::make_range(ineighbor_iterator2(lst.begin()), ineighbor_iterator2(lst.end()));
03291 return result;
03292 }
03293
03294 template <BIGRAPH_TEMPLATE>
03295 template <typename Vertex1Container, typename Vertex2Container>
03296 VVBiGraph<BIGRAPH_ARGS> VVBiGraph<BIGRAPH_ARGS>::subgraph( const Vertex1Container& verts1, const Vertex2Container& verts2 ) const
03297 {
03298 typename Vertex1Container::const_iterator it1;
03299 typename Vertex2Container::const_iterator it2;
03300 VVBiGraph result;
03301
03302 for(it1 = verts1.begin() ; it1 != verts1.end() ; ++it1)
03303 {
03304 result.insert(*it1);
03305 }
03306 for(it2 = verts2.begin() ; it2 != verts2.end() ; ++it2)
03307 {
03308 result.insert(*it2);
03309 }
03310
03311 for(typename neighborhood1_t::iterator it_n = result.neighborhood1.begin() ;
03312 it_n != result.neighborhood1.end() ; ++it_n)
03313 {
03314 const vertex1_t& v = it_n->first;
03315 result.updateVertexCache(v, it_n);
03316
03317 typename neighborhood1_t::const_iterator it_orign = this->findVertex(v);
03318 const edge_list1_t& orig_lst = it_orign->second.edges;
03319 edge_list1_t& lst = it_n->second.edges;
03320
03321 for(typename edge_list1_t::const_reverse_iterator it_sn = orig_lst.rbegin() ;
03322 it_sn != orig_lst.rend() ; ++it_sn)
03323 {
03324
03325
03326 if(result.contains(it_sn->target))
03327 {
03328
03329 ineighbor_iterator2 it_in = result.insertInEdge(v, it_sn->target).first;
03330
03331 lst.push_front(neighbor1_t(it_sn->target, *it_sn, it_n->second, result.graph_id));
03332
03333 result.updateEdgeCache(v, lst.begin(), *it_in);
03334 }
03335 }
03336
03337 if(it_orign->second.flagged and result.contains(*it_orign->second.flagged))
03338 {
03339 const_neighbor1_found_t found = this->findInVertex(v, *it_orign->second.flagged);
03340 it_n->second.flagged = &(found.it->target);
03341 }
03342 }
03343
03344 for(typename neighborhood2_t::iterator it_n = result.neighborhood2.begin() ;
03345 it_n != result.neighborhood2.end() ; ++it_n)
03346 {
03347 const vertex2_t& v = it_n->first;
03348 result.updateVertexCache(v, it_n);
03349
03350 typename neighborhood2_t::const_iterator it_orign = this->findVertex(v);
03351 const edge_list2_t& orig_lst = it_orign->second.edges;
03352 edge_list2_t& lst = it_n->second.edges;
03353
03354 for(typename edge_list2_t::const_reverse_iterator it_sn = orig_lst.rbegin() ;
03355 it_sn != orig_lst.rend() ; ++it_sn)
03356 {
03357
03358
03359 if(result.contains(it_sn->target))
03360 {
03361
03362 ineighbor_iterator1 it_in = result.insertInEdge(v, it_sn->target).first;
03363
03364 lst.push_front(neighbor2_t(it_sn->target, *it_sn, it_n->second, result.graph_id));
03365
03366 result.updateEdgeCache(v, lst.begin(), *it_in);
03367 }
03368 }
03369
03370 if(it_orign->second.flagged and result.contains(*it_orign->second.flagged))
03371 {
03372 const_neighbor2_found_t found = this->findInVertex(v, *it_orign->second.flagged);
03373 it_n->second.flagged = &(found.it->target);
03374 }
03375 }
03376 return result;
03377 }
03378
03379 template <BIGRAPH_TEMPLATE>
03380 VVBiGraph<BIGRAPH_ARGS>::VVBiGraph(const VVBiGraph& copy)
03381 : graph_id(graph::getNextGraphId())
03382 {
03383 *this = copy;
03384 }
03385
03386 #ifdef USE_CXX0X
03387
03388 template <BIGRAPH_TEMPLATE>
03389 VVBiGraph<BIGRAPH_ARGS>::VVBiGraph(VVBiGraph&& copy)
03390 : neighborhood1(std::move(copy.neighborhood1))
03391 , neighborhood2(std::move(copy.neighborhood2))
03392 , lookup1(std::move(copy.lookup1))
03393 , lookup2(std::move(copy.lookup2))
03394 , graph_id(copy.graph_id)
03395 {
03396 copy.graph_id = graph::getNextGraphId();
03397 copy.neighborhood1.clear();
03398 copy.neighborhood2.clear();
03399 copy.lookup1.clear();
03400 copy.lookup2.clear();
03401 }
03402 #endif
03403
03404 template <BIGRAPH_TEMPLATE>
03405 bool VVBiGraph<BIGRAPH_ARGS>::operator==(const VVBiGraph& other) const
03406 {
03407 if(neighborhood1.size() != other.neighborhood1.size() or
03408 neighborhood2.size() != other.neighborhood2.size())
03409 return false;
03410 for(typename neighborhood1_t::const_iterator it1 = neighborhood1.begin() ;
03411 it1 != neighborhood1.end() ; ++it1)
03412 {
03413 const vertex1_t& v1 = it1->first;
03414 typename lookup1_t::const_iterator it_found = other.lookup1.find(v1);
03415 if(it_found == other.lookup1.end())
03416 return false;
03417 if(it1->second.edges.empty())
03418 {
03419 if(!it_found->second->second.edges.empty())
03420 return false;
03421 }
03422 else
03423 {
03424 const edge_list1_t& lst = it1->second.edges;
03425 const edge_list1_t& olst = it_found->second->second.edges;
03426 if(lst.size() != olst.size()) return false;
03427 const vertex2_t& v2 = lst.begin()->target;
03428 bool found = false;
03429 for(typename edge_list1_t::const_iterator it_olst = olst.begin() ;
03430 it_olst != olst.end() ; ++it_olst)
03431 {
03432 if(it_olst->target == v2)
03433 {
03434 found = true;
03435 for(typename edge_list1_t::const_iterator it_lst = lst.begin() ;
03436 it_lst != lst.end() ; ++it_lst)
03437 {
03438 if(it_lst->target != it_olst->target) return false;
03439 ++it_olst;
03440 if(it_olst == olst.end()) it_olst = olst.begin();
03441 }
03442 break;
03443 }
03444 }
03445 if(!found) return false;
03446 }
03447 }
03448 for(typename neighborhood2_t::const_iterator it2 = neighborhood2.begin() ;
03449 it2 != neighborhood2.end() ; ++it2)
03450 {
03451 const vertex2_t& v2 = it2->first;
03452 typename lookup2_t::const_iterator it_found = other.lookup2.find(v2);
03453 if(it_found == other.lookup2.end())
03454 return false;
03455 if(it2->second.edges.empty())
03456 {
03457 if(!it_found->second->second.edges.empty())
03458 return false;
03459 }
03460 else
03461 {
03462 const edge_list2_t& lst = it2->second.edges;
03463 const edge_list2_t& olst = it_found->second->second.edges;
03464 if(lst.size() != olst.size()) return false;
03465 const vertex1_t& v1 = lst.begin()->target;
03466 bool found = false;
03467 for(typename edge_list2_t::const_iterator it_olst = olst.begin() ;
03468 it_olst != olst.end() ; ++it_olst)
03469 {
03470 if(it_olst->target == v1)
03471 {
03472 found = true;
03473 for(typename edge_list2_t::const_iterator it_lst = lst.begin() ;
03474 it_lst != lst.end() ; ++it_lst)
03475 {
03476 if(it_lst->target != it_olst->target) return false;
03477 ++it_olst;
03478 if(it_olst == olst.end()) it_olst = olst.begin();
03479 }
03480 break;
03481 }
03482 }
03483 if(!found) return false;
03484 }
03485 }
03486 return true;
03487 }
03488
03489 template <BIGRAPH_TEMPLATE>
03490 VVBiGraph<BIGRAPH_ARGS>&
03491 VVBiGraph<BIGRAPH_ARGS>::operator=( const VVBiGraph& other )
03492 {
03493
03494 neighborhood1 = other.neighborhood1;
03495 neighborhood2 = other.neighborhood2;
03496 lookup1.clear();
03497 lookup2.clear();
03498 for(typename neighborhood1_t::iterator it1 = neighborhood1.begin() ;
03499 it1 != neighborhood1.end() ; ++it1)
03500 lookup1[it1->first] = it1;
03501 for(typename neighborhood2_t::iterator it2 = neighborhood2.begin() ;
03502 it2 != neighborhood2.end() ; ++it2)
03503 lookup2[it2->first] = it2;
03504
03505 for(typename neighborhood1_t::iterator it1 = neighborhood1.begin() ;
03506 it1 != neighborhood1.end() ; ++it1)
03507 {
03508 const vertex1_t& src = it1->first;
03509 updateVertexCache(src, it1);
03510 #ifndef VVBIGRAPH_NO_EDGE_CACHE
03511 edge_list1_t& lst = it1->second.edges;
03512 for(typename edge_list1_t::iterator it1_e = lst.begin() ;
03513 it1_e != lst.end() ; ++it1_e)
03514 {
03515
03516 typename lookup2_t::iterator it_found = lookup2.find(it1_e->target);
03517 const vertex1_t& iv = *(it_found->second->second.in_edges.find(src));
03518 updateEdgeCache(src, it1_e, iv);
03519 it1_e->set(&it1->second, graph_id);
03520 }
03521 #endif
03522 }
03523
03524 for(typename neighborhood2_t::iterator it2 = neighborhood2.begin() ;
03525 it2 != neighborhood2.end() ; ++it2)
03526 {
03527 const vertex2_t& src = it2->first;
03528 updateVertexCache(src, it2);
03529 #ifndef VVBIGRAPH_NO_EDGE_CACHE
03530 edge_list2_t& lst = it2->second.edges;
03531 for(typename edge_list2_t::iterator it2_e = lst.begin() ;
03532 it2_e != lst.end() ; ++it2_e)
03533 {
03534
03535 typename lookup1_t::iterator it_found = lookup1.find(it2_e->target);
03536 const vertex2_t& iv = *(it_found->second->second.in_edges.find(src));
03537 updateEdgeCache(src, it2_e, iv);
03538 it2_e->set(&it2->second, graph_id);
03539 }
03540 #endif
03541 }
03542 return *this;
03543 }
03544
03545 template <BIGRAPH_TEMPLATE>
03546 void VVBiGraph<BIGRAPH_ARGS>::swap( VVBiGraph& other )
03547 {
03548 neighborhood1.swap(other.neighborhood1);
03549 neighborhood2.swap(other.neighborhood2);
03550 lookup1.swap(other.lookup1);
03551 lookup2.swap(other.lookup2);
03552 std::swap(graph_id, other.graph_id);
03553 }
03554
03555 template <typename BiGraph>
03556 void create_bigraph_methods(BiGraph& G)
03557 {
03558 if(G.size())
03559 {
03560 if(G.valence(G.any_vertex1()) > G.size())
03561 {
03562
03563 typename BiGraph::vertex1_t v1 = G.any_vertex1();
03564 typename BiGraph::vertex2_t v2 = G.any_vertex2();
03565 G.erase(v1);
03566 G.erase(v2);
03567 G.insert(v1);
03568 G.insert(v2);
03569 G.get_vertex1(10);
03570 G.get_vertex2(10);
03571 G.reference(v1);
03572 G.reference(v2);
03573 G.empty();
03574 G.no_vertex1();
03575 G.no_vertex2();
03576 G.anyIn(v1);
03577 G.anyIn(v2);
03578 G.valence(v1);
03579 G.valence(v2);
03580 G.empty(v1);
03581 G.empty(v2);
03582 G.iAnyIn(v1);
03583 G.iAnyIn(v2);
03584 G.iValence(v1);
03585 G.iValence(v2);
03586 G.iEmpty(v1);
03587 G.iEmpty(v2);
03588 G.nextTo(v1, v2);
03589 G.nextTo(v2, v1);
03590 G.prevTo(v1, v2);
03591 G.prevTo(v2, v1);
03592 G.edge(v1, v2);
03593 G.edge(v2, v1);
03594 G.flag(v1,v2);
03595 G.flag(v2,v1);
03596 G.flagged(v1);
03597 G.flagged(v2);
03598 G.neighbors(v1);
03599 G.neighbors(v2);
03600 G.iNeighbors(v1);
03601 G.iNeighbors(v2);
03602 G.source(typename BiGraph::edge1_t());
03603 G.source(typename BiGraph::edge2_t());
03604 G.target(typename BiGraph::edge1_t());
03605 G.target(typename BiGraph::edge2_t());
03606 G.eraseEdge(v1, v2);
03607 G.eraseEdge(v2, v1);
03608 G.replace(v1, v2, v2);
03609 G.replace(v2, v1, v1);
03610 G.spliceAfter(v1, v2, v2);
03611 G.spliceAfter(v2, v1, v1);
03612 G.spliceBefore(v1, v2, v2);
03613 G.spliceBefore(v2, v1, v1);
03614 G.insertEdge(v1,v2);
03615 G.insertEdge(v2,v1);
03616 G.eraseAllEdges(v1);
03617 G.eraseAllEdges(v2);
03618 G.begin_vertex1();
03619 G.begin_vertex2();
03620 G.end_vertex1();
03621 G.end_vertex1();
03622 G.find(v1);
03623 G.find(v2);
03624 G.count(v1);
03625 G.count(v2);
03626 G.findIn(v1, v2);
03627 G.findIn(v2, v1);
03628 }
03629 }
03630 }
03631
03632 }
03633
03634 namespace std
03635 {
03636 template <BIGRAPH_TEMPLATE>
03637 void swap(graph::VVBiGraph<BIGRAPH_ARGS>& g1, graph::VVBiGraph<BIGRAPH_ARGS>& g2)
03638 {
03639 g1.swap(g2);
03640 }
03641 }
03642
03643 #endif // GRAPH_VVBIGRAPH_H
03644