[Lemon-commits] [lemon_svn] deba: r2593 - in hugo/trunk: lemon lemon/bits test

Lemon SVN svn at lemon.cs.elte.hu
Mon Nov 6 20:53:46 CET 2006


Author: deba
Date: Wed Mar  1 11:25:30 2006
New Revision: 2593

Modified:
   hugo/trunk/lemon/bits/edge_set_extender.h
   hugo/trunk/lemon/bits/graph_extender.h
   hugo/trunk/lemon/graph_adaptor.h
   hugo/trunk/lemon/list_graph.h
   hugo/trunk/lemon/ugraph_adaptor.h
   hugo/trunk/test/graph_adaptor_test.cc

Log:
The graph adadptors can be alteration observed.
In most cases it uses the adapted graph alteration notifiers.
Only special case is now the UndirGraphAdaptor, where
we have to proxy the signals from the graph.

The SubBidirGraphAdaptor is removed, because it doest not
gives more feature than the EdgeSubGraphAdaptor<UndirGraphAdaptor<Graph>>.

The ResGraphAdaptor is based on this composition.




Modified: hugo/trunk/lemon/bits/edge_set_extender.h
==============================================================================
--- hugo/trunk/lemon/bits/edge_set_extender.h	(original)
+++ hugo/trunk/lemon/bits/edge_set_extender.h	Wed Mar  1 11:25:30 2006
@@ -68,6 +68,8 @@
 
   public:
 
+    using Parent::getNotifier;
+
     /// \brief Gives back the edge alteration notifier.
     ///
     /// Gives back the edge alteration notifier.
@@ -322,6 +324,8 @@
     mutable UEdgeNotifier uedge_notifier;
 
   public:
+
+    using Parent::getNotifier;
     
     EdgeNotifier& getNotifier(Edge) const {
       return edge_notifier;

Modified: hugo/trunk/lemon/bits/graph_extender.h
==============================================================================
--- hugo/trunk/lemon/bits/graph_extender.h	(original)
+++ hugo/trunk/lemon/bits/graph_extender.h	Wed Mar  1 11:25:30 2006
@@ -1568,7 +1568,7 @@
   protected:
 
     template <typename _Value>
-    class NodeMapBase : public NodeNotifier::ObserverBase {
+    class NodeMapBase {
     public:
       typedef BpUGraphExtender Graph;
 
@@ -1590,21 +1590,10 @@
       typedef True ReferenceMapTag;
 
       NodeMapBase(const Graph& _g) 
-	: graph(&_g), bNodeMap(_g), aNodeMap(_g) {
-	NodeNotifier::ObserverBase::attach(_g.getNotifier(Node()));
-      }
+	: aNodeMap(_g), bNodeMap(_g) {}
       NodeMapBase(const Graph& _g, const _Value& _v) 
-	: graph(&_g), bNodeMap(_g, _v), 
-	  aNodeMap(_g, _v) {
-	NodeNotifier::ObserverBase::attach(_g.getNotifier(Node()));
-      }
+	: aNodeMap(_g, _v), bNodeMap(_g, _v) {}
 
-      virtual ~NodeMapBase() {      
-	if (NodeNotifier::ObserverBase::attached()) {
-          NodeNotifier::ObserverBase::detach();
-	}
-      }
-    
       ConstReference operator[](const Key& node) const {
 	if (Parent::aNode(node)) {
 	  return aNodeMap[node];
@@ -1629,21 +1618,13 @@
 	}
       }
 
-    protected:
-      
-      virtual void add(const Node&) {}
-      virtual void add(const std::vector<Node>&) {}
-      virtual void erase(const Node&) {}
-      virtual void erase(const std::vector<Node>&) {}
-      virtual void clear() {}
-      virtual void build() {}
+      const Graph* getGraph() const {
+        return aNodeMap.getGraph();
+      }
 
-      const Graph* getGraph() const { return graph; }
-      
     private:
-      const Graph* graph;
-      BNodeMap<_Value> bNodeMap;
       ANodeMap<_Value> aNodeMap;
+      BNodeMap<_Value> bNodeMap;
     };
     
   public:

Modified: hugo/trunk/lemon/graph_adaptor.h
==============================================================================
--- hugo/trunk/lemon/graph_adaptor.h	(original)
+++ hugo/trunk/lemon/graph_adaptor.h	Wed Mar  1 11:25:30 2006
@@ -113,25 +113,45 @@
     
     int id(const Node& v) const { return graph->id(v); }
     int id(const Edge& e) const { return graph->id(e); }
+
+    int maxNodeId() const {
+      return graph->maxNodeId();
+    }
+
+    int maxEdgeId() const {
+      return graph->maxEdgeId();
+    }
+
+    typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
+
+    NodeNotifier& getNotifier(Node) const {
+      return graph->getNotifier(Node());
+    } 
+
+    typedef typename ItemSetTraits<Graph, Edge>::ItemNotifier EdgeNotifier;
+
+    EdgeNotifier& getNotifier(Edge) const {
+      return graph->getNotifier(Edge());
+    } 
     
     template <typename _Value>
     class NodeMap : public _Graph::template NodeMap<_Value> {
     public:
       typedef typename _Graph::template NodeMap<_Value> Parent;
-      explicit NodeMap(const GraphAdaptorBase<_Graph>& gw) 
-	: Parent(*gw.graph) { }
-      NodeMap(const GraphAdaptorBase<_Graph>& gw, const _Value& value)
-	: Parent(*gw.graph, value) { }
+      explicit NodeMap(const GraphAdaptorBase<_Graph>& ga) 
+	: Parent(*ga.graph) { }
+      NodeMap(const GraphAdaptorBase<_Graph>& ga, const _Value& value)
+	: Parent(*ga.graph, value) { }
     };
 
     template <typename _Value>
     class EdgeMap : public _Graph::template EdgeMap<_Value> {
     public:
       typedef typename _Graph::template EdgeMap<_Value> Parent;
-      explicit EdgeMap(const GraphAdaptorBase<_Graph>& gw) 
-	: Parent(*gw.graph) { }
-      EdgeMap(const GraphAdaptorBase<_Graph>& gw, const _Value& value)
-	: Parent(*gw.graph, value) { }
+      explicit EdgeMap(const GraphAdaptorBase<_Graph>& ga) 
+	: Parent(*ga.graph) { }
+      EdgeMap(const GraphAdaptorBase<_Graph>& ga, const _Value& value)
+	: Parent(*ga.graph, value) { }
     };
 
   };
@@ -149,6 +169,17 @@
     explicit GraphAdaptor(Graph& _graph) { setGraph(_graph); }
   };
 
+  /// \brief Just gives back a graph adaptor
+  ///
+  /// Just gives back a graph adaptor which 
+  /// should be provide original graph
+  template<typename Graph>
+  GraphAdaptor<const Graph>
+  graphAdaptor(const Graph& graph) {
+    return GraphAdaptor<const Graph>(graph);
+  }
+
+
   template <typename _Graph>
   class RevGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
   public:
@@ -168,6 +199,13 @@
 
     Node source(const Edge& e) const { return Parent::target(e); }
     Node target(const Edge& e) const { return Parent::source(e); }
+
+    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
+    Edge findEdge(const Node& source, const Node& target, 
+		  const Edge& prev = INVALID) {
+      return Parent::findEdge(target, source, prev);
+    }
+
   };
     
 
@@ -184,7 +222,7 @@
   ///\endcode
   /// then
   ///\code
-  /// RevGraphAdaptor<ListGraph> gw(g);
+  /// RevGraphAdaptor<ListGraph> ga(g);
   ///\endcode
   ///implements the graph obtained from \c g by 
   /// reversing the orientation of its edges.
