Ticket #462: 81d113c593ef.patch
File 81d113c593ef.patch, 27.7 KB (added by , 11 years ago) |
---|
-
lemon/bits/graph_extender.h
# HG changeset patch # User Alpar Juttner <alpar@cs.elte.hu> # Date 1382812662 -7200 # Sat Oct 26 20:37:42 2013 +0200 # Node ID 81d113c593ef2fe691f5cc7ad2842a114fdb837f # Parent ce896fa7fd65d16cb390579f12f57249aeb874a4 Extended run time checking in debug mode, WIP (#462) diff --git a/lemon/bits/graph_extender.h b/lemon/bits/graph_extender.h
a b 56 56 return Parent::maxArcId(); 57 57 } 58 58 59 static Node fromId(int id, Node){60 return Parent::nodeFromId(id);59 Node fromId(int id, Node) const { 60 return this->nodeFromId(id); 61 61 } 62 62 63 static Arc fromId(int id, Arc){64 return Parent::arcFromId(id);63 Arc fromId(int id, Arc) const { 64 return this->arcFromId(id); 65 65 } 66 66 67 67 Node oppositeNode(const Node &node, const Arc &arc) const { … … 355 355 return Parent::maxEdgeId(); 356 356 } 357 357 358 static Node fromId(int id, Node){358 Node fromId(int id, Node) const { 359 359 return Parent::nodeFromId(id); 360 360 } 361 361 362 static Arc fromId(int id, Arc){362 Arc fromId(int id, Arc) const { 363 363 return Parent::arcFromId(id); 364 364 } 365 365 366 static Edge fromId(int id, Edge){366 Edge fromId(int id, Edge) const { 367 367 return Parent::edgeFromId(id); 368 368 } 369 369 … … 791 791 return Parent::maxEdgeId(); 792 792 } 793 793 794 static Node fromId(int id, Node){794 Node fromId(int id, Node) const { 795 795 return Parent::nodeFromId(id); 796 796 } 797 797 798 static Arc fromId(int id, Arc){798 Arc fromId(int id, Arc) const { 799 799 return Parent::arcFromId(id); 800 800 } 801 801 802 static Edge fromId(int id, Edge){802 fromId(int id, Edge) const { 803 803 return Parent::edgeFromId(id); 804 804 } 805 805 -
lemon/list_graph.h
diff --git a/lemon/list_graph.h b/lemon/list_graph.h
a b 67 67 friend class ListDigraph; 68 68 protected: 69 69 70 #ifdef LEMON_ENABLE_DEBUG 71 const Digraph *graph; 72 #endif 70 73 int id; 71 explicit Node(int pid) { id = pid;} 72 74 75 void set(const Digraph *g, int pid) 76 { 77 #ifdef LEMON_ENABLE_DEBUG 78 graph=g; 79 #else 80 ignore_unused_variable_warning(g); 81 #endif 82 id = pid; 83 } 84 85 explicit Node(const Digraph *g, int pid) { set(g,pid); } 86 87 void check_initialized() const { 88 LEMON_DEBUG(graph || id == -1, "Node used uninitialized"); 89 } 90 void check_comparable(const Node &node) const { 91 check_initialized(); 92 node.check_initialized(); 93 LEMON_DEBUG(!graph || !node.graph || graph == node.graph, 94 "Compare nodes pointing to different graphs"); 95 } 73 96 public: 74 Node() {} 75 Node (Invalid) { id = -1; } 76 bool operator==(const Node& node) const {return id == node.id;} 77 bool operator!=(const Node& node) const {return id != node.id;} 78 bool operator<(const Node& node) const {return id < node.id;} 97 Node() 98 #ifdef LEMON_ENABLE_DEBUG 99 : graph(NULL), id(-2) 100 #endif 101 {} 102 Node (Invalid) 103 #ifdef LEMON_ENABLE_DEBUG 104 : graph(NULL) 105 #endif 106 { id = -1; } 107 bool operator==(const Node& node) const 108 { 109 check_comparable(node); 110 return id == node.id; 111 } 112 bool operator!=(const Node& node) const { 113 check_comparable(node); 114 return id != node.id; 115 } 116 bool operator<(const Node& node) const { 117 check_comparable(node); 118 return id < node.id; 119 } 79 120 }; 80 121 81 122 class Arc { … … 83 124 friend class ListDigraph; 84 125 protected: 85 126 127 #ifdef LEMON_ENABLE_DEBUG 128 const Digraph *graph; 129 #endif 86 130 int id; 87 explicit Arc(int pid) { id = pid;} 131 132 void set(const Digraph *g, int pid) 133 { 134 #ifdef LEMON_ENABLE_DEBUG 135 graph=g; 136 #else 137 ignore_unused_variable_warning(g); 138 #endif 139 id = pid; 140 } 141 142 explicit Arc(const Digraph *g, int pid) { set(g,pid); } 143 144 void check_initialized() const { 145 LEMON_DEBUG(graph || id == -1, "Arc used uninitialized"); 146 } 147 void check_comparable(const Arc &arc) const { 148 check_initialized(); 149 arc.check_initialized(); 150 LEMON_DEBUG(!graph || !arc.graph || graph == arc.graph, 151 "Compare arcs pointing to different graphs"); 152 } 88 153 89 154 public: 90 Arc() {} 91 Arc (Invalid) { id = -1; } 92 bool operator==(const Arc& arc) const {return id == arc.id;} 93 bool operator!=(const Arc& arc) const {return id != arc.id;} 94 bool operator<(const Arc& arc) const {return id < arc.id;} 155 Arc() 156 #ifdef LEMON_ENABLE_DEBUG 157 : graph(NULL), id(-2) 158 #endif 159 {} 160 Arc (Invalid) 161 #ifdef LEMON_ENABLE_DEBUG 162 : graph(NULL) 163 #endif 164 { id = -1; } 165 bool operator==(const Arc& arc) const { 166 check_comparable(arc); 167 return id == arc.id; 168 } 169 bool operator!=(const Arc& arc) const { 170 check_comparable(arc); 171 return id != arc.id; 172 } 173 bool operator<(const Arc& arc) const { 174 check_comparable(arc); 175 return id < arc.id; 176 } 95 177 }; 96 178 97 98 179 protected: 180 void check_mine(const Node &node) const 181 { 182 ignore_unused_variable_warning(node); 183 LEMON_DEBUG(node.graph == this && 184 node.id >= 0 && node.id < static_cast<int>(nodes.size()) && 185 nodes[node.id].prev != -2, 186 "Node points to a wrong graphs"); 187 } 188 void check_mine(const Arc &arc) const 189 { 190 ignore_unused_variable_warning(arc); 191 LEMON_DEBUG(arc.graph == this && 192 arc.id >= 0 && 193 arc.id < static_cast<int>(arcs.size()) && 194 arcs[arc.id].prev_in != -2, 195 "Arc points to a wrong graphs"); 196 } 197 198 public: 99 199 ListDigraphBase() 100 200 : nodes(), first_node(-1), 101 201 first_free_node(-1), arcs(), first_free_arc(-1) {} … … 104 204 int maxNodeId() const { return nodes.size()-1; } 105 205 int maxArcId() const { return arcs.size()-1; } 106 206 107 Node source(Arc e) const { return Node(arcs[e.id].source); } 108 Node target(Arc e) const { return Node(arcs[e.id].target); } 207 Node source(Arc e) const 208 { 209 check_mine(e); 210 return Node(this,arcs[e.id].source); 211 } 212 Node target(Arc e) const 213 { 214 check_mine(e); 215 return Node(this,arcs[e.id].target); 216 } 109 217 110 218 111 219 void first(Node& node) const { 112 node. id = first_node;220 node.set(this, first_node); 113 221 } 114 222 115 223 void next(Node& node) const { 224 check_mine(node); 116 225 node.id = nodes[node.id].next; 117 226 } 118 227 … … 122 231 for(n = first_node; 123 232 n != -1 && nodes[n].first_out == -1; 124 233 n = nodes[n].next) {} 125 arc. id = (n == -1) ? -1 : nodes[n].first_out;234 arc.set(this, (n == -1) ? -1 : nodes[n].first_out); 126 235 } 127 236 128 237 void next(Arc& arc) const { 238 check_mine(arc); 129 239 if (arcs[arc.id].next_out != -1) { 130 240 arc.id = arcs[arc.id].next_out; 131 241 } else { … … 138 248 } 139 249 140 250 void firstOut(Arc &e, const Node& v) const { 141 e.id = nodes[v.id].first_out; 251 check_mine(v); 252 e.set(this, nodes[v.id].first_out); 142 253 } 143 254 void nextOut(Arc &e) const { 255 check_mine(e); 144 256 e.id=arcs[e.id].next_out; 145 257 } 146 258 147 259 void firstIn(Arc &e, const Node& v) const { 148 e.id = nodes[v.id].first_in; 260 check_mine(v); 261 e.set(this,nodes[v.id].first_in); 149 262 } 150 263 void nextIn(Arc &e) const { 264 check_mine(e); 151 265 e.id=arcs[e.id].next_in; 152 266 } 153 267 154 268 155 static int id(Node v) { return v.id; } 156 static int id(Arc e) { return e.id; } 157 158 static Node nodeFromId(int id) { return Node(id);} 159 static Arc arcFromId(int id) { return Arc(id);} 269 int id(Node v) const { check_mine(v); /* TODO: INVALID? */ return v.id; } 270 int id(Arc e) const { check_mine(e); /* TODO: INVALID? */ return e.id; } 271 272 //TODO: Check if id is valid. 273 Node nodeFromId(int id) const { return Node(this, id);} //TODO 274 Arc arcFromId(int id) const { return Arc(this, id);} //TODO 160 275 161 276 bool valid(Node n) const { 162 return n.id >= 0 && n.id < static_cast<int>(nodes.size()) && 163 nodes[n.id].prev != -2; 277 LEMON_DEBUG(n.graph == this || (n.graph == NULL && n.id == -1), 278 "Node belongs to a different graph"); 279 return ( n.id >= 0 && 280 n.id < static_cast<int>(nodes.size()) && 281 nodes[n.id].prev != -2 ); 164 282 } 165 283 166 bool valid(Arc a) const { 167 return a.id >= 0 && a.id < static_cast<int>(arcs.size()) && 168 arcs[a.id].prev_in != -2; 284 bool valid(Arc a) const { 285 LEMON_DEBUG(a.graph == this || (a.graph == NULL && a.id == -1), 286 "Arc belongs to a different graph"); 287 return ( a.id >= 0 && 288 a.id < static_cast<int>(arcs.size()) && 289 arcs[a.id].prev_in != -2 ); 169 290 } 170 291 171 292 Node addNode() { … … 186 307 187 308 nodes[n].first_in = nodes[n].first_out = -1; 188 309 189 return Node( n);310 return Node(this, n); 190 311 } 191 312 192 313 Arc addArc(Node u, Node v) { 314 check_mine(u); 315 check_mine(v); 193 316 int n; 194 317 195 318 if (first_free_arc == -1) { … … 217 340 218 341 nodes[u.id].first_out = nodes[v.id].first_in = n; 219 342 220 return Arc( n);343 return Arc(this, n); 221 344 } 222 345 223 346 void erase(const Node& node) { 347 check_mine(node); 224 348 int n = node.id; 225 349 226 350 if(nodes[n].next != -1) { … … 240 364 } 241 365 242 366 void erase(const Arc& arc) { 367 check_mine(arc); 243 368 int n = arc.id; 244 369 245 370 if(arcs[n].next_in!=-1) { … … 277 402 protected: 278 403 void changeTarget(Arc e, Node n) 279 404 { 405 check_mine(e); 406 check_mine(n); 280 407 if(arcs[e.id].next_in != -1) 281 408 arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in; 282 409 if(arcs[e.id].prev_in != -1) … … 292 419 } 293 420 void changeSource(Arc e, Node n) 294 421 { 422 check_mine(e); 423 check_mine(n); 295 424 if(arcs[e.id].next_out != -1) 296 425 arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out; 297 426 if(arcs[e.id].prev_out != -1) … … 453 582 ///feature. 454 583 void contract(Node u, Node v, bool r = true) 455 584 { 585 check_mine(u); 586 check_mine(v); 456 587 for(OutArcIt e(*this,v);e!=INVALID;) { 457 588 OutArcIt f=e; 458 589 ++f; … … 485 616 ///\warning This functionality cannot be used together with the 486 617 ///Snapshot feature. 487 618 Node split(Node n, bool connect = true) { 619 check_mine(n); 488 620 Node b = addNode(); 489 621 nodes[b.id].first_out=nodes[n.id].first_out; 490 622 nodes[n.id].first_out=-1; … … 509 641 ///\warning This functionality cannot be used together with the 510 642 ///Snapshot feature. 511 643 Node split(Arc a) { 644 check_mine(a); 512 645 Node v = addNode(); 513 646 addArc(v,target(a)); 514 647 changeTarget(a,v); … … 821 954 friend class ListGraphBase; 822 955 protected: 823 956 957 #ifdef LEMON_ENABLE_DEBUG 958 const Graph *graph; 959 #endif 824 960 int id; 825 explicit Node(int pid) { id = pid;} 961 962 void set(const Graph *g, int pid) 963 { 964 #ifdef LEMON_ENABLE_DEBUG 965 graph=g; 966 #else 967 ignore_unused_variable_warning(g); 968 #endif 969 id = pid; 970 } 971 972 explicit Node(const Graph *g, int pid) { set(g,pid); } 973 974 void check_initialized() const { 975 LEMON_DEBUG(graph || id == -1, "Node used uninitialized"); 976 } 977 void check_comparable(const Node &node) const { 978 check_initialized(); 979 node.check_initialized(); 980 LEMON_DEBUG(!graph || !node.graph || graph == node.graph, 981 "Compare nodes pointing to different graphs"); 982 } 826 983 827 984 public: 828 Node() {} 829 Node (Invalid) { id = -1; } 830 bool operator==(const Node& node) const {return id == node.id;} 831 bool operator!=(const Node& node) const {return id != node.id;} 832 bool operator<(const Node& node) const {return id < node.id;} 985 Node() 986 #ifdef LEMON_ENABLE_DEBUG 987 : graph(NULL), id(-2) 988 #endif 989 {} 990 Node (Invalid) 991 #ifdef LEMON_ENABLE_DEBUG 992 : graph(NULL) 993 #endif 994 { id = -1; } 995 bool operator==(const Node& node) const 996 { 997 check_comparable(node); 998 return id == node.id; 999 } 1000 bool operator!=(const Node& node) const { 1001 check_comparable(node); 1002 return id != node.id; 1003 } 1004 bool operator<(const Node& node) const { 1005 check_comparable(node); 1006 return id < node.id; 1007 } 833 1008 }; 834 1009 1010 class Arc; 1011 835 1012 class Edge { 836 1013 friend class ListGraphBase; 1014 friend class Arc; 837 1015 protected: 838 1016 1017 #ifdef LEMON_ENABLE_DEBUG 1018 const Graph *graph; 1019 #endif 839 1020 int id; 840 explicit Edge(int pid) { id = pid;} 1021 1022 void set(const Graph *g, int pid) 1023 { 1024 #ifdef LEMON_ENABLE_DEBUG 1025 graph=g; 1026 #else 1027 ignore_unused_variable_warning(g); 1028 #endif 1029 id = pid; 1030 } 1031 1032 explicit Edge(const Graph *g, int pid) { set(g,pid); } 1033 1034 void check_initialized() const { 1035 LEMON_DEBUG(graph || id == -1, "Arc used uninitialized"); 1036 } 1037 void check_comparable(const Edge &edge) const { 1038 check_initialized(); 1039 edge.check_initialized(); 1040 LEMON_DEBUG(!graph || !edge.graph || graph == edge.graph, 1041 "Compare arcs pointing to different graphs"); 1042 } 841 1043 842 1044 public: 843 Edge() {} 844 Edge (Invalid) { id = -1; } 845 bool operator==(const Edge& edge) const {return id == edge.id;} 846 bool operator!=(const Edge& edge) const {return id != edge.id;} 847 bool operator<(const Edge& edge) const {return id < edge.id;} 1045 Edge() 1046 #ifdef LEMON_ENABLE_DEBUG 1047 : graph(NULL), id(-2) 1048 #endif 1049 {} 1050 Edge (Invalid) 1051 #ifdef LEMON_ENABLE_DEBUG 1052 : graph(NULL) 1053 #endif 1054 { id = -1; } 1055 bool operator==(const Edge& edge) const { 1056 check_comparable(edge); 1057 return id == edge.id; 1058 } 1059 bool operator!=(const Edge& edge) const { 1060 check_comparable(edge); 1061 return id != edge.id; 1062 } 1063 bool operator<(const Edge& edge) const { 1064 check_comparable(edge); 1065 return id < edge.id; 1066 } 848 1067 }; 849 1068 850 1069 class Arc { 851 1070 friend class ListGraphBase; 852 1071 protected: 853 1072 1073 #ifdef LEMON_ENABLE_DEBUG 1074 const Graph *graph; 1075 #endif 854 1076 int id; 855 explicit Arc(int pid) { id = pid;} 1077 1078 void set(const Graph *g, int pid) 1079 { 1080 #ifdef LEMON_ENABLE_DEBUG 1081 graph=g; 1082 #else 1083 ignore_unused_variable_warning(g); 1084 #endif 1085 id = pid; 1086 } 1087 1088 explicit Arc(const Graph *g, int pid) { set(g,pid); } 1089 1090 void check_initialized() const { 1091 LEMON_DEBUG(graph || id == -1, "Arc used uninitialized"); 1092 } 1093 void check_comparable(const Arc &arc) const { 1094 check_initialized(); 1095 arc.check_initialized(); 1096 LEMON_DEBUG(!graph || !arc.graph || graph == arc.graph, 1097 "Compare arcs pointing to different graphs"); 1098 } 856 1099 857 1100 public: 858 1101 operator Edge() const { 859 return id != -1 ? edgeFromId(id / 2) : INVALID; 1102 #ifdef LEMON_ENABLE_DEBUG 1103 return id != -1 ? Edge(graph, id / 2) : INVALID; 1104 #else 1105 return id != -1 ? Edge(NULL , id / 2) : INVALID; 1106 #endif 860 1107 } 861 1108 862 Arc() {} 863 Arc (Invalid) { id = -1; } 864 bool operator==(const Arc& arc) const {return id == arc.id;} 865 bool operator!=(const Arc& arc) const {return id != arc.id;} 866 bool operator<(const Arc& arc) const {return id < arc.id;} 1109 Arc() 1110 #ifdef LEMON_ENABLE_DEBUG 1111 : graph(NULL), id(-2) 1112 #endif 1113 {} 1114 Arc (Invalid) 1115 #ifdef LEMON_ENABLE_DEBUG 1116 : graph(NULL) 1117 #endif 1118 { id = -1; } 1119 bool operator==(const Arc& arc) const { 1120 check_comparable(arc); 1121 return id == arc.id; 1122 } 1123 bool operator!=(const Arc& arc) const { 1124 check_comparable(arc); 1125 return id != arc.id; 1126 } 1127 bool operator<(const Arc& arc) const { 1128 check_comparable(arc); 1129 return id < arc.id; 1130 } 867 1131 }; 868 1132 1133 1134 protected: 1135 void check_mine(const Node &node) const 1136 { 1137 ignore_unused_variable_warning(node); 1138 LEMON_DEBUG(node.graph == this && 1139 node.id >= 0 && node.id < static_cast<int>(nodes.size()) && 1140 nodes[node.id].prev != -2, 1141 "Node points to a wrong graphs"); 1142 } 1143 void check_mine(const Edge &edge) const //TODO 1144 { 1145 ignore_unused_variable_warning(edge); 1146 LEMON_DEBUG(edge.id >= 0 && 1147 2 * edge.id < static_cast<int>(arcs.size()) && 1148 arcs[2 * edge.id].prev_out != -2, 1149 "Edge points to a wrong graphs"); 1150 } 1151 void check_mine(const Arc &arc) const //TODO 1152 { 1153 ignore_unused_variable_warning(arc); 1154 LEMON_DEBUG(arc.id >= 0 && 1155 arc.id < static_cast<int>(arcs.size()) && 1156 arcs[arc.id].prev_out != -2, 1157 "Arc points to a wrong graphs"); 1158 } 1159 1160 public: 869 1161 ListGraphBase() 870 1162 : nodes(), first_node(-1), 871 1163 first_free_node(-1), arcs(), first_free_arc(-1) {} … … 875 1167 int maxEdgeId() const { return arcs.size() / 2 - 1; } 876 1168 int maxArcId() const { return arcs.size()-1; } 877 1169 878 Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); } 879 Node target(Arc e) const { return Node(arcs[e.id].target); } 880 881 Node u(Edge e) const { return Node(arcs[2 * e.id].target); } 882 Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); } 883 884 static bool direction(Arc e) { 1170 Node source(Arc e) const 1171 { 1172 check_mine(e); 1173 return Node(this, arcs[e.id ^ 1].target); 1174 } 1175 Node target(Arc e) const 1176 { 1177 check_mine(e); 1178 return Node(this, arcs[e.id].target); 1179 } 1180 1181 Node u(Edge e) const 1182 { 1183 check_mine(e); 1184 return Node(this, arcs[2 * e.id].target); 1185 } 1186 Node v(Edge e) const 1187 { 1188 check_mine(e); 1189 return Node(this, arcs[2 * e.id + 1].target); 1190 } 1191 1192 bool direction(Arc e) const { 1193 check_mine(e); 885 1194 return (e.id & 1) == 1; 886 1195 } 887 1196 888 static Arc direct(Edge e, bool d) { 889 return Arc(e.id * 2 + (d ? 1 : 0)); 1197 Arc direct(Edge e, bool d) const { 1198 check_mine(e); 1199 return Arc(this, e.id * 2 + (d ? 1 : 0)); 890 1200 } 891 1201 892 1202 void first(Node& node) const { 893 node. id = first_node;1203 node.set(this,first_node); 894 1204 } 895 1205 896 1206 void next(Node& node) const { 1207 check_mine(node); 897 1208 node.id = nodes[node.id].next; 898 1209 } 899 1210 … … 902 1213 while (n != -1 && nodes[n].first_out == -1) { 903 1214 n = nodes[n].next; 904 1215 } 905 e. id = (n == -1) ? -1 : nodes[n].first_out;1216 e.set(this, (n == -1) ? -1 : nodes[n].first_out); 906 1217 } 907 1218 908 1219 void next(Arc& e) const { 1220 check_mine(e); 909 1221 if (arcs[e.id].next_out != -1) { 910 1222 e.id = arcs[e.id].next_out; 911 1223 } else { … … 919 1231 920 1232 void first(Edge& e) const { 921 1233 int n = first_node; 1234 int eid; 922 1235 while (n != -1) { 923 e .id = nodes[n].first_out;924 while ((e .id & 1) != 1) {925 e .id = arcs[e.id].next_out;1236 eid = nodes[n].first_out; 1237 while ((eid & 1) != 1) { 1238 eid = arcs[eid].next_out; 926 1239 } 927 if (e.id != -1) { 928 e.id /= 2; 1240 if (eid != -1) { 1241 eid /= 2; 1242 e.set(this,eid); 929 1243 return; 930 1244 } 931 1245 n = nodes[n].next; 932 1246 } 933 e. id = -1;1247 e.set(this,-1); 934 1248 } 935 1249 936 1250 void next(Edge& e) const { 1251 check_mine(e); 937 1252 int n = arcs[e.id * 2].target; 938 1253 e.id = arcs[(e.id * 2) | 1].next_out; 939 1254 while ((e.id & 1) != 1) { … … 959 1274 } 960 1275 961 1276 void firstOut(Arc &e, const Node& v) const { 962 e.id = nodes[v.id].first_out; 1277 check_mine(v); 1278 e.set(this, nodes[v.id].first_out); 963 1279 } 1280 964 1281 void nextOut(Arc &e) const { 1282 check_mine(e); 965 1283 e.id = arcs[e.id].next_out; 966 1284 } 967 1285 968 1286 void firstIn(Arc &e, const Node& v) const { 969 e.id = ((nodes[v.id].first_out) ^ 1); 970 if (e.id == -2) e.id = -1; 1287 check_mine(v); 1288 int eid = ((nodes[v.id].first_out) ^ 1); 1289 if (eid == -2) eid = -1; 1290 e.set(this, eid); 971 1291 } 972 1292 void nextIn(Arc &e) const { 1293 check_mine(e); 973 1294 e.id = ((arcs[e.id ^ 1].next_out) ^ 1); 974 1295 if (e.id == -2) e.id = -1; 975 1296 } 976 1297 977 1298 void firstInc(Edge &e, bool& d, const Node& v) const { 1299 check_mine(v); 978 1300 int a = nodes[v.id].first_out; 979 if (a != -1 ) { 980 e.id = a / 2; 981 d = ((a & 1) == 1); 982 } else { 983 e.id = -1; 984 d = true; 985 } 1301 // //GCC falsely report that eid is used uninitialized: 1302 // int eid; 1303 // if (a != -1 ) { 1304 // e.id = a / 2; 1305 // d = ((a & 1) == 1); 1306 // } else { 1307 // e.id = -1; 1308 // d = true; 1309 // } 1310 int eid = (a != -1 ) ? 1311 ( d = ((a & 1) == 1), a / 2 ) : 1312 ( d = true, -1 ); 1313 e.set(this,eid); 986 1314 } 987 1315 void nextInc(Edge &e, bool& d) const { 1316 check_mine(e); 988 1317 int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out); 989 1318 if (a != -1 ) { 990 1319 e.id = a / 2; … … 995 1324 } 996 1325 } 997 1326 998 static int id(Node v) { return v.id; } 999 static int id(Arc e) { return e.id; } 1000 static int id(Edge e) { return e.id; } 1001 1002 static Node nodeFromId(int id) { return Node(id);} 1003 static Arc arcFromId(int id) { return Arc(id);} 1004 static Edge edgeFromId(int id) { return Edge(id);} 1005 1327 int id(Node v) const { check_mine(v); return v.id; } 1328 int id(Arc e) const { check_mine(e); return e.id; } 1329 int id(Edge e) const { check_mine(e); return e.id; } 1330 1331 //TODO: Check if id is valid. 1332 Node nodeFromId(int id) const { return Node(this, id);} 1333 Arc arcFromId(int id) const { return Arc(this, id);} 1334 Edge edgeFromId(int id) const { return Edge(this, id);} 1335 1006 1336 bool valid(Node n) const { 1007 return n.id >= 0 && n.id < static_cast<int>(nodes.size()) && 1008 nodes[n.id].prev != -2; 1337 LEMON_DEBUG(n.graph == this || (n.graph == NULL && n.id == -1), 1338 "Node belongs to a different graph"); 1339 return ( n.id >= 0 && 1340 n.id < static_cast<int>(nodes.size()) && 1341 nodes[n.id].prev != -2); 1009 1342 } 1010 1343 1011 1344 bool valid(Arc a) const { 1012 return a.id >= 0 && a.id < static_cast<int>(arcs.size()) && 1013 arcs[a.id].prev_out != -2; 1345 LEMON_DEBUG(a.graph == this || (a.graph == NULL && a.id == -1), 1346 "Arc belongs to a different graph"); 1347 return ( a.id >= 0 && 1348 a.id < static_cast<int>(arcs.size()) && 1349 arcs[a.id].prev_out != -2); 1014 1350 } 1015 1351 1016 1352 bool valid(Edge e) const { 1017 return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) && 1018 arcs[2 * e.id].prev_out != -2; 1353 LEMON_DEBUG(e.graph == this || (e.graph == NULL && e.id == -1), 1354 "Arc belongs to a different graph"); 1355 return (e.id >= 0 && 1356 2 * e.id < static_cast<int>(arcs.size()) && 1357 arcs[2 * e.id].prev_out != -2); 1019 1358 } 1020 1359 1021 1360 Node addNode() { … … 1036 1375 1037 1376 nodes[n].first_out = -1; 1038 1377 1039 return Node( n);1378 return Node(this,n); 1040 1379 } 1041 1380 1042 1381 Edge addEdge(Node u, Node v) { 1382 check_mine(u); 1383 check_mine(v); 1043 1384 int n; 1044 1385 1045 1386 if (first_free_arc == -1) { … … 1068 1409 arcs[n | 1].prev_out = -1; 1069 1410 nodes[u.id].first_out = (n | 1); 1070 1411 1071 return Edge( n / 2);1412 return Edge(this, n / 2); 1072 1413 } 1073 1414 1074 1415 void erase(const Node& node) { 1416 check_mine(node); 1075 1417 int n = node.id; 1076 1418 1077 1419 if(nodes[n].next != -1) { … … 1090 1432 } 1091 1433 1092 1434 void erase(const Edge& edge) { 1435 check_mine(edge); 1093 1436 int n = edge.id * 2; 1094 1437 1095 1438 if (arcs[n].next_out != -1) { … … 1128 1471 protected: 1129 1472 1130 1473 void changeV(Edge e, Node n) { 1474 check_mine(e); 1475 check_mine(n); 1131 1476 if(arcs[2 * e.id].next_out != -1) { 1132 1477 arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out; 1133 1478 } … … 1149 1494 } 1150 1495 1151 1496 void changeU(Edge e, Node n) { 1497 check_mine(e); 1498 check_mine(n); 1152 1499 if(arcs[(2 * e.id) | 1].next_out != -1) { 1153 1500 arcs[arcs[(2 * e.id) | 1].next_out].prev_out = 1154 1501 arcs[(2 * e.id) | 1].prev_out; … … 1313 1660 ///\warning This functionality cannot be used together with the 1314 1661 ///Snapshot feature. 1315 1662 void contract(Node a, Node b, bool r = true) { 1663 check_mine(a); 1664 check_mine(b); 1316 1665 for(IncEdgeIt e(*this, b); e!=INVALID;) { 1317 1666 IncEdgeIt f = e; ++f; 1318 1667 if (r && runningNode(e) == a) { -
test/CMakeLists.txt
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
a b 35 35 hao_orlin_test 36 36 heap_test 37 37 kruskal_test 38 lemon_debug_test 38 39 lgf_reader_writer_test 39 40 lgf_test 40 41 maps_test -
test/digraph_test.cc
diff --git a/test/digraph_test.cc b/test/digraph_test.cc
a b 236 236 checkGraphOutArcList(G, n1, 0); 237 237 checkGraphOutArcList(G, n2, 0); 238 238 checkGraphOutArcList(G, n3, 1); 239 checkGraphOutArcList(G, n4, 0);240 239 241 240 checkGraphInArcList(G, n1, 1); 242 241 checkGraphInArcList(G, n2, 0); 243 242 checkGraphInArcList(G, n3, 0); 244 checkGraphInArcList(G, n4, 0);245 243 246 244 checkGraphConArcList(G, 1); 247 245 } -
new file test/lemon_debug_test.cc
diff --git a/test/lemon_debug_test.cc b/test/lemon_debug_test.cc new file mode 100644
- + 1 /* -*- mode: C++; indent-tabs-mode: nil; -*- 2 * 3 * This file is a part of LEMON, a generic C++ optimization library. 4 * 5 * Copyright (C) 2003-2013 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). 8 * 9 * Permission to use, modify and distribute this software is granted 10 * provided that this copyright notice appears in all copies. For 11 * precise terms see the accompanying LICENSE file. 12 * 13 * This software is provided "AS IS" with no warranty of any kind, 14 * express or implied, and with no claim as to its suitability for any 15 * purpose. 16 * 17 */ 18 19 #ifndef LEMON_ENABLE_DEBUG 20 #define LEMON_ENABLE_DEBUG 21 #endif 22 #undef NDEBUG 23 #define LEMON_ASSERT_CUSTOM 24 #define LEMON_CUSTOM_ASSERT_HANDLER test_assert_handler 25 26 #include <lemon/error.h> 27 #include <sstream> 28 29 class DebugException : public lemon::Exception 30 { 31 public: 32 std::string _file; 33 int _line; 34 std::string _function; 35 std::string _message; 36 std::string _assertion; 37 std::string _what; 38 DebugException(const char* file, int line, 39 const char* function, const char* message, 40 const char* assertion) 41 : _file(file), _line(line), _function(function), _message(message), 42 _assertion(assertion) 43 { 44 std::ostringstream f; 45 f << _file << ':' << _line << ": " << _function << ": " << _assertion; 46 _what = f.str(); 47 } 48 49 virtual const char* what() const throw() { 50 return _what.c_str(); 51 } 52 virtual ~DebugException() throw() {} 53 }; 54 55 void test_assert_handler(const char* file, int line, 56 const char* function, const char* message, 57 const char* assertion) 58 { 59 throw DebugException(file, line, function, message, assertion); 60 } 61 62 #define LEMON_CUSTOM_ASSERT_HANDLER test_assert_handler 63 64 #include <lemon/list_graph.h> 65 #include "test_tools.h" 66 67 using namespace lemon; 68 69 int main() 70 { 71 ListDigraph g,h; 72 73 ListDigraph::Node n = g.addNode(); 74 ListDigraph::NodeMap<int> map(g); 75 ListDigraph::Node n2 = h.addNode(); 76 77 map[n]=12; 78 79 g.erase(n); 80 81 try { 82 map[n]=13; 83 check(true, "It should'n pass"); 84 } catch (DebugException &d) { 85 check(d._message == "Node points to a wrong graphs", 86 "Wrong exception is thrown"); 87 } 88 89 try { 90 map[n2]=13; 91 check(true, "It should'n pass"); 92 } catch (DebugException &d) { 93 check(d._message == "Node points to a wrong graphs", 94 "Wrong exception is thrown"); 95 } 96 97 check(true, "Something is wrong."); 98 99 return 0; 100 }