Main Page   Class Hierarchy   Compound List   File List   Compound Members  

PG_edges.hpp

00001 #ifndef _PG_EDGES_HPP_
00002 #define _PG_EDGES_HPP_
00003 
00004 #include <map>
00005 
00006 #include "PG_property.hpp"
00007 
00008 namespace ParGraph
00009 {
00010 struct directed_out_edges_type {};
00011 struct directed_in_out_edges_type {};
00012 
00013 struct has_out_edges {};
00014 struct has_no_out_edges {};
00015 struct has_in_edges {};
00016 struct has_no_in_edges {};
00017 struct is_double_sided_edge {};
00018 struct is_not_double_sided_edge {};
00019 
00020 template< class Property, class EdgeKind >
00021 struct edgelist_kind_traits {};
00022 template< class Edge >
00023 struct edge_traits
00024 {
00025   typedef typename Edge::value_type::second_type data_type;
00026   typedef typename data_type::property_type property_type;
00027 };
00028 
00029 template< class EdgeList >
00030 struct edgelist_traits : edgelist_kind_traits< typename EdgeList::property_type, typename EdgeList::edge_kind >
00031 {
00032 };
00033 
00034 template< class P >
00035 class DirectedOutEdges;
00036 template< class P >
00037 class DirectedInOutEdges;
00038 
00039 template< class Iter >
00040 struct user_edge_type
00041 {
00042   typedef typename Iter::value_type::second_type::property_type edge_property;
00043   known_vertex_type source, target;
00044   Iter edge;
00045 
00046   user_edge_type() {}
00047   user_edge_type( known_vertex_type v1, known_vertex_type v2, Iter e ) : source(v1), target(v2), edge(e) {}
00048 };
00049 
00051 template< class Edge >
00052 inline EdgeID_t get_edge_id( Edge e )
00053 {
00054   return e.edge->first;
00055 }
00056 
00058 template< class Edge, class Graph >
00059 inline known_vertex_type source( Edge e, const Graph &g )
00060 {
00061   return e.source;
00062 }
00063 
00065 template< class Edge, class Graph >
00066 inline known_vertex_type target( Edge e, const Graph &g )
00067 {
00068   return e.target;
00069 }
00070 
00071 template< class Edge >
00072 inline known_vertex_type get_v2( Edge e )
00073 {
00074   return e.edge->second.get_v2();
00075 }
00076 
00077 template< class Edge >
00078 inline EdgeID_t get_v2_id( Edge e )
00079 {
00080   return get_id( e.edge->second.get_v2());
00081 }
00082 
00083 template< class Edge >
00084 inline bool is_out_edge( Edge &e )
00085 {
00086   return e.target == e.edge->second.get_v2();
00087 }
00088 
00090 template< class Edge >
00091 inline typename Edge::edge_property &
00092 get_edge_property( Edge &e )
00093 {
00094   return e.edge->second.get_property_reference();
00095 }
00096 
00097 template< class PropertyWrapper >
00098 class EdgeBase
00099 {
00100   known_vertex_type other_vertex;
00101   PropertyWrapper prop_wrapper;
00102 
00103 public:
00104   typedef typename PropertyWrapper::property_type property_type;
00105   EdgeBase() {}
00106   EdgeBase( known_vertex_type id ) : other_vertex( id ) {}
00107   EdgeBase( known_vertex_type id, typename PropertyWrapper::constructor_argument_type p ) :
00108                                                  other_vertex( id ), prop_wrapper(p) {}
00109 
00110   known_vertex_type get_v2() const { return other_vertex; }
00111   void set_v2( known_vertex_type v ) { other_vertex = v; }
00112 
00113   typename PropertyWrapper::property_type & get_property_reference()
00114         { return prop_wrapper.get_reference(); }
00115   const typename PropertyWrapper::property_type & get_property_reference() const
00116         { return prop_wrapper.get_reference(); }
00117 // only for DoubleSidedPropertyWrapper ! :
00118   void join( EdgeBase< PropertyWrapper > & e2 ) 
00119         { prop_wrapper.join( e2.prop_wrapper ); }
00120   void delete_property()
00121         { prop_wrapper.delete_property(); }
00122 
00123   friend class DirectedOutEdges< typename PropertyWrapper::property_type >;
00124   friend class DirectedInOutEdges< typename PropertyWrapper::property_type >;
00125 };
00126 
00127 // ------- Edge Property Wrapper ------------------------------------
00128 
00129 template< class Property >
00130 struct SimpleEdgePropertyWrapper
00131 {
00132   Property prop;
00133 
00134   typedef Property property_type;
00135   typedef Property & constructor_argument_type;
00136 
00137   SimpleEdgePropertyWrapper() {}
00138   SimpleEdgePropertyWrapper( Property & p ) : prop(p) {}
00139   Property & get_reference() { return prop; }
00140   const Property & get_reference() const { return prop; }
00141 };
00142 
00143 template< class Property >
00144 struct DoubleSidedEdgePropertyWrapper
00145 {
00146   Property * prop;
00147 
00148   typedef Property property_type;
00149   typedef Property * constructor_argument_type;
00150 
00151   DoubleSidedEdgePropertyWrapper() {}
00152   DoubleSidedEdgePropertyWrapper( Property * p ) : prop(p) {}
00153     //~DoubleSidedEdgePropertyWrapper() { }
00154   Property & get_reference() { return *prop; }
00155   const Property & get_reference() const { return *prop; }
00156   void delete_property() { delete prop; }
00157   void new_property() { prop = new Property; }
00158   static Property * static_new_property() { return new Property; }
00159   static Property * static_new_property( const Property & p ) { return new Property(p); }
00160   void join( DoubleSidedEdgePropertyWrapper<Property> & w2 )
00161   {
00162     if( prop != w2.prop )
00163     {
00164         delete w2.prop;
00165         w2.prop = prop;
00166     }
00167   }
00168 };
00169 
00170 template<>
00171 struct DoubleSidedEdgePropertyWrapper< no_property >
00172 {
00173   no_property prop;
00174   typedef no_property property_type;
00175   typedef no_property constructor_argument_type;
00176 
00177   DoubleSidedEdgePropertyWrapper() {}
00178   DoubleSidedEdgePropertyWrapper( const no_property & ) {}
00179   no_property & get_reference() { return prop; }
00180   const no_property & get_reference() const { return prop; }
00181   void delete_property() { }
00182   void join( DoubleSidedEdgePropertyWrapper<no_property> & ) { }
00183   void new_property() {}
00184   static no_property static_new_property() { return no_property(); }
00185   static no_property static_new_property( const no_property & ) { return no_property(); }
00186 };
00187 
00188 // --------- Edge Iterator
00189 template< class Iter >
00190 class InEdgeIterator
00191 {
00192   known_vertex_type target;
00193   Iter iter;
00194 public:
00195   typedef user_edge_type< Iter > value_type;
00196   InEdgeIterator() : iter() {}
00197   InEdgeIterator( known_vertex_type v, Iter _iter ) : target(v), iter(_iter) {}
00198   InEdgeIterator( const InEdgeIterator<Iter> & other ) : target( other.target ), iter( other.iter ) {}
00199   void operator++(int)
00200   {
00201     iter++;
00202   }
00203   void operator++()
00204   {
00205     iter++;
00206   }
00207   bool operator==( const InEdgeIterator<Iter> & other ) const
00208   {
00209     return iter == other.iter;
00210   }
00211   bool operator!=( const InEdgeIterator<Iter> & other ) const
00212   {
00213     return iter != other.iter;
00214   }
00215   value_type operator*() const
00216   {
00217     return value_type( iter->second.get_v2(), target, iter);
00218   }
00219   InEdgeIterator & operator=( const InEdgeIterator<Iter> & other )
00220   {
00221     iter = other.iter;
00222     target = other.target;
00223     return *this;
00224   }
00225 };
00226 
00227 template< class Iter >
00228 class OutEdgeIterator
00229 {
00230   known_vertex_type source;
00231   Iter iter;
00232 public:
00233   typedef user_edge_type< Iter > value_type;
00234   OutEdgeIterator() : iter() {}
00235   OutEdgeIterator( known_vertex_type v, Iter _iter ) : source(v), iter(_iter) {}
00236   OutEdgeIterator( const OutEdgeIterator<Iter> & other ) : source( other.source ), iter( other.iter ) {}
00237   void operator++(int)
00238   {
00239     iter++;
00240   }
00241   void operator++()
00242   {
00243     iter++;
00244   }
00245   bool operator==( const OutEdgeIterator<Iter> & other ) const
00246   {
00247     return iter == other.iter;
00248   }
00249   bool operator!=( const OutEdgeIterator<Iter> & other ) const
00250   {
00251     return iter != other.iter;
00252   }
00253   value_type operator*() const
00254   {
00255     return value_type( source, iter->second.get_v2(), iter);
00256   }
00257   OutEdgeIterator & operator=( const OutEdgeIterator<Iter> & other )
00258   {
00259     iter = other.iter;
00260     source = other.source;
00261     return *this;
00262   }
00263 };
00264 
00265 // --------- Directed Out Edges ----------------------
00266 
00267 template< class Property >
00268 class DirectedOutEdges
00269 {
00270 public:
00271   typedef EdgeBase<SimpleEdgePropertyWrapper<Property> > edge_type;
00272   typedef std::pair< EdgeID_t, edge_type > Edge_with_ID_t;
00273   typedef typename std::map< const EdgeID_t, edge_type > map_type;
00274   typedef OutEdgeIterator< typename map_type::iterator > out_iterator;
00275   typedef OutEdgeIterator< typename map_type::const_iterator > const_out_iterator;
00276   typedef user_edge_type< typename map_type::iterator > Edge;
00277   typedef typename map_type::iterator mapiterator;
00278   typedef typename map_type::const_iterator const_mapiterator;
00279 
00280 public:
00281   std::map< const EdgeID_t, edge_type > out_edges;
00282 
00283 public:
00284   DirectedOutEdges() : out_edges() {}
00285 
00286   void clear()
00287   {
00288     out_edges.clear();
00289   }
00290 
00291 /*  void _pgdist_fill_buf( AllToAllBuffer & buf ) const
00292   {
00293     typename std::map< const EdgeID_t, edge_type >::const_iterator it = out_edges.begin();
00294     buf.put( out_edges.size() );
00295     for(; it != out_edges.end() ; it++ )
00296     {
00297       buf.put( &(*it).first, 1 );
00298       buf.put( &(*it).second.other_vertex, 1 );
00299       put_property_into_buffer( (*it).second.prop_wrapper.prop, buf );
00300     }
00301   }
00302   void _pgdist_read_buf( AllToAllBuffer & buf )
00303   {
00304     Edge_with_ID_t tmp;
00305     size_t size;
00306     buf.get( &size, 1 );
00307     for( unsigned int i = 0 ; i < size ; i++ )
00308     {
00309       buf.get( &tmp.first, 1 );
00310       buf.get( &tmp.second.other_vertex, 1 );
00311       get_property_from_buffer( tmp.second.prop_wrapper.prop, buf );
00312       out_edges.insert( tmp );
00313     }
00314     }*/
00315   template< class Tag, class Graph, class DistHelper >
00316   void _pgdist_fill_buf( Tag t, Graph & g, DistHelper & dh, AllToAllBuffer & buf ) const
00317   {
00318     typename std::map< const EdgeID_t, edge_type >::const_iterator it = out_edges.begin();
00319     buf.put( out_edges.size() );
00320     for(; it != out_edges.end() ; it++ )
00321     {
00322       buf.put( &(*it).first, 1 );
00323       buf.put( get_id((*it).second.other_vertex) );
00324       dh.write_proc( (*it).second.other_vertex, buf );
00325       g.dek_known_vertex_counter((*it).second.other_vertex);
00326       put_property_into_buffer( (*it).second.prop_wrapper.prop, buf );
00327     }
00328   }
00329   template< class Tag, class Graph, class DistHelper >
00330   void _pgdist_read_buf( Tag t, Graph & g, DistHelper & dh, AllToAllBuffer & buf )
00331   {
00332     Edge_with_ID_t tmp;
00333     size_t size;
00334     buf.get( &size, 1 );
00335     for( unsigned int i = 0 ; i < size ; i++ )
00336     {
00337       buf.get( &tmp.first, 1 );
00338       VertexID_t v;
00339       buf.get( &v, 1 );
00340       proc_t p = dh.read_proc( buf );
00341       if( p == _libbase.rank() ) p = _libbase.size();
00342       tmp.second.other_vertex = g.ink_known_vertex_counter_and_set_processor( v, p );
00343       get_property_from_buffer( tmp.second.prop_wrapper.prop, buf );
00344       out_edges.insert( tmp );
00345     }
00346   }
00347 
00348   void add( EdgeID_t id, VertexID_t v )
00349   {
00350     out_edges.insert( std::make_pair( id, edge_type( v ) ) );
00351   }
00352 
00353   void add( EdgeID_t id, VertexID_t v, Property & p )
00354   {
00355     out_edges.insert( std::make_pair( id, edge_type( v, p ) ) );
00356   }
00357 
00358     //template< class M, class G >
00359     //friend map_type & get_out_edges( M, VertexID_t, G& );
00360     //friend struct WorkOnEdgeList;
00361 };
00362 
00363 template< class Property >
00364 class DirectedInOutEdges
00365 {
00366 public:
00367   typedef EdgeBase<DoubleSidedEdgePropertyWrapper<Property> > edge_type;
00368   typedef std::pair< EdgeID_t, edge_type > Edge_with_ID_t;
00369   typedef typename std::map< const EdgeID_t, edge_type > map_type;
00370   typedef InEdgeIterator< typename map_type::iterator > in_iterator;
00371   typedef OutEdgeIterator< typename map_type::iterator > out_iterator;
00372   typedef InEdgeIterator< typename map_type::const_iterator > const_in_iterator;
00373   typedef OutEdgeIterator< typename map_type::const_iterator > const_out_iterator;
00374   typedef typename map_type::const_iterator const_mapiterator;
00375   typedef typename map_type::iterator mapiterator;
00376   typedef user_edge_type< typename map_type::iterator > Edge;
00377 
00378 public:
00379   std::map< const EdgeID_t, edge_type > in_edges;
00380   std::map< const EdgeID_t, edge_type > out_edges;
00381 
00382 public:
00383   DirectedInOutEdges() : in_edges(), out_edges() {}
00384 
00385   edge_type & get_edge_reference( EdgeID_t id );
00386   const edge_type & get_edge_reference( EdgeID_t id ) const;
00387   edge_type & get_inedge_reference( EdgeID_t id );
00388   const edge_type & get_inedge_reference( EdgeID_t id ) const;
00389   template< class G, class M >
00390   void remove_edges( G&, M );
00391   template< class G >
00392   void complete_graph_remove_edges( G& );
00393   template< class V, class G, class M, class F >
00394   void remove_edges_if( V, G&, M, F& );
00395   template< class G, class M >
00396   void remove_in_edges( G&, M );
00397   template< class G, class M >
00398   void remove_in_edges( G&, M, AllToAllBuffer& );
00399   void remove_edge( EdgeID_t );
00400   template< class G, class M >
00401   void remove_in_edge( Edge, G&, M );
00402   template< class G, class M >
00403   void remove_out_edge( Edge, G&, M );
00404   template< class G, class M >
00405   void remove_in_edge( mapiterator, G&, M );
00406   template< class G, class M >
00407   void remove_out_edge( mapiterator, G&, M );
00408   template< class G, class M >
00409   void remove_in_edge( Edge, G&, M, AllToAllBuffer& );
00410   template< class G, class M >
00411   void remove_out_edge( Edge, G&, M, AllToAllBuffer& );
00412 
00413   void clear()
00414   {
00415     in_edges.clear();
00416     out_edges.clear();
00417   }
00418 
00419 /*  void _pgdist_fill_buf( AllToAllBuffer & buf ) const
00420   {
00421     buf.put( in_edges.size() );
00422     typename std::map< const EdgeID_t, edge_type >::const_iterator it = in_edges.begin();
00423     for(; it != in_edges.end() ; it++ )
00424     {
00425       buf.put( &(*it).first, 1 );
00426       buf.put( &(*it).second.other_vertex, 1 );
00427       put_property_into_buffer( (*it).second.get_property_reference(), buf );
00428     }
00429     buf.put( out_edges.size() );
00430     it = out_edges.begin();
00431     for(; it != out_edges.end() ; it++ )
00432     {
00433       buf.put( &(*it).first, 1 );
00434       buf.put( &(*it).second.other_vertex, 1 );
00435       put_property_into_buffer( (*it).second.get_property_reference(), buf );
00436     }
00437   }
00438   void _pgdist_read_buf( AllToAllBuffer & buf )
00439   {
00440     Edge_with_ID_t tmp;
00441     size_t size;
00442     buf.get( &size, 1 );
00443     for( size_t i = 0 ; i < size ; i++ )
00444     {
00445       buf.get( &tmp.first, 1 );
00446       buf.get( &tmp.second.other_vertex, 1 );
00447       tmp.second.prop_wrapper.new_property();
00448       get_property_from_buffer( tmp.second.get_property_reference(), buf );
00449       in_edges.insert( tmp );
00450     }
00451     buf.get( &size, 1 );
00452     for( size_t i = 0 ; i < size ; i++ )
00453     {
00454       buf.get( &tmp.first, 1 );
00455       buf.get( &tmp.second.other_vertex, 1 );
00456       tmp.second.prop_wrapper.new_property();
00457       get_property_from_buffer( tmp.second.get_property_reference(), buf );
00458       out_edges.insert( tmp );
00459     }
00460     }*/
00461   template< class Tag, class Graph, class DistHelper >
00462   void _pgdist_fill_buf( Tag t, Graph & g, DistHelper & dh, AllToAllBuffer & buf )
00463   {
00464     buf.put( in_edges.size() );
00465     mapiterator it = in_edges.begin();
00466     for(; it != in_edges.end() ; it++ )
00467     {
00468       buf.put( &(it->first), 1 );
00469       buf.put( get_id(it->second.other_vertex) );
00470       dh.write_proc( it->second.other_vertex, buf );
00471       g.dek_known_vertex_counter(it->second.other_vertex);
00472       put_property_into_buffer( it->second.get_property_reference(), buf );
00473       if( ! g.is_vertex_local( it->second.other_vertex ) )
00474       {
00475         it->second.prop_wrapper.delete_property();
00476       }
00477     }
00478     buf.put( out_edges.size() );
00479     it = out_edges.begin();
00480     for(; it != out_edges.end() ; it++ )
00481     {
00482       buf.put( &(it->first), 1 );
00483       buf.put( get_id(it->second.other_vertex) );
00484       dh.write_proc( it->second.other_vertex, buf );
00485       g.dek_known_vertex_counter(it->second.other_vertex);
00486       put_property_into_buffer( it->second.get_property_reference(), buf );
00487       if( ! g.is_vertex_local( it->second.other_vertex ) )
00488       {
00489         it->second.prop_wrapper.delete_property();
00490       } 
00491     }
00492   }
00493   template< class Tag, class Graph, class DistHelper >
00494   void _pgdist_read_buf( Tag t, Graph & g, DistHelper & dh, AllToAllBuffer & buf )
00495   {
00496     Edge_with_ID_t tmp;
00497     size_t size;
00498     Property trash;
00499     buf.get( &size, 1 );
00500     for( size_t i = 0 ; i < size ; i++ )
00501     {
00502       buf.get( &tmp.first, 1 );
00503       VertexID_t v;
00504       buf.get( &v, 1 );
00505       proc_t p = dh.read_proc( buf );
00506       if( p == _libbase.rank() ) p = _libbase.size();
00507       tmp.second.other_vertex = g.ink_known_vertex_counter_and_set_processor( v, p );
00508       if( g.is_vertex_local( tmp.second.other_vertex ) )
00509       {
00510         get_property_from_buffer( trash, buf );
00511         tmp.second.prop_wrapper.prop = get_property_value( // join with other edge
00512             g.get_property_reference( tmp.second.other_vertex ), t ).get_edge_reference( tmp.first ).prop_wrapper.prop;
00513       }
00514       else
00515       {
00516         tmp.second.prop_wrapper.new_property();
00517         get_property_from_buffer( tmp.second.get_property_reference(), buf );
00518       }
00519       in_edges.insert( tmp );
00520     }
00521     buf.get( &size, 1 );
00522     for( size_t i = 0 ; i < size ; i++ )
00523     {
00524       buf.get( &tmp.first, 1 );
00525       VertexID_t v;
00526       buf.get( &v, 1 );
00527       proc_t p = dh.read_proc( buf );
00528       if( p == _libbase.rank() ) p = _libbase.size();
00529       tmp.second.other_vertex = g.ink_known_vertex_counter_and_set_processor( v, p );
00530       if( g.is_vertex_local( tmp.second.other_vertex ) )
00531       {
00532         get_property_from_buffer( trash, buf );
00533         tmp.second.prop_wrapper.prop = get_property_value( // join with other edge
00534             g.get_property_reference( tmp.second.other_vertex ), t ).get_edge_reference( tmp.first ).prop_wrapper.prop;
00535       }
00536       else
00537       {
00538         tmp.second.prop_wrapper.new_property();
00539         get_property_from_buffer( tmp.second.get_property_reference(), buf );
00540       }
00541       out_edges.insert( tmp );
00542     }
00543   }
00544 
00545   // template< class M, class P, class G >
00546   // friend void add_edge_with_id( M, EdgeID_t, VertexID_t, VertexID_t, P&, G&, AllToAllBuffer& );
00547   // template< class M, class G >
00548   // friend void add_delayed_edges( M, G&, AllToAllBuffer& );
00549 
00550   // template< class M, class G >
00551   // friend map_type & get_out_edges( M, VertexID_t, G& );
00552   // friend struct WorkOnEdgeList;
00553 };
00554 
00555 template< class P >
00556 typename DirectedInOutEdges<P>::edge_type &
00557 DirectedInOutEdges<P>::get_edge_reference( EdgeID_t id )
00558 {
00559   if( out_edges.find( id ) != out_edges.end() )
00560       return (*out_edges.find( id )).second;
00561   return (*in_edges.find( id )).second;
00562 }
00563 
00564 template< class P >
00565 const typename DirectedInOutEdges<P>::edge_type &
00566 DirectedInOutEdges<P>::get_edge_reference( EdgeID_t id ) const
00567 {
00568   if( out_edges.find( id ) != out_edges.end() )
00569       return (*out_edges.find( id )).second;
00570   return (*in_edges.find( id )).second;
00571 }
00572 
00573 template< class P >
00574 typename DirectedInOutEdges<P>::edge_type &
00575 DirectedInOutEdges<P>::get_inedge_reference( EdgeID_t id )
00576 {
00577   return (*in_edges.find( id )).second;
00578 }
00579 
00580 template< class P >
00581 const typename DirectedInOutEdges<P>::edge_type &
00582 DirectedInOutEdges<P>::get_inedge_reference( EdgeID_t id ) const
00583 {
00584   return (*in_edges.find( id )).second;
00585 }
00586 
00587 template< class P>
00588 template< class Graph, class EdgeMap >
00589 void
00590 DirectedInOutEdges<P>::remove_edges( Graph &g, EdgeMap m )
00591 {
00592   mapiterator eit, eitnext;
00593   eit = out_edges.begin();
00594   for(; eit != out_edges.end() ; eit = eitnext )
00595   {
00596     eitnext = eit; eitnext++;
00597     remove_out_edge( eit, g, m );
00598   }
00599   mapiterator eit2, eitnext2;
00600   eit2 = in_edges.begin();
00601   for(; eit2 != in_edges.end() ; eit2 = eitnext2 )
00602   {
00603     eitnext2 = eit2; eitnext2++;
00604     remove_in_edge( eit2, g, m );
00605   }
00606 }
00607 
00608 template< class P>
00609 template< class Graph >
00610 void
00611 DirectedInOutEdges<P>::complete_graph_remove_edges( Graph &g )
00612 {
00613   mapiterator eit, eitnext;
00614   eit = out_edges.begin();
00615   for(; eit != out_edges.end() ; eit = eitnext )
00616   {
00617     eitnext = eit; eitnext++;
00618     (*eit).second.delete_property();
00619     out_edges.erase( eit );
00620   }
00621   mapiterator eit2, eitnext2;
00622   eit2 = in_edges.begin();
00623   for(; eit2 != in_edges.end() ; eit2 = eitnext2 )
00624   {
00625     eitnext2 = eit2; eitnext2++;
00626     if( ! g.is_vertex_local( (*eit2).second.get_v2() ) )
00627         (*eit2).second.delete_property();
00628     in_edges.erase( eit2 );
00629   }
00630 }
00631 
00632 template< class P>
00633 template< class Vertex, class Graph, class EdgeMap, class Function >
00634 void
00635 DirectedInOutEdges<P>::remove_edges_if( Vertex v, Graph &g, EdgeMap m, Function & f )
00636 {
00637   mapiterator eit, eitnext;
00638   eit = out_edges.begin();
00639   for(; eit != out_edges.end() ; eit = eitnext )
00640   {
00641     eitnext = eit; eitnext++;
00642     if( f( Edge( v, eit->second.get_v2(), eit ) ) )
00643     {
00644       remove_out_edge( eit, g, m );
00645     }
00646   }
00647   mapiterator eit2, eitnext2;
00648   eit2 = in_edges.begin();
00649   for(; eit2 != in_edges.end() ; eit2 = eitnext2 )
00650   {
00651     eitnext2 = eit2; eitnext2++;
00652     if( f( Edge( eit2->second.get_v2(), v, eit2 ) ) )
00653     {
00654       remove_in_edge( eit2, g, m );
00655     }
00656   }
00657 }
00658 
00659 template< class P>
00660 void
00661 DirectedInOutEdges<P>::remove_edge( EdgeID_t e )
00662 {
00663   bool prop_deleted = false;
00664   mapiterator outit = out_edges.find(e);
00665   if( outit != out_edges.end() )
00666   {
00667     (*outit).second.prop_wrapper.delete_property();
00668     out_edges.erase( outit );
00669     prop_deleted = true;
00670   }
00671   mapiterator init = in_edges.find(e);
00672   if( init != in_edges.end() )
00673   {
00674     if( prop_deleted == false ) (*init).second.prop_wrapper.delete_property();
00675     in_edges.erase( init );
00676   }
00677 }
00678 
00679 template< class P>
00680 template< class Graph, class EdgeMap >
00681 void
00682 DirectedInOutEdges<P>::remove_in_edges( Graph &g, EdgeMap m )
00683 {
00684   Edge eit, eitnext;
00685   eit = get_in_edges( m, *this ).begin();
00686   for(; eit != in_edges.end() ; eit = eitnext )
00687   {
00688     eitnext = eit; eitnext++;
00689     remove_in_edge( eit, g, m );
00690   }
00691 }
00692 
00693 template< class P>
00694 template< class Graph, class EdgeMap >
00695 void
00696 DirectedInOutEdges<P>::remove_in_edges( Graph &g, EdgeMap m, AllToAllBuffer &buf )
00697 {
00698   Edge eit, eitnext;
00699   eit = get_in_edges( m, *this ).begin();
00700   for(; eit != get_in_edges( m, *this ).end() ; eit = eitnext )
00701   {
00702     eitnext = eit; eitnext++;
00703     remove_in_edge( eit, g, m, buf );
00704   }
00705 }
00706 
00707 template< class P>
00708 template< class Graph, class EdgeMap >
00709 void
00710 DirectedInOutEdges<P>::remove_in_edge( Edge e, Graph &g, EdgeMap m )
00711 {
00712   e.edge->second.delete_property();
00713   if( g.is_vertex_local( e.source ) )
00714   {
00715     get_out_edges( m, e.source, g ).erase( e.edge->first );
00716   }
00717   in_edges.erase( e.edge );
00718 }
00719 
00720 template< class P>
00721 template< class Graph, class EdgeMap >
00722 void
00723 DirectedInOutEdges<P>::remove_out_edge( Edge e, Graph &g, EdgeMap m )
00724 {
00725   e.edge->second.delete_property();
00726   if( g.is_vertex_local( e.target ) )
00727   {
00728     get_in_edges( m, e.target, g ).erase( e.edge->first );
00729   }
00730   out_edges.erase( e.edge );
00731 }
00732 
00733 template< class P>
00734 template< class Graph, class EdgeMap >
00735 void
00736 DirectedInOutEdges<P>::remove_in_edge( mapiterator e, Graph &g, EdgeMap m )
00737 {
00738   e->second.delete_property();
00739   if( g.is_vertex_local( e->second.get_v2() ) )
00740   {
00741     get_out_edges( m, e->second.get_v2(), g ).erase( e->first );
00742   }
00743   in_edges.erase( e );
00744 }
00745 
00746 template< class P>
00747 template< class Graph, class EdgeMap >
00748 void
00749 DirectedInOutEdges<P>::remove_out_edge( mapiterator e, Graph &g, EdgeMap m )
00750 {
00751   e->second.delete_property();
00752   if( g.is_vertex_local( e->second.get_v2() ) )
00753   {
00754     get_in_edges( m, e->second.get_v2(), g ).erase( e->first );
00755   }
00756   out_edges.erase( e );
00757 }
00758 
00759 template< class P>
00760 template< class Graph, class EdgeMap >
00761 void
00762 DirectedInOutEdges<P>::remove_in_edge( Edge e, Graph &g, EdgeMap m, AllToAllBuffer & buf )
00763 {
00764   e.edge->second.prop_wrapper.delete_property();
00765 
00766   if( g.is_vertex_local( e.source ) )
00767   {
00768     get_out_edges( m, e.source, g ).erase( e.edge->first );
00769   }
00770   else
00771   {
00772     buf.put( e.edge->first );
00773     buf.put( e.source );
00774   }
00775   in_edges.erase( e.edge );
00776 }
00777 
00778 template< class P>
00779 template< class Graph, class EdgeMap >
00780 void
00781 DirectedInOutEdges<P>::remove_out_edge( Edge e, Graph &g, EdgeMap m, AllToAllBuffer & buf )
00782 {
00783   (*e).second.prop_wrapper.delete_property();
00784   if( g.is_vertex_local( e.target ) )
00785   {
00786     get_in_edges( m, e.target, g ).erase( e.edge->first );
00787   }
00788   else
00789   {
00790     buf.put( e.edge->first );
00791     buf.put( e.target );
00792   }
00793   out_edges.erase( e.edge );
00794 }
00795 
00796 // --------------- Edge List -----------------------------
00797 
00798 template< class Property >
00799 struct edgelist_kind_traits<Property,directed_out_edges_type>
00800 {
00801   typedef has_out_edges has_out_edges_tag;
00802   typedef has_no_in_edges has_in_edges_tag;
00803   typedef is_not_double_sided_edge is_double_sided_edge_tag;
00804 
00805   typedef DirectedOutEdges<Property> base;
00806 
00807   typedef typename base::out_iterator out_iterator;
00808   typedef typename base::const_iterator const_iterator;
00809   typedef typename base::out_iterator out_iterator;
00810   typedef typename base::const_out_iterator const_out_iterator;
00811   typedef typename base::Edge Edge;
00812   typedef typename base::const_Edge const_Edge;
00813 };
00814 
00815 template< class Property >
00816 struct edgelist_kind_traits<Property,directed_in_out_edges_type>
00817 {
00818   typedef has_out_edges has_out_edges_tag;
00819   typedef has_in_edges has_in_edges_tag;
00820   typedef is_double_sided_edge is_double_sided_edge_tag;
00821 
00822   typedef DirectedInOutEdges<Property> base;
00823 
00824   typedef typename base::in_iterator in_iterator;
00825   typedef typename base::out_iterator out_iterator;
00826   typedef typename base::const_in_iterator const_in_iterator;
00827   typedef typename base::const_out_iterator const_out_iterator;
00828   typedef typename base::Edge Edge;
00829 };
00830 
00831 template< class Property, class EdgeKind >
00832 class EdgeList : public edgelist_kind_traits<Property,EdgeKind>::base
00833 {
00834   typedef EdgeKind edge_kind;
00835   typedef Property property_type;
00836 };
00837 
00838 // ----------- Edge Distribution Traits --------------------
00839 
00840 template< class P, class EdgeKind >
00841 struct property_distribution_traits< EdgeList<P,EdgeKind> >
00842 {
00843   typedef complex_distribution distribution_type;
00844 };
00845 
00846 // ---------- Functions -----------------------------------
00847 
00849 template< class Map, class Graph >
00850 void
00851 copy_properties_out2in( Map m, Graph & g )
00852 {
00853   AllToAllBuffer buf;
00854 
00855   typename Graph::VertexIterator v_it, v_end;
00856   boost::tie( v_it, v_end ) = g.get_local_vertices();
00857 
00858   for(; v_it != v_end ; v_it++ )
00859   {
00860     typename Map::value_type::out_iterator e_it, e_end;
00861     boost::tie( e_it, e_end ) = out_edges( g, *v_it, m );
00862     for(; e_it != e_end ; e_it++ )
00863     {
00864       if( !g.is_vertex_local( (*e_it).second.get_v2() ) )
00865       {
00866         buf.set_proc( g.owning_processor( (*e_it).second.get_v2() ) );
00867         buf.put( (*e_it).second.get_v2() );
00868         buf.put( (*e_it).first );
00869         put_property_into_buffer( (*e_it).second.get_property_reference(), buf );
00870       }
00871     }
00872   }
00873   buf.communicate();
00874 
00875   while( ! buf.is_empty() )
00876   {
00877     EdgeID_t eid;
00878     VertexID_t vid;
00879     buf.get( &vid, 1 );
00880     buf.get( &eid, 1 );
00881     get_property_from_buffer( (*get_in_edges( m, vid, g ).find( eid )).second.get_property_reference(), buf );
00882   }
00883 }
00884 
00886 template< class EdgeMap, class EdgePropertyMap, class Graph >
00887 void
00888 copy_property_in2out( EdgeMap m1, EdgePropertyMap m2, Graph & g )
00889 {
00890   AllToAllBuffer buf;
00891   typename Graph::VertexIterator v_it, v_end;
00892   boost::tie( v_it, v_end ) = g.get_local_vertices();
00893 
00894   for(; v_it != v_end ; v_it++ )
00895   {
00896     typename EdgeMap::in_iterator e_it, e_end;
00897     boost::tie( e_it, e_end ) = in_edges( g, *v_it, m1 );
00898     for(; e_it != e_end ; e_it++ )
00899     {
00900       if( !g.is_vertex_local( get_v2(*e_it) ) )
00901       {
00902         buf.set_proc( g.owning_processor( get_v2(*e_it) ) );
00903         buf.put( get_v2_id(*e_it) );
00904         buf.put( get_edge_id(*e_it) );
00905         buf.put( get( m2, *e_it ) );
00906       }
00907     }
00908   }
00909   buf.communicate();
00910 
00911   while( ! buf.is_empty() )
00912   {
00913     EdgeID_t eid;
00914     VertexID_t vid;
00915     buf.get( &vid, 1 );
00916     buf.get( &eid, 1 );
00917     typename EdgePropertyMap::value_type tmp;
00918     buf.get( &tmp );
00919     put( m2, out_edge( g, vid, eid, m1 ), tmp );
00920   }
00921 }
00922 
00928 template< class Map, class Graph >
00929 void
00930 add_delayed_edges( Map m, Graph & g, AllToAllBuffer & delayed_buf )
00931 {
00932   AllToAllBuffer asking_buf;
00933   typedef typename Map::edge_property_type Property;
00934 
00935   delayed_buf.communicate();
00936 
00937   while( ! delayed_buf.is_empty() )
00938   {
00939     EdgeID_t eid;
00940     VertexID_t v1id, v2id;
00941     typename DoubleSidedEdgePropertyWrapper< Property >::constructor_argument_type prop
00942         = DoubleSidedEdgePropertyWrapper< Property >::static_new_property();
00943     proc_t source_proc = delayed_buf.get( &eid, 1 );
00944     delayed_buf.get( &v1id, 1 );
00945     delayed_buf.get( &v2id, 1 );
00946     get_property_from_buffer( *prop, delayed_buf );
00947     if( g.is_vertex_local( v1id ) )
00948     {
00949       known_vertex_type v2;
00950       if( g.is_vertex_known( v2id ) )
00951            v2 = g.ink_known_vertex_counter( v2id );
00952       else
00953       {
00954           ask_for_position( source_proc, v2id, asking_buf );
00955           v2 = g.make_vertex_known( v2id, size() );
00956       }
00957       get_out_edges( m, v1id, g ).insert( 
00958           make_pair( eid, typename Map::value_type::edge_type(v2,prop) ));
00959     }
00960     if( g.is_vertex_local( v2id ) )
00961     {
00962       known_vertex_type v1;
00963       if( g.is_vertex_known( v1id ) )
00964            v1 = g.ink_known_vertex_counter( v1id );
00965       else
00966       {
00967           ask_for_position( source_proc, v1id, asking_buf );
00968           v1 = g.make_vertex_known( v1id, size() );
00969       }
00970       get_in_edges( m, v2id, g ).insert(
00971           make_pair( eid, typename Map::value_type::edge_type(v1,prop) ));
00972     }
00973   }
00974 
00975   do_asking_for_position( g, asking_buf );
00976 }
00977 
00981 template< class Map, class V1, class V2, class Graph >
00982 EdgeID_t
00983 add_edge( Map m, V1 v1, V2 v2, 
00984           Graph & g, AllToAllBuffer & delayed_buf )
00985 {
00986   EdgeID_t new_ID = g.get_free_edge_id();
00987   add_edge_with_id_worker( m, new_ID, g.get_known_vertex(v1), g.get_known_vertex(v2), Map::edge_property_type(), g, delayed_buf );
00988   return new_ID;
00989 }
00990 
00994 template< class Map, class V1, class V2, class Property, class Graph >
00995 EdgeID_t
00996 add_edge( Map m, V1 v1, V2 v2, Property & prop, 
00997           Graph & g, AllToAllBuffer & delayed_buf )
00998 {
00999   EdgeID_t new_ID = g.get_free_edge_id();
01000   add_edge_with_id_worker( m, new_ID, g.get_known_vertex(v1), g.get_known_vertex(v2), prop, g, delayed_buf );
01001   return new_ID;
01002 }
01003 
01007 template< class Map, class V1, class V2, class Property, class Graph >
01008 inline void
01009 add_edge_with_id( Map m, EdgeID_t new_ID, V1 v1, V2 v2, Property & prop, 
01010           Graph & g, AllToAllBuffer & delayed_buf )
01011 {
01012   add_edge_with_id_worker( m, new_ID, g.get_known_vertex(v1), g.get_known_vertex(v2), prop, g, delayed_buf );
01013 }
01014 
01015 template< class Map, class Property, class Graph >
01016 void
01017 add_edge_with_id_worker( Map m, EdgeID_t new_ID, typename Graph::KnownVertex v1, 
01018                   typename Graph::KnownVertex v2, Property & prop, 
01019                   Graph & g, AllToAllBuffer & delayed_buf )
01020 {
01021   bool v1_is_local;
01022   proc_t v1_lays_on;
01023   typename DoubleSidedEdgePropertyWrapper< Property >::constructor_argument_type prop_pointer;
01024 
01025   if( v1_is_local = g.is_vertex_local( v1 ) )
01026   {
01027     prop_pointer =
01028         DoubleSidedEdgePropertyWrapper< Property >::static_new_property(prop);
01029     get_out_edges( m, v1, g ).insert(
01030         make_pair( new_ID, typename Map::value_type::edge_type(v2,prop_pointer) ));
01031 
01032     g.ink_known_vertex_counter( v2 );
01033   }
01034   else
01035   {
01036     delayed_buf.set_proc( v1_lays_on = g.owning_processor( v1 ) );
01037     delayed_buf.put( new_ID );
01038     delayed_buf.put( get_id(v1) );
01039     delayed_buf.put( get_id(v2) );
01040     put_property_into_buffer( prop, delayed_buf );
01041   }
01042 
01043   if( g.is_vertex_local( v2 ) )
01044   {
01045     if( !v1_is_local )
01046     {
01047       prop_pointer =
01048          DoubleSidedEdgePropertyWrapper< Property >::static_new_property(prop);
01049     }
01050     get_in_edges( m, v2, g ).insert(
01051         make_pair( new_ID, typename Map::value_type::edge_type(v1,prop_pointer) ));
01052 
01053     g.ink_known_vertex_counter( v1 );
01054   }
01055   else if( v1_is_local || v1_lays_on != g.owning_processor( v2 ) )
01056   {
01057     // an edge is _not_ sent twice to the same proc
01058     delayed_buf.set_proc( g.owning_processor( v2 ) );
01059     delayed_buf.put( new_ID );
01060     delayed_buf.put( get_id(v1) );
01061     delayed_buf.put( get_id(v2) );
01062     put_property_into_buffer( prop, delayed_buf );
01063   }
01064 }
01065 
01066 template< class Map, class Graph >
01067 EdgeID_t
01068 add_edge( Map m, VertexID_t v1, VertexID_t v2id, Graph & g )
01069 {
01070     EdgeID_t new_ID = g.get_free_edge_id();
01071 
01072     known_vertex_type v2 = g.ink_known_vertex_counter( v2id );
01073     get( m, v1, g ).add( new_ID, v2 );
01074 
01075     return new_ID;
01076 }
01077 
01078 template< class Map, class V1, class V2, class Property, class Graph >
01079 EdgeID_t
01080 add_edge( Map m, V1 v1, V2 v2, Property & prop, Graph & g )
01081 {
01082   EdgeID_t new_ID = g.get_free_edge_id();
01083   add_edge_with_id( m, new_ID, v1, v2, prop, g );
01084   return new_ID;
01085 }
01086 
01087 template< class Map, class V1, class V2, class Property, class Graph >
01088 inline void
01089 add_edge_with_id( Map m, EdgeID_t new_ID, V1 v1, V2 v2, Property & prop, 
01090           Graph & g )
01091 {
01092   add_edge_with_id_worker( m, new_ID, g.get_known_vertex(v1), g.get_known_vertex(v2), prop, g );
01093 }
01094 
01095 template< class Map, class Property, class Graph >
01096 void
01097 add_edge_with_id_worker( Map m, EdgeID_t new_ID, typename Graph::KnownVertex v1, 
01098                          typename Graph::KnownVertex v2, Property & prop, Graph & g )
01099 {
01100   get( m, v1, g ).add( new_ID, v2, prop );
01101   g.ink_known_vertex_counter( v2 );
01102 }
01103 
01105 template< class Graph, class Vertex, class EdgeMap >
01106 inline pair<typename EdgeMap::in_iterator,
01107     typename EdgeMap::in_iterator>
01108 in_edges( Graph &g, Vertex v, EdgeMap m )
01109 {
01110   typename Graph::VertexProperty & prop = g.get_property_reference(v);
01111   return make_pair( typename EdgeMap::in_iterator( v,
01112                         get_in_edges( m, prop ).begin()),
01113                     typename EdgeMap::in_iterator( v,
01114                         get_in_edges( m, prop ).end()) ); 
01115 }
01116 
01117 template< class EdgeList >
01118 inline pair<typename EdgeList::const_mapiterator, typename EdgeList::const_mapiterator>
01119 in_edges( const EdgeList &edges )
01120 {
01121   return make_pair( typename EdgeList::const_mapiterator(
01122                         edges.in_edges.begin()),
01123                     typename EdgeList::const_mapiterator(
01124                         edges.in_edges.end()) );
01125 }
01126 
01128 template< class Graph, class Vertex, class EdgeMap >
01129 inline typename EdgeMap::Edge
01130 in_edge( Graph &g, Vertex v, EdgeID_t e, EdgeMap m )
01131 {
01132   typename EdgeMap::mapiterator it = get_in_edges( m, v, g ).find( e );
01133   return typename EdgeMap::Edge( it->second.get_v2(), g.get_known_vertex(v), it );
01134 }
01135 
01137 template< class Graph, class Vertex, class EdgeMap >
01138 inline pair< typename EdgeMap::Edge, bool >
01139 in_edge_test( Graph &g, Vertex v, EdgeID_t e, EdgeMap m )
01140 {
01141   typename EdgeMap::mapiterator tmp = get_in_edges( m, v, g ).find( e );
01142   if( tmp != get_in_edges( m, v, g ).end() )
01143       return make_pair( typename EdgeMap::Edge( tmp->second.get_v2(), g.get_known_vertex(v), tmp ), true );
01144   else
01145       return make_pair( typename EdgeMap::Edge( g.get_known_vertex(v), g.get_known_vertex(v), tmp ), false );  
01146 }
01147 
01149 template< class Graph, class Vertex, class EdgeMap >
01150 inline pair<typename EdgeMap::out_iterator,
01151     typename EdgeMap::out_iterator>
01152 out_edges( Graph &g, Vertex v, EdgeMap m )
01153 {
01154   typename Graph::VertexProperty & prop = g.get_property_reference(v);
01155   return make_pair( typename EdgeMap::out_iterator( v,
01156                         get_out_edges( m, prop ).begin()),
01157                     typename EdgeMap::out_iterator( v,
01158                         get_out_edges( m, prop ).end()) ); 
01159 }
01160 
01161 template< class EdgeList >
01162 inline pair<typename EdgeList::const_mapiterator, typename EdgeList::const_mapiterator>
01163 out_edges( const EdgeList &edges )
01164 {
01165   return make_pair( typename EdgeList::const_mapiterator(edges.out_edges.begin()), 
01166                     typename EdgeList::const_mapiterator(edges.out_edges.end()) );
01167 }
01168 
01170 template< class Graph, class Vertex, class EdgeMap >
01171 inline typename EdgeMap::Edge
01172 out_edge( Graph &g, Vertex v, EdgeID_t e, EdgeMap m )
01173 {
01174   typename EdgeMap::mapiterator it = get_out_edges( m, v, g ).find( e );
01175   return typename EdgeMap::Edge( g.get_known_vertex(v), it->second.get_v2(), it );
01176 }
01177 
01179 template< class Graph, class Vertex, class EdgeMap >
01180 inline pair< typename EdgeMap::Edge, bool >
01181 out_edge_test( Graph &g, Vertex v, EdgeID_t e, EdgeMap m )
01182 {
01183   typename EdgeMap::mapiterator tmp = get_out_edges( m, v, g ).find( e );
01184   if( tmp != get_out_edges( m, v, g ).end() )
01185       return make_pair( typename EdgeMap::Edge( g.get_known_vertex(v), tmp->second.get_v2(), tmp ), true );
01186   else
01187       return make_pair( typename EdgeMap::Edge( g.get_known_vertex(v), g.get_known_vertex(v), tmp ), false );  
01188 }
01189 
01191 template< class Graph, class Vertex, class EdgeMap >
01192 inline size_t
01193 out_degree( Graph &g, Vertex v, EdgeMap m )
01194 {
01195   return get_out_edges( m, v, g ).size();
01196 }
01197 
01199 template< class Graph, class Vertex, class EdgeMap >
01200 inline size_t
01201 in_degree( Graph &g, Vertex v, EdgeMap m )
01202 {
01203   return get_in_edges( m, v, g ).size();
01204 }
01205 
01211 template< class Graph, class EdgeMap >
01212 void
01213 remove_delayed_edges( Graph &g, EdgeMap m, AllToAllBuffer &buf )
01214 {
01215   buf.communicate();
01216 
01217   while( ! buf.is_empty() )
01218   {
01219     EdgeID_t e;
01220     VertexID_t v;
01221     buf.get( &e, 1 );
01222     buf.get( &v, 1 );
01223     get( m, v, g ).remove_edge( e );
01224   }
01225 }
01226 
01230 template< class Edge, class Graph, class EdgeMap >
01231 void
01232 remove_edge( Edge &e, Graph &g, EdgeMap m )
01233 {
01234   if( is_out_edge(e) )
01235   {
01236     get( m, source(e,g), g ).remove_out_edge( e, g, m );
01237   }
01238   else
01239   {
01240     get( m, target(e,g), g ).remove_in_edge( e, g, m );
01241   };
01242 }
01243 
01244 template< class Graph, class EdgeMap >
01245 void
01246 remove_edges( Graph &g, EdgeMap m )
01247 {
01248   typename Graph::VertexIterator vit, vend;
01249   boost::tie( vit, vend ) = g.get_local_vertices();
01250   for(; vit != vend ; vit++ )
01251   {
01252     get( m, *vit, g ).complete_graph_remove_edges( g );
01253   }
01254 }
01255 
01256 template< class Graph, class EdgeMap, class Function >
01257 void
01258 remove_edges_if( Graph &g, EdgeMap m, Function &f )
01259 {
01260   typename Graph::VertexIterator vit, vend;
01261   boost::tie( vit, vend ) = g.get_local_vertices();
01262   for(; vit != vend ; vit++ )
01263   {
01264     get( m, *vit, g ).remove_edges_if( *vit, g, m, f );
01265   }
01266 }
01267 
01268 template< class Graph, class Iterator, class EdgeMap >
01269 void
01270 remove_in_edges( Graph &g, Iterator vit, Iterator vend, EdgeMap m )
01271 {
01272   for(; vit != vend ; vit++ )
01273   {
01274     get( m, *vit, g ).remove_in_edges( g, m );
01275   }
01276 }
01277 
01278 template< class Graph, class Iterator, class EdgeMap >
01279 void
01280 remove_in_edges( Graph &g, Iterator vit, Iterator vend, EdgeMap m, AllToAllBuffer &buf )
01281 {
01282   for(; vit != vend ; vit++ )
01283   {
01284     get( m, *vit, g ).remove_in_edges( g, m, buf );
01285   }
01286 }
01287 
01288 template< class Graph, class Iterator, class EdgeMap >
01289 void
01290 remove_out_edges( Graph &g, Iterator vit, Iterator vend, EdgeMap m )
01291 {
01292   for(; vit != vend ; vit++ )
01293   {
01294     get( m, *vit, g ).remove_out_edges( g, m );
01295   }
01296 }
01297 
01301 template< class Graph, class Iterator, class EdgeMap >
01302 void
01303 remove_out_edges( Graph &g, Iterator vit, Iterator vend, EdgeMap m, AllToAllBuffer &buf )
01304 {
01305   for(; vit != vend ; vit++ )
01306   {
01307     get( m, *vit, g ).remove_out_edges( g, m, buf );
01308   }
01309 }
01310 
01311 }
01312 
01313 #endif // _PG_EDGES_HPP_

Generated on Sun Feb 29 05:14:24 2004 for ParGraph by doxygen1.3-rc3