New EdgeSet Adaptor
authordeba
Fri, 10 Jun 2005 12:22:22 +0000
changeset 1472c3bda060cfa3
parent 1471 11a13908b510
child 1473 876c7b7f4dae
New EdgeSet Adaptor
lemon/graph_adaptor.h
     1.1 --- a/lemon/graph_adaptor.h	Fri Jun 10 12:16:56 2005 +0000
     1.2 +++ b/lemon/graph_adaptor.h	Fri Jun 10 12:22:22 2005 +0000
     1.3 @@ -27,7 +27,12 @@
     1.4  
     1.5  #include <lemon/invalid.h>
     1.6  #include <lemon/maps.h>
     1.7 +#include <lemon/bits/erasable_graph_extender.h>
     1.8 +#include <lemon/bits/clearable_graph_extender.h>
     1.9 +#include <lemon/bits/extendable_graph_extender.h>
    1.10  #include <lemon/bits/iterable_graph_extender.h>
    1.11 +#include <lemon/bits/alteration_notifier.h>
    1.12 +#include <lemon/bits/default_map.h>
    1.13  #include <lemon/bits/undir_graph_extender.h>
    1.14  #include <iostream>
    1.15  
    1.16 @@ -1210,6 +1215,280 @@
    1.17  
    1.18    };
    1.19  
    1.20 +  /// \e
    1.21 +  template <typename _Graph>
    1.22 +  class NewEdgeSetAdaptorBase {
    1.23 +  public:
    1.24 +
    1.25 +    typedef _Graph Graph;
    1.26 +    typedef typename Graph::Node Node;
    1.27 +    typedef typename Graph::NodeIt NodeIt;
    1.28 +
    1.29 +  protected:
    1.30 +
    1.31 +    struct NodeT {
    1.32 +      int first_out, first_in;
    1.33 +      NodeT() : first_out(-1), first_in(-1) {}
    1.34 +    };
    1.35 +    
    1.36 +    class NodesImpl : protected Graph::template NodeMap<NodeT> {
    1.37 +
    1.38 +      typedef typename Graph::template NodeMap<NodeT> Parent;
    1.39 +      typedef NewEdgeSetAdaptorBase<Graph> Adaptor;
    1.40 +
    1.41 +      Adaptor& adaptor;
    1.42 +
    1.43 +    public:
    1.44 +
    1.45 +      NodesImpl(Adaptor& _adaptor, const Graph& _graph) 
    1.46 +	: Parent(_graph), adaptor(_adaptor) {}
    1.47 +
    1.48 +      virtual ~NodesImpl() {}
    1.49 +
    1.50 +      virtual void build() {
    1.51 +	Parent::build();
    1.52 +      }
    1.53 +
    1.54 +      virtual void clear() {
    1.55 +	adaptor._clear();
    1.56 +	Parent::clear();
    1.57 +      }
    1.58 +      
    1.59 +      virtual void add(const Node& node) {
    1.60 +	Parent::add(node);
    1.61 +	adaptor._add(node);
    1.62 +      }
    1.63 +      
    1.64 +      virtual void erase(const Node& node) {
    1.65 +	adaptor._erase(node);
    1.66 +	Parent::erase(node);
    1.67 +      }
    1.68 +
    1.69 +      NodeT& operator[](const Node& node) {
    1.70 +	return Parent::operator[](node);
    1.71 +      }
    1.72 +
    1.73 +      const NodeT& operator[](const Node& node) const {
    1.74 +	return Parent::operator[](node);
    1.75 +      }
    1.76 +      
    1.77 +    };
    1.78 +
    1.79 +    NodesImpl* nodes;
    1.80 +
    1.81 +    struct EdgeT {
    1.82 +      Node source, target;
    1.83 +      int next_out, next_in;
    1.84 +      int prev_out, prev_in;
    1.85 +      EdgeT() : prev_out(-1), prev_in(-1) {}
    1.86 +    };
    1.87 +
    1.88 +    std::vector<EdgeT> edges;
    1.89 +
    1.90 +    int first_edge;
    1.91 +    int first_free_edge;
    1.92 +
    1.93 +    virtual void _clear() = 0;
    1.94 +    virtual void _add(const Node& node) = 0;
    1.95 +    virtual void _erase(const Node& node) = 0;
    1.96 +    
    1.97 +    const Graph* graph;
    1.98 +
    1.99 +    void initalize(const Graph& _graph, NodesImpl& _nodes) {
   1.100 +      graph = &_graph;
   1.101 +      nodes = &_nodes;
   1.102 +    }
   1.103 +    
   1.104 +  public:
   1.105 +
   1.106 +    class Edge {
   1.107 +      friend class NewEdgeSetAdaptorBase<Graph>;
   1.108 +    protected:
   1.109 +      Edge(int _id) : id(_id) {}
   1.110 +      int id;
   1.111 +    public:
   1.112 +      Edge() {}
   1.113 +      Edge(Invalid) : id(-1) {}
   1.114 +      bool operator==(const Edge& edge) const { return id == edge.id; }
   1.115 +      bool operator!=(const Edge& edge) const { return id != edge.id; }
   1.116 +      bool operator<(const Edge& edge) const { return id < edge.id; }
   1.117 +    };
   1.118 +
   1.119 +    NewEdgeSetAdaptorBase() : first_edge(-1), first_free_edge(-1) {} 
   1.120 +    virtual ~NewEdgeSetAdaptorBase() {}
   1.121 +
   1.122 +    Edge addEdge(const Node& source, const Node& target) {
   1.123 +      int n;
   1.124 +      if (first_free_edge == -1) {
   1.125 +	n = edges.size();
   1.126 +	edges.push_back(EdgeT());
   1.127 +      } else {
   1.128 +	n = first_free_edge;
   1.129 +	first_free_edge = edges[first_free_edge].next_in;
   1.130 +      }
   1.131 +      edges[n].next_in = (*nodes)[target].first_in;
   1.132 +      (*nodes)[target].first_in = n;
   1.133 +      edges[n].next_out = (*nodes)[source].first_out;
   1.134 +      (*nodes)[source].first_out = n;
   1.135 +      edges[n].source = source;
   1.136 +      edges[n].target = target;
   1.137 +      return Edge(n);
   1.138 +    }
   1.139 +
   1.140 +    void erase(const Edge& edge) {
   1.141 +      int n = edge.id;
   1.142 +      if (edges[n].prev_in != -1) {
   1.143 +	edges[edges[n].prev_in].next_in = edges[n].next_in;
   1.144 +      } else {
   1.145 +	(*nodes)[edges[n].target].first_in = edges[n].next_in;
   1.146 +      }
   1.147 +      if (edges[n].next_in != -1) {
   1.148 +	edges[edges[n].next_in].prev_in = edges[n].prev_in;
   1.149 +      }
   1.150 +
   1.151 +      if (edges[n].prev_out != -1) {
   1.152 +	edges[edges[n].prev_out].next_out = edges[n].next_out;
   1.153 +      } else {
   1.154 +	(*nodes)[edges[n].source].first_out = edges[n].next_out;
   1.155 +      }
   1.156 +      if (edges[n].next_out != -1) {
   1.157 +	edges[edges[n].next_out].prev_out = edges[n].prev_out;
   1.158 +      }
   1.159 +           
   1.160 +    }
   1.161 +
   1.162 +    void first(Node& node) const {
   1.163 +      graph->first(node);
   1.164 +    }
   1.165 +
   1.166 +    void next(Node& node) const {
   1.167 +      graph->next(node);
   1.168 +    }
   1.169 +
   1.170 +    void first(Edge& edge) const {
   1.171 +      Node node;
   1.172 +      for (first(node); node != INVALID && (*nodes)[node].first_in == -1; 
   1.173 +	   next(node));
   1.174 +      edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
   1.175 +    }
   1.176 +
   1.177 +    void next(Edge& edge) const {
   1.178 +      if (edges[edge.id].next_in != -1) {
   1.179 +	edge.id = edges[edge.id].next_in;
   1.180 +      } else {
   1.181 +	Node node = edges[edge.id].target;
   1.182 +	for (next(node); node != INVALID && (*nodes)[node].first_in == -1; 
   1.183 +	     next(node));
   1.184 +	edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
   1.185 +      }      
   1.186 +    }
   1.187 +
   1.188 +    void firstOut(Edge& edge, const Node& node) const {
   1.189 +      edge.id = (*nodes)[node].first_out;    
   1.190 +    }
   1.191 +    
   1.192 +    void nextOut(Edge& edge) const {
   1.193 +      edge.id = edges[edge.id].next_out;        
   1.194 +    }
   1.195 +
   1.196 +    void firstIn(Edge& edge, const Node& node) const {
   1.197 +      edge.id = (*nodes)[node].first_in;          
   1.198 +    }
   1.199 +
   1.200 +    void nextIn(Edge& edge) const {
   1.201 +      edge.id = edges[edge.id].next_in;    
   1.202 +    }
   1.203 +
   1.204 +    int id(const Node& node) const { return graph->id(node); }
   1.205 +    int id(const Edge& edge) const { return edge.id; }
   1.206 +
   1.207 +    Node fromId(int id, Node) const { return graph->fromId(id, Node()); }
   1.208 +    Edge fromId(int id, Edge) const { return Edge(id); }
   1.209 +
   1.210 +    int maxId(Node) const { return graph->maxId(Node()); };
   1.211 +    int maxId(Edge) const { return edges.size() - 1; }
   1.212 +
   1.213 +    Node source(const Edge& edge) const { return edges[edge.id].source;}
   1.214 +    Node target(const Edge& edge) const { return edges[edge.id].target;}
   1.215 +
   1.216 +  };
   1.217 +
   1.218 +  template <typename _Graph>
   1.219 +  class NewEdgeSetAdaptor :
   1.220 +    public ErasableGraphExtender<
   1.221 +    ClearableGraphExtender<
   1.222 +    ExtendableGraphExtender<
   1.223 +    DefaultMappableGraphExtender<
   1.224 +    IterableGraphExtender<
   1.225 +    AlterableGraphExtender<
   1.226 +    NewEdgeSetAdaptorBase<_Graph> > > > > > > {
   1.227 +
   1.228 +  public:
   1.229 +
   1.230 +    typedef ErasableGraphExtender<
   1.231 +      ClearableGraphExtender<
   1.232 +      ExtendableGraphExtender<
   1.233 +      DefaultMappableGraphExtender<
   1.234 +      IterableGraphExtender<
   1.235 +      AlterableGraphExtender<
   1.236 +      NewEdgeSetAdaptorBase<_Graph> > > > > > > Parent;
   1.237 +    
   1.238 +
   1.239 +    typedef typename Parent::Node Node;
   1.240 +    typedef typename Parent::Edge Edge;
   1.241 +
   1.242 +  private:
   1.243 +
   1.244 +    virtual void _clear() {
   1.245 +      Parent::edges.clear();
   1.246 +      Parent::first_edge = -1;
   1.247 +      Parent::first_free_edge = -1;
   1.248 +      Parent::getNotifier(Edge()).clear();
   1.249 +      Parent::getNotifier(Node()).clear();
   1.250 +    }
   1.251 +
   1.252 +    virtual void _add(const Node& node) {
   1.253 +      Parent::getNotifier(Node()).add(node);
   1.254 +    }
   1.255 +
   1.256 +    virtual void _erase(const Node& node) {
   1.257 +      Edge edge;
   1.258 +      Parent::firstOut(edge, node);
   1.259 +      while (edge != INVALID) {
   1.260 +	Parent::erase(edge);
   1.261 +	Parent::firstOut(edge, node);
   1.262 +      }
   1.263 +
   1.264 +      Parent::firstIn(edge, node);
   1.265 +      while (edge != INVALID) {
   1.266 +	Parent::erase(edge);
   1.267 +	Parent::firstIn(edge, node);
   1.268 +      }
   1.269 +      
   1.270 +      Parent::getNotifier(Node()).erase(node);
   1.271 +    }
   1.272 +
   1.273 +
   1.274 +    typedef typename Parent::NodesImpl NodesImpl;
   1.275 +
   1.276 +    NodesImpl nodes;
   1.277 +    
   1.278 +  public:
   1.279 +
   1.280 +    NewEdgeSetAdaptor(const _Graph& _graph) : nodes(*this, _graph) {
   1.281 +      Parent::initalize(_graph, nodes);
   1.282 +    }
   1.283 +
   1.284 +    void clear() {
   1.285 +      Parent::edges.clear();
   1.286 +      Parent::first_edge = -1;
   1.287 +      Parent::first_free_edge = -1;
   1.288 +
   1.289 +      Parent::getNotifier(Edge()).clear();      
   1.290 +    }
   1.291 +    
   1.292 +  };
   1.293 +
   1.294    ///@}
   1.295  
   1.296  } //namespace lemon