COIN-OR::LEMON - Graph Library

Ticket #462: 81d113c593ef.patch

File 81d113c593ef.patch, 27.7 KB (added by Alpar Juttner, 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  
    5656      return Parent::maxArcId();
    5757    }
    5858
    59     static Node fromId(int id, Node) {
    60       return Parent::nodeFromId(id);
     59    Node fromId(int id, Node) const {
     60      return this->nodeFromId(id);
    6161    }
    6262
    63     static Arc fromId(int id, Arc) {
    64       return Parent::arcFromId(id);
     63    Arc fromId(int id, Arc) const {
     64      return this->arcFromId(id);
    6565    }
    6666
    6767    Node oppositeNode(const Node &node, const Arc &arc) const {
     
    355355      return Parent::maxEdgeId();
    356356    }
    357357
    358     static Node fromId(int id, Node) {
     358    Node fromId(int id, Node) const {
    359359      return Parent::nodeFromId(id);
    360360    }
    361361
    362     static Arc fromId(int id, Arc) {
     362    Arc fromId(int id, Arc) const {
    363363      return Parent::arcFromId(id);
    364364    }
    365365
    366     static Edge fromId(int id, Edge) {
     366    Edge fromId(int id, Edge) const {
    367367      return Parent::edgeFromId(id);
    368368    }
    369369
     
    791791      return Parent::maxEdgeId();
    792792    }
    793793
    794     static Node fromId(int id, Node) {
     794    Node fromId(int id, Node) const {
    795795      return Parent::nodeFromId(id);
    796796    }
    797797
    798     static Arc fromId(int id, Arc) {
     798    Arc fromId(int id, Arc) const {
    799799      return Parent::arcFromId(id);
    800800    }
    801801
    802     static Edge fromId(int id, Edge) {
     802    fromId(int id, Edge) const {
    803803      return Parent::edgeFromId(id);
    804804    }
    805805
  • lemon/list_graph.h

    diff --git a/lemon/list_graph.h b/lemon/list_graph.h
    a b  
    6767      friend class ListDigraph;
    6868    protected:
    6969
     70#ifdef LEMON_ENABLE_DEBUG
     71      const Digraph *graph;
     72#endif
    7073      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      }
    7396    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      }
    79120    };
    80121
    81122    class Arc {
     
    83124      friend class ListDigraph;
    84125    protected:
    85126
     127#ifdef LEMON_ENABLE_DEBUG
     128      const Digraph *graph;
     129#endif
    86130      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      }
    88153
    89154    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      }
    95177    };
    96178
    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:
    99199    ListDigraphBase()
    100200      : nodes(), first_node(-1),
    101201        first_free_node(-1), arcs(), first_free_arc(-1) {}
     
    104204    int maxNodeId() const { return nodes.size()-1; }
    105205    int maxArcId() const { return arcs.size()-1; }
    106206
    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    }
    109217
    110218
    111219    void first(Node& node) const {
    112       node.id = first_node;
     220      node.set(this, first_node);
    113221    }
    114222
    115223    void next(Node& node) const {
     224      check_mine(node);
    116225      node.id = nodes[node.id].next;
    117226    }
    118227
     
    122231      for(n = first_node;
    123232          n != -1 && nodes[n].first_out == -1;
    124233          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);
    126235    }
    127236
    128237    void next(Arc& arc) const {
     238      check_mine(arc);
    129239      if (arcs[arc.id].next_out != -1) {
    130240        arc.id = arcs[arc.id].next_out;
    131241      } else {
     
    138248    }
    139249
    140250    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);
    142253    }
    143254    void nextOut(Arc &e) const {
     255      check_mine(e);
    144256      e.id=arcs[e.id].next_out;
    145257    }
    146258
    147259    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);
    149262    }
    150263    void nextIn(Arc &e) const {
     264      check_mine(e);
    151265      e.id=arcs[e.id].next_in;
    152266    }
    153267
    154268
    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
    160275
    161276    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 );
    164282    }
    165283
    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 );
    169290    }
    170291
    171292    Node addNode() {
     
    186307
    187308      nodes[n].first_in = nodes[n].first_out = -1;
    188309
    189       return Node(n);
     310      return Node(this, n);
    190311    }
    191312
    192313    Arc addArc(Node u, Node v) {
     314      check_mine(u);
     315      check_mine(v);
    193316      int n;
    194317
    195318      if (first_free_arc == -1) {
     
    217340
    218341      nodes[u.id].first_out = nodes[v.id].first_in = n;
    219342
    220       return Arc(n);
     343      return Arc(this, n);
    221344    }
    222345
    223346    void erase(const Node& node) {
     347      check_mine(node);
    224348      int n = node.id;
    225349
    226350      if(nodes[n].next != -1) {
     
    240364    }
    241365
    242366    void erase(const Arc& arc) {
     367      check_mine(arc);
    243368      int n = arc.id;
    244369
    245370      if(arcs[n].next_in!=-1) {
     
    277402  protected:
    278403    void changeTarget(Arc e, Node n)
    279404    {
     405      check_mine(e);
     406      check_mine(n);
    280407      if(arcs[e.id].next_in != -1)
    281408        arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in;
    282409      if(arcs[e.id].prev_in != -1)
     
    292419    }
    293420    void changeSource(Arc e, Node n)
    294421    {
     422      check_mine(e);
     423      check_mine(n);
    295424      if(arcs[e.id].next_out != -1)
    296425        arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out;
    297426      if(arcs[e.id].prev_out != -1)
     
    453582    ///feature.
    454583    void contract(Node u, Node v, bool r = true)
    455584    {
     585      check_mine(u);
     586      check_mine(v);
    456587      for(OutArcIt e(*this,v);e!=INVALID;) {
    457588        OutArcIt f=e;
    458589        ++f;
     
    485616    ///\warning This functionality cannot be used together with the
    486617    ///Snapshot feature.
    487618    Node split(Node n, bool connect = true) {
     619      check_mine(n);
    488620      Node b = addNode();
    489621      nodes[b.id].first_out=nodes[n.id].first_out;
    490622      nodes[n.id].first_out=-1;
     
    509641    ///\warning This functionality cannot be used together with the
    510642    ///Snapshot feature.
    511643    Node split(Arc a) {
     644      check_mine(a);
    512645      Node v = addNode();
    513646      addArc(v,target(a));
    514647      changeTarget(a,v);
     
    821954      friend class ListGraphBase;
    822955    protected:
    823956
     957#ifdef LEMON_ENABLE_DEBUG
     958      const Graph *graph;
     959#endif
    824960      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      }
    826983
    827984    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      }
    8331008    };
    8341009
     1010    class Arc;
     1011
    8351012    class Edge {
    8361013      friend class ListGraphBase;
     1014      friend class Arc;
    8371015    protected:
    8381016
     1017#ifdef LEMON_ENABLE_DEBUG
     1018      const Graph *graph;
     1019#endif
    8391020      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      }
    8411043
    8421044    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      }
    8481067    };
    8491068
    8501069    class Arc {
    8511070      friend class ListGraphBase;
    8521071    protected:
    8531072
     1073#ifdef LEMON_ENABLE_DEBUG
     1074      const Graph *graph;
     1075#endif
    8541076      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      }
    8561099
    8571100    public:
    8581101      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
    8601107      }
    8611108
    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      }
    8671131    };
    8681132
     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:
    8691161    ListGraphBase()
    8701162      : nodes(), first_node(-1),
    8711163        first_free_node(-1), arcs(), first_free_arc(-1) {}
     
    8751167    int maxEdgeId() const { return arcs.size() / 2 - 1; }
    8761168    int maxArcId() const { return arcs.size()-1; }
    8771169
    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);
    8851194      return (e.id & 1) == 1;
    8861195    }
    8871196
    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));
    8901200    }
    8911201
    8921202    void first(Node& node) const {
    893       node.id = first_node;
     1203      node.set(this,first_node);
    8941204    }
    8951205
    8961206    void next(Node& node) const {
     1207      check_mine(node);
    8971208      node.id = nodes[node.id].next;
    8981209    }
    8991210
     
    9021213      while (n != -1 && nodes[n].first_out == -1) {
    9031214        n = nodes[n].next;
    9041215      }
    905       e.id = (n == -1) ? -1 : nodes[n].first_out;
     1216      e.set(this, (n == -1) ? -1 : nodes[n].first_out);
    9061217    }
    9071218
    9081219    void next(Arc& e) const {
     1220      check_mine(e);
    9091221      if (arcs[e.id].next_out != -1) {
    9101222        e.id = arcs[e.id].next_out;
    9111223      } else {
     
    9191231
    9201232    void first(Edge& e) const {
    9211233      int n = first_node;
     1234      int eid;
    9221235      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;
    9261239        }
    927         if (e.id != -1) {
    928           e.id /= 2;
     1240        if (eid != -1) {
     1241          eid /= 2;
     1242          e.set(this,eid);
    9291243          return;
    9301244        }
    9311245        n = nodes[n].next;
    9321246      }
    933       e.id = -1;
     1247      e.set(this,-1);
    9341248    }
    9351249
    9361250    void next(Edge& e) const {
     1251      check_mine(e);
    9371252      int n = arcs[e.id * 2].target;
    9381253      e.id = arcs[(e.id * 2) | 1].next_out;
    9391254      while ((e.id & 1) != 1) {
     
    9591274    }
    9601275
    9611276    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);
    9631279    }
     1280
    9641281    void nextOut(Arc &e) const {
     1282      check_mine(e);
    9651283      e.id = arcs[e.id].next_out;
    9661284    }
    9671285
    9681286    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);
    9711291    }
    9721292    void nextIn(Arc &e) const {
     1293      check_mine(e);
    9731294      e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
    9741295      if (e.id == -2) e.id = -1;
    9751296    }
    9761297
    9771298    void firstInc(Edge &e, bool& d, const Node& v) const {
     1299      check_mine(v);
    9781300      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);
    9861314    }
    9871315    void nextInc(Edge &e, bool& d) const {
     1316      check_mine(e);
    9881317      int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
    9891318      if (a != -1 ) {
    9901319        e.id = a / 2;
     
    9951324      }
    9961325    }
    9971326
    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   
    10061336    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);
    10091342    }
    10101343
    10111344    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);
    10141350    }
    10151351
    10161352    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);
    10191358    }
    10201359
    10211360    Node addNode() {
     
    10361375
    10371376      nodes[n].first_out = -1;
    10381377
    1039       return Node(n);
     1378      return Node(this,n);
    10401379    }
    10411380
    10421381    Edge addEdge(Node u, Node v) {
     1382      check_mine(u);
     1383      check_mine(v);
    10431384      int n;
    10441385
    10451386      if (first_free_arc == -1) {
     
    10681409      arcs[n | 1].prev_out = -1;
    10691410      nodes[u.id].first_out = (n | 1);
    10701411
    1071       return Edge(n / 2);
     1412      return Edge(this, n / 2);
    10721413    }
    10731414
    10741415    void erase(const Node& node) {
     1416      check_mine(node);
    10751417      int n = node.id;
    10761418
    10771419      if(nodes[n].next != -1) {
     
    10901432    }
    10911433
    10921434    void erase(const Edge& edge) {
     1435      check_mine(edge);
    10931436      int n = edge.id * 2;
    10941437
    10951438      if (arcs[n].next_out != -1) {
     
    11281471  protected:
    11291472
    11301473    void changeV(Edge e, Node n) {
     1474      check_mine(e);
     1475      check_mine(n);
    11311476      if(arcs[2 * e.id].next_out != -1) {
    11321477        arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
    11331478      }
     
    11491494    }
    11501495
    11511496    void changeU(Edge e, Node n) {
     1497      check_mine(e);
     1498      check_mine(n);
    11521499      if(arcs[(2 * e.id) | 1].next_out != -1) {
    11531500        arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
    11541501          arcs[(2 * e.id) | 1].prev_out;
     
    13131660    ///\warning This functionality cannot be used together with the
    13141661    ///Snapshot feature.
    13151662    void contract(Node a, Node b, bool r = true) {
     1663      check_mine(a);
     1664      check_mine(b);
    13161665      for(IncEdgeIt e(*this, b); e!=INVALID;) {
    13171666        IncEdgeIt f = e; ++f;
    13181667        if (r && runningNode(e) == a) {
  • test/CMakeLists.txt

    diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
    a b  
    3535  hao_orlin_test
    3636  heap_test
    3737  kruskal_test
     38  lemon_debug_test
    3839  lgf_reader_writer_test
    3940  lgf_test
    4041  maps_test
  • test/digraph_test.cc

    diff --git a/test/digraph_test.cc b/test/digraph_test.cc
    a b  
    236236  checkGraphOutArcList(G, n1, 0);
    237237  checkGraphOutArcList(G, n2, 0);
    238238  checkGraphOutArcList(G, n3, 1);
    239   checkGraphOutArcList(G, n4, 0);
    240239
    241240  checkGraphInArcList(G, n1, 1);
    242241  checkGraphInArcList(G, n2, 0);
    243242  checkGraphInArcList(G, n3, 0);
    244   checkGraphInArcList(G, n4, 0);
    245243
    246244  checkGraphConArcList(G, 1);
    247245}
  • 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
     29class DebugException : public lemon::Exception
     30{   
     31public:
     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
     55void 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
     67using namespace lemon;
     68
     69int 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}