[Lemon-commits] Alpar Juttner: Merge

Lemon HG hg at lemon.cs.elte.hu
Tue May 26 16:57:39 CEST 2015


details:   http://lemon.cs.elte.hu/hg/lemon/rev/138714057145
changeset: 1356:138714057145
user:      Alpar Juttner <alpar [at] cs.elte.hu>
date:      Fri May 22 17:44:29 2015 +0200
description:
	Merge

diffstat:

 lemon/list_graph.h |  3434 ++++++++++++++++++++++++++--------------------------
 1 files changed, 1717 insertions(+), 1717 deletions(-)

diffs (truncated from 3458 to 300 lines):

diff --git a/lemon/list_graph.h b/lemon/list_graph.h
--- a/lemon/list_graph.h
+++ b/lemon/list_graph.h
@@ -582,6 +582,1723 @@
           snapshot.addNode(node);
         }
         virtual void add(const std::vector<Node>& nodes) {
+          for (int i = nodes.size() - 1; i >= 0; --i) {
+            snapshot.addNode(nodes[i]);
+          }
+        }
+        virtual void erase(const Node& node) {
+          snapshot.eraseNode(node);
+        }
+        virtual void erase(const std::vector<Node>& nodes) {
+          for (int i = 0; i < int(nodes.size()); ++i) {
+            snapshot.eraseNode(nodes[i]);
+          }
+        }
+        virtual void build() {
+          Node node;
+          std::vector<Node> nodes;
+          for (notifier()->first(node); node != INVALID;
+               notifier()->next(node)) {
+            nodes.push_back(node);
+          }
+          for (int i = nodes.size() - 1; i >= 0; --i) {
+            snapshot.addNode(nodes[i]);
+          }
+        }
+        virtual void clear() {
+          Node node;
+          for (notifier()->first(node); node != INVALID;
+               notifier()->next(node)) {
+            snapshot.eraseNode(node);
+          }
+        }
+
+        Snapshot& snapshot;
+      };
+
+      class ArcObserverProxy : public ArcNotifier::ObserverBase {
+      public:
+
+        ArcObserverProxy(Snapshot& _snapshot)
+          : snapshot(_snapshot) {}
+
+        using ArcNotifier::ObserverBase::attach;
+        using ArcNotifier::ObserverBase::detach;
+        using ArcNotifier::ObserverBase::attached;
+
+      protected:
+
+        virtual void add(const Arc& arc) {
+          snapshot.addArc(arc);
+        }
+        virtual void add(const std::vector<Arc>& arcs) {
+          for (int i = arcs.size() - 1; i >= 0; --i) {
+            snapshot.addArc(arcs[i]);
+          }
+        }
+        virtual void erase(const Arc& arc) {
+          snapshot.eraseArc(arc);
+        }
+        virtual void erase(const std::vector<Arc>& arcs) {
+          for (int i = 0; i < int(arcs.size()); ++i) {
+            snapshot.eraseArc(arcs[i]);
+          }
+        }
+        virtual void build() {
+          Arc arc;
+          std::vector<Arc> arcs;
+          for (notifier()->first(arc); arc != INVALID;
+               notifier()->next(arc)) {
+            arcs.push_back(arc);
+          }
+          for (int i = arcs.size() - 1; i >= 0; --i) {
+            snapshot.addArc(arcs[i]);
+          }
+        }
+        virtual void clear() {
+          Arc arc;
+          for (notifier()->first(arc); arc != INVALID;
+               notifier()->next(arc)) {
+            snapshot.eraseArc(arc);
+          }
+        }
+
+        Snapshot& snapshot;
+      };
+
+      ListDigraph *digraph;
+
+      NodeObserverProxy node_observer_proxy;
+      ArcObserverProxy arc_observer_proxy;
+
+      std::list<Node> added_nodes;
+      std::list<Arc> added_arcs;
+
+
+      void addNode(const Node& node) {
+        added_nodes.push_front(node);
+      }
+      void eraseNode(const Node& node) {
+        std::list<Node>::iterator it =
+          std::find(added_nodes.begin(), added_nodes.end(), node);
+        if (it == added_nodes.end()) {
+          clear();
+          arc_observer_proxy.detach();
+          throw NodeNotifier::ImmediateDetach();
+        } else {
+          added_nodes.erase(it);
+        }
+      }
+
+      void addArc(const Arc& arc) {
+        added_arcs.push_front(arc);
+      }
+      void eraseArc(const Arc& arc) {
+        std::list<Arc>::iterator it =
+          std::find(added_arcs.begin(), added_arcs.end(), arc);
+        if (it == added_arcs.end()) {
+          clear();
+          node_observer_proxy.detach();
+          throw ArcNotifier::ImmediateDetach();
+        } else {
+          added_arcs.erase(it);
+        }
+      }
+
+      void attach(ListDigraph &_digraph) {
+        digraph = &_digraph;
+        node_observer_proxy.attach(digraph->notifier(Node()));
+        arc_observer_proxy.attach(digraph->notifier(Arc()));
+      }
+
+      void detach() {
+        node_observer_proxy.detach();
+        arc_observer_proxy.detach();
+      }
+
+      bool attached() const {
+        return node_observer_proxy.attached();
+      }
+
+      void clear() {
+        added_nodes.clear();
+        added_arcs.clear();
+      }
+
+    public:
+
+      /// \brief Default constructor.
+      ///
+      /// Default constructor.
+      /// You have to call save() to actually make a snapshot.
+      Snapshot()
+        : digraph(0), node_observer_proxy(*this),
+          arc_observer_proxy(*this) {}
+
+      /// \brief Constructor that immediately makes a snapshot.
+      ///
+      /// This constructor immediately makes a snapshot of the given digraph.
+      Snapshot(ListDigraph &gr)
+        : node_observer_proxy(*this),
+          arc_observer_proxy(*this) {
+        attach(gr);
+      }
+
+      /// \brief Make a snapshot.
+      ///
+      /// This function makes a snapshot of the given digraph.
+      /// It can be called more than once. In case of a repeated
+      /// call, the previous snapshot gets lost.
+      void save(ListDigraph &gr) {
+        if (attached()) {
+          detach();
+          clear();
+        }
+        attach(gr);
+      }
+
+      /// \brief Undo the changes until the last snapshot.
+      ///
+      /// This function undos the changes until the last snapshot
+      /// created by save() or Snapshot(ListDigraph&).
+      ///
+      /// \warning This method invalidates the snapshot, i.e. repeated
+      /// restoring is not supported unless you call save() again.
+      void restore() {
+        detach();
+        for(std::list<Arc>::iterator it = added_arcs.begin();
+            it != added_arcs.end(); ++it) {
+          digraph->erase(*it);
+        }
+        for(std::list<Node>::iterator it = added_nodes.begin();
+            it != added_nodes.end(); ++it) {
+          digraph->erase(*it);
+        }
+        clear();
+      }
+
+      /// \brief Returns \c true if the snapshot is valid.
+      ///
+      /// This function returns \c true if the snapshot is valid.
+      bool valid() const {
+        return attached();
+      }
+    };
+
+  };
+
+  ///@}
+
+  class ListGraphBase {
+
+  protected:
+
+    struct NodeT {
+      int first_out;
+      int prev, next;
+    };
+
+    struct ArcT {
+      int target;
+      int prev_out, next_out;
+    };
+
+    std::vector<NodeT> nodes;
+
+    int first_node;
+
+    int first_free_node;
+
+    std::vector<ArcT> arcs;
+
+    int first_free_arc;
+
+  public:
+
+    typedef ListGraphBase Graph;
+
+    class Node {
+      friend class ListGraphBase;
+    protected:
+
+      int id;
+      explicit Node(int pid) { id = pid;}
+
+    public:
+      Node() {}
+      Node (Invalid) { id = -1; }
+      bool operator==(const Node& node) const {return id == node.id;}
+      bool operator!=(const Node& node) const {return id != node.id;}
+      bool operator<(const Node& node) const {return id < node.id;}
+    };
+
+    class Edge {
+      friend class ListGraphBase;
+    protected:
+
+      int id;
+      explicit Edge(int pid) { id = pid;}
+
+    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;}
+    };
+
+    class Arc {
+      friend class ListGraphBase;
+    protected:
+
+      int id;
+      explicit Arc(int pid) { id = pid;}
+
+    public:
+      operator Edge() const {
+        return id != -1 ? edgeFromId(id / 2) : INVALID;
+      }
+
+      Arc() {}
+      Arc (Invalid) { id = -1; }
+      bool operator==(const Arc& arc) const {return id == arc.id;}
+      bool operator!=(const Arc& arc) const {return id != arc.id;}
+      bool operator<(const Arc& arc) const {return id < arc.id;}
+    };
+
+    ListGraphBase()
+      : nodes(), first_node(-1),
+        first_free_node(-1), arcs(), first_free_arc(-1) {}
+
+
+    int maxNodeId() const { return nodes.size()-1; }
+    int maxEdgeId() const { return arcs.size() / 2 - 1; }
+    int maxArcId() const { return arcs.size()-1; }
+


More information about the Lemon-commits mailing list