vvbigraph.h

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