[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