@@ -202,7 +240,15 @@
     explicit RevGraphAdaptor(_Graph& _graph) { setGraph(_graph); }
   };
 
-  
+  /// \brief Just gives back a reverse graph adaptor
+  ///
+  /// Just gives back a reverse graph adaptor
+  template<typename Graph>
+  RevGraphAdaptor<const Graph>
+  revGraphAdaptor(const Graph& graph) {
+    return RevGraphAdaptor<const Graph>(graph);
+  }
+
   template <typename _Graph, typename NodeFilterMap, 
 	    typename EdgeFilterMap, bool checked = true>
   class SubGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
@@ -315,9 +361,21 @@
     ///
     bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; }
 
-    typedef False FindEdgeTag;
     typedef False NodeNumTag;
     typedef False EdgeNumTag;
+
+    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
+    Edge findEdge(const Node& source, const Node& target, 
+		  const Edge& prev = INVALID) {
+      if (!(*node_filter_map)[source] || !(*node_filter_map)[target]) {
+        return INVALID;
+      }
+      Edge edge = Parent::findEdge(source, target, prev);
+      while (edge != INVALID && !(*edge_filter_map)[edge]) {
+        edge = Parent::findEdge(source, target, edge);
+      }
+      return edge;
+    }
   };
 
   template <typename _Graph, typename NodeFilterMap, typename EdgeFilterMap>
@@ -422,9 +480,21 @@
     ///
     bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; }
 
-    typedef False FindEdgeTag;
     typedef False NodeNumTag;
     typedef False EdgeNumTag;
+
+    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
+    Edge findEdge(const Node& source, const Node& target, 
+		  const Edge& prev = INVALID) {
+      if (!(*node_filter_map)[source] || !(*node_filter_map)[target]) {
+        return INVALID;
+      }
+      Edge edge = Parent::findEdge(source, target, prev);
+      while (edge != INVALID && !(*edge_filter_map)[edge]) {
+        edge = Parent::findEdge(source, target, edge);
+      }
+      return edge;
+    }
   };
 
   /// \brief A graph adaptor for hiding nodes and edges from a graph.
@@ -468,11 +538,11 @@
   /// nm.set(u, false);
   /// Graph::EdgeMap<bool> em(g, true);
   /// em.set(e, false);
-  /// typedef SubGraphAdaptor<Graph, Graph::NodeMap<bool>, Graph::EdgeMap<bool> > SubGW;
-  /// SubGW gw(g, nm, em);
-  /// for (SubGW::NodeIt n(gw); n!=INVALID; ++n) std::cout << g.id(n) << std::endl;
+  /// typedef SubGraphAdaptor<Graph, Graph::NodeMap<bool>, Graph::EdgeMap<bool> > SubGA;
+  /// SubGA ga(g, nm, em);
+  /// for (SubGA::NodeIt n(ga); n!=INVALID; ++n) std::cout << g.id(n) << std::endl;
   /// std::cout << ":-)" << std::endl;
-  /// for (SubGW::EdgeIt e(gw); e!=INVALID; ++e) std::cout << g.id(e) << std::endl;
+  /// for (SubGA::EdgeIt e(ga); e!=INVALID; ++e) std::cout << g.id(e) << std::endl;
   ///\endcode
   /// The output of the above code is the following.
   ///\code
@@ -480,7 +550,7 @@
   /// :-)
   /// 1
   ///\endcode
-  /// Note that \c n is of type \c SubGW::NodeIt, but it can be converted to
+  /// Note that \c n is of type \c SubGA::NodeIt, but it can be converted to
   /// \c Graph::Node that is why \c g.id(n) can be applied.
   /// 
   /// For other examples see also the documentation of NodeSubGraphAdaptor and 
@@ -508,6 +578,41 @@
     }
   };
 
+  /// \brief Just gives back a sub graph adaptor
+  ///
+  /// Just gives back a sub graph adaptor
+  template<typename Graph, typename NodeFilterMap, typename EdgeFilterMap>
+  SubGraphAdaptor<const Graph, NodeFilterMap, EdgeFilterMap>
+  subGraphAdaptor(const Graph& graph, 
+                   NodeFilterMap& nfm, EdgeFilterMap& efm) {
+    return SubGraphAdaptor<const Graph, NodeFilterMap, EdgeFilterMap>
+      (graph, nfm, efm);
+  }
+
+  template<typename Graph, typename NodeFilterMap, typename EdgeFilterMap>
+  SubGraphAdaptor<const Graph, const NodeFilterMap, EdgeFilterMap>
+  subGraphAdaptor(const Graph& graph, 
+                   NodeFilterMap& nfm, EdgeFilterMap& efm) {
+    return SubGraphAdaptor<const Graph, const NodeFilterMap, EdgeFilterMap>
+      (graph, nfm, efm);
+  }
+
+  template<typename Graph, typename NodeFilterMap, typename EdgeFilterMap>
+  SubGraphAdaptor<const Graph, NodeFilterMap, const EdgeFilterMap>
+  subGraphAdaptor(const Graph& graph, 
+                   NodeFilterMap& nfm, EdgeFilterMap& efm) {
+    return SubGraphAdaptor<const Graph, NodeFilterMap, const EdgeFilterMap>
+      (graph, nfm, efm);
+  }
+
+  template<typename Graph, typename NodeFilterMap, typename EdgeFilterMap>
+  SubGraphAdaptor<const Graph, const NodeFilterMap, const EdgeFilterMap>
+  subGraphAdaptor(const Graph& graph, 
+                   NodeFilterMap& nfm, EdgeFilterMap& efm) {
+    return SubGraphAdaptor<const Graph, const NodeFilterMap, 
+      const EdgeFilterMap>(graph, nfm, efm);
+  }
+
 
 
   ///\brief An adaptor for hiding nodes from a graph.
@@ -533,6 +638,11 @@
 			    ConstMap<typename Graph::Edge,bool> > Parent;
   protected:
     ConstMap<typename Graph::Edge, bool> const_true_map;
+
+    NodeSubGraphAdaptor() : const_true_map(true) {
+      Parent::setEdgeFilterMap(const_true_map);
+    }
+
   public:
     NodeSubGraphAdaptor(Graph& _graph, NodeFilterMap& _node_filter_map) : 
       Parent(), const_true_map(true) { 
@@ -543,6 +653,21 @@
   };
 
 
+  /// \brief Just gives back a node sub graph adaptor
+  ///
+  /// Just gives back a node sub graph adaptor
+  template<typename Graph, typename NodeFilterMap>
+  NodeSubGraphAdaptor<const Graph, NodeFilterMap>
+  nodeSubGraphAdaptor(const Graph& graph, NodeFilterMap& nfm) {
+    return NodeSubGraphAdaptor<const Graph, NodeFilterMap>(graph, nfm);
+  }
+
+  template<typename Graph, typename NodeFilterMap>
+  NodeSubGraphAdaptor<const Graph, const NodeFilterMap>
+  nodeSubGraphAdaptor(const Graph& graph, const NodeFilterMap& nfm) {
+    return NodeSubGraphAdaptor<const Graph, const NodeFilterMap>(graph, nfm);
+  }
+
   ///\brief An adaptor for hiding edges from a graph.
   ///
   ///\warning Graph adaptors are in even more experimental state
@@ -630,8 +755,8 @@
   ///  TightEdgeFilter;
   ///TightEdgeFilter tight_edge_filter(g, dijkstra.distMap(), length);
   ///
-  ///typedef EdgeSubGraphAdaptor<Graph, TightEdgeFilter> SubGW;
-  ///SubGW gw(g, tight_edge_filter);
+  ///typedef EdgeSubGraphAdaptor<Graph, TightEdgeFilter> SubGA;
+  ///SubGA ga(g, tight_edge_filter);
   ///\endcode
   ///Then, the maximum nimber of edge-disjoint \c s-\c t paths are computed 
   ///with a max flow algorithm Preflow.
@@ -639,8 +764,8 @@
   ///ConstMap<Edge, int> const_1_map(1);
   ///Graph::EdgeMap<int> flow(g, 0);
   ///
-  ///Preflow<SubGW, int, ConstMap<Edge, int>, Graph::EdgeMap<int> > 
-  ///  preflow(gw, s, t, const_1_map, flow);
+  ///Preflow<SubGA, int, ConstMap<Edge, int>, Graph::EdgeMap<int> > 
+  ///  preflow(ga, s, t, const_1_map, flow);
   ///preflow.run();
   ///\endcode
   ///Last, the output is:
@@ -688,6 +813,11 @@
 			    EdgeFilterMap, false> Parent;
   protected:
     ConstMap<typename Graph::Node, bool> const_true_map;
+
+    EdgeSubGraphAdaptor() : const_true_map(true) {
+      Parent::setNodeFilterMap(const_true_map);
+    }
+
   public:
     EdgeSubGraphAdaptor(Graph& _graph, EdgeFilterMap& _edge_filter_map) : 
       Parent(), const_true_map(true) { 
@@ -697,462 +827,382 @@
     }
   };
 
-  template <typename _Graph>
+  /// \brief Just gives back an edge sub graph adaptor
+  ///
+  /// Just gives back an edge sub graph adaptor
+  template<typename Graph, typename EdgeFilterMap>
+  EdgeSubGraphAdaptor<const Graph, EdgeFilterMap>
+  edgeSubGraphAdaptor(const Graph& graph, EdgeFilterMap& efm) {
+    return EdgeSubGraphAdaptor<const Graph, EdgeFilterMap>(graph, efm);
+  }
+
+  template<typename Graph, typename EdgeFilterMap>
+  EdgeSubGraphAdaptor<const Graph, const EdgeFilterMap>
+  edgeSubGraphAdaptor(const Graph& graph, const EdgeFilterMap& efm) {
+    return EdgeSubGraphAdaptor<const Graph, const EdgeFilterMap>(graph, efm);
+  }
+
+  template <typename _Graph, typename Enable = void>
   class UndirGraphAdaptorBase : 
     public UGraphBaseExtender<GraphAdaptorBase<_Graph> > {
   public:
     typedef _Graph Graph;
     typedef UGraphBaseExtender<GraphAdaptorBase<_Graph> > Parent;
+
   protected:
-    UndirGraphAdaptorBase() : Parent() { }
+
+    UndirGraphAdaptorBase() : Parent() {}
+
   public:
+
     typedef typename Parent::UEdge UEdge;
     typedef typename Parent::Edge Edge;
+
     
-    template <typename T>
+    template <typename _Value>
     class EdgeMap {
-    protected:
-      const UndirGraphAdaptorBase<_Graph>* g;
-      template <typename TT> friend class EdgeMap;
-      typename _Graph::template EdgeMap<T> forward_map, backward_map; 
+    private:
+      
+      typedef typename _Graph::template EdgeMap<_Value> MapImpl;
+      
     public:
-      typedef T Value;
+
+      typedef typename MapTraits<MapImpl>::ReferenceMapTag ReferenceMapTag;
+
+      typedef _Value Value;
       typedef Edge Key;
       
-      EdgeMap(const UndirGraphAdaptorBase<_Graph>& _g) : g(&_g), 
-	forward_map(*(g->graph)), backward_map(*(g->graph)) { }
+      EdgeMap(const UndirGraphAdaptorBase<_Graph>& _g) :
+	forward_map(*(_g.graph)), backward_map(*(_g.graph)) {}
 
-      EdgeMap(const UndirGraphAdaptorBase<_Graph>& _g, T a) : g(&_g), 
-	forward_map(*(g->graph), a), backward_map(*(g->graph), a) { }
+      EdgeMap(const UndirGraphAdaptorBase<_Graph>& _g, const Value& a) 
+        : forward_map(*(_g.graph), a), backward_map(*(_g.graph), a) {}
       
-      void set(Edge e, T a) { 
-	if (g->direction(e)) 
+      void set(const Edge& e, const Value& a) { 
+	if (Parent::direction(e)) {
 	  forward_map.set(e, a); 
-	else 
-	  backward_map.set(e, a); 
+        } else { 
+	  backward_map.set(e, a);
+        } 
       }
 
-      T operator[](Edge e) const { 
-	if (g->direction(e)) 
+      typename MapTraits<MapImpl>::ConstReturnValue operator[](Edge e) const { 
+	if (Parent::direction(e)) {
 	  return forward_map[e]; 
-	else 
+	} else { 
+	  return backward_map[e]; 
+        }
+      }
+
+      typename MapTraits<MapImpl>::ReturnValue operator[](Edge e) { 
+	if (Parent::direction(e)) {
+	  return forward_map[e]; 
+	} else { 
 	  return backward_map[e]; 
+        }
       }
+
+    protected:
+
+      MapImpl forward_map, backward_map; 
+
     };
         
-    template <typename T>
-    class UEdgeMap {
-      template <typename TT> friend class UEdgeMap;
-      typename _Graph::template EdgeMap<T> map; 
+    template <typename _Value>
+    class UEdgeMap : public _Graph::template EdgeMap<_Value> {
     public:
-      typedef T Value;
-      typedef UEdge Key;
-      
-      UEdgeMap(const UndirGraphAdaptorBase<_Graph>& g) : 
-	map(*(g.graph)) { }
 
-      UEdgeMap(const UndirGraphAdaptorBase<_Graph>& g, T a) : 
-	map(*(g.graph), a) { }
-      
-      void set(UEdge e, T a) { 
-	map.set(e, a); 
-      }
+      typedef typename _Graph::template EdgeMap<_Value> Parent; 
 
-      T operator[](UEdge e) const { 
-	return map[e]; 
-      }
+      UEdgeMap(const UndirGraphAdaptorBase<_Graph>& g) 
+        : Parent(*(g.graph)) {}
+
+      UEdgeMap(const UndirGraphAdaptorBase<_Graph>& g, const _Value& a) 
+        : Parent(*(g.graph), a) {}
+      
     };
       
   };
 
-  ///\brief An undirected graph is made from a directed graph by an adaptor
-  ///\ingroup graph_adaptors
-  ///
-  /// Undocumented, untested!!!
-  /// If somebody knows nice demo application, let's polulate it.
-  /// 
-  /// \author Marton Makai
-  template<typename _Graph>
-  class UndirGraphAdaptor : 
-    public UGraphAdaptorExtender<
-    UndirGraphAdaptorBase<_Graph> > {
+  template <typename _Graph>
+  class UndirGraphAdaptorBase<
+    _Graph, typename enable_if<
+    typename _Graph::EdgeNotifier::Notifier>::type > 
+      : public UGraphBaseExtender<GraphAdaptorBase<_Graph> > {
   public:
+
     typedef _Graph Graph;
-    typedef UGraphAdaptorExtender<
-      UndirGraphAdaptorBase<_Graph> > Parent;
+    typedef UGraphBaseExtender<GraphAdaptorBase<_Graph> > Parent;
+
   protected:
-    UndirGraphAdaptor() { }
-  public:
-    UndirGraphAdaptor(_Graph& _graph) { 
-      setGraph(_graph);
+
+    UndirGraphAdaptorBase() 
+      : Parent(), edge_notifier(), edge_notifier_proxy(edge_notifier) {}
+
+    void setGraph(_Graph& graph) {
+      Parent::setGraph(graph);
+      edge_notifier_proxy.setUEdgeNotifier(graph.getNotifier(UEdge()));
     }
-  };
 
-  
-  template <typename _Graph, 
-	    typename ForwardFilterMap, typename BackwardFilterMap>
-  class SubBidirGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
   public:
-    typedef _Graph Graph;
-    typedef GraphAdaptorBase<_Graph> Parent;
-  protected:
-    ForwardFilterMap* forward_filter;
-    BackwardFilterMap* backward_filter;
-    SubBidirGraphAdaptorBase() : Parent(), 
-				 forward_filter(0), backward_filter(0) { }
 
-    void setForwardFilterMap(ForwardFilterMap& _forward_filter) {
-      forward_filter=&_forward_filter;
-    }
-    void setBackwardFilterMap(BackwardFilterMap& _backward_filter) {
-      backward_filter=&_backward_filter;
+    ~UndirGraphAdaptorBase() {
+      getNotifier(Edge()).clear();
     }
 
-  public:
-//     SubGraphAdaptorBase(Graph& _graph, 
-// 			NodeFilterMap& _node_filter_map, 
-// 			EdgeFilterMap& _edge_filter_map) : 
-//       Parent(&_graph), 
-//       node_filter_map(&node_filter_map), 
-//       edge_filter_map(&edge_filter_map) { }
 
-    typedef typename Parent::Node Node;
-    typedef typename _Graph::Edge GraphEdge;
-    template <typename T> class EdgeMap;
-    // SubBidirGraphAdaptorBase<..., ..., ...>::Edge is inherited from 
-    // _Graph::Edge. It contains an extra bool flag which is true 
-    // if and only if the 
-    // edge is the backward version of the original edge.
-    class Edge : public _Graph::Edge {
-      friend class SubBidirGraphAdaptorBase<
-	Graph, ForwardFilterMap, BackwardFilterMap>;
-      template<typename T> friend class EdgeMap;
-    protected:
-      bool backward; //true, iff backward
-    public:
-      Edge() { }
-      // \todo =false is needed, or causes problems?
-      // If \c _backward is false, then we get an edge corresponding to the 
-      // original one, otherwise its oppositely directed pair is obtained.
-      Edge(const typename _Graph::Edge& e, bool _backward/*=false*/) : 
-	_Graph::Edge(e), backward(_backward) { }
-      Edge(Invalid i) : _Graph::Edge(i), backward(true) { }
-      bool operator==(const Edge& v) const { 
-	return (this->backward==v.backward && 
-		static_cast<typename _Graph::Edge>(*this)==
-		static_cast<typename _Graph::Edge>(v));
-      } 
-      bool operator!=(const Edge& v) const { 
-	return (this->backward!=v.backward || 
-		static_cast<typename _Graph::Edge>(*this)!=
-		static_cast<typename _Graph::Edge>(v));
-      }
-    };
+    typedef typename Parent::UEdge UEdge;
+    typedef typename Parent::Edge Edge;
 
-    void first(Node& i) const { 
-      Parent::first(i); 
-    }
+    typedef typename Parent::EdgeNotifier UEdgeNotifier;
 
-    void first(Edge& i) const { 
-      Parent::first(i); 
-      i.backward=false;
-      while (*static_cast<GraphEdge*>(&i)!=INVALID && 
-	     !(*forward_filter)[i]) Parent::next(i);
-      if (*static_cast<GraphEdge*>(&i)==INVALID) {
-	Parent::first(i); 
-	i.backward=true;
-	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
-	       !(*backward_filter)[i]) Parent::next(i);
-      }
-    }
+    using Parent::getNotifier;
 
-    void firstIn(Edge& i, const Node& n) const { 
-      Parent::firstIn(i, n); 
-      i.backward=false;
-      while (*static_cast<GraphEdge*>(&i)!=INVALID && 
-	     !(*forward_filter)[i]) Parent::nextIn(i);
-      if (*static_cast<GraphEdge*>(&i)==INVALID) {
-	Parent::firstOut(i, n); 
-	i.backward=true;
-	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
-	       !(*backward_filter)[i]) Parent::nextOut(i);
-      }
-    }
+    typedef AlterationNotifier<Edge> EdgeNotifier;
+    EdgeNotifier& getNotifier(Edge) const { return edge_notifier; }
 
-    void firstOut(Edge& i, const Node& n) const { 
-      Parent::firstOut(i, n); 
-      i.backward=false;
-      while (*static_cast<GraphEdge*>(&i)!=INVALID && 
-	     !(*forward_filter)[i]) Parent::nextOut(i);
-      if (*static_cast<GraphEdge*>(&i)==INVALID) {
-	Parent::firstIn(i, n); 
-	i.backward=true;
-	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
-	       !(*backward_filter)[i]) Parent::nextIn(i);
-      }
-    }
+  protected:
 
-    void next(Node& i) const { 
-      Parent::next(i); 
-    }
+    class NotifierProxy : public UEdgeNotifier::ObserverBase {
+    public:
 
-    void next(Edge& i) const { 
-      if (!(i.backward)) {
-	Parent::next(i);
-	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
-	       !(*forward_filter)[i]) Parent::next(i);
-	if (*static_cast<GraphEdge*>(&i)==INVALID) {
-	  Parent::first(i); 
-	  i.backward=true;
-	  while (*static_cast<GraphEdge*>(&i)!=INVALID && 
-		 !(*backward_filter)[i]) Parent::next(i);
-	}
-      } else {
-	Parent::next(i);
-	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
-	       !(*backward_filter)[i]) Parent::next(i);
+      typedef typename UEdgeNotifier::ObserverBase Parent;
+      typedef UndirGraphAdaptorBase AdaptorBase;
+      
+      NotifierProxy(EdgeNotifier& _edge_notifier)
+        : Parent(), edge_notifier(_edge_notifier) {
       }
-    }
 
-    void nextIn(Edge& i) const { 
-      if (!(i.backward)) {
-	Node n=Parent::target(i);
-	Parent::nextIn(i);
-	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
-	       !(*forward_filter)[i]) Parent::nextIn(i);
-	if (*static_cast<GraphEdge*>(&i)==INVALID) {
-	  Parent::firstOut(i, n); 
-	  i.backward=true;
-	  while (*static_cast<GraphEdge*>(&i)!=INVALID && 
-		 !(*backward_filter)[i]) Parent::nextOut(i);
-	}
-      } else {
-	Parent::nextOut(i);
-	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
-	       !(*backward_filter)[i]) Parent::nextOut(i);
+      virtual ~NotifierProxy() {
+        if (Parent::attached()) {
+          Parent::detach();
+        }
       }
-    }
 
-    void nextOut(Edge& i) const { 
-      if (!(i.backward)) {
-	Node n=Parent::source(i);
-	Parent::nextOut(i);
-	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
-	       !(*forward_filter)[i]) Parent::nextOut(i);
-	if (*static_cast<GraphEdge*>(&i)==INVALID) {
-	  Parent::firstIn(i, n); 
-	  i.backward=true;
-	  while (*static_cast<GraphEdge*>(&i)!=INVALID && 
-		 !(*backward_filter)[i]) Parent::nextIn(i);
-	}
-      } else {
-	Parent::nextIn(i);
-	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
-	       !(*backward_filter)[i]) Parent::nextIn(i);
+      void setUEdgeNotifier(UEdgeNotifier& _uedge_notifier) {
+        Parent::attach(_uedge_notifier);
       }
-    }
-
-    Node source(Edge e) const { 
-      return ((!e.backward) ? this->graph->source(e) : this->graph->target(e)); }
-    Node target(Edge e) const { 
-      return ((!e.backward) ? this->graph->target(e) : this->graph->source(e)); }
 
-    /// Gives back the opposite edge.
-
-    ///\e
-    ///
-    Edge opposite(const Edge& e) const { 
-      Edge f=e;
-      f.backward=!f.backward;
-      return f;
-    }
+      
+    protected:
 
-    ///\e
+      virtual void add(const UEdge& uedge) {
+        std::vector<Edge> edges;
+        edges.push_back(AdaptorBase::Parent::direct(uedge, true));
+        edges.push_back(AdaptorBase::Parent::direct(uedge, false));
+        edge_notifier.add(edges);
+      }
+      virtual void add(const std::vector<UEdge>& uedges) {
+        std::vector<Edge> edges;
+        for (int i = 0; i < (int)uedges.size(); ++i) { 
+          edges.push_back(AdaptorBase::Parent::direct(uedges[i], true));
+          edges.push_back(AdaptorBase::Parent::direct(uedges[i], false));
+        }
+        edge_notifier.add(edges);
+      }
+      virtual void erase(const UEdge& uedge) {
+        std::vector<Edge> edges;
+        edges.push_back(AdaptorBase::Parent::direct(uedge, true));
+        edges.push_back(AdaptorBase::Parent::direct(uedge, false));
+        edge_notifier.erase(edges);
+      }
+      virtual void erase(const std::vector<UEdge>& uedges) {
+        std::vector<Edge> edges;
+        for (int i = 0; i < (int)uedges.size(); ++i) { 
+          edges.push_back(AdaptorBase::Parent::direct(uedges[i], true));
+          edges.push_back(AdaptorBase::Parent::direct(uedges[i], false));
+        }
+        edge_notifier.erase(edges);
+      }
+      virtual void build() {
+        edge_notifier.build();
+      }
+      virtual void clear() {
+        edge_notifier.clear();
+      }
 
-    /// \warning This is a linear time operation and works only if 
-    /// \c Graph::EdgeIt is defined.
-    /// \todo hmm
-    int edgeNum() const { 
-      int i=0;
-      Edge e;
-      for (first(e); e!=INVALID; next(e)) ++i;
-      return i; 
-    }
+      EdgeNotifier& edge_notifier;
+    };
 
-    bool forward(const Edge& e) const { return !e.backward; }
-    bool backward(const Edge& e) const { return e.backward; }
 
-    ///\e
+    mutable EdgeNotifier edge_notifier;
+    NotifierProxy edge_notifier_proxy;
 
-    /// \c SubBidirGraphAdaptorBase<..., ..., ...>::EdgeMap contains two 
-    /// _Graph::EdgeMap one for the forward edges and 
-    /// one for the backward edges.
-    template <typename T>
+  public:
+    
+    
+    template <typename _Value>
     class EdgeMap {
-      template <typename TT> friend class EdgeMap;
-      typename _Graph::template EdgeMap<T> forward_map, backward_map; 
+    private:
+      
+      typedef typename _Graph::template EdgeMap<_Value> MapImpl;
+      
     public:
-      typedef T Value;
+
+      typedef typename MapTraits<MapImpl>::ReferenceMapTag ReferenceMapTag;
+
+      typedef _Value Value;
       typedef Edge Key;
+      
+      EdgeMap(const UndirGraphAdaptorBase<_Graph>& _g) :
+	forward_map(*(_g.graph)), backward_map(*(_g.graph)) {}
 
-      EdgeMap(const SubBidirGraphAdaptorBase<_Graph, 
-	      ForwardFilterMap, BackwardFilterMap>& g) : 
-	forward_map(*(g.graph)), backward_map(*(g.graph)) { }
-
-      EdgeMap(const SubBidirGraphAdaptorBase<_Graph, 
-	      ForwardFilterMap, BackwardFilterMap>& g, T a) : 
-	forward_map(*(g.graph), a), backward_map(*(g.graph), a) { }
+      EdgeMap(const UndirGraphAdaptorBase<_Graph>& _g, const Value& a) 
+        : forward_map(*(_g.graph), a), backward_map(*(_g.graph), a) {}
       
-      void set(Edge e, T a) { 
-	if (!e.backward) 
+      void set(const Edge& e, const Value& a) { 
+	if (Parent::direction(e)) {
 	  forward_map.set(e, a); 
-	else 
-	  backward_map.set(e, a); 
+        } else { 
+	  backward_map.set(e, a);
+        } 
       }
 
-//       typename _Graph::template EdgeMap<T>::ConstReference 
-//       operator[](Edge e) const { 
-// 	if (!e.backward) 
-// 	  return forward_map[e]; 
-// 	else 
-// 	  return backward_map[e]; 
-//       }
-
-//      typename _Graph::template EdgeMap<T>::Reference 
-      T operator[](Edge e) const { 
-	if (!e.backward) 
+      typename MapTraits<MapImpl>::ConstReturnValue 
+      operator[](const Edge& e) const { 
+	if (Parent::direction(e)) {
 	  return forward_map[e]; 
-	else 
+	} else { 
 	  return backward_map[e]; 
+        }
       }
 
-      void update() { 
-	forward_map.update(); 
-	backward_map.update();
+      typename MapTraits<MapImpl>::ReturnValue 
+      operator[](const Edge& e) { 
+	if (Parent::direction(e)) {
+	  return forward_map[e]; 
+	} else { 
+	  return backward_map[e]; 
+        }
       }
+
+    protected:
+
+      MapImpl forward_map, backward_map; 
+
     };
+        
+    template <typename _Value>
+    class UEdgeMap : public _Graph::template EdgeMap<_Value> {
+    public:
 
-  };
+      typedef typename _Graph::template EdgeMap<_Value> Parent; 
 
+      UEdgeMap(const UndirGraphAdaptorBase<_Graph>& g) 
+        : Parent(*(g.graph)) {}
 
-  ///\brief An adaptor for composing a subgraph of a 
-  /// bidirected graph made from a directed one. 
+      UEdgeMap(const UndirGraphAdaptorBase<_Graph>& g, const _Value& a) 
+        : Parent(*(g.graph), a) {}
+      
+    };
+      
+  };
+
+  ///\brief An undirected graph is made from a directed graph by an adaptor
   ///\ingroup graph_adaptors
   ///
-  /// An adaptor for composing a subgraph of a 
-  /// bidirected graph made from a directed one. 
-  ///
-  ///\warning Graph adaptors are in even more experimental state
-  ///than the other
-  ///parts of the lib. Use them at you own risk.
-  ///
-  /// Let \f$ G=(V, A) \f$ be a directed graph and for each directed edge 
-  ///\f$ e\in A \f$, let \f$ \bar e \f$ denote the edge obtained by
-  /// reversing its orientation. We are given moreover two bool valued 
-  /// maps on the edge-set, 
-  ///\f$ forward\_filter \f$, and \f$ backward\_filter \f$. 
-  /// SubBidirGraphAdaptor implements the graph structure with node-set 
-  ///\f$ V \f$ and edge-set 
-  ///\f$ \{e : e\in A \mbox{ and } forward\_filter(e) \mbox{ is true}\}+\{\bar e : e\in A \mbox{ and } backward\_filter(e) \mbox{ is true}\} \f$. 
-  /// The purpose of writing + instead of union is because parallel 
-  /// edges can arise. (Similarly, antiparallel edges also can arise).
-  /// In other words, a subgraph of the bidirected graph obtained, which 
-  /// is given by orienting the edges of the original graph in both directions.
-  /// As the oppositely directed edges are logically different, 
-  /// the maps are able to attach different values for them. 
-  ///
-  /// An example for such a construction is \c RevGraphAdaptor where the 
-  /// forward_filter is everywhere false and the backward_filter is 
-  /// everywhere true. We note that for sake of efficiency, 
-  /// \c RevGraphAdaptor is implemented in a different way. 
-  /// But BidirGraphAdaptor is obtained from 
-  /// SubBidirGraphAdaptor by considering everywhere true 
-  /// valued maps both for forward_filter and backward_filter. 
-  ///
-  /// The most important application of SubBidirGraphAdaptor 
-  /// is ResGraphAdaptor, which stands for the residual graph in directed 
-  /// flow and circulation problems. 
-  /// As adaptors usually, the SubBidirGraphAdaptor implements the 
-  /// above mentioned graph structure without its physical storage, 
-  /// that is the whole stuff is stored in constant memory. 
-  template<typename _Graph, 
-	   typename ForwardFilterMap, typename BackwardFilterMap>
-  class SubBidirGraphAdaptor : 
-    public GraphAdaptorExtender<
-    SubBidirGraphAdaptorBase<_Graph, ForwardFilterMap, BackwardFilterMap> > {
+  /// Undocumented, untested!!!
+  /// If somebody knows nice demo application, let's polulate it.
+  /// 
+  /// \author Marton Makai
+  template<typename _Graph>
+  class UndirGraphAdaptor : 
+    public UGraphAdaptorExtender<
+    UndirGraphAdaptorBase<_Graph> > {
   public:
     typedef _Graph Graph;
-    typedef GraphAdaptorExtender<
-      SubBidirGraphAdaptorBase<
-      _Graph, ForwardFilterMap, BackwardFilterMap> > Parent;
+    typedef UGraphAdaptorExtender<
+      UndirGraphAdaptorBase<_Graph> > Parent;
   protected:
-    SubBidirGraphAdaptor() { }
+    UndirGraphAdaptor() { }
   public:
-    SubBidirGraphAdaptor(_Graph& _graph, ForwardFilterMap& _forward_filter, 
-			 BackwardFilterMap& _backward_filter) { 
+    UndirGraphAdaptor(_Graph& _graph) { 
       setGraph(_graph);
-      setForwardFilterMap(_forward_filter);
-      setBackwardFilterMap(_backward_filter);
     }
-  };
 
+    template <typename _ForwardMap, typename _BackwardMap>
+    class CombinedEdgeMap {
+    public:
+      
+      typedef _ForwardMap ForwardMap;
+      typedef _BackwardMap BackwardMap;
 
+      typedef typename MapTraits<ForwardMap>::ReferenceMapTag ReferenceMapTag;
 
-  ///\brief An adaptor for composing bidirected graph from a directed one. 
-  ///\ingroup graph_adaptors
-  ///
-  ///\warning Graph adaptors are in even more experimental state
-  ///than the other
-  ///parts of the lib. Use them at you own risk.
-  ///
-  /// An adaptor for composing bidirected graph from a directed one. 
-  /// A bidirected graph is composed over the directed one without physical 
-  /// storage. As the oppositely directed edges are logically different ones 
-  /// the maps are able to attach different values for them.
-  template<typename Graph>
-  class BidirGraphAdaptor : 
-    public SubBidirGraphAdaptor<
-    Graph, 
-    ConstMap<typename Graph::Edge, bool>, 
-    ConstMap<typename Graph::Edge, bool> > {
-  public:
-    typedef  SubBidirGraphAdaptor<
-      Graph, 
-      ConstMap<typename Graph::Edge, bool>, 
-      ConstMap<typename Graph::Edge, bool> > Parent; 
-  protected:
-    ConstMap<typename Graph::Edge, bool> cm;
+      typedef typename ForwardMap::Value Value;
+      typedef typename Parent::Edge Key;
+      
+      CombinedEdgeMap() : forward_map(0), backward_map(0) {}
 
-    BidirGraphAdaptor() : Parent(), cm(true) { 
-      Parent::setForwardFilterMap(cm);
-      Parent::setBackwardFilterMap(cm);
-    }
-  public:
-    BidirGraphAdaptor(Graph& _graph) : Parent(), cm(true) { 
-      Parent::setGraph(_graph);
-      Parent::setForwardFilterMap(cm);
-      Parent::setBackwardFilterMap(cm);
-    }
+      CombinedEdgeMap(ForwardMap& _forward_map, BackwardMap& _backward_map) 
+        : forward_map(&_forward_map), backward_map(&_backward_map) {}
+      
+      void set(const Key& e, const Value& a) { 
+	if (Parent::direction(e)) {
+	  forward_map->set(e, a); 
+        } else { 
+	  backward_map->set(e, a);
+        } 
+      }
+
+      typename MapTraits<ForwardMap>::ConstReturnValue 
+      operator[](const Key& e) const { 
+	if (Parent::direction(e)) {
+	  return (*forward_map)[e]; 
+	} else { 
+	  return (*backward_map)[e]; 
+        }
+      }
+
+      typename MapTraits<ForwardMap>::ReturnValue 
+      operator[](const Key& e) { 
+	if (Parent::direction(e)) {
+	  return (*forward_map)[e]; 
+	} else { 
+	  return (*backward_map)[e]; 
+        }
+      }
+
+      void setForwardMap(ForwardMap& _forward_map) {
+        forward_map = &_forward_map;
+      }
+
+      void setBackwardMap(BackwardMap& _backward_map) {
+        backward_map = &_backward_map;
+      }
+
+    protected:
+
+      ForwardMap* forward_map;
+      BackwardMap* backward_map; 
+
+    };
 
-    int edgeNum() const { 
-      return 2*this->graph->edgeNum();
-    }
   };
 
+  /// \brief Just gives back an undir graph adaptor
+  ///
+  /// Just gives back an undir graph adaptor
+  template<typename Graph>
+  UndirGraphAdaptor<const Graph>
+  undirGraphAdaptor(const Graph& graph) {
+    return UndirGraphAdaptor<const Graph>(graph);
+  }
 
   template<typename Graph, typename Number,
 	   typename CapacityMap, typename FlowMap>
   class ResForwardFilter {
-    //    const Graph* graph;
     const CapacityMap* capacity;
     const FlowMap* flow;
   public:
-    ResForwardFilter(/*const Graph& _graph, */
-		     const CapacityMap& _capacity, const FlowMap& _flow) :
-      /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { }
-    ResForwardFilter() : /*graph(0),*/ capacity(0), flow(0) { }
-    void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; }
-    void setFlow(const FlowMap& _flow) { flow=&_flow; }
+    typedef typename Graph::Edge Key;
+    typedef bool Value;
+
+    ResForwardFilter(const CapacityMap& _capacity, const FlowMap& _flow) 
+      : capacity(&_capacity), flow(&_flow) { }
+    ResForwardFilter() : capacity(0), flow(0) { }
+    void setCapacity(const CapacityMap& _capacity) { capacity = &_capacity; }
+    void setFlow(const FlowMap& _flow) { flow = &_flow; }
     bool operator[](const typename Graph::Edge& e) const {
       return (Number((*flow)[e]) < Number((*capacity)[e]));
     }
@@ -1164,12 +1214,14 @@
     const CapacityMap* capacity;
     const FlowMap* flow;
   public:
-    ResBackwardFilter(/*const Graph& _graph,*/ 
-		      const CapacityMap& _capacity, const FlowMap& _flow) :
-      /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { }
-    ResBackwardFilter() : /*graph(0),*/ capacity(0), flow(0) { }
-    void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; }
-    void setFlow(const FlowMap& _flow) { flow=&_flow; }
+    typedef typename Graph::Edge Key;
+    typedef bool Value;
+
+    ResBackwardFilter(const CapacityMap& _capacity, const FlowMap& _flow) 
+      : capacity(&_capacity), flow(&_flow) { }
+    ResBackwardFilter() : capacity(0), flow(0) { }
+    void setCapacity(const CapacityMap& _capacity) { capacity = &_capacity; }
+    void setFlow(const FlowMap& _flow) { flow = &_flow; }
     bool operator[](const typename Graph::Edge& e) const {
       return (Number(0) < Number((*flow)[e]));
     }
@@ -1207,80 +1259,118 @@
   ///typedef ListGraph Graph;
   ///Graph::EdgeMap<int> f(g);
   ///Graph::EdgeMap<int> c(g);
-  ///ResGraphAdaptor<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> > gw(g);
+  ///ResGraphAdaptor<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> > ga(g);
   ///\endcode
   ///\author Marton Makai
   ///
   template<typename Graph, typename Number, 
 	   typename CapacityMap, typename FlowMap>
   class ResGraphAdaptor : 
-    public SubBidirGraphAdaptor< 
-    Graph, 
+    public EdgeSubGraphAdaptor< 
+    UndirGraphAdaptor<Graph>, 
+    typename UndirGraphAdaptor<Graph>::template CombinedEdgeMap<
     ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,  
-    ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > {
+    ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > > {
   public:
-    typedef SubBidirGraphAdaptor< 
-      Graph, 
-      ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,  
-      ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > Parent;
+
+    typedef UndirGraphAdaptor<Graph> UGraph;
+
+    typedef ResForwardFilter<Graph, Number, CapacityMap, FlowMap> 
+    ForwardFilter;
+
+    typedef ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> 
+    BackwardFilter;
+
+    typedef typename UGraph::
+    template CombinedEdgeMap<ForwardFilter, BackwardFilter>
+    EdgeFilter;
+
+    typedef EdgeSubGraphAdaptor<UGraph, EdgeFilter> Parent;
+
   protected:
+
     const CapacityMap* capacity;
     FlowMap* flow;
-    ResForwardFilter<Graph, Number, CapacityMap, FlowMap> forward_filter;
-    ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> backward_filter;
-    ResGraphAdaptor() : Parent(), 
- 			capacity(0), flow(0) { }
+
+    UGraph ugraph;
+    ForwardFilter forward_filter;
+    BackwardFilter backward_filter;
+    EdgeFilter edge_filter;
+
     void setCapacityMap(const CapacityMap& _capacity) {
       capacity=&_capacity;
       forward_filter.setCapacity(_capacity);
       backward_filter.setCapacity(_capacity);
     }
+
     void setFlowMap(FlowMap& _flow) {
       flow=&_flow;
       forward_filter.setFlow(_flow);
       backward_filter.setFlow(_flow);
     }
+
   public:
+
     ResGraphAdaptor(Graph& _graph, const CapacityMap& _capacity, 
-		       FlowMap& _flow) : 
-      Parent(), capacity(&_capacity), flow(&_flow), 
-      forward_filter(/*_graph,*/ _capacity, _flow), 
-      backward_filter(/*_graph,*/ _capacity, _flow) {
-      Parent::setGraph(_graph);
-      Parent::setForwardFilterMap(forward_filter);
-      Parent::setBackwardFilterMap(backward_filter);
+                    FlowMap& _flow) 
+      : Parent(), capacity(&_capacity), flow(&_flow),
+        ugraph(_graph),
+        forward_filter(_capacity, _flow), 
+        backward_filter(_capacity, _flow),
+        edge_filter(forward_filter, backward_filter) {
+      Parent::setGraph(ugraph);
+      Parent::setEdgeFilterMap(edge_filter);
     }
 
     typedef typename Parent::Edge Edge;
 
     void augment(const Edge& e, Number a) const {
-      if (Parent::forward(e))  
+      if (UGraph::direction(e)) {
 	flow->set(e, (*flow)[e]+a);
-      else  
+      } else {  
 	flow->set(e, (*flow)[e]-a);
+      }
+    }
+
+    static bool forward(const Edge& e) {
+      return UGraph::direction(e);
+    }
+
+    static bool backward(const Edge& e) {
+      return !UGraph::direction(e);
+    }
+
+    static Edge forward(const typename Graph::Edge& e) {
+      return UGraph::direct(e, true);
+    }
+
+    static Edge backward(const typename Graph::Edge& e) {
+      return UGraph::direct(e, false);
     }
 
+
     /// \brief Residual capacity map.
     ///
     /// In generic residual graphs the residual capacity can be obtained 
     /// as a map. 
     class ResCap {
     protected:
-      const ResGraphAdaptor<Graph, Number, CapacityMap, FlowMap>* res_graph;
+      const ResGraphAdaptor* res_graph;
     public:
       typedef Number Value;
       typedef Edge Key;
-      ResCap(const ResGraphAdaptor<Graph, Number, CapacityMap, FlowMap>& 
-	     _res_graph) : res_graph(&_res_graph) { }
+      ResCap(const ResGraphAdaptor& _res_graph) 
+        : res_graph(&_res_graph) {}
+      
       Number operator[](const Edge& e) const { 
-	if (res_graph->forward(e)) 
+	if (ResGraphAdaptor::direction(e)) 
 	  return (*(res_graph->capacity))[e]-(*(res_graph->flow))[e]; 
 	else 
 	  return (*(res_graph->flow))[e]; 
       }
+      
     };
 
-    //    KEEP_MAPS(Parent, ResGraphAdaptor);
   };
 
 

Modified: hugo/trunk/lemon/list_graph.h
==============================================================================
--- hugo/trunk/lemon/list_graph.h	(original)
+++ hugo/trunk/lemon/list_graph.h	Wed Mar  1 11:25:30 2006
@@ -962,8 +962,8 @@
   /// \brief A smart bipartite undirected graph class.
   ///
   /// This is a bipartite undirected graph implementation.
-  /// Except from this it conforms to 
-  /// the \ref concept::BpUGraph "BpUGraph" concept.
+  /// It is conforms to the \ref concept::ErasableBpUGraph "ErasableBpUGraph" 
+  /// concept.
   /// \sa concept::BpUGraph.
   ///
   class ListBpUGraph : public ExtendedListBpUGraphBase {};

Modified: hugo/trunk/lemon/ugraph_adaptor.h
==============================================================================
--- hugo/trunk/lemon/ugraph_adaptor.h	(original)
+++ hugo/trunk/lemon/ugraph_adaptor.h	Wed Mar  1 11:25:30 2006
@@ -42,9 +42,6 @@
   ///
   /// \brief Base type for the Graph Adaptors
   ///
-  /// \warning Graph adaptors are in even more experimental state than the 
-  /// other parts of the lib. Use them at you own risk.
-  ///
   /// This is the base type for most of LEMON graph adaptors. 
   /// This class implements a trivial graph adaptor i.e. it only wraps the 
   /// functions and types of the graph. The purpose of this class is to 
@@ -93,7 +90,6 @@
     void nextOut(Edge& i) const { graph->nextOut(i); }
     void nextInc(UEdge &i, bool &d) const { graph->nextInc(i, d); }
 
-
     Node source(const UEdge& e) const { return graph->source(e); }
     Node target(const UEdge& e) const { return graph->target(e); }
 
@@ -111,7 +107,6 @@
 		  const Edge& prev = INVALID) {
       return graph->findEdge(source, target, prev);
     }
-
     UEdge findUEdge(const Node& source, const Node& target, 
                     const UEdge& prev = INVALID) {
       return graph->findUEdge(source, target, prev);
@@ -132,18 +127,36 @@
 
     bool direction(const Edge& e) const { return graph->direction(e); }
     Edge direct(const UEdge& e, bool d) const { return graph->direct(e, d); }
-    Edge direct(const UEdge& e, const Node& n) const { 
-      return graph->direct(e, n); 
+
+    int maxNodeId() const {
+      return graph->maxNodeId();
     }
 
-    Node oppositeNode(const Node& n, const Edge& e) const { 
-      return graph->oppositeNode(n, e); 
+    int maxEdgeId() const {
+      return graph->maxEdgeId();
     }
 
-    Edge oppositeEdge(const Edge& e) const { 
-      return graph->oppositeEdge(e); 
+    int maxUEdgeId() const {
+      return graph->maxEdgeId();
     }
 
+    typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
+
+    NodeNotifier& getNotifier(Node) const {
+      return graph->getNotifier(Node());
+    } 
+
+    typedef typename ItemSetTraits<Graph, Edge>::ItemNotifier EdgeNotifier;
+
+    EdgeNotifier& getNotifier(Edge) const {
+      return graph->getNotifier(Edge());
+    } 
+
+    typedef typename ItemSetTraits<Graph, UEdge>::ItemNotifier UEdgeNotifier;
+
+    UEdgeNotifier& getNotifier(UEdge) const {
+      return graph->getNotifier(UEdge());
+    } 
 
     template <typename _Value>
     class NodeMap : public Graph::template NodeMap<_Value> {
@@ -379,6 +392,30 @@
 
     typedef False NodeNumTag;
     typedef False EdgeNumTag;
+
+    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
+    Edge findEdge(const Node& source, const Node& target, 
+		  const Edge& prev = INVALID) {
+      if (!(*node_filter_map)[source] || !(*node_filter_map)[target]) {
+        return INVALID;
+      }
+      Edge edge = Parent::findEdge(source, target, prev);
+      while (edge != INVALID && !(*uedge_filter_map)[edge]) {
+        edge = Parent::findEdge(source, target, edge);
+      }
+      return edge;
+    }
+    UEdge findUEdge(const Node& source, const Node& target, 
+		  const UEdge& prev = INVALID) {
+      if (!(*node_filter_map)[source] || !(*node_filter_map)[target]) {
+        return INVALID;
+      }
+      UEdge uedge = Parent::findUEdge(source, target, prev);
+      while (uedge != INVALID && !(*uedge_filter_map)[uedge]) {
+        uedge = Parent::findUEdge(source, target, uedge);
+      }
+      return uedge;
+    }
   };
 
   template <typename _UGraph, typename NodeFilterMap, typename UEdgeFilterMap>
@@ -504,6 +541,24 @@
 
     typedef False NodeNumTag;
     typedef False EdgeNumTag;
+
+    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
+    Edge findEdge(const Node& source, const Node& target, 
+		  const Edge& prev = INVALID) {
+      Edge edge = Parent::findEdge(source, target, prev);
+      while (edge != INVALID && !(*uedge_filter_map)[edge]) {
+        edge = Parent::findEdge(source, target, edge);
+      }
+      return edge;
+    }
+    UEdge findUEdge(const Node& source, const Node& target, 
+		  const UEdge& prev = INVALID) {
+      UEdge uedge = Parent::findUEdge(source, target, prev);
+      while (uedge != INVALID && !(*uedge_filter_map)[uedge]) {
+        uedge = Parent::findUEdge(source, target, uedge);
+      }
+      return uedge;
+    }
   };
 
   /// \ingroup graph_adaptors
@@ -581,7 +636,6 @@
   ///
   /// \brief An adaptor for hiding nodes from an undirected graph.
   ///
-  ///
   /// An adaptor for hiding nodes from an undirected graph.
   /// This adaptor specializes SubUGraphAdaptor in the way that only
   /// the node-set 
@@ -598,6 +652,11 @@
     typedef _UGraph Graph;
   protected:
     ConstMap<typename _UGraph::UEdge, bool> const_true_map;
+
+    NodeSubUGraphAdaptor() : const_true_map(true) {
+      Parent::setUEdgeFilterMap(const_true_map);
+    }
+
   public:
     NodeSubUGraphAdaptor(Graph& _graph, NodeFilterMap& _node_filter_map) : 
       Parent(), const_true_map(true) { 
@@ -639,6 +698,11 @@
     typedef _UGraph Graph;
   protected:
     ConstMap<typename Graph::Node, bool> const_true_map;
+
+    EdgeSubUGraphAdaptor() : const_true_map(true) {
+      Parent::setNodeFilterMap(const_true_map);
+    }
+
   public:
     EdgeSubUGraphAdaptor(Graph& _graph, UEdgeFilterMap& _uedge_filter_map) : 
       Parent(), const_true_map(true) { 
@@ -670,6 +734,10 @@
     typedef typename _UGraph::Node Node;
     typedef typename _UGraph::UEdge Edge;
    
+    void reverseEdge(const Edge& edge) {
+      direction->set(edge, !(*direction)[edge]);
+    }
+
     void first(Node& i) const { graph->first(i); }
     void first(Edge& i) const { graph->first(i); }
     void firstIn(Edge& i, const Node& n) const {
@@ -746,10 +814,26 @@
     int id(const Node& v) const { return graph->id(v); }
     int id(const Edge& e) const { return graph->id(e); }
 
-    void reverseEdge(const Edge& edge) {
-      direction->set(edge, !(*direction)[edge]);
+    int maxNodeId() const {
+      return graph->maxNodeId();
     }
 
+    int maxEdgeId() const {
+      return graph->maxEdgeId();
+    }
+
+    typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
+
+    NodeNotifier& getNotifier(Node) const {
+      return graph->getNotifier(Node());
+    } 
+
+    typedef typename ItemSetTraits<Graph, Edge>::ItemNotifier EdgeNotifier;
+
+    EdgeNotifier& getNotifier(Edge) const {
+      return graph->getNotifier(Edge());
+    } 
+
     template <typename _Value>
     class NodeMap : public _UGraph::template NodeMap<_Value> {
     public:
@@ -788,7 +872,8 @@
 
 
   /// \ingroup graph_adaptors
-  /// \brief A directed graph is made from a undirected graph by an adaptor
+  ///
+  /// \brief A directed graph is made from an undirected graph by an adaptor
   ///
   /// This adaptor gives a direction for each uedge in the undirected graph.
   /// The direction of the edges stored in the DirectionMap. This map is

Modified: hugo/trunk/test/graph_adaptor_test.cc
==============================================================================
--- hugo/trunk/test/graph_adaptor_test.cc	(original)
+++ hugo/trunk/test/graph_adaptor_test.cc	Wed Mar  1 11:25:30 2006
@@ -58,9 +58,6 @@
     checkConcept<StaticGraph, EdgeSubGraphAdaptor<Graph, 
       Graph::EdgeMap<bool> > >();
     
-    checkConcept<StaticGraph, SubBidirGraphAdaptor<Graph, 
-      Graph::EdgeMap<bool>, Graph::EdgeMap<bool> > >();
-    //    checkConcept<StaticGraph, BidirGraph<Graph> >();
     checkConcept<StaticGraph, ResGraphAdaptor<Graph, int, 
       Graph::EdgeMap<int>, Graph::EdgeMap<int> > >();
 



More information about the Lemon-commits mailing list