lemon/list_graph.h
changeset 2205 c20b0eb92a33
parent 2160 abd867cf8a9c
child 2231 06faf3f06d67
equal deleted inserted replaced
37:2c4c326fae8a 38:f2b87333b73b
   500     /// later.
   500     /// later.
   501     ///
   501     ///
   502     /// The newly added nodes and edges can be removed using the
   502     /// The newly added nodes and edges can be removed using the
   503     /// restore() function.
   503     /// restore() function.
   504     ///
   504     ///
   505     /// \warning Edge and node deletions cannot be restored.
   505     /// \warning Edge and node deletions cannot be restored. This
       
   506     /// events invalidate the snapshot. 
   506     class Snapshot {
   507     class Snapshot {
   507     public:
       
   508       
       
   509       class UnsupportedOperation : public LogicError {
       
   510       public:
       
   511 	virtual const char* what() const throw() {
       
   512 	  return "lemon::ListGraph::Snapshot::UnsupportedOperation";
       
   513 	}
       
   514       };
       
   515             
       
   516 
       
   517     protected:
   508     protected:
   518 
   509 
   519       typedef Parent::NodeNotifier NodeNotifier;
   510       typedef Parent::NodeNotifier NodeNotifier;
   520 
   511 
   521       class NodeObserverProxy : public NodeNotifier::ObserverBase {
   512       class NodeObserverProxy : public NodeNotifier::ObserverBase {
   541         virtual void erase(const Node& node) {
   532         virtual void erase(const Node& node) {
   542           snapshot.eraseNode(node);
   533           snapshot.eraseNode(node);
   543         }
   534         }
   544         virtual void erase(const std::vector<Node>& nodes) {
   535         virtual void erase(const std::vector<Node>& nodes) {
   545           for (int i = 0; i < (int)nodes.size(); ++i) {
   536           for (int i = 0; i < (int)nodes.size(); ++i) {
   546             if (!snapshot.eraseNode(nodes[i])) break;
   537             snapshot.eraseNode(nodes[i]);
   547           }
   538           }
   548         }
   539         }
   549         virtual void build() {
   540         virtual void build() {
   550           NodeNotifier* notifier = getNotifier();
   541           NodeNotifier* notifier = getNotifier();
   551           Node node;
   542           Node node;
   559         }
   550         }
   560         virtual void clear() {
   551         virtual void clear() {
   561           NodeNotifier* notifier = getNotifier();
   552           NodeNotifier* notifier = getNotifier();
   562           Node node;
   553           Node node;
   563           for (notifier->first(node); node != INVALID; notifier->next(node)) {
   554           for (notifier->first(node); node != INVALID; notifier->next(node)) {
   564             if (!snapshot.eraseNode(node)) break;
   555             snapshot.eraseNode(node);
   565           }
   556           }
   566         }
   557         }
   567 
   558 
   568         Snapshot& snapshot;
   559         Snapshot& snapshot;
   569       };
   560       };
   591         virtual void erase(const Edge& edge) {
   582         virtual void erase(const Edge& edge) {
   592           snapshot.eraseEdge(edge);
   583           snapshot.eraseEdge(edge);
   593         }
   584         }
   594         virtual void erase(const std::vector<Edge>& edges) {
   585         virtual void erase(const std::vector<Edge>& edges) {
   595           for (int i = 0; i < (int)edges.size(); ++i) {
   586           for (int i = 0; i < (int)edges.size(); ++i) {
   596             if (!snapshot.eraseEdge(edges[i])) break;
   587             snapshot.eraseEdge(edges[i]);
   597           }
   588           }
   598         }
   589         }
   599         virtual void build() {
   590         virtual void build() {
   600           EdgeNotifier* notifier = getNotifier();
   591           EdgeNotifier* notifier = getNotifier();
   601           Edge edge;
   592           Edge edge;
   609         }
   600         }
   610         virtual void clear() {
   601         virtual void clear() {
   611           EdgeNotifier* notifier = getNotifier();
   602           EdgeNotifier* notifier = getNotifier();
   612           Edge edge;
   603           Edge edge;
   613           for (notifier->first(edge); edge != INVALID; notifier->next(edge)) {
   604           for (notifier->first(edge); edge != INVALID; notifier->next(edge)) {
   614             if (!snapshot.eraseEdge(edge)) break;
   605             snapshot.eraseEdge(edge);
   615           }
   606           }
   616         }
   607         }
   617 
   608 
   618         Snapshot& snapshot;
   609         Snapshot& snapshot;
   619       };
   610       };
   628 
   619 
   629 
   620 
   630       void addNode(const Node& node) {
   621       void addNode(const Node& node) {
   631         added_nodes.push_front(node);        
   622         added_nodes.push_front(node);        
   632       }
   623       }
   633       bool eraseNode(const Node& node) {
   624       void eraseNode(const Node& node) {
   634         std::list<Node>::iterator it = 
   625         std::list<Node>::iterator it = 
   635           std::find(added_nodes.begin(), added_nodes.end(), node);
   626           std::find(added_nodes.begin(), added_nodes.end(), node);
   636         if (it == added_nodes.end()) {
   627         if (it == added_nodes.end()) {
   637           clear();
   628           clear();
   638           return false;
   629           edge_observer_proxy.detach();
       
   630           throw NodeNotifier::ImmediateDetach();
   639         } else {
   631         } else {
   640           added_nodes.erase(it);
   632           added_nodes.erase(it);
   641           return true;
       
   642         }
   633         }
   643       }
   634       }
   644 
   635 
   645       void addEdge(const Edge& edge) {
   636       void addEdge(const Edge& edge) {
   646         added_edges.push_front(edge);        
   637         added_edges.push_front(edge);        
   647       }
   638       }
   648       bool eraseEdge(const Edge& edge) {
   639       void eraseEdge(const Edge& edge) {
   649         std::list<Edge>::iterator it = 
   640         std::list<Edge>::iterator it = 
   650           std::find(added_edges.begin(), added_edges.end(), edge);
   641           std::find(added_edges.begin(), added_edges.end(), edge);
   651         if (it == added_edges.end()) {
   642         if (it == added_edges.end()) {
   652           clear();
   643           clear();
   653           return false;
   644           node_observer_proxy.detach(); 
       
   645           throw EdgeNotifier::ImmediateDetach();
   654         } else {
   646         } else {
   655           added_edges.erase(it);
   647           added_edges.erase(it);
   656           return true;
       
   657         }        
   648         }        
   658       }
   649       }
   659 
   650 
   660       void attach(ListGraph &_graph) {
   651       void attach(ListGraph &_graph) {
   661 	graph = &_graph;
   652 	graph = &_graph;
   666       void detach() {
   657       void detach() {
   667 	node_observer_proxy.detach();
   658 	node_observer_proxy.detach();
   668 	edge_observer_proxy.detach();
   659 	edge_observer_proxy.detach();
   669       }
   660       }
   670 
   661 
       
   662       bool attached() const {
       
   663         return node_observer_proxy.attached();
       
   664       }
       
   665 
   671       void clear() {
   666       void clear() {
   672         detach();
       
   673         added_nodes.clear();
   667         added_nodes.clear();
   674         added_edges.clear();        
   668         added_edges.clear();        
   675       }
   669       }
   676 
   670 
   677     public:
   671     public:
   700       ///
   694       ///
   701       /// This function can be called more than once. In case of a repeated
   695       /// This function can be called more than once. In case of a repeated
   702       /// call, the previous snapshot gets lost.
   696       /// call, the previous snapshot gets lost.
   703       /// \param _graph The graph we make the snapshot of.
   697       /// \param _graph The graph we make the snapshot of.
   704       void save(ListGraph &_graph) {
   698       void save(ListGraph &_graph) {
   705         clear();
   699         if (attached()) {
       
   700           detach();
       
   701           clear();
       
   702         }
   706         attach(_graph);
   703         attach(_graph);
   707       }
   704       }
   708       
   705       
   709       /// \brief Undo the changes until the last snapshot.
   706       /// \brief Undo the changes until the last snapshot.
   710       // 
   707       // 
   711       /// Undo the changes until the last snapshot created by save().
   708       /// Undo the changes until the last snapshot created by save().
   712       void restore() {
   709       void restore() {
   713 	detach();
   710 	detach();
   714 	while(!added_edges.empty()) {
   711 	for(std::list<Edge>::iterator it = added_edges.begin(); 
   715 	  graph->erase(added_edges.front());
   712             it != added_edges.end(); ++it) {
   716 	  added_edges.pop_front();
   713 	  graph->erase(*it);
   717 	}
   714 	}
   718  	while(!added_nodes.empty()) {
   715 	for(std::list<Node>::iterator it = added_nodes.begin(); 
   719 	  graph->erase(added_nodes.front());
   716             it != added_nodes.end(); ++it) {
   720 	  added_nodes.pop_front();
   717 	  graph->erase(*it);
   721 	}
   718 	}
       
   719         clear();
   722       }
   720       }
   723 
   721 
   724       /// \brief Gives back true when the snapshot is valid.
   722       /// \brief Gives back true when the snapshot is valid.
   725       ///
   723       ///
   726       /// Gives back true when the snapshot is valid.
   724       /// Gives back true when the snapshot is valid.
   727       bool valid() const {
   725       bool valid() const {
   728         return node_observer_proxy.attached();
   726         return attached();
   729       }
   727       }
   730     };
   728     };
   731     
   729     
   732   };
   730   };
   733 
   731 
   857 	}
   855 	}
   858 	e = f;
   856 	e = f;
   859       }
   857       }
   860       erase(b);
   858       erase(b);
   861     }
   859     }
       
   860 
       
   861 
       
   862     /// \brief Class to make a snapshot of the graph and restore
       
   863     /// to it later.
       
   864     ///
       
   865     /// Class to make a snapshot of the graph and to restore it
       
   866     /// later.
       
   867     ///
       
   868     /// The newly added nodes and undirected edges can be removed
       
   869     /// using the restore() function.
       
   870     ///
       
   871     /// \warning Edge and node deletions cannot be restored. This
       
   872     /// events invalidate the snapshot. 
       
   873     class Snapshot {
       
   874     protected:
       
   875 
       
   876       typedef Parent::NodeNotifier NodeNotifier;
       
   877 
       
   878       class NodeObserverProxy : public NodeNotifier::ObserverBase {
       
   879       public:
       
   880 
       
   881         NodeObserverProxy(Snapshot& _snapshot)
       
   882           : snapshot(_snapshot) {}
       
   883 
       
   884         using NodeNotifier::ObserverBase::attach;
       
   885         using NodeNotifier::ObserverBase::detach;
       
   886         using NodeNotifier::ObserverBase::attached;
       
   887         
       
   888       protected:
       
   889         
       
   890         virtual void add(const Node& node) {
       
   891           snapshot.addNode(node);
       
   892         }
       
   893         virtual void add(const std::vector<Node>& nodes) {
       
   894           for (int i = nodes.size() - 1; i >= 0; ++i) {
       
   895             snapshot.addNode(nodes[i]);
       
   896           }
       
   897         }
       
   898         virtual void erase(const Node& node) {
       
   899           snapshot.eraseNode(node);
       
   900         }
       
   901         virtual void erase(const std::vector<Node>& nodes) {
       
   902           for (int i = 0; i < (int)nodes.size(); ++i) {
       
   903             snapshot.eraseNode(nodes[i]);
       
   904           }
       
   905         }
       
   906         virtual void build() {
       
   907           NodeNotifier* notifier = getNotifier();
       
   908           Node node;
       
   909           std::vector<Node> nodes;
       
   910           for (notifier->first(node); node != INVALID; notifier->next(node)) {
       
   911             nodes.push_back(node);
       
   912           }
       
   913           for (int i = nodes.size() - 1; i >= 0; --i) {
       
   914             snapshot.addNode(nodes[i]);
       
   915           }
       
   916         }
       
   917         virtual void clear() {
       
   918           NodeNotifier* notifier = getNotifier();
       
   919           Node node;
       
   920           for (notifier->first(node); node != INVALID; notifier->next(node)) {
       
   921             snapshot.eraseNode(node);
       
   922           }
       
   923         }
       
   924 
       
   925         Snapshot& snapshot;
       
   926       };
       
   927 
       
   928       class UEdgeObserverProxy : public UEdgeNotifier::ObserverBase {
       
   929       public:
       
   930 
       
   931         UEdgeObserverProxy(Snapshot& _snapshot)
       
   932           : snapshot(_snapshot) {}
       
   933 
       
   934         using UEdgeNotifier::ObserverBase::attach;
       
   935         using UEdgeNotifier::ObserverBase::detach;
       
   936         using UEdgeNotifier::ObserverBase::attached;
       
   937         
       
   938       protected:
       
   939 
       
   940         virtual void add(const UEdge& edge) {
       
   941           snapshot.addUEdge(edge);
       
   942         }
       
   943         virtual void add(const std::vector<UEdge>& edges) {
       
   944           for (int i = edges.size() - 1; i >= 0; ++i) {
       
   945             snapshot.addUEdge(edges[i]);
       
   946           }
       
   947         }
       
   948         virtual void erase(const UEdge& edge) {
       
   949           snapshot.eraseUEdge(edge);
       
   950         }
       
   951         virtual void erase(const std::vector<UEdge>& edges) {
       
   952           for (int i = 0; i < (int)edges.size(); ++i) {
       
   953             snapshot.eraseUEdge(edges[i]);
       
   954           }
       
   955         }
       
   956         virtual void build() {
       
   957           UEdgeNotifier* notifier = getNotifier();
       
   958           UEdge edge;
       
   959           std::vector<UEdge> edges;
       
   960           for (notifier->first(edge); edge != INVALID; notifier->next(edge)) {
       
   961             edges.push_back(edge);
       
   962           }
       
   963           for (int i = edges.size() - 1; i >= 0; --i) {
       
   964             snapshot.addUEdge(edges[i]);
       
   965           }
       
   966         }
       
   967         virtual void clear() {
       
   968           UEdgeNotifier* notifier = getNotifier();
       
   969           UEdge edge;
       
   970           for (notifier->first(edge); edge != INVALID; notifier->next(edge)) {
       
   971             snapshot.eraseUEdge(edge);
       
   972           }
       
   973         }
       
   974 
       
   975         Snapshot& snapshot;
       
   976       };
       
   977       
       
   978       ListUGraph *graph;
       
   979 
       
   980       NodeObserverProxy node_observer_proxy;
       
   981       UEdgeObserverProxy edge_observer_proxy;
       
   982 
       
   983       std::list<Node> added_nodes;
       
   984       std::list<UEdge> added_edges;
       
   985 
       
   986 
       
   987       void addNode(const Node& node) {
       
   988         added_nodes.push_front(node);        
       
   989       }
       
   990       void eraseNode(const Node& node) {
       
   991         std::list<Node>::iterator it = 
       
   992           std::find(added_nodes.begin(), added_nodes.end(), node);
       
   993         if (it == added_nodes.end()) {
       
   994           clear();
       
   995           edge_observer_proxy.detach();
       
   996           throw NodeNotifier::ImmediateDetach();
       
   997         } else {
       
   998           added_nodes.erase(it);
       
   999         }
       
  1000       }
       
  1001 
       
  1002       void addUEdge(const UEdge& edge) {
       
  1003         added_edges.push_front(edge);        
       
  1004       }
       
  1005       void eraseUEdge(const UEdge& edge) {
       
  1006         std::list<UEdge>::iterator it = 
       
  1007           std::find(added_edges.begin(), added_edges.end(), edge);
       
  1008         if (it == added_edges.end()) {
       
  1009           clear();
       
  1010           node_observer_proxy.detach();
       
  1011           throw UEdgeNotifier::ImmediateDetach();
       
  1012         } else {
       
  1013           added_edges.erase(it);
       
  1014         }        
       
  1015       }
       
  1016 
       
  1017       void attach(ListUGraph &_graph) {
       
  1018 	graph = &_graph;
       
  1019 	node_observer_proxy.attach(graph->getNotifier(Node()));
       
  1020         edge_observer_proxy.attach(graph->getNotifier(UEdge()));
       
  1021       }
       
  1022             
       
  1023       void detach() {
       
  1024 	node_observer_proxy.detach();
       
  1025 	edge_observer_proxy.detach();
       
  1026       }
       
  1027 
       
  1028       bool attached() const {
       
  1029         return node_observer_proxy.attached();
       
  1030       }
       
  1031 
       
  1032       void clear() {
       
  1033         added_nodes.clear();
       
  1034         added_edges.clear();        
       
  1035       }
       
  1036 
       
  1037     public:
       
  1038 
       
  1039       /// \brief Default constructor.
       
  1040       ///
       
  1041       /// Default constructor.
       
  1042       /// To actually make a snapshot you must call save().
       
  1043       Snapshot() 
       
  1044         : graph(0), node_observer_proxy(*this), 
       
  1045           edge_observer_proxy(*this) {}
       
  1046       
       
  1047       /// \brief Constructor that immediately makes a snapshot.
       
  1048       ///      
       
  1049       /// This constructor immediately makes a snapshot of the graph.
       
  1050       /// \param _graph The graph we make a snapshot of.
       
  1051       Snapshot(ListUGraph &_graph) 
       
  1052         : node_observer_proxy(*this), 
       
  1053           edge_observer_proxy(*this) {
       
  1054 	attach(_graph);
       
  1055       }
       
  1056       
       
  1057       /// \brief Make a snapshot.
       
  1058       ///
       
  1059       /// Make a snapshot of the graph.
       
  1060       ///
       
  1061       /// This function can be called more than once. In case of a repeated
       
  1062       /// call, the previous snapshot gets lost.
       
  1063       /// \param _graph The graph we make the snapshot of.
       
  1064       void save(ListUGraph &_graph) {
       
  1065         if (attached()) {
       
  1066           detach();
       
  1067           clear();
       
  1068         }
       
  1069         attach(_graph);
       
  1070       }
       
  1071       
       
  1072       /// \brief Undo the changes until the last snapshot.
       
  1073       // 
       
  1074       /// Undo the changes until the last snapshot created by save().
       
  1075       void restore() {
       
  1076 	detach();
       
  1077 	for(std::list<UEdge>::iterator it = added_edges.begin(); 
       
  1078             it != added_edges.end(); ++it) {
       
  1079 	  graph->erase(*it);
       
  1080 	}
       
  1081 	for(std::list<Node>::iterator it = added_nodes.begin(); 
       
  1082             it != added_nodes.end(); ++it) {
       
  1083 	  graph->erase(*it);
       
  1084 	}
       
  1085         clear();
       
  1086       }
       
  1087 
       
  1088       /// \brief Gives back true when the snapshot is valid.
       
  1089       ///
       
  1090       /// Gives back true when the snapshot is valid.
       
  1091       bool valid() const {
       
  1092         return attached();
       
  1093       }
       
  1094     };
   862   };
  1095   };
   863 
  1096 
   864 
  1097 
   865   class ListBpUGraphBase {
  1098   class ListBpUGraphBase {
   866   public:
  1099   public:
  1103         bNodes[bNodeId].next = (first_bnode << 1) + 1;
  1336         bNodes[bNodeId].next = (first_bnode << 1) + 1;
  1104         bNodes[first_bnode].prev = (bNodeId << 1) + 1;
  1337         bNodes[first_bnode].prev = (bNodeId << 1) + 1;
  1105       } else {
  1338       } else {
  1106         bNodes[bNodeId].next = -1;
  1339         bNodes[bNodeId].next = -1;
  1107       }
  1340       }
       
  1341       bNodes[bNodeId].prev = -1;
  1108       first_bnode = bNodeId;
  1342       first_bnode = bNodeId;
  1109       bNodes[bNodeId].first_edge = -1;
  1343       bNodes[bNodeId].first_edge = -1;
  1110       return Node((bNodeId << 1) + 1);
  1344       return Node((bNodeId << 1) + 1);
  1111     }
  1345     }
  1112 
  1346 
  1146       if (aNode(node)) {
  1380       if (aNode(node)) {
  1147         int aNodeId = node.id >> 1;
  1381         int aNodeId = node.id >> 1;
  1148         if (aNodes[aNodeId].prev != -1) {
  1382         if (aNodes[aNodeId].prev != -1) {
  1149           aNodes[aNodes[aNodeId].prev >> 1].next = aNodes[aNodeId].next;
  1383           aNodes[aNodes[aNodeId].prev >> 1].next = aNodes[aNodeId].next;
  1150         } else {
  1384         } else {
  1151           first_anode = aNodes[aNodeId].next >> 1;
  1385           first_anode = 
       
  1386             aNodes[aNodeId].next != -1 ? aNodes[aNodeId].next >> 1 : -1;
  1152         }
  1387         }
  1153         if (aNodes[aNodeId].next != -1) {
  1388         if (aNodes[aNodeId].next != -1) {
  1154           aNodes[aNodes[aNodeId].next >> 1].prev = aNodes[aNodeId].prev;
  1389           aNodes[aNodes[aNodeId].next >> 1].prev = aNodes[aNodeId].prev;
  1155         }
  1390         }
  1156         aNodes[aNodeId].next = first_free_anode;
  1391         aNodes[aNodeId].next = first_free_anode;
  1158       } else {
  1393       } else {
  1159         int bNodeId = node.id >> 1;
  1394         int bNodeId = node.id >> 1;
  1160         if (bNodes[bNodeId].prev != -1) {
  1395         if (bNodes[bNodeId].prev != -1) {
  1161           bNodes[bNodes[bNodeId].prev >> 1].next = bNodes[bNodeId].next;
  1396           bNodes[bNodes[bNodeId].prev >> 1].next = bNodes[bNodeId].next;
  1162         } else {
  1397         } else {
  1163           first_bnode = bNodes[bNodeId].next >> 1;
  1398           first_bnode = 
       
  1399             bNodes[bNodeId].next != -1 ? bNodes[bNodeId].next >> 1 : -1;
  1164         }
  1400         }
  1165         if (bNodes[bNodeId].next != -1) {
  1401         if (bNodes[bNodeId].next != -1) {
  1166           bNodes[bNodes[bNodeId].next >> 1].prev = bNodes[bNodeId].prev;
  1402           bNodes[bNodes[bNodeId].next >> 1].prev = bNodes[bNodeId].prev;
  1167         }
  1403         }
  1168         bNodes[bNodeId].next = first_free_bnode;
  1404         bNodes[bNodeId].next = first_free_bnode;
  1394         }
  1630         }
  1395       }
  1631       }
  1396       erase(b);
  1632       erase(b);
  1397     }
  1633     }
  1398 
  1634 
       
  1635     /// \brief Class to make a snapshot of the graph and restore
       
  1636     /// to it later.
       
  1637     ///
       
  1638     /// Class to make a snapshot of the graph and to restore it
       
  1639     /// later.
       
  1640     ///
       
  1641     /// The newly added nodes and undirected edges can be removed
       
  1642     /// using the restore() function.
       
  1643     ///
       
  1644     /// \warning Edge and node deletions cannot be restored. This
       
  1645     /// events invalidate the snapshot. 
       
  1646     class Snapshot {
       
  1647     protected:
       
  1648 
       
  1649       typedef Parent::NodeNotifier NodeNotifier;
       
  1650 
       
  1651       class NodeObserverProxy : public NodeNotifier::ObserverBase {
       
  1652       public:
       
  1653 
       
  1654         NodeObserverProxy(Snapshot& _snapshot)
       
  1655           : snapshot(_snapshot) {}
       
  1656 
       
  1657         using NodeNotifier::ObserverBase::attach;
       
  1658         using NodeNotifier::ObserverBase::detach;
       
  1659         using NodeNotifier::ObserverBase::attached;
       
  1660         
       
  1661       protected:
       
  1662         
       
  1663         virtual void add(const Node& node) {
       
  1664           snapshot.addNode(node);
       
  1665         }
       
  1666         virtual void add(const std::vector<Node>& nodes) {
       
  1667           for (int i = nodes.size() - 1; i >= 0; ++i) {
       
  1668             snapshot.addNode(nodes[i]);
       
  1669           }
       
  1670         }
       
  1671         virtual void erase(const Node& node) {
       
  1672           snapshot.eraseNode(node);
       
  1673         }
       
  1674         virtual void erase(const std::vector<Node>& nodes) {
       
  1675           for (int i = 0; i < (int)nodes.size(); ++i) {
       
  1676             snapshot.eraseNode(nodes[i]);
       
  1677           }
       
  1678         }
       
  1679         virtual void build() {
       
  1680           NodeNotifier* notifier = getNotifier();
       
  1681           Node node;
       
  1682           std::vector<Node> nodes;
       
  1683           for (notifier->first(node); node != INVALID; notifier->next(node)) {
       
  1684             nodes.push_back(node);
       
  1685           }
       
  1686           for (int i = nodes.size() - 1; i >= 0; --i) {
       
  1687             snapshot.addNode(nodes[i]);
       
  1688           }
       
  1689         }
       
  1690         virtual void clear() {
       
  1691           NodeNotifier* notifier = getNotifier();
       
  1692           Node node;
       
  1693           for (notifier->first(node); node != INVALID; notifier->next(node)) {
       
  1694             snapshot.eraseNode(node);
       
  1695           }
       
  1696         }
       
  1697 
       
  1698         Snapshot& snapshot;
       
  1699       };
       
  1700 
       
  1701       class UEdgeObserverProxy : public UEdgeNotifier::ObserverBase {
       
  1702       public:
       
  1703 
       
  1704         UEdgeObserverProxy(Snapshot& _snapshot)
       
  1705           : snapshot(_snapshot) {}
       
  1706 
       
  1707         using UEdgeNotifier::ObserverBase::attach;
       
  1708         using UEdgeNotifier::ObserverBase::detach;
       
  1709         using UEdgeNotifier::ObserverBase::attached;
       
  1710         
       
  1711       protected:
       
  1712 
       
  1713         virtual void add(const UEdge& edge) {
       
  1714           snapshot.addUEdge(edge);
       
  1715         }
       
  1716         virtual void add(const std::vector<UEdge>& edges) {
       
  1717           for (int i = edges.size() - 1; i >= 0; ++i) {
       
  1718             snapshot.addUEdge(edges[i]);
       
  1719           }
       
  1720         }
       
  1721         virtual void erase(const UEdge& edge) {
       
  1722           snapshot.eraseUEdge(edge);
       
  1723         }
       
  1724         virtual void erase(const std::vector<UEdge>& edges) {
       
  1725           for (int i = 0; i < (int)edges.size(); ++i) {
       
  1726             snapshot.eraseUEdge(edges[i]);
       
  1727           }
       
  1728         }
       
  1729         virtual void build() {
       
  1730           UEdgeNotifier* notifier = getNotifier();
       
  1731           UEdge edge;
       
  1732           std::vector<UEdge> edges;
       
  1733           for (notifier->first(edge); edge != INVALID; notifier->next(edge)) {
       
  1734             edges.push_back(edge);
       
  1735           }
       
  1736           for (int i = edges.size() - 1; i >= 0; --i) {
       
  1737             snapshot.addUEdge(edges[i]);
       
  1738           }
       
  1739         }
       
  1740         virtual void clear() {
       
  1741           UEdgeNotifier* notifier = getNotifier();
       
  1742           UEdge edge;
       
  1743           for (notifier->first(edge); edge != INVALID; notifier->next(edge)) {
       
  1744             snapshot.eraseUEdge(edge);
       
  1745           }
       
  1746         }
       
  1747 
       
  1748         Snapshot& snapshot;
       
  1749       };
       
  1750       
       
  1751       ListBpUGraph *graph;
       
  1752 
       
  1753       NodeObserverProxy node_observer_proxy;
       
  1754       UEdgeObserverProxy edge_observer_proxy;
       
  1755 
       
  1756       std::list<Node> added_nodes;
       
  1757       std::list<UEdge> added_edges;
       
  1758 
       
  1759 
       
  1760       void addNode(const Node& node) {
       
  1761         added_nodes.push_front(node);        
       
  1762       }
       
  1763       void eraseNode(const Node& node) {
       
  1764         std::list<Node>::iterator it = 
       
  1765           std::find(added_nodes.begin(), added_nodes.end(), node);
       
  1766         if (it == added_nodes.end()) {
       
  1767           clear();
       
  1768           edge_observer_proxy.detach();
       
  1769           throw NodeNotifier::ImmediateDetach();
       
  1770         } else {
       
  1771           added_nodes.erase(it);
       
  1772         }
       
  1773       }
       
  1774 
       
  1775       void addUEdge(const UEdge& edge) {
       
  1776         added_edges.push_front(edge);        
       
  1777       }
       
  1778       void eraseUEdge(const UEdge& edge) {
       
  1779         std::list<UEdge>::iterator it = 
       
  1780           std::find(added_edges.begin(), added_edges.end(), edge);
       
  1781         if (it == added_edges.end()) {
       
  1782           clear();
       
  1783           node_observer_proxy.detach();
       
  1784           throw UEdgeNotifier::ImmediateDetach();
       
  1785         } else {
       
  1786           added_edges.erase(it);
       
  1787         }        
       
  1788       }
       
  1789 
       
  1790       void attach(ListBpUGraph &_graph) {
       
  1791 	graph = &_graph;
       
  1792 	node_observer_proxy.attach(graph->getNotifier(Node()));
       
  1793         edge_observer_proxy.attach(graph->getNotifier(UEdge()));
       
  1794       }
       
  1795             
       
  1796       void detach() {
       
  1797 	node_observer_proxy.detach();
       
  1798 	edge_observer_proxy.detach();
       
  1799       }
       
  1800 
       
  1801       bool attached() const {
       
  1802         return node_observer_proxy.attached();
       
  1803       }
       
  1804 
       
  1805       void clear() {
       
  1806         added_nodes.clear();
       
  1807         added_edges.clear();        
       
  1808       }
       
  1809 
       
  1810     public:
       
  1811 
       
  1812       /// \brief Default constructor.
       
  1813       ///
       
  1814       /// Default constructor.
       
  1815       /// To actually make a snapshot you must call save().
       
  1816       Snapshot() 
       
  1817         : graph(0), node_observer_proxy(*this), 
       
  1818           edge_observer_proxy(*this) {}
       
  1819       
       
  1820       /// \brief Constructor that immediately makes a snapshot.
       
  1821       ///      
       
  1822       /// This constructor immediately makes a snapshot of the graph.
       
  1823       /// \param _graph The graph we make a snapshot of.
       
  1824       Snapshot(ListBpUGraph &_graph) 
       
  1825         : node_observer_proxy(*this), 
       
  1826           edge_observer_proxy(*this) {
       
  1827 	attach(_graph);
       
  1828       }
       
  1829       
       
  1830       /// \brief Make a snapshot.
       
  1831       ///
       
  1832       /// Make a snapshot of the graph.
       
  1833       ///
       
  1834       /// This function can be called more than once. In case of a repeated
       
  1835       /// call, the previous snapshot gets lost.
       
  1836       /// \param _graph The graph we make the snapshot of.
       
  1837       void save(ListBpUGraph &_graph) {
       
  1838         if (attached()) {
       
  1839           detach();
       
  1840           clear();
       
  1841         }
       
  1842         attach(_graph);
       
  1843       }
       
  1844       
       
  1845       /// \brief Undo the changes until the last snapshot.
       
  1846       // 
       
  1847       /// Undo the changes until the last snapshot created by save().
       
  1848       void restore() {
       
  1849 	detach();
       
  1850 	for(std::list<UEdge>::iterator it = added_edges.begin(); 
       
  1851             it != added_edges.end(); ++it) {
       
  1852 	  graph->erase(*it);
       
  1853 	}
       
  1854 	for(std::list<Node>::iterator it = added_nodes.begin(); 
       
  1855             it != added_nodes.end(); ++it) {
       
  1856 	  graph->erase(*it);
       
  1857 	}
       
  1858         clear();
       
  1859       }
       
  1860 
       
  1861       /// \brief Gives back true when the snapshot is valid.
       
  1862       ///
       
  1863       /// Gives back true when the snapshot is valid.
       
  1864       bool valid() const {
       
  1865         return attached();
       
  1866       }
       
  1867     };
  1399   };
  1868   };
  1400 
  1869 
  1401   
  1870   
  1402   /// @}  
  1871   /// @}  
  1403 } //namespace lemon
  1872 } //namespace lemon