vvgraph.h

Go to the documentation of this file.
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& /*other*/) { 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         //typedef std::map<vertex_t, single_neighborhood_t> neighborhood_t;
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         //typedef std::map<vertex_t, typename neighborhood_t::iterator> lookup_t;
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;//vertex_t(0);
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;//vertex_t(0);
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;//vertex_t(0);
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;//vertex_t(0);
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;//vertex_t(0);
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       // Remove the incoming edges
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;//vertex_t(0);
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;//vertex_t(0);
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;//vertex_t(0);
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;//vertex_t(0);
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       //typename neighborhood_t::iterator found = neighborhood.find(new_neighbor);
02266       //if(found == neighborhood.end())
02267       //return std::make_pair(ineighbor_iterator(), false);
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       //typename neighborhood_t::iterator found = neighborhood.find(new_neighbor);
02277       //if(found == neighborhood.end())
02278       //return;
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         // Caching in the neighbor
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         // Caching in the incoming edge source
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;//vertex_t(0);
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;//vertex_t(0);
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       // First, insert the vertexes in the result graph
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       // Then, creates the in and out edges
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         // For each vertex, find out which edges to add
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         // Going backward because it is easier to retrieve the iterator ...
02674         for( it_sn = orig_lst.rbegin() ; it_sn != orig_lst.rend() ; ++it_sn )
02675         {
02676           // For each existing edge from the vertex, keep only the ones whose 
02677           // target are on the subgraph
02678           if(result.contains(it_sn->target))
02679           {
02680             // Insert the incoming edge
02681             ineighbor_iterator it_in = result.insertInEdge(v, it_sn->target).first;
02682             // Insert the outgoing edge
02683             lst.push_front(neighbor_t(it_sn->target, *it_sn, it_n->second, result.graph_id));
02684             // Update the cache
02685             result.updateEdgeCache(v, lst.begin(), *it_in);
02686           }
02687         }
02688         // At last, update the flag, if any
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       //    for(const_iterator it = other.begin() ; it != other.end() ; ++it)
02769       //    {
02770       //      this->insert(*it);
02771       //    }
02772 
02773       //    for(const_iterator it = other.begin() ; it != other.end() ; ++it)
02774       //    {
02775       //      vertex_t prev(0);
02776       //      const vertex_t& v = *it;
02777       //      const_neighbor_iterator_range ns = other.neighbors(v);
02778       //      for(const_neighbor_iterator itn = ns.first ; itn != ns.second ; ++itn)
02779       //      {
02780       //        const vertex_t& n = *itn;
02781       //        if(prev)
02782       //          this->spliceAfter(v, prev, n);
02783       //        else
02784       //          this->insertEdge(v,n);
02785       //        prev = n;
02786       //      }
02787       //    }
02788 
02789       // Copy the structure
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       // And reconstruct the cache
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             // Find the incoming vertex corresponding the this edge
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             //const vertex_t& iv = *(neighborhood[it_e->target].in_edges.find(src));
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           // Call all fcts
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Fri May 31 15:37:51 2013 for VVE by  doxygen 1.6.3