[Lemon-commits] [lemon_svn] deba: r1952 - hugo/trunk/lemon

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


Author: deba
Date: Fri Jun 10 14:22:22 2005
New Revision: 1952

Modified:
   hugo/trunk/lemon/graph_adaptor.h

Log:
New EdgeSet Adaptor



Modified: hugo/trunk/lemon/graph_adaptor.h
==============================================================================
--- hugo/trunk/lemon/graph_adaptor.h	(original)
+++ hugo/trunk/lemon/graph_adaptor.h	Fri Jun 10 14:22:22 2005
@@ -27,7 +27,12 @@
 
 #include <lemon/invalid.h>
 #include <lemon/maps.h>
+#include <lemon/bits/erasable_graph_extender.h>
+#include <lemon/bits/clearable_graph_extender.h>
+#include <lemon/bits/extendable_graph_extender.h>
 #include <lemon/bits/iterable_graph_extender.h>
+#include <lemon/bits/alteration_notifier.h>
+#include <lemon/bits/default_map.h>
 #include <lemon/bits/undir_graph_extender.h>
 #include <iostream>
 
@@ -1210,6 +1215,280 @@
 
   };
 
+  /// \e
+  template <typename _Graph>
+  class NewEdgeSetAdaptorBase {
+  public:
+
+    typedef _Graph Graph;
+    typedef typename Graph::Node Node;
+    typedef typename Graph::NodeIt NodeIt;
+
+  protected:
+
+    struct NodeT {
+      int first_out, first_in;
+      NodeT() : first_out(-1), first_in(-1) {}
+    };
+    
+    class NodesImpl : protected Graph::template NodeMap<NodeT> {
+
+      typedef typename Graph::template NodeMap<NodeT> Parent;
+      typedef NewEdgeSetAdaptorBase<Graph> Adaptor;
+
+      Adaptor& adaptor;
+
+    public:
+
+      NodesImpl(Adaptor& _adaptor, const Graph& _graph) 
+	: Parent(_graph), adaptor(_adaptor) {}
+
+      virtual ~NodesImpl() {}
+
+      virtual void build() {
+	Parent::build();
+      }
+
+      virtual void clear() {
+	adaptor._clear();
+	Parent::clear();
+      }
+      
+      virtual void add(const Node& node) {
+	Parent::add(node);
+	adaptor._add(node);
+      }
+      
+      virtual void erase(const Node& node) {
+	adaptor._erase(node);
+	Parent::erase(node);
+      }
+
+      NodeT& operator[](const Node& node) {
+	return Parent::operator[](node);
+      }
+
+      const NodeT& operator[](const Node& node) const {
+	return Parent::operator[](node);
+      }
+      
+    };
+
+    NodesImpl* nodes;
+
+    struct EdgeT {
+      Node source, target;
+      int next_out, next_in;
+      int prev_out, prev_in;
+      EdgeT() : prev_out(-1), prev_in(-1) {}
+    };
+
+    std::vector<EdgeT> edges;
+
+    int first_edge;
+    int first_free_edge;
+
+    virtual void _clear() = 0;
+    virtual void _add(const Node& node) = 0;
+    virtual void _erase(const Node& node) = 0;
+    
+    const Graph* graph;
+
+    void initalize(const Graph& _graph, NodesImpl& _nodes) {
+      graph = &_graph;
+      nodes = &_nodes;
+    }
+    
+  public:
+
+    class Edge {
+      friend class NewEdgeSetAdaptorBase<Graph>;
+    protected:
+      Edge(int _id) : id(_id) {}
+      int id;
+    public:
+      Edge() {}
+      Edge(Invalid) : id(-1) {}
+      bool operator==(const Edge& edge) const { return id == edge.id; }
+      bool operator!=(const Edge& edge) const { return id != edge.id; }
+      bool operator<(const Edge& edge) const { return id < edge.id; }
+    };
+
+    NewEdgeSetAdaptorBase() : first_edge(-1), first_free_edge(-1) {} 
+    virtual ~NewEdgeSetAdaptorBase() {}
+
+    Edge addEdge(const Node& source, const Node& target) {
+      int n;
+      if (first_free_edge == -1) {
+	n = edges.size();
+	edges.push_back(EdgeT());
+      } else {
+	n = first_free_edge;
+	first_free_edge = edges[first_free_edge].next_in;
+      }
+      edges[n].next_in = (*nodes)[target].first_in;
+      (*nodes)[target].first_in = n;
+      edges[n].next_out = (*nodes)[source].first_out;
+      (*nodes)[source].first_out = n;
+      edges[n].source = source;
+      edges[n].target = target;
+      return Edge(n);
+    }
+
+    void erase(const Edge& edge) {
+      int n = edge.id;
+      if (edges[n].prev_in != -1) {
+	edges[edges[n].prev_in].next_in = edges[n].next_in;
+      } else {
+	(*nodes)[edges[n].target].first_in = edges[n].next_in;
+      }
+      if (edges[n].next_in != -1) {
+	edges[edges[n].next_in].prev_in = edges[n].prev_in;
+      }
+
+      if (edges[n].prev_out != -1) {
+	edges[edges[n].prev_out].next_out = edges[n].next_out;
+      } else {
+	(*nodes)[edges[n].source].first_out = edges[n].next_out;
+      }
+      if (edges[n].next_out != -1) {
+	edges[edges[n].next_out].prev_out = edges[n].prev_out;
+      }
+           
+    }
+
+    void first(Node& node) const {
+      graph->first(node);
+    }
+
+    void next(Node& node) const {
+      graph->next(node);
+    }
+
+    void first(Edge& edge) const {
+      Node node;
+      for (first(node); node != INVALID && (*nodes)[node].first_in == -1; 
+	   next(node));
+      edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
+    }
+
+    void next(Edge& edge) const {
+      if (edges[edge.id].next_in != -1) {
+	edge.id = edges[edge.id].next_in;
+      } else {
+	Node node = edges[edge.id].target;
+	for (next(node); node != INVALID && (*nodes)[node].first_in == -1; 
+	     next(node));
+	edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
+      }      
+    }
+
+    void firstOut(Edge& edge, const Node& node) const {
+      edge.id = (*nodes)[node].first_out;    
+    }
+    
+    void nextOut(Edge& edge) const {
+      edge.id = edges[edge.id].next_out;        
+    }
+
+    void firstIn(Edge& edge, const Node& node) const {
+      edge.id = (*nodes)[node].first_in;          
+    }
+
+    void nextIn(Edge& edge) const {
+      edge.id = edges[edge.id].next_in;    
+    }
+
+    int id(const Node& node) const { return graph->id(node); }
+    int id(const Edge& edge) const { return edge.id; }
+
+    Node fromId(int id, Node) const { return graph->fromId(id, Node()); }
+    Edge fromId(int id, Edge) const { return Edge(id); }
+
+    int maxId(Node) const { return graph->maxId(Node()); };
+    int maxId(Edge) const { return edges.size() - 1; }
+
+    Node source(const Edge& edge) const { return edges[edge.id].source;}
+    Node target(const Edge& edge) const { return edges[edge.id].target;}
+
+  };
+
+  template <typename _Graph>
+  class NewEdgeSetAdaptor :
+    public ErasableGraphExtender<
+    ClearableGraphExtender<
+    ExtendableGraphExtender<
+    DefaultMappableGraphExtender<
+    IterableGraphExtender<
+    AlterableGraphExtender<
+    NewEdgeSetAdaptorBase<_Graph> > > > > > > {
+
+  public:
+
+    typedef ErasableGraphExtender<
+      ClearableGraphExtender<
+      ExtendableGraphExtender<
+      DefaultMappableGraphExtender<
+      IterableGraphExtender<
+      AlterableGraphExtender<
+      NewEdgeSetAdaptorBase<_Graph> > > > > > > Parent;
+    
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Edge Edge;
+
+  private:
+
+    virtual void _clear() {
+      Parent::edges.clear();
+      Parent::first_edge = -1;
+      Parent::first_free_edge = -1;
+      Parent::getNotifier(Edge()).clear();
+      Parent::getNotifier(Node()).clear();
+    }
+
+    virtual void _add(const Node& node) {
+      Parent::getNotifier(Node()).add(node);
+    }
+
+    virtual void _erase(const Node& node) {
+      Edge edge;
+      Parent::firstOut(edge, node);
+      while (edge != INVALID) {
+	Parent::erase(edge);
+	Parent::firstOut(edge, node);
+      }
+
+      Parent::firstIn(edge, node);
+      while (edge != INVALID) {
+	Parent::erase(edge);
+	Parent::firstIn(edge, node);
+      }
+      
+      Parent::getNotifier(Node()).erase(node);
+    }
+
+
+    typedef typename Parent::NodesImpl NodesImpl;
+
+    NodesImpl nodes;
+    
+  public:
+
+    NewEdgeSetAdaptor(const _Graph& _graph) : nodes(*this, _graph) {
+      Parent::initalize(_graph, nodes);
+    }
+
+    void clear() {
+      Parent::edges.clear();
+      Parent::first_edge = -1;
+      Parent::first_free_edge = -1;
+
+      Parent::getNotifier(Edge()).clear();      
+    }
+    
+  };
+
   ///@}
 
 } //namespace lemon



More information about the Lemon-commits mailing list