00001 #ifndef GRAPH_VVGRAPH_H
00002 #define GRAPH_VVGRAPH_H
00003
00010 #include <config.h>
00011 #include <graph/vertex.h>
00012 #include <graph/edge.h>
00013
00014 #include <util/tie.h>
00015 #include <util/member_iterator.h>
00016 #include <util/circ_iterator.h>
00017 #include <util/set_vector.h>
00018 #include <util/range.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 <vector>
00029 #include <set>
00030 #include <map>
00031
00032 #ifdef USE_ALLOCATOR
00033 # include <memory>
00034 #endif // defined USE_ALLOCATOR
00035
00036 #include <iostream>
00037
00038 #ifdef USE_CXX0X
00039 # include <initializer_list>
00040 #endif
00041
00042 #ifdef VVGRAPH_NO_CACHE
00043 # define VVGRAPH_NO_EDGE_CACHE
00044 # define VVGRAPH_NO_VERTEX_CACHE
00045 #endif
00046
00047 #ifdef VVGRAPH_NO_VERTEX_CACHE
00048 # define VVGRAPH_COMPACT_VERTEX true
00049 #else
00050 # define VVGRAPH_COMPACT_VERTEX compact
00051 #endif
00052
00053 #ifdef VVGRAPH_NO_EDGE_CACHE
00054 # define VVGRAPH_COMPACT_EDGE true
00055 #else
00056 # define VVGRAPH_COMPACT_EDGE compact
00057 #endif
00058
00059 #ifdef USE_ALLOCATOR
00060 # define GRAPH_TEMPLATE typename VertexContent, typename EdgeContent, bool compact, typename Alloc
00061 # define GRAPH_ARGS VertexContent,EdgeContent,compact,Alloc
00062 #else // USE_ALLOCATOR
00063 # define GRAPH_TEMPLATE typename VertexContent, typename EdgeContent, bool compact
00064 # define GRAPH_ARGS VertexContent,EdgeContent,compact
00065 #endif // USE_ALLOCATOR
00066
00072 namespace graph
00073 {
00074
00075 template <bool compact, typename T>
00076 struct __vvgraph_set
00077 { };
00078
00079 template <typename T>
00080 struct __vvgraph_set<true,T>
00081 {
00082 typedef util::set_vector<T> type;
00083 };
00084
00085 template <typename T>
00086 struct __vvgraph_set<false,T>
00087 {
00088 typedef std::set<T> type;
00089 };
00090
00091 template <bool compact, typename EdgeContent, typename VVGraph, typename single_neighborhood_t, typename edge_list_t>
00092 struct __vvgraph_EdgeCache
00093 {
00094 };
00095
00096 template <typename VVGraph, typename EdgeContent, typename single_neighborhood_t, typename edge_list_t>
00097 struct __vvgraph_EdgeCache<false, EdgeContent, VVGraph, single_neighborhood_t, edge_list_t>
00098 : public EdgeContent
00099 {
00100 typedef typename VVGraph::vertex_t vertex_t;
00101
00105 __vvgraph_EdgeCache(const EdgeContent& copy,
00106 single_neighborhood_t *n,
00107 intptr_t id)
00108 : EdgeContent(copy)
00109 , _neighborhood(n)
00110 , gid(id)
00111 { }
00112
00116 __vvgraph_EdgeCache(const __vvgraph_EdgeCache& copy)
00117 : EdgeContent(copy)
00118 , _neighborhood(copy._neighborhood)
00119 , gid(copy.gid)
00120 { }
00121
00122 #ifdef USE_CXX0X
00123 __vvgraph_EdgeCache(__vvgraph_EdgeCache&& copy)
00124 : EdgeContent(std::move(copy))
00125 , _neighborhood(std::move(copy._neighborhood))
00126 , gid(std::move(copy.gid))
00127 {
00128 copy.gid = 0;
00129 }
00130 #endif
00131
00132 __vvgraph_EdgeCache& operator=(const __vvgraph_EdgeCache& copy)
00133 {
00134 _neighborhood = copy._neighborhood;
00135 gid = copy.gid;
00136 static_cast<EdgeContent&>(*this) = static_cast<const EdgeContent&>(copy);
00137 return *this;
00138 }
00139
00140 void setIt(const typename edge_list_t::iterator& i)
00141 {
00142 _it = i;
00143 }
00144
00145 bool eraseEdge()
00146 {
00147 if(_neighborhood->flagged && *_neighborhood->flagged == _it->target) _neighborhood->flagged = 0;
00148 _neighborhood->edges.erase(_it);
00149 return true;
00150 }
00151
00152 void set(single_neighborhood_t* n, intptr_t id)
00153 {
00154 _neighborhood = n;
00155 gid = id;
00156 }
00157
00158 single_neighborhood_t* neighborhood() { return _neighborhood; }
00159
00160 typename edge_list_t::iterator it() { return _it; }
00161
00165 single_neighborhood_t* _neighborhood;
00169 typename edge_list_t::iterator _it;
00170
00174 intptr_t gid;
00175
00176 intptr_t graph_id() { return gid; }
00177 };
00178
00179 template <typename EdgeContent, typename VVGraph, typename single_neighborhood_t, typename edge_list_t>
00180 struct __vvgraph_EdgeCache<true, EdgeContent, VVGraph, single_neighborhood_t, edge_list_t>
00181 : public EdgeContent
00182 {
00183 typedef typename VVGraph::vertex_t vertex_t;
00184
00188 __vvgraph_EdgeCache(const EdgeContent& copy,
00189 single_neighborhood_t *,
00190 intptr_t)
00191 : EdgeContent(copy)
00192 { }
00193
00197 __vvgraph_EdgeCache(const __vvgraph_EdgeCache& copy)
00198 : EdgeContent(copy)
00199 { }
00200
00201 #ifdef USE_CXX0X
00202 __vvgraph_EdgeCache(__vvgraph_EdgeCache&& ) = default;
00203 #endif
00204
00205 __vvgraph_EdgeCache& operator=(const __vvgraph_EdgeCache& copy)
00206 {
00207 static_cast<EdgeContent&>(*this) = static_cast<const EdgeContent&>(copy);
00208 return *this;
00209 }
00210
00211 void setIt(const typename edge_list_t::iterator&)
00212 {
00213 }
00214
00215 bool eraseEdge()
00216 {
00217 return false;
00218 }
00219
00220 intptr_t graph_id() { return 0; }
00221
00222 single_neighborhood_t* neighborhood() { return 0; }
00223
00224 typename edge_list_t::iterator it() { return typename edge_list_t::iterator(); }
00225
00226 void set(single_neighborhood_t*, intptr_t ) {}
00227 };
00228
00229 template <bool compact, typename VVGraph, typename single_neighborhood_t>
00230 struct __vvgraph_VertexCache
00231 {
00232 __vvgraph_VertexCache() {}
00233 __vvgraph_VertexCache(const __vvgraph_VertexCache& ) {}
00234
00235 #ifdef USE_CXX0X
00236 __vvgraph_VertexCache(__vvgraph_VertexCache&& ) = default;
00237 #endif
00238
00239 typedef typename VVGraph::vertex_t vertex_t;
00240 typedef typename std::list<std::pair<vertex_t,single_neighborhood_t> >::iterator iterator;
00241 intptr_t graph_id() { return 0; }
00242 void update(intptr_t, const vertex_t& , iterator ) {}
00243 iterator neighborhood() { return iterator(); }
00244 };
00245
00246 template <typename VVGraph, typename single_neighborhood_t>
00247 struct __vvgraph_VertexCache<false,VVGraph,single_neighborhood_t>
00248 {
00249 typedef typename VVGraph::vertex_t vertex_t;
00250 typedef typename std::list<std::pair<vertex_t,single_neighborhood_t> >::iterator iterator;
00251
00252 __vvgraph_VertexCache() : gid(0) {}
00253 __vvgraph_VertexCache(const __vvgraph_VertexCache& copy ) : gid(copy.gid), _neighborhood(copy._neighborhood) {}
00254
00255 #ifdef USE_CXX0X
00256 __vvgraph_VertexCache(__vvgraph_VertexCache&& copy)
00257 : gid(std::move(copy.gid))
00258 , _neighborhood(std::move(copy._neighborhood))
00259 {
00260 copy.gid = 0;
00261 }
00262 #endif
00263
00264 intptr_t graph_id() { return gid; }
00265 iterator neighborhood() { return _neighborhood; }
00266
00267 void update(intptr_t graph_id, const vertex_t& v, iterator it)
00268 {
00269 gid = graph_id;
00270 _neighborhood = it;
00271 v.cache = reinterpret_cast<void*>(this);
00272 v.cache_source = 0;
00273 }
00274
00281 intptr_t gid;
00282
00288 iterator _neighborhood;
00289 };
00290
00296 struct _EmptyEdgeContent
00297 {
00298 _EmptyEdgeContent& operator=(const _EmptyEdgeContent& ) { return *this; }
00299 bool serialize(storage::VVEStorage&) { return true; }
00300 };
00301
00302 intptr_t getNextGraphId();
00303
00357 template <typename VertexContent, typename EdgeContent = _EmptyEdgeContent, bool compact = false
00358 #ifdef USE_ALLOCATOR
00359 , typename Alloc = DEFAULT_ALLOC(VertexContent)
00360 #endif // USE_ALLOCATOR
00361 >
00362 class VVGraph
00363 {
00364 public:
00365 #ifdef USE_ALLOCATOR
00366 typedef typename Alloc::template rebind<EdgeContent>::other EdgeAlloc;
00367 static EdgeAlloc edge_alloc;
00368 #endif
00369
00371
00372
00375 #ifdef USE_ALLOCATOR
00376 typedef Vertex<VertexContent, Alloc> vertex_t;
00377 #else // USE_ALLOCATOR
00378 typedef Vertex<VertexContent> vertex_t;
00379 #endif // USE_ALLOCATOR
00380
00383 typedef Edge<EdgeContent> edge_t;
00387 typedef Edge<const EdgeContent> const_edge_t;
00394 typedef Arc<EdgeContent> arc_t;
00396
00400 typedef vertex_t value_type;
00401
00407 VVGraph()
00408 : graph_id(graph::getNextGraphId())
00409 {}
00410
00416 VVGraph(const VVGraph& copy);
00417
00418 #ifdef USE_CXX0X
00419
00422 VVGraph(VVGraph&& copy);
00423 #endif
00424
00425 protected:
00426 class single_neighborhood_t;
00427
00431 struct neighbor_t : public __vvgraph_EdgeCache<VVGRAPH_COMPACT_EDGE,EdgeContent,VVGraph,single_neighborhood_t,std::list<neighbor_t> >
00432 {
00433 typedef __vvgraph_EdgeCache<VVGRAPH_COMPACT_EDGE,EdgeContent,VVGraph,single_neighborhood_t,std::list<neighbor_t> > base;
00437 typedef std::list<neighbor_t> edge_list_t;
00438
00442 neighbor_t(const vertex_t& tgt, const EdgeContent& 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 void clear_edge()
00457 {
00458 static_cast<EdgeContent&>(*this) = EdgeContent();
00459 }
00460
00461 ~neighbor_t()
00462 {
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_t target;
00478
00485 bool operator==(const neighbor_t& other) const
00486 {
00487 return (target == other.target) &&
00488 (static_cast<const EdgeContent&>(*this) == static_cast<const EdgeContent&>(other));
00489 }
00490
00491 };
00492
00493 typedef typename neighbor_t::base EdgeCache;
00494
00498 typedef typename neighbor_t::edge_list_t edge_list_t;
00499
00503 typedef typename __vvgraph_set<compact,vertex_t>::type in_edges_t;
00504
00508 struct single_neighborhood_t : public __vvgraph_VertexCache<VVGRAPH_COMPACT_VERTEX,VVGraph,single_neighborhood_t>
00509 {
00510 typedef __vvgraph_VertexCache<VVGRAPH_COMPACT_VERTEX,VVGraph,single_neighborhood_t> base;
00511
00512 single_neighborhood_t()
00513 : base()
00514 , flagged(0)
00515 {}
00516
00517 single_neighborhood_t(const single_neighborhood_t& copy)
00518 : base(copy)
00519 , edges(copy.edges)
00520 , in_edges(copy.in_edges)
00521 , flagged(copy.flagged)
00522 {
00523 if(flagged)
00524 {
00525 for(typename edge_list_t::iterator it = edges.begin() ; it != edges.end() ; ++it)
00526 {
00527 if(it->target == *flagged)
00528 {
00529 flagged = &it->target;
00530 return;
00531 }
00532 }
00533 }
00534 }
00535
00539 edge_list_t edges;
00540
00544 in_edges_t in_edges;
00545
00549 const vertex_t* flagged;
00550
00556 bool operator==(const single_neighborhood_t& other) const
00557 {
00558 return edges == other.edges;
00559 }
00560 };
00561
00562 typedef typename single_neighborhood_t::base VertexCache;
00563
00564 public:
00565
00566
00570 typedef std::list<std::pair<vertex_t, single_neighborhood_t> > neighborhood_t;
00571
00575 typedef std::unordered_map<vertex_t, typename neighborhood_t::iterator> lookup_t;
00576
00577
00581 typedef typename neighborhood_t::value_type neighborhood_value_type;
00582
00586 typedef typename neighborhood_t::size_type size_type;
00587
00589
00590
00593 typedef util::SelectMemberIterator<typename neighborhood_t::iterator, const vertex_t,
00594 &neighborhood_value_type::first> iterator;
00598 typedef util::SelectMemberIterator<typename neighborhood_t::const_iterator, const vertex_t,
00599 &neighborhood_value_type::first> const_iterator;
00600
00604 typedef util::SelectMemberIterator<typename edge_list_t::iterator, vertex_t,
00605 &neighbor_t::target> neighbor_iterator;
00609 typedef util::range<neighbor_iterator> neighbor_iterator_range;
00610
00615 typedef util::CircIterator<neighbor_iterator> circ_neighbor_iterator;
00616
00620 typedef util::range<circ_neighbor_iterator> circ_neighbor_iterator_range;
00621
00628 typedef typename in_edges_t::const_iterator ineighbor_iterator;
00629
00635 typedef util::range<ineighbor_iterator> ineighbor_iterator_range;
00636
00640 typedef util::SelectMemberIterator<typename edge_list_t::const_iterator,
00641 const vertex_t, &neighbor_t::target> const_neighbor_iterator;
00647 typedef util::range<const_neighbor_iterator> const_neighbor_iterator_range;
00648
00653 typedef util::CircIterator<const_neighbor_iterator> const_circ_neighbor_iterator;
00654
00658 typedef util::range<const_circ_neighbor_iterator> const_circ_neighbor_iterator_range;
00659
00661
00663
00664
00680 size_type erase( const vertex_t& v );
00681
00694 iterator insert( const vertex_t& v );
00696
00698
00699
00712 const vertex_t& any() const;
00713
00743 const vertex_t& operator[](size_type idx) const;
00744
00758 bool contains( const vertex_t& v ) const;
00759
00780 const vertex_t& reference( vertex_t v ) const
00781 {
00782 typename neighborhood_t::const_iterator found = this->findVertex(v);
00783 if(found != neighborhood.end())
00784 return found->first;
00785 return vertex_t::null;
00786 }
00787
00791 size_type size() const { return neighborhood.size(); }
00792
00796 bool empty() const { return neighborhood.empty(); }
00797
00799
00801
00802
00822 const vertex_t& anyIn( const vertex_t& v ) const;
00823
00840 size_type valence( const vertex_t& v ) const;
00841
00863 bool empty( const vertex_t& v ) const;
00864
00886 const vertex_t& iAnyIn(const vertex_t& v) const;
00887
00905 size_type iValence( const vertex_t& v ) const;
00906
00928 bool iEmpty( const vertex_t& v ) const;
00929
00949 const vertex_t& nextTo( const vertex_t& v, const vertex_t& neighbor, unsigned int n = 1 ) const;
00950
00970 const vertex_t& prevTo( const vertex_t& v, const vertex_t& ref, unsigned int n = 1 ) const;
00971
00998 edge_t edge( const vertex_t& src, const vertex_t& tgt );
00999
01028 arc_t arc(const vertex_t& src, const vertex_t& tgt);
01029
01058 const_edge_t edge( const vertex_t& src, const vertex_t& tgt ) const;
01059
01091 bool flag(const vertex_t& src, const vertex_t& neighbor);
01092
01098 const vertex_t& flagged(const vertex_t& src) const;
01099
01116 const_neighbor_iterator_range neighbors(const vertex_t& v) const;
01133 neighbor_iterator_range neighbors(const vertex_t& v);
01134
01149 circ_neighbor_iterator_range neighbors(const vertex_t& v, const vertex_t& n);
01150
01165 const_circ_neighbor_iterator_range neighbors(const vertex_t& v, const vertex_t& n) const;
01166
01186 ineighbor_iterator_range iNeighbors(const vertex_t& v) const;
01187
01201 const vertex_t& source( const edge_t& edge ) const
01202 {
01203 typename neighborhood_t::const_iterator found = this->findVertex(vertex_t(edge.source()));
01204 if(found != neighborhood.end())
01205 return found->first;
01206 return vertex_t::null;
01207 }
01208
01209 const vertex_t& source( const arc_t& arc) const
01210 {
01211 typename neighborhood_t::const_iterator found = this->findVertex(vertex_t(arc.source()));
01212 if(found != neighborhood.end())
01213 return found->first;
01214 return vertex_t::null;
01215 }
01216
01230 const vertex_t& target( const edge_t& edge ) const
01231 {
01232 typename neighborhood_t::const_iterator found = this->findVertex(vertex_t(edge.target()));
01233 if(found != neighborhood.end())
01234 return found->first;
01235 return vertex_t::null;
01236 }
01237
01238 const vertex_t& target( const arc_t& arc) const
01239 {
01240 typename neighborhood_t::const_iterator found = this->findVertex(vertex_t(arc.target()));
01241 if(found != neighborhood.end())
01242 return found->first;
01243 return vertex_t::null;
01244 }
01245
01247
01249
01250
01272 size_type eraseEdge( const vertex_t& src, const vertex_t& tgt);
01273
01305 edge_t replace( const vertex_t& v, const vertex_t& neighbor, const vertex_t& new_neighbor );
01306
01333 edge_t spliceAfter( const vertex_t& v, const vertex_t& neighbor, const vertex_t& new_neighbor );
01334
01340 template <typename VertexContainer>
01341 std::vector<edge_t> spliceAfter( const vertex_t& v, const vertex_t& neighbor, const VertexContainer& new_neighbor );
01342
01369 edge_t spliceBefore( const vertex_t& v, const vertex_t& neighbor, const vertex_t& new_neighbor );
01370
01376 template <typename VertexContainer>
01377 std::vector<edge_t> spliceBefore( const vertex_t& v, const vertex_t& neighbor, const VertexContainer& new_neighbor );
01378
01397 edge_t insertEdge( const vertex_t& src, const vertex_t& tgt );
01398
01402 template <typename VertexContainer>
01403 std::vector<edge_t> insertEdges(const vertex_t& src, const VertexContainer& targets);
01404
01425 bool eraseAllEdges( const vertex_t& v );
01426
01444 bool clear( const vertex_t& v );
01445
01447
01449
01450
01453 VVGraph& operator=( const VVGraph& other );
01454
01458 void swap(VVGraph& other);
01459
01469 bool operator==(const VVGraph& other) const;
01470
01474 void clear() { neighborhood.clear(); lookup.clear(); }
01475
01492 void eraseAllEdges();
01493
01509 template <typename VertexContainer>
01510 VVGraph subgraph( const VertexContainer& vertexes ) const;
01512
01514
01515
01522 iterator erase(iterator pos);
01523
01527 neighbor_iterator eraseEdge(const vertex_t& v, neighbor_iterator pos);
01528
01532 circ_neighbor_iterator eraseEdge(const vertex_t& v, circ_neighbor_iterator pos);
01533
01539 iterator insert( iterator pos, const vertex_t& v );
01543 template <typename Iterator>
01544 void insert( Iterator first, Iterator last );
01545
01549 iterator begin() { return neighborhood.begin(); }
01553 iterator end() { return neighborhood.end(); }
01554
01558 const_iterator begin() const { return neighborhood.begin(); }
01562 const_iterator end() const { return neighborhood.end(); }
01563
01584 void store_vertices(std::vector<vertex_t>& vertices, bool cached = true) const
01585 {
01586 vertices.resize(this->size(), vertex_t::null);
01587 size_t k = 0;
01588 for(typename neighborhood_t::const_iterator it = neighborhood.begin() ;
01589 it != neighborhood.end() ; ++it)
01590 {
01591 const vertex_t& v = it->first;
01592 vertices[k] = v;
01593 #ifndef VVGRAPH_NO_CACHE
01594 if(cached)
01595 {
01596 vertices[k].cache = v.cache;
01597 vertices[k].cache_source = v.cache_source;
01598 }
01599 #endif
01600 ++k;
01601 }
01602 }
01603
01609 iterator find(const vertex_t& v) { return this->findVertex(v); }
01615 const_iterator find(const vertex_t& v) const { return this->findVertex(v); }
01616
01620 size_type count( const vertex_t& v ) const;
01621
01631 neighbor_iterator findIn(const vertex_t& v, const vertex_t& n);
01641 const_neighbor_iterator findIn(const vertex_t& v, const vertex_t& n) const;
01642
01648 void eraseAllEdges( iterator it );
01649
01653 void clear( iterator it );
01654
01656
01657 protected:
01664 template <class Neighborhood, class Iterator>
01665 struct search_result_t
01666 {
01672 search_result_t()
01673 : found(false)
01674 , neighborhood(0) {}
01675
01679 search_result_t( Iterator i,
01680 Neighborhood* n,
01681 bool ok = true)
01682 : found(ok)
01683 , it(i)
01684 , neighborhood(n)
01685 {}
01686
01690 search_result_t(const search_result_t& copy)
01691 : found(copy.found)
01692 , it(copy.it)
01693 , neighborhood(copy.neighborhood)
01694 {}
01695
01699 operator bool() { return found; }
01700
01704 bool found;
01708 Iterator it;
01712 Neighborhood* neighborhood;
01713 };
01714
01718 typedef typename edge_list_t::iterator int_neighbor_iterator;
01722 typedef typename edge_list_t::const_iterator int_const_neighbor_iterator;
01723
01727 typedef search_result_t<single_neighborhood_t, int_neighbor_iterator> neighbor_found_t;
01731 typedef search_result_t<const single_neighborhood_t, int_const_neighbor_iterator> const_neighbor_found_t;
01732
01740 typename neighborhood_t::iterator findVertex(const vertex_t& v);
01741
01745 typename neighborhood_t::const_iterator findVertex(const vertex_t& v) const;
01746
01761 neighbor_found_t findInVertex( const vertex_t& v, const vertex_t& neighbor);
01762
01766 const_neighbor_found_t findInVertex( const vertex_t& v, const vertex_t& neighbor) const;
01767
01772 std::pair<ineighbor_iterator,bool> insertInEdge(const vertex_t& v, const vertex_t& new_neighbor);
01773
01778 void undoInEdge(const vertex_t& new_neighbor, ineighbor_iterator& it);
01779
01784 void updateEdgeCache(const vertex_t& v,
01785 typename edge_list_t::iterator new_edge_it,
01786 const vertex_t& in_edge);
01787
01791 void updateVertexCache(const vertex_t& v,
01792 typename neighborhood_t::iterator it);
01793
01797 neighborhood_t neighborhood;
01798
01802 lookup_t lookup;
01803
01807 intptr_t graph_id;
01808 };
01809
01810 #ifdef USE_ALLOCATOR
01811 template <GRAPH_TEMPLATE>
01812 typename VVGraph<GRAPH_ARGS>::EdgeAlloc VVGraph<GRAPH_ARGS>::edge_alloc;
01813 #endif
01814
01815 template <GRAPH_TEMPLATE>
01816 typename VVGraph<GRAPH_ARGS>::iterator
01817 VVGraph<GRAPH_ARGS>::erase( iterator it )
01818 {
01819 eraseAllEdges(it);
01820 lookup.erase(*it);
01821 return neighborhood.erase(it.base());
01822 }
01823
01824 template <GRAPH_TEMPLATE>
01825 typename VVGraph<GRAPH_ARGS>::size_type
01826 VVGraph<GRAPH_ARGS>::erase( const vertex_t& v )
01827 {
01828 if(eraseAllEdges(v))
01829 {
01830 typename lookup_t::iterator it_found = lookup.find(v);
01831 if(it_found == lookup.end()) return 0;
01832 typename neighborhood_t::iterator it = it_found->second;
01833 neighborhood.erase(it);
01834 lookup.erase(v);
01835 return 1;
01836 }
01837 return 0;
01838 }
01839 template <GRAPH_TEMPLATE>
01840 void VVGraph<GRAPH_ARGS>::eraseAllEdges()
01841 {
01842 for(typename neighborhood_t::iterator it = neighborhood.begin();
01843 it != neighborhood.end() ; ++it)
01844 {
01845 it->second.edges.clear();
01846 it->second.in_edges.clear();
01847 it->second.flagged = 0;
01848 }
01849 }
01850
01851 template <GRAPH_TEMPLATE>
01852 bool VVGraph<GRAPH_ARGS>::eraseAllEdges( const vertex_t& v )
01853 {
01854 typename neighborhood_t::iterator it_found = this->findVertex(v);
01855 if(it_found != neighborhood.end() )
01856 {
01857 eraseAllEdges(it_found);
01858 return true;
01859 }
01860 return false;
01861 }
01862
01863 template <GRAPH_TEMPLATE>
01864 void VVGraph<GRAPH_ARGS>::eraseAllEdges( iterator it_found )
01865 {
01866 const vertex_t& v = *it_found;
01867 for(typename edge_list_t::iterator it_el = it_found.base()->second.edges.begin() ;
01868 it_el != it_found.base()->second.edges.end() ; ++it_el)
01869 {
01870 typename lookup_t::iterator it_found = lookup.find(it_el->target);
01871 if(it_found != lookup.end())
01872 it_found->second->second.in_edges.erase(v);
01873 }
01874 it_found.base()->second.edges.clear();
01875 it_found.base()->second.flagged = 0;
01876
01877 in_edges_t &in_edges = it_found.base()->second.in_edges;
01878 for( typename in_edges_t::iterator it = in_edges.begin() ;
01879 it != in_edges.end() ; ++it )
01880 {
01881 #ifndef VVGRAPH_NO_EDGE_CACHE
01882 EdgeCache *cache = reinterpret_cast<EdgeCache*>(it->cache);
01883 if(!cache or !cache->eraseEdge())
01884 {
01885 #endif
01886 neighbor_found_t found = findInVertex(*it, v);
01887 found.neighborhood->edges.erase(found.it);
01888 if(found.neighborhood->flagged && *found.neighborhood->flagged == v) found.neighborhood->flagged = 0;
01889 #ifndef VVGRAPH_NO_EDGE_CACHE
01890 }
01891 #endif
01892 }
01893 in_edges.clear();
01894 }
01895
01896
01897 template <GRAPH_TEMPLATE>
01898 bool VVGraph<GRAPH_ARGS>::clear( const vertex_t& v )
01899 {
01900 typename neighborhood_t::iterator it_found = this->findVertex(v);
01901 if(it_found != neighborhood.end() )
01902 {
01903 clear(it_found);
01904 return true;
01905 }
01906 return false;
01907 }
01908
01909 template <GRAPH_TEMPLATE>
01910 void VVGraph<GRAPH_ARGS>::clear( iterator it )
01911 {
01912 const vertex_t& v = *it;
01913 for(typename edge_list_t::iterator it_el = it.base()->second.edges.begin() ;
01914 it_el != it.base()->second.edges.end() ; ++it_el)
01915 {
01916 typename neighborhood_t::iterator it_found = this->findVertex(it_el->target);
01917 it_found->second.in_edges.erase(v);
01918 }
01919 it.base()->second.edges.clear();
01920 }
01921
01922 template <GRAPH_TEMPLATE>
01923 typename VVGraph<GRAPH_ARGS>::size_type
01924 VVGraph<GRAPH_ARGS>::count( const vertex_t& v ) const
01925 {
01926 return lookup.count(v);
01927 }
01928
01929 template <GRAPH_TEMPLATE>
01930 typename VVGraph<GRAPH_ARGS>::iterator
01931 VVGraph<GRAPH_ARGS>::insert( const vertex_t& v )
01932 {
01933 typename lookup_t::iterator it_found;
01934 bool inserted;
01935 util::tie(it_found, inserted) = lookup.insert(std::make_pair(v, typename neighborhood_t::iterator()));
01936 if(inserted)
01937 {
01938 neighborhood.push_front(std::make_pair(v,single_neighborhood_t()));
01939 typename neighborhood_t::iterator it = neighborhood.begin();
01940 it_found->second = it;
01941 updateVertexCache(it->first, it);
01942 return it;
01943 }
01944 return it_found->second;
01945 }
01946
01947 template <GRAPH_TEMPLATE>
01948 void VVGraph<GRAPH_ARGS>::updateVertexCache(const vertex_t& v,
01949 typename neighborhood_t::iterator it)
01950 {
01951 #ifndef VVGRAPH_NO_VERTEX_CACHE
01952 it->second.update(graph_id, v, it);
01953 #endif
01954 }
01955
01956 template <GRAPH_TEMPLATE>
01957 typename VVGraph<GRAPH_ARGS>::iterator
01958 VVGraph<GRAPH_ARGS>::insert( iterator , const vertex_t& v )
01959 {
01960 return this->insert(v);
01961 }
01962
01963 template <GRAPH_TEMPLATE>
01964 template <typename Iterator>
01965 void VVGraph<GRAPH_ARGS>::insert( Iterator first, Iterator last )
01966 {
01967 for(Iterator it = first ; it != last ; ++it)
01968 {
01969 insert(*it);
01970 }
01971 }
01972
01973 template <GRAPH_TEMPLATE>
01974 const typename VVGraph<GRAPH_ARGS>::vertex_t&
01975 VVGraph<GRAPH_ARGS>::any() const
01976 {
01977 if(neighborhood.empty())
01978 return vertex_t::null;
01979 return *begin();
01980 }
01981
01982 template <GRAPH_TEMPLATE>
01983 const typename VVGraph<GRAPH_ARGS>::vertex_t&
01984 VVGraph<GRAPH_ARGS>::operator[](size_type idx) const
01985 {
01986 typename neighborhood_t::const_iterator it = neighborhood.begin();
01987 std::advance(it, idx);
01988 return it->first;
01989 }
01990
01991 template <GRAPH_TEMPLATE>
01992 const typename VVGraph<GRAPH_ARGS>::vertex_t&
01993 VVGraph<GRAPH_ARGS>::anyIn( const vertex_t& v ) const
01994 {
01995 if(v.isNull())
01996 return vertex_t::null;
01997 typename neighborhood_t::const_iterator it_found = this->findVertex(v);
01998 if(it_found == neighborhood.end() || it_found->second.edges.empty())
01999 return vertex_t::null;
02000 const edge_list_t& lst = it_found->second.edges;
02001 return lst.front().target;
02002 }
02003
02004 template <GRAPH_TEMPLATE>
02005 typename VVGraph<GRAPH_ARGS>::size_type
02006 VVGraph<GRAPH_ARGS>::valence( const vertex_t& v ) const
02007 {
02008 if(v.isNull())
02009 return 0;
02010 typename neighborhood_t::const_iterator it_found = this->findVertex(v);
02011 if(it_found == neighborhood.end())
02012 return 0;
02013 return it_found->second.edges.size();
02014 }
02015
02016 template <GRAPH_TEMPLATE>
02017 bool VVGraph<GRAPH_ARGS>::empty( const vertex_t& v ) const
02018 {
02019 if(v.isNull())
02020 return true;
02021 typename neighborhood_t::const_iterator it_found = this->findVertex(v);
02022 if(it_found == neighborhood.end())
02023 return true;
02024 return it_found->second.edges.empty();
02025 }
02026
02027 template <GRAPH_TEMPLATE>
02028 const typename VVGraph<GRAPH_ARGS>::vertex_t&
02029 VVGraph<GRAPH_ARGS>::iAnyIn( const vertex_t& v ) const
02030 {
02031 if(v.isNull())
02032 return vertex_t::null;
02033 typename neighborhood_t::const_iterator it_found = this->findVertex(v);
02034 if(it_found == neighborhood.end() || it_found->second.in_edges.empty())
02035 return vertex_t::null;
02036 const in_edges_t& lst = it_found->second.in_edges;
02037 return *lst.begin();
02038 }
02039
02040 template <GRAPH_TEMPLATE>
02041 typename VVGraph<GRAPH_ARGS>::size_type
02042 VVGraph<GRAPH_ARGS>::iValence( const vertex_t& v ) const
02043 {
02044 if(v.isNull())
02045 return 0;
02046 typename neighborhood_t::const_iterator it_found = this->findVertex(v);
02047 if(it_found == neighborhood.end())
02048 return 0;
02049 return it_found->second.in_edges.size();
02050 }
02051
02052 template <GRAPH_TEMPLATE>
02053 bool VVGraph<GRAPH_ARGS>::iEmpty( const vertex_t& v ) const
02054 {
02055 if(v.isNull())
02056 return true;
02057 typename neighborhood_t::const_iterator it_found = this->findVertex(v);
02058 if(it_found == neighborhood.end())
02059 return true;
02060 return it_found->second.in_edges.empty();
02061 }
02062
02063 template <GRAPH_TEMPLATE>
02064 typename VVGraph<GRAPH_ARGS>::neighborhood_t::iterator
02065 VVGraph<GRAPH_ARGS>::findVertex( const vertex_t& v )
02066 {
02067 #ifndef VVGRAPH_NO_VERTEX_CACHE
02068 if(v.cache)
02069 {
02070 if(v.cache_source == 0)
02071 {
02072 VertexCache* cache = reinterpret_cast<VertexCache*>(v.cache);
02073 if(cache->graph_id() == graph_id)
02074 {
02075 return cache->neighborhood();
02076 }
02077 }
02078 }
02079 #endif // VVGRAPH_NO_VERTEX_CACHE
02080 typename lookup_t::const_iterator it_found = lookup.find(v);
02081 if(it_found != lookup.end())
02082 return it_found->second;
02083 return neighborhood.end();
02084 }
02085
02086 template <GRAPH_TEMPLATE>
02087 typename VVGraph<GRAPH_ARGS>::neighborhood_t::const_iterator
02088 VVGraph<GRAPH_ARGS>::findVertex( const vertex_t& v ) const
02089 {
02090 #ifndef VVGRAPH_NO_VERTEX_CACHE
02091 if(v.cache)
02092 {
02093 if(v.cache_source == 0)
02094 {
02095 VertexCache* cache = reinterpret_cast<VertexCache*>(v.cache);
02096 if(cache->graph_id() == graph_id)
02097 return cache->neighborhood();
02098 }
02099 }
02100 #endif // VVGRAPH_NO_VERTEX_CACHE
02101 typename lookup_t::const_iterator it_found = lookup.find(v);
02102 if(it_found != lookup.end())
02103 return it_found->second;
02104 return neighborhood.end();
02105 }
02106
02107 template <GRAPH_TEMPLATE>
02108 typename VVGraph<GRAPH_ARGS>::neighbor_found_t
02109 VVGraph<GRAPH_ARGS>::findInVertex( const vertex_t& v, const vertex_t& n)
02110 {
02111 if(v.isNull() || n.isNull() || v == n)
02112 return neighbor_found_t();
02113 #ifndef VVGRAPH_NO_EDGE_CACHE
02114 if(n.cache_source == v.id())
02115 {
02116 EdgeCache* cache = reinterpret_cast<EdgeCache*>(n.cache);
02117 if(cache->graph_id() == graph_id)
02118 {
02119 return neighbor_found_t(cache->it(), cache->neighborhood());
02120 }
02121 }
02122 else if(v.cache_source == v.id())
02123 {
02124 EdgeCache* cache = reinterpret_cast<EdgeCache*>(v.cache);
02125 if(cache->graph_id() == graph_id and cache->it()->target == n)
02126 {
02127 return neighbor_found_t(cache->it(), cache->neighborhood());
02128 }
02129 }
02130 #endif // VVGRAPH_NO_EDGE_CACHE
02131 typename neighborhood_t::iterator it_found = this->findVertex(v);
02132 if(it_found == neighborhood.end())
02133 return neighbor_found_t();
02134 edge_list_t &lst = it_found->second.edges;
02135 single_neighborhood_t &neighborhood = it_found->second;
02136 for(typename edge_list_t::iterator it = lst.begin() ;
02137 it != lst.end() ; ++it)
02138 {
02139 if(it->target == n)
02140 {
02141 return neighbor_found_t(it, &neighborhood);
02142 }
02143 }
02144 return neighbor_found_t(lst.end(), &neighborhood, false);
02145 }
02146
02147 template <GRAPH_TEMPLATE>
02148 typename VVGraph<GRAPH_ARGS>::const_neighbor_found_t
02149 VVGraph<GRAPH_ARGS>::findInVertex( const vertex_t& v, const vertex_t& n) const
02150 {
02151 if(v.isNull() || n.isNull() || v == n)
02152 return const_neighbor_found_t();
02153 #ifndef VVGRAPH_NO_EDGE_CACHE
02154 if(n.cache_source == v.id())
02155 {
02156 EdgeCache *cache = reinterpret_cast<EdgeCache*>(n.cache);
02157 if(cache->graph_id() == graph_id)
02158 {
02159 return const_neighbor_found_t(cache->it(), cache->neighborhood());
02160 }
02161 }
02162 else if(v.cache_source == v.id())
02163 {
02164 EdgeCache *cache = reinterpret_cast<EdgeCache*>(v.cache);
02165 if(cache->graph_id() == graph_id and cache->it()->target == n)
02166 {
02167 return const_neighbor_found_t(cache->it(), cache->neighborhood());
02168 }
02169 }
02170 #endif // VVGRAPH_NO_EDGE_CACHE
02171 typename neighborhood_t::const_iterator it_found = this->findVertex(v);
02172 if(it_found == neighborhood.end())
02173 return const_neighbor_found_t();
02174 const edge_list_t &lst = it_found->second.edges;
02175 const single_neighborhood_t &neighborhood = it_found->second;
02176 for(typename edge_list_t::const_iterator it = lst.begin() ;
02177 it != lst.end() ; ++it)
02178 {
02179 if(it->target == n)
02180 {
02181 return const_neighbor_found_t(it, &neighborhood);
02182 }
02183 }
02184 return const_neighbor_found_t(lst.end(), &neighborhood, false);
02185 }
02186
02187 template <GRAPH_TEMPLATE>
02188 typename VVGraph<GRAPH_ARGS>::neighbor_iterator
02189 VVGraph<GRAPH_ARGS>::findIn(const vertex_t& v, const vertex_t& n)
02190 {
02191 neighbor_found_t found = this->findInVertex(v, n);
02192 if(found.neighborhood)
02193 return neighbor_iterator(found.it);
02194 return neighbor_iterator();
02195 }
02196
02197 template <GRAPH_TEMPLATE>
02198 typename VVGraph<GRAPH_ARGS>::const_neighbor_iterator
02199 VVGraph<GRAPH_ARGS>::findIn(const vertex_t& v, const vertex_t& n) const
02200 {
02201 const_neighbor_found_t found = this->findInVertex(v, n);
02202 if(found.neighborhood)
02203 return const_neighbor_iterator(found.it);
02204 return const_neighbor_iterator(found.it);
02205 }
02206
02207 template <GRAPH_TEMPLATE>
02208 typename VVGraph<GRAPH_ARGS>::neighbor_iterator
02209 VVGraph<GRAPH_ARGS>::eraseEdge(const vertex_t& v, neighbor_iterator pos)
02210 {
02211 typename neighborhood_t::iterator it_found = this->findVertex(v);
02212 if(it_found == neighborhood.end())
02213 return neighbor_iterator();
02214 const vertex_t& n = *pos;
02215 typename neighborhood_t::iterator it_found2 = this->findVertex(n);
02216 if(it_found2 == neighborhood.end())
02217 return neighbor_iterator();
02218 size_type result = it_found2->second.in_edges.erase(v);
02219 if(result)
02220 {
02221 typename edge_list_t::iterator it = pos.base();
02222 return it_found->second.edges.erase(it);
02223 }
02224 return neighbor_iterator();
02225 }
02226
02227 template <GRAPH_TEMPLATE>
02228 typename VVGraph<GRAPH_ARGS>::circ_neighbor_iterator
02229 VVGraph<GRAPH_ARGS>::eraseEdge(const vertex_t& v, circ_neighbor_iterator pos)
02230 {
02231 neighbor_iterator nit = eraseEdge(v, pos.base());
02232 if(pos.isInitIterator(nit))
02233 return pos.end();
02234 return circ_neighbor_iterator(pos, nit);
02235 }
02236
02237 template <GRAPH_TEMPLATE>
02238 typename VVGraph<GRAPH_ARGS>::size_type
02239 VVGraph<GRAPH_ARGS>::eraseEdge( const vertex_t& v, const vertex_t& n )
02240 {
02241 neighbor_found_t found = this->findInVertex(v, n);
02242 if(!found)
02243 return 0;
02244 if(found.neighborhood->flagged && *found.neighborhood->flagged == n) found.neighborhood->flagged = 0;
02245 found.neighborhood->edges.erase(found.it);
02246 typename lookup_t::iterator it_found = lookup.find(n);
02247 if(it_found != lookup.end())
02248 it_found->second->second.in_edges.erase(v);
02249 return 1;
02250 }
02251
02252 template <GRAPH_TEMPLATE>
02253 bool VVGraph<GRAPH_ARGS>::contains( const vertex_t& v ) const
02254 {
02255 return this->findVertex(v) != neighborhood.end();
02256 }
02257
02258 template <GRAPH_TEMPLATE>
02259 std::pair<typename VVGraph<GRAPH_ARGS>::ineighbor_iterator,bool>
02260 VVGraph<GRAPH_ARGS>::insertInEdge(const vertex_t& v, const vertex_t& new_neighbor)
02261 {
02262 typename lookup_t::iterator found = lookup.find(new_neighbor);
02263 if(found == lookup.end())
02264 return std::make_pair(ineighbor_iterator(), false);
02265
02266
02267
02268 return found->second->second.in_edges.insert(v);
02269 }
02270
02271 template <GRAPH_TEMPLATE>
02272 void VVGraph<GRAPH_ARGS>::undoInEdge(const vertex_t& new_neighbor,
02273 ineighbor_iterator& it)
02274 {
02275 typename lookup_t::iterator found = lookup.find(new_neighbor);
02276
02277
02278
02279 if(found == lookup.end())
02280 return;
02281 found->second->second.in_edges.erase(it);
02282 }
02283
02284 template <GRAPH_TEMPLATE>
02285 void VVGraph<GRAPH_ARGS>::updateEdgeCache(const vertex_t& v,
02286 typename edge_list_t::iterator new_edge_it,
02287 const vertex_t& in_edge)
02288 {
02289 #ifndef VVGRAPH_NO_EDGE_CACHE
02290 if(not compact)
02291 {
02292
02293 neighbor_t& neighbor = *new_edge_it;
02294 neighbor.setIt(new_edge_it);
02295 neighbor.target.cache_source = v.id();
02296 neighbor.target.cache = reinterpret_cast<void*>(&neighbor);
02297
02298
02299 in_edge.cache_source = v.id();
02300 in_edge.cache = reinterpret_cast<void*>(&neighbor);
02301 }
02302 #endif // VVGRAPH_NO_EDGE_CACHE
02303 }
02304
02305 template <GRAPH_TEMPLATE>
02306 typename VVGraph<GRAPH_ARGS>::edge_t
02307 VVGraph<GRAPH_ARGS>::replace( const vertex_t& v,
02308 const vertex_t& neighbor,
02309 const vertex_t& new_neighbor )
02310 {
02311 if(new_neighbor.isNull() or (v == new_neighbor) or (neighbor == new_neighbor))
02312 return edge_t();
02313 neighbor_found_t found = this->findInVertex(v, neighbor);
02314 if(!found)
02315 return edge_t();
02316 typename neighborhood_t::iterator n_found = this->findVertex(neighbor);
02317 ineighbor_iterator it_in;
02318 bool inserted;
02319 util::tie(it_in, inserted) = insertInEdge(v, new_neighbor);
02320 if(!inserted)
02321 return edge_t();
02322 n_found->second.in_edges.erase(v);
02323 found.it->target = new_neighbor;
02324 found.it->clear_edge();
02325 updateEdgeCache(v, found.it, *it_in);
02326 if(n_found->second.flagged and *n_found->second.flagged == neighbor) n_found->second.flagged = 0;
02327 return edge_t(v.id(), new_neighbor.id(), &*found.it);
02328 }
02329
02330 template <GRAPH_TEMPLATE>
02331 const typename VVGraph<GRAPH_ARGS>::vertex_t&
02332 VVGraph<GRAPH_ARGS>::nextTo( const vertex_t& v,
02333 const vertex_t& ref,
02334 unsigned int n ) const
02335 {
02336 const_neighbor_found_t found = this->findInVertex(v, ref);
02337 if(!found)
02338 return vertex_t::null;
02339 typename edge_list_t::const_iterator it = found.it;
02340 const edge_list_t& lst = found.neighborhood->edges;
02341 for(unsigned int i = 0 ; i < n ; ++i)
02342 {
02343 ++it;
02344 if(it == lst.end())
02345 it = lst.begin();
02346 }
02347 return it->target;
02348 }
02349
02350 template <GRAPH_TEMPLATE>
02351 const typename VVGraph<GRAPH_ARGS>::vertex_t&
02352 VVGraph<GRAPH_ARGS>::prevTo( const vertex_t& v,
02353 const vertex_t& ref,
02354 unsigned int n ) const
02355 {
02356 const_neighbor_found_t found = this->findInVertex(v, ref);
02357 if(!found)
02358 return vertex_t::null;
02359 typename edge_list_t::const_iterator it = found.it;
02360 const edge_list_t& lst = found.neighborhood->edges;
02361 for(unsigned int i = 0 ; i < n ; ++i)
02362 {
02363 if(it == lst.begin())
02364 it = lst.end();
02365 --it;
02366 }
02367 return it->target;
02368 }
02369
02370 template <GRAPH_TEMPLATE>
02371 typename VVGraph<GRAPH_ARGS>::edge_t
02372 VVGraph<GRAPH_ARGS>::edge( const vertex_t& src,
02373 const vertex_t& tgt )
02374 {
02375 neighbor_found_t found = this->findInVertex(src, tgt);
02376 if(!found)
02377 return edge_t();
02378 return edge_t(src.id(), tgt.id(), &*found.it);
02379 }
02380
02381 template <GRAPH_TEMPLATE>
02382 typename VVGraph<GRAPH_ARGS>::arc_t
02383 VVGraph<GRAPH_ARGS>::arc( const vertex_t& src,
02384 const vertex_t& tgt )
02385 {
02386 neighbor_found_t found = this->findInVertex(src, tgt);
02387 if(!found)
02388 return arc_t();
02389 neighbor_found_t other = this->findInVertex(tgt, src);
02390 if(!other)
02391 return arc_t();
02392 return arc_t(src.id(), tgt.id(), &*found.it, &*other.it);
02393 }
02394
02395 template <GRAPH_TEMPLATE>
02396 typename VVGraph<GRAPH_ARGS>::const_edge_t
02397 VVGraph<GRAPH_ARGS>::edge( const vertex_t& src,
02398 const vertex_t& tgt ) const
02399 {
02400 const_neighbor_found_t found = this->findInVertex(src, tgt);
02401 if(!found)
02402 return const_edge_t();
02403 return const_edge_t(src.id(), tgt.id(), &*found.it);
02404 }
02405
02406 template <GRAPH_TEMPLATE>
02407 bool VVGraph<GRAPH_ARGS>::flag( const vertex_t& src,
02408 const vertex_t& neighbor )
02409 {
02410 neighbor_found_t found = this->findInVertex(src, neighbor);
02411 if(!found)
02412 return false;
02413 found.neighborhood->flagged = &(found.it->target);
02414 return true;
02415 }
02416
02417 template <GRAPH_TEMPLATE>
02418 const typename VVGraph<GRAPH_ARGS>::vertex_t&
02419 VVGraph<GRAPH_ARGS>::flagged( const vertex_t& src ) const
02420 {
02421 typename neighborhood_t::const_iterator found = this->findVertex(src);
02422 if(found == neighborhood.end() or found->second.flagged == 0)
02423 return vertex_t::null;
02424 return *found->second.flagged;
02425 }
02426
02427 template <GRAPH_TEMPLATE>
02428 typename VVGraph<GRAPH_ARGS>::edge_t
02429 VVGraph<GRAPH_ARGS>::spliceAfter( const vertex_t& v,
02430 const vertex_t& neighbor,
02431 const vertex_t& new_neighbor )
02432 {
02433 if(new_neighbor.isNull() || v == new_neighbor)
02434 return edge_t();
02435 neighbor_found_t found = this->findInVertex(v, neighbor);
02436 if(!found)
02437 return edge_t();
02438 ineighbor_iterator it_in;
02439 bool inserted;
02440 util::tie(it_in, inserted) = insertInEdge(v, new_neighbor);
02441 if(!inserted)
02442 return edge_t();
02443 ++found.it;
02444 typename edge_list_t::iterator new_edge_it = found.neighborhood->edges.insert(found.it, neighbor_t(new_neighbor, EdgeContent(), *found.neighborhood, graph_id));
02445 updateEdgeCache(v, new_edge_it, *it_in);
02446 return edge_t(v.id(), new_neighbor.id(), &*new_edge_it);
02447 }
02448
02449 template <GRAPH_TEMPLATE>
02450 template <typename VertexContainer>
02451 std::vector<typename VVGraph<GRAPH_ARGS>::edge_t>
02452 VVGraph<GRAPH_ARGS>::spliceAfter( const vertex_t& v,
02453 const vertex_t& neighbor,
02454 const VertexContainer& new_neighbors )
02455 {
02456 std::vector<edge_t> result;
02457 neighbor_found_t found = this->findInVertex(v, neighbor);
02458 if(!found) return result;
02459 ineighbor_iterator it_in;
02460 bool inserted;
02461 ++found.it;
02462 result.reserve(new_neighbors.size());
02463 for(typename VertexContainer::const_iterator it = new_neighbors.begin() ;
02464 it != new_neighbors.end() ; ++it) {
02465 const vertex_t& new_neighbor = *it;
02466 util::tie(it_in, inserted) = insertInEdge(v, new_neighbor);
02467 if(!inserted) return result;
02468 typename edge_list_t::iterator new_edge_it = found.neighborhood->edges.insert(found.it, neighbor_t(new_neighbor, EdgeContent(), *found.neighborhood, graph_id));
02469 updateEdgeCache(v, new_edge_it, *it_in);
02470 result.push_back(edge_t(v.id(), new_neighbor.id(), &*new_edge_it));
02471 }
02472 return result;
02473 }
02474
02475 template <GRAPH_TEMPLATE>
02476 typename VVGraph<GRAPH_ARGS>::edge_t
02477 VVGraph<GRAPH_ARGS>::spliceBefore( const vertex_t& v,
02478 const vertex_t& neighbor,
02479 const vertex_t& new_neighbor )
02480 {
02481 if(new_neighbor.isNull() || v == new_neighbor)
02482 return edge_t();
02483 neighbor_found_t found = this->findInVertex(v, neighbor);
02484 if(!found)
02485 return edge_t();
02486 ineighbor_iterator it_in;
02487 bool inserted;
02488 util::tie(it_in, inserted) = insertInEdge(v, new_neighbor);
02489 if(!inserted)
02490 return edge_t();
02491 typename edge_list_t::iterator new_edge_it = found.neighborhood->edges.insert(found.it, neighbor_t(new_neighbor, EdgeContent(), *found.neighborhood, graph_id));
02492 updateEdgeCache(v, new_edge_it, *it_in);
02493 return edge_t(v.id(), new_neighbor.id(), &*new_edge_it);
02494 }
02495
02496 template <GRAPH_TEMPLATE>
02497 template <typename VertexContainer>
02498 std::vector<typename VVGraph<GRAPH_ARGS>::edge_t>
02499 VVGraph<GRAPH_ARGS>::spliceBefore( const vertex_t& v,
02500 const vertex_t& neighbor,
02501 const VertexContainer& new_neighbors )
02502 {
02503 std::vector<edge_t> result;
02504 neighbor_found_t found = this->findInVertex(v, neighbor);
02505 if(!found) return result;
02506 ineighbor_iterator it_in;
02507 bool inserted;
02508 result.reserve(new_neighbors.size());
02509 for(typename VertexContainer::const_iterator it = new_neighbors.begin() ;
02510 it != new_neighbors.end() ; ++it) {
02511 const vertex_t& new_neighbor = *it;
02512 util::tie(it_in, inserted) = insertInEdge(v, new_neighbor);
02513 if(!inserted) return result;
02514 typename edge_list_t::iterator new_edge_it = found.neighborhood->edges.insert(found.it, neighbor_t(new_neighbor, EdgeContent(), *found.neighborhood, graph_id));
02515 updateEdgeCache(v, new_edge_it, *it_in);
02516 result.push_back(edge_t(v.id(), new_neighbor.id(), &*new_edge_it));
02517 }
02518 return result;
02519 }
02520
02521
02522 template <GRAPH_TEMPLATE>
02523 template <typename VertexContainer>
02524 std::vector<typename VVGraph<GRAPH_ARGS>::edge_t>
02525 VVGraph<GRAPH_ARGS>::insertEdges( const vertex_t& v, const VertexContainer& new_neighbors )
02526 {
02527 std::vector<edge_t> result;
02528 typename neighborhood_t::iterator it_found = this->findVertex(v);
02529 if(it_found == neighborhood.end()) return result;
02530 ineighbor_iterator it_in;
02531 bool inserted;
02532 edge_list_t& lst = it_found->second.edges;
02533 typename edge_list_t::iterator lst_it = lst.begin();
02534 result.reserve(new_neighbors.size());
02535 for(typename VertexContainer::const_iterator it = new_neighbors.begin() ;
02536 it != new_neighbors.end() ; ++it) {
02537 const vertex_t& new_neighbor = *it;
02538 if(new_neighbor.isNull() or new_neighbor == v) return result;
02539 util::tie(it_in, inserted) = this->insertInEdge(v, new_neighbor);
02540 if(!inserted) return result;
02541 typename edge_list_t::iterator new_lst_it = lst.insert(lst_it, neighbor_t(new_neighbor, EdgeContent(), it_found->second, graph_id));
02542 updateEdgeCache(v, new_lst_it, *it_in);
02543 result.push_back(edge_t(v.id(), new_neighbor.id(), &*new_lst_it));
02544 }
02545 return result;
02546 }
02547
02548 template <GRAPH_TEMPLATE>
02549 typename VVGraph<GRAPH_ARGS>::edge_t
02550 VVGraph<GRAPH_ARGS>::insertEdge( const vertex_t& v,
02551 const vertex_t& new_neighbor )
02552 {
02553 if(v.isNull() || new_neighbor.isNull() || v == new_neighbor )
02554 return edge_t();
02555 typename neighborhood_t::iterator it_found = this->findVertex(v);
02556 if(it_found == neighborhood.end())
02557 return edge_t();
02558 ineighbor_iterator it_in;
02559 bool inserted;
02560 util::tie(it_in, inserted) = insertInEdge(v, new_neighbor);
02561 if(!inserted)
02562 return edge_t();
02563 edge_list_t &lst = it_found->second.edges;
02564 lst.push_front(neighbor_t(new_neighbor, EdgeContent(), it_found->second, graph_id));
02565 typename edge_list_t::iterator it = lst.begin();
02566 updateEdgeCache(v, it, *it_in);
02567 return edge_t(v.id(), new_neighbor.id(), &*it);
02568 }
02569
02570 template <GRAPH_TEMPLATE>
02571 typename VVGraph<GRAPH_ARGS>::const_neighbor_iterator_range
02572 VVGraph<GRAPH_ARGS>::neighbors(const vertex_t& v) const
02573 {
02574 const_neighbor_iterator_range result;
02575 if(v.isNull())
02576 return result;
02577 typename neighborhood_t::const_iterator it_found = this->findVertex(v);
02578 if(it_found == neighborhood.end())
02579 return result;
02580 const edge_list_t &lst = it_found->second.edges;
02581 result = util::make_range(const_neighbor_iterator(lst.begin()),
02582 const_neighbor_iterator(lst.end()));
02583 return result;
02584 }
02585
02586 template <GRAPH_TEMPLATE>
02587 typename VVGraph<GRAPH_ARGS>::neighbor_iterator_range
02588 VVGraph<GRAPH_ARGS>::neighbors(const vertex_t& v)
02589 {
02590 neighbor_iterator_range result;
02591 if(v.isNull())
02592 return result;
02593 typename neighborhood_t::iterator it_found = this->findVertex(v);
02594 if(it_found == neighborhood.end())
02595 return result;
02596 edge_list_t &lst = it_found->second.edges;
02597 result = util::make_range(neighbor_iterator(lst.begin()),
02598 neighbor_iterator(lst.end()));
02599 return result;
02600 }
02601
02602 template <GRAPH_TEMPLATE>
02603 typename VVGraph<GRAPH_ARGS>::const_circ_neighbor_iterator_range
02604 VVGraph<GRAPH_ARGS>::neighbors(const vertex_t& v, const vertex_t& n) const
02605 {
02606 const_circ_neighbor_iterator_range result;
02607 if(v.isNull())
02608 return result;
02609 const_neighbor_found_t found = this->findInVertex(v, n);
02610 if(!found)
02611 return result;
02612 const edge_list_t &lst = found.neighborhood->edges;
02613 result = util::make_range(const_circ_neighbor_iterator(lst.begin(), lst.end(), found.it),
02614 const_circ_neighbor_iterator(lst.begin(), lst.end()));
02615 return result;
02616 }
02617
02618 template <GRAPH_TEMPLATE>
02619 typename VVGraph<GRAPH_ARGS>::circ_neighbor_iterator_range
02620 VVGraph<GRAPH_ARGS>::neighbors(const vertex_t& v, const vertex_t& n)
02621 {
02622 circ_neighbor_iterator_range result;
02623 if(v.isNull())
02624 return result;
02625 neighbor_found_t found = this->findInVertex(v, n);
02626 if(!found)
02627 return result;
02628 edge_list_t &lst = found.neighborhood->edges;
02629 result = util::make_range(circ_neighbor_iterator(lst.begin(), lst.end(), found.it),
02630 circ_neighbor_iterator(lst.begin(), lst.end()));
02631 return result;
02632 }
02633
02634 template <GRAPH_TEMPLATE>
02635 typename VVGraph<GRAPH_ARGS>::ineighbor_iterator_range
02636 VVGraph<GRAPH_ARGS>::iNeighbors(const vertex_t& v) const
02637 {
02638 ineighbor_iterator_range result;
02639 if(v.isNull())
02640 return result;
02641 typename neighborhood_t::const_iterator it_found = this->findVertex(v);
02642 if(it_found == neighborhood.end())
02643 return result;
02644 const in_edges_t &lst = it_found->second.in_edges;
02645 result = util::make_range(ineighbor_iterator(lst.begin()),
02646 ineighbor_iterator(lst.end()));
02647 return result;
02648 }
02649
02650 template <GRAPH_TEMPLATE>
02651 template <typename VertexContainer>
02652 VVGraph<GRAPH_ARGS> VVGraph<GRAPH_ARGS>::subgraph( const VertexContainer& verts ) const
02653 {
02654 typename VertexContainer::const_iterator it;
02655 VVGraph result;
02656
02657 for(it = verts.begin() ; it != verts.end() ; ++it)
02658 {
02659 result.insert(*it);
02660 }
02661 typename neighborhood_t::const_iterator it_orign;
02662 typename neighborhood_t::iterator it_n;
02663 typename edge_list_t::const_reverse_iterator it_sn;
02664
02665 for(it_n = result.neighborhood.begin() ; it_n != result.neighborhood.end() ; ++it_n)
02666 {
02667 const vertex_t& v = it_n->first;
02668 result.updateVertexCache(v, it_n);
02669
02670 it_orign = this->findVertex(v);
02671 const edge_list_t& orig_lst = it_orign->second.edges;
02672 edge_list_t& lst = it_n->second.edges;
02673
02674 for( it_sn = orig_lst.rbegin() ; it_sn != orig_lst.rend() ; ++it_sn )
02675 {
02676
02677
02678 if(result.contains(it_sn->target))
02679 {
02680
02681 ineighbor_iterator it_in = result.insertInEdge(v, it_sn->target).first;
02682
02683 lst.push_front(neighbor_t(it_sn->target, *it_sn, it_n->second, result.graph_id));
02684
02685 result.updateEdgeCache(v, lst.begin(), *it_in);
02686 }
02687 }
02688
02689 if(it_orign->second.flagged and result.contains(*it_orign->second.flagged))
02690 {
02691 const_neighbor_found_t found = this->findInVertex(v, *it_orign->second.flagged);
02692 it_n->second.flagged = &(found.it->target);
02693 }
02694 }
02695 return result;
02696 }
02697
02698 template <GRAPH_TEMPLATE>
02699 VVGraph<GRAPH_ARGS>::VVGraph(const VVGraph& copy)
02700 : graph_id(graph::getNextGraphId())
02701 {
02702 *this = copy;
02703 }
02704
02705 #ifdef USE_CXX0X
02706 template <GRAPH_TEMPLATE>
02707 VVGraph<GRAPH_ARGS>::VVGraph(VVGraph&& copy)
02708 : neighborhood(std::move(copy.neighborhood))
02709 , lookup(std::move(copy.lookup))
02710 , graph_id(copy.graph_id)
02711 {
02712 copy.neighborhood.clear();
02713 copy.lookup.clear();
02714 copy.graph_id = graph::getNextGraphId();
02715 }
02716 #endif
02717
02718 template <GRAPH_TEMPLATE>
02719 bool VVGraph<GRAPH_ARGS>::operator==(const VVGraph& other) const
02720 {
02721 if(neighborhood.size() != other.neighborhood.size())
02722 return false;
02723 for(typename neighborhood_t::const_iterator it = neighborhood.begin() ;
02724 it != neighborhood.end() ; ++it)
02725 {
02726 const vertex_t& v1 = it->first;
02727 typename lookup_t::const_iterator it_found = other.lookup.find(v1);
02728 if(it_found == other.lookup.end())
02729 return false;
02730 if(it->second.edges.empty())
02731 {
02732 if(!it_found->second->second.edges.empty())
02733 return false;
02734 }
02735 else
02736 {
02737 const edge_list_t& lst = it->second.edges;
02738 const edge_list_t& olst = it_found->second->second.edges;
02739 if(lst.size() != olst.size()) return false;
02740 const vertex_t& v2 = lst.begin()->target;
02741 bool found = false;
02742 for(typename edge_list_t::const_iterator it_olst = olst.begin() ;
02743 it_olst != olst.end() ; ++it_olst)
02744 {
02745 if(it_olst->target == v2)
02746 {
02747 found = true;
02748 for(typename edge_list_t::const_iterator it_lst = lst.begin() ;
02749 it_lst != lst.end() ; ++it_lst)
02750 {
02751 if(it_lst->target != it_olst->target) return false;
02752 ++it_olst;
02753 if(it_olst == olst.end()) it_olst = olst.begin();
02754 }
02755 break;
02756 }
02757 }
02758 if(!found) return false;
02759 }
02760 }
02761 return true;
02762 }
02763
02764 template <GRAPH_TEMPLATE>
02765 VVGraph<GRAPH_ARGS>&
02766 VVGraph<GRAPH_ARGS>::operator=( const VVGraph& other )
02767 {
02768
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786
02787
02788
02789
02790 neighborhood = other.neighborhood;
02791 lookup.clear();
02792 typename neighborhood_t::iterator it;
02793 for(it = neighborhood.begin() ; it != neighborhood.end() ; ++it)
02794 {
02795 lookup[it->first] = it;
02796 }
02797
02798 typename edge_list_t::iterator it_e;
02799 for(it = neighborhood.begin() ; it != neighborhood.end() ; ++it)
02800 {
02801 const vertex_t& src = it->first;
02802 updateVertexCache(src, it);
02803 #ifndef VVGRAPH_NO_EDGE_CACHE
02804 if(not compact)
02805 {
02806 edge_list_t& lst = it->second.edges;
02807 for(it_e = lst.begin() ; it_e != lst.end() ; ++it_e)
02808 {
02809
02810 typename lookup_t::iterator it_found = lookup.find(it_e->target);
02811 const vertex_t& iv = *(it_found->second->second.in_edges.find(src));
02812
02813 updateEdgeCache(src, it_e, iv);
02814 it_e->set(&it->second, graph_id);
02815 }
02816 }
02817 #endif
02818 }
02819 return *this;
02820 }
02821
02822 template <GRAPH_TEMPLATE>
02823 void VVGraph<GRAPH_ARGS>::swap(VVGraph& other)
02824 {
02825 neighborhood.swap(other.neighborhood);
02826 lookup.swap(lookup);
02827 std::swap(graph_id, other.graph_id);
02828 }
02829
02830 template <typename Graph>
02831 void create_graph_methods(Graph& G)
02832 {
02833 if(G.size())
02834 {
02835 if(G.valence(G.any()) > G.size())
02836 {
02837
02838 typename Graph::vertex_t v = G.any();
02839 G.erase(v);
02840 G.insert(v);
02841 G[10];
02842 G.reference(v);
02843 G.empty();
02844 G.anyIn(v);
02845 G.valence(v);
02846 G.empty(v);
02847 G.iAnyIn(v);
02848 G.iValence(v);
02849 G.iEmpty(v);
02850 G.nextTo(v, v);
02851 G.prevTo(v, v);
02852 G.edge(v, v);
02853 G.flag(v,v);
02854 G.flagged(v);
02855 G.neighbors(v);
02856 G.iNeighbors(v);
02857 G.source(typename Graph::edge_t());
02858 G.target(typename Graph::edge_t());
02859 G.eraseEdge(v, v);
02860 G.replace(v, v, v);
02861 G.spliceAfter(v, v, v);
02862 G.spliceBefore(v, v, v);
02863 G.insertEdge(v,v);
02864 G.eraseAllEdges(v);
02865 G.begin();
02866 G.end();
02867 G.find(v);
02868 G.count(v);
02869 G.findIn(v, v);
02870 G.swap(G);
02871 G = G;
02872 {
02873 const Graph& cG = G;
02874 cG[10];
02875 cG.reference(v);
02876 cG.empty();
02877 cG.anyIn(v);
02878 cG.valence(v);
02879 cG.empty(v);
02880 cG.iAnyIn(v);
02881 cG.iValence(v);
02882 cG.iEmpty(v);
02883 cG.nextTo(v, v);
02884 cG.prevTo(v, v);
02885 cG.edge(v, v);
02886 cG.flagged(v);
02887 cG.neighbors(v);
02888 cG.iNeighbors(v);
02889 cG.source(typename Graph::edge_t());
02890 cG.target(typename Graph::edge_t());
02891 cG.begin();
02892 cG.end();
02893 cG.find(v);
02894 cG.count(v);
02895 cG.findIn(v, v);
02896 }
02897 }
02898 }
02899 }
02900
02901
02902 }
02903
02904 namespace std
02905 {
02909 template <GRAPH_TEMPLATE>
02910 void swap(graph::VVGraph<GRAPH_ARGS>& g1, graph::VVGraph<GRAPH_ARGS>& g2)
02911 {
02912 g1.swap(g2);
02913 }
02914 }
02915
02916 #undef GRAPH_TEMPLATE
02917 #undef GRAPH_ARGS
02918
02919 #endif // GRAPH_VVGRAPH_H
02920