COIN-OR::LEMON - Graph Library

Ticket #67: 591e8758d98b.patch

File 591e8758d98b.patch, 63.7 KB (added by Balazs Dezso, 11 years ago)
  • lemon/Makefile.am

    # HG changeset patch
    # User Balazs Dezso <deba@inf.elte.hu>
    # Date 1216821431 -7200
    # Node ID 591e8758d98b933f7a01982806303142e4e0d180
    # Parent  af4e8ba94294a7854bd448deb64744cef238dcf4
    Arc and Edge set ports from SVN 3489
    
    diff -r af4e8ba94294 -r 591e8758d98b lemon/Makefile.am
    a b  
    2828        lemon/dfs.h \
    2929        lemon/dijkstra.h \
    3030        lemon/dim2.h \
     31        lemon/edge_set.h \
    3132        lemon/error.h \
    3233        lemon/graph_to_eps.h \
    3334        lemon/kruskal.h \
     
    4950        lemon/bits/base_extender.h \
    5051        lemon/bits/bezier.h \
    5152        lemon/bits/default_map.h \
     53        lemon/bits/edge_set_extender.h \
    5254        lemon/bits/enable_if.h \
    5355        lemon/bits/graph_extender.h \
    5456        lemon/bits/map_extender.h \
  • new file lemon/bits/edge_set_extender.h

    diff -r af4e8ba94294 -r 591e8758d98b lemon/bits/edge_set_extender.h
    - +  
     1/* -*- C++ -*-
     2 *
     3 * This file is a part of LEMON, a generic C++ optimization library
     4 *
     5 * Copyright (C) 2003-2008
     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_BITS_EDGE_SET_EXTENDER_H
     20#define LEMON_BITS_EDGE_SET_EXTENDER_H
     21
     22#include <lemon/error.h>
     23#include <lemon/bits/default_map.h>
     24
     25///\ingroup digraphbits
     26///\file
     27///\brief Extenders for the arc set types
     28namespace lemon {
     29
     30  /// \ingroup digraphbits
     31  ///
     32  /// \brief Extender for the ArcSets
     33  template <typename Base>
     34  class ArcSetExtender : public Base {
     35  public:
     36
     37    typedef Base Parent;
     38    typedef ArcSetExtender Digraph;
     39
     40    // Base extensions
     41
     42    typedef typename Parent::Node Node;
     43    typedef typename Parent::Arc Arc;
     44
     45    int maxId(Node) const {
     46      return Parent::maxNodeId();
     47    }
     48
     49    int maxId(Arc) const {
     50      return Parent::maxArcId();
     51    }
     52
     53    Node fromId(int id, Node) const {
     54      return Parent::nodeFromId(id);
     55    }
     56
     57    Arc fromId(int id, Arc) const {
     58      return Parent::arcFromId(id);
     59    }
     60
     61    Node oppositeNode(const Node &n, const Arc &e) const {
     62      if (n == Parent::source(e))
     63        return Parent::target(e);
     64      else if(n==Parent::target(e))
     65        return Parent::source(e);
     66      else
     67        return INVALID;
     68    }
     69
     70
     71    // Alteration notifier extensions
     72
     73    /// The arc observer registry.
     74    typedef AlterationNotifier<ArcSetExtender, Arc> ArcNotifier;
     75
     76  protected:
     77
     78    mutable ArcNotifier arc_notifier;
     79
     80  public:
     81
     82    using Parent::notifier;
     83
     84    /// \brief Gives back the arc alteration notifier.
     85    ///
     86    /// Gives back the arc alteration notifier.
     87    ArcNotifier& notifier(Arc) const {
     88      return arc_notifier;
     89    }
     90
     91    // Iterable extensions
     92
     93    class NodeIt : public Node {
     94      const Digraph* digraph;
     95    public:
     96
     97      NodeIt() {}
     98
     99      NodeIt(Invalid i) : Node(i) { }
     100
     101      explicit NodeIt(const Digraph& _graph) : digraph(&_graph) {
     102        _graph.first(static_cast<Node&>(*this));
     103      }
     104
     105      NodeIt(const Digraph& _graph, const Node& node)
     106        : Node(node), digraph(&_graph) {}
     107
     108      NodeIt& operator++() {
     109        digraph->next(*this);
     110        return *this;
     111      }
     112
     113    };
     114
     115
     116    class ArcIt : public Arc {
     117      const Digraph* digraph;
     118    public:
     119
     120      ArcIt() { }
     121
     122      ArcIt(Invalid i) : Arc(i) { }
     123
     124      explicit ArcIt(const Digraph& _graph) : digraph(&_graph) {
     125        _graph.first(static_cast<Arc&>(*this));
     126      }
     127
     128      ArcIt(const Digraph& _graph, const Arc& e) :
     129        Arc(e), digraph(&_graph) { }
     130
     131      ArcIt& operator++() {
     132        digraph->next(*this);
     133        return *this;
     134      }
     135
     136    };
     137
     138
     139    class OutArcIt : public Arc {
     140      const Digraph* digraph;
     141    public:
     142
     143      OutArcIt() { }
     144
     145      OutArcIt(Invalid i) : Arc(i) { }
     146
     147      OutArcIt(const Digraph& _graph, const Node& node)
     148        : digraph(&_graph) {
     149        _graph.firstOut(*this, node);
     150      }
     151
     152      OutArcIt(const Digraph& _graph, const Arc& arc)
     153        : Arc(arc), digraph(&_graph) {}
     154
     155      OutArcIt& operator++() {
     156        digraph->nextOut(*this);
     157        return *this;
     158      }
     159
     160    };
     161
     162
     163    class InArcIt : public Arc {
     164      const Digraph* digraph;
     165    public:
     166
     167      InArcIt() { }
     168
     169      InArcIt(Invalid i) : Arc(i) { }
     170
     171      InArcIt(const Digraph& _graph, const Node& node)
     172        : digraph(&_graph) {
     173        _graph.firstIn(*this, node);
     174      }
     175
     176      InArcIt(const Digraph& _graph, const Arc& arc) :
     177        Arc(arc), digraph(&_graph) {}
     178
     179      InArcIt& operator++() {
     180        digraph->nextIn(*this);
     181        return *this;
     182      }
     183
     184    };
     185
     186    /// \brief Base node of the iterator
     187    ///
     188    /// Returns the base node (ie. the source in this case) of the iterator
     189    Node baseNode(const OutArcIt &e) const {
     190      return Parent::source(static_cast<const Arc&>(e));
     191    }
     192    /// \brief Running node of the iterator
     193    ///
     194    /// Returns the running node (ie. the target in this case) of the
     195    /// iterator
     196    Node runningNode(const OutArcIt &e) const {
     197      return Parent::target(static_cast<const Arc&>(e));
     198    }
     199
     200    /// \brief Base node of the iterator
     201    ///
     202    /// Returns the base node (ie. the target in this case) of the iterator
     203    Node baseNode(const InArcIt &e) const {
     204      return Parent::target(static_cast<const Arc&>(e));
     205    }
     206    /// \brief Running node of the iterator
     207    ///
     208    /// Returns the running node (ie. the source in this case) of the
     209    /// iterator
     210    Node runningNode(const InArcIt &e) const {
     211      return Parent::source(static_cast<const Arc&>(e));
     212    }
     213
     214    using Parent::first;
     215
     216    // Mappable extension
     217   
     218    template <typename _Value>
     219    class ArcMap
     220      : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
     221    public:
     222      typedef ArcSetExtender Digraph;
     223      typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
     224
     225      explicit ArcMap(const Digraph& _g)
     226        : Parent(_g) {}
     227      ArcMap(const Digraph& _g, const _Value& _v)
     228        : Parent(_g, _v) {}
     229
     230      ArcMap& operator=(const ArcMap& cmap) {
     231        return operator=<ArcMap>(cmap);
     232      }
     233
     234      template <typename CMap>
     235      ArcMap& operator=(const CMap& cmap) {
     236        Parent::operator=(cmap);
     237        return *this;
     238      }
     239
     240    };
     241
     242
     243    // Alteration extension
     244
     245    Arc addArc(const Node& from, const Node& to) {
     246      Arc arc = Parent::addArc(from, to);
     247      notifier(Arc()).add(arc);
     248      return arc;
     249    }
     250   
     251    void clear() {
     252      notifier(Arc()).clear();
     253      Parent::clear();
     254    }
     255
     256    void erase(const Arc& arc) {
     257      notifier(Arc()).erase(arc);
     258      Parent::erase(arc);
     259    }
     260
     261    ArcSetExtender() {
     262      arc_notifier.setContainer(*this);
     263    }
     264
     265    ~ArcSetExtender() {
     266      arc_notifier.clear();
     267    }
     268
     269  };
     270
     271
     272  /// \ingroup digraphbits
     273  ///
     274  /// \brief Extender for the EdgeSets
     275  template <typename Base>
     276  class EdgeSetExtender : public Base {
     277
     278  public:
     279
     280    typedef Base Parent;
     281    typedef EdgeSetExtender Digraph;
     282
     283    typedef typename Parent::Node Node;
     284    typedef typename Parent::Arc Arc;
     285    typedef typename Parent::Edge Edge;
     286
     287
     288    int maxId(Node) const {
     289      return Parent::maxNodeId();
     290    }
     291
     292    int maxId(Arc) const {
     293      return Parent::maxArcId();
     294    }
     295
     296    int maxId(Edge) const {
     297      return Parent::maxEdgeId();
     298    }
     299
     300    Node fromId(int id, Node) const {
     301      return Parent::nodeFromId(id);
     302    }
     303
     304    Arc fromId(int id, Arc) const {
     305      return Parent::arcFromId(id);
     306    }
     307
     308    Edge fromId(int id, Edge) const {
     309      return Parent::edgeFromId(id);
     310    }
     311
     312    Node oppositeNode(const Node &n, const Edge &e) const {
     313      if( n == Parent::u(e))
     314        return Parent::v(e);
     315      else if( n == Parent::v(e))
     316        return Parent::u(e);
     317      else
     318        return INVALID;
     319    }
     320
     321    Arc oppositeArc(const Arc &e) const {
     322      return Parent::direct(e, !Parent::direction(e));
     323    }
     324
     325    using Parent::direct;
     326    Arc direct(const Edge &e, const Node &s) const {
     327      return Parent::direct(e, Parent::u(e) == s);
     328    }
     329
     330    typedef AlterationNotifier<EdgeSetExtender, Arc> ArcNotifier;
     331    typedef AlterationNotifier<EdgeSetExtender, Edge> EdgeNotifier;
     332
     333
     334  protected:
     335
     336    mutable ArcNotifier arc_notifier;
     337    mutable EdgeNotifier edge_notifier;
     338
     339  public:
     340
     341    using Parent::notifier;
     342   
     343    ArcNotifier& notifier(Arc) const {
     344      return arc_notifier;
     345    }
     346
     347    EdgeNotifier& notifier(Edge) const {
     348      return edge_notifier;
     349    }
     350
     351
     352    class NodeIt : public Node {
     353      const Digraph* digraph;
     354    public:
     355
     356      NodeIt() {}
     357
     358      NodeIt(Invalid i) : Node(i) { }
     359
     360      explicit NodeIt(const Digraph& _graph) : digraph(&_graph) {
     361        _graph.first(static_cast<Node&>(*this));
     362      }
     363
     364      NodeIt(const Digraph& _graph, const Node& node)
     365        : Node(node), digraph(&_graph) {}
     366
     367      NodeIt& operator++() {
     368        digraph->next(*this);
     369        return *this;
     370      }
     371
     372    };
     373
     374
     375    class ArcIt : public Arc {
     376      const Digraph* digraph;
     377    public:
     378
     379      ArcIt() { }
     380
     381      ArcIt(Invalid i) : Arc(i) { }
     382
     383      explicit ArcIt(const Digraph& _graph) : digraph(&_graph) {
     384        _graph.first(static_cast<Arc&>(*this));
     385      }
     386
     387      ArcIt(const Digraph& _graph, const Arc& e) :
     388        Arc(e), digraph(&_graph) { }
     389
     390      ArcIt& operator++() {
     391        digraph->next(*this);
     392        return *this;
     393      }
     394
     395    };
     396
     397
     398    class OutArcIt : public Arc {
     399      const Digraph* digraph;
     400    public:
     401
     402      OutArcIt() { }
     403
     404      OutArcIt(Invalid i) : Arc(i) { }
     405
     406      OutArcIt(const Digraph& _graph, const Node& node)
     407        : digraph(&_graph) {
     408        _graph.firstOut(*this, node);
     409      }
     410
     411      OutArcIt(const Digraph& _graph, const Arc& arc)
     412        : Arc(arc), digraph(&_graph) {}
     413
     414      OutArcIt& operator++() {
     415        digraph->nextOut(*this);
     416        return *this;
     417      }
     418
     419    };
     420
     421
     422    class InArcIt : public Arc {
     423      const Digraph* digraph;
     424    public:
     425
     426      InArcIt() { }
     427
     428      InArcIt(Invalid i) : Arc(i) { }
     429
     430      InArcIt(const Digraph& _graph, const Node& node)
     431        : digraph(&_graph) {
     432        _graph.firstIn(*this, node);
     433      }
     434
     435      InArcIt(const Digraph& _graph, const Arc& arc) :
     436        Arc(arc), digraph(&_graph) {}
     437
     438      InArcIt& operator++() {
     439        digraph->nextIn(*this);
     440        return *this;
     441      }
     442
     443    };
     444
     445
     446    class EdgeIt : public Parent::Edge {
     447      const Digraph* digraph;
     448    public:
     449
     450      EdgeIt() { }
     451
     452      EdgeIt(Invalid i) : Edge(i) { }
     453
     454      explicit EdgeIt(const Digraph& _graph) : digraph(&_graph) {
     455        _graph.first(static_cast<Edge&>(*this));
     456      }
     457
     458      EdgeIt(const Digraph& _graph, const Edge& e) :
     459        Edge(e), digraph(&_graph) { }
     460
     461      EdgeIt& operator++() {
     462        digraph->next(*this);
     463        return *this;
     464      }
     465
     466    };
     467
     468    class IncEdgeIt : public Parent::Edge {
     469      friend class EdgeSetExtender;
     470      const Digraph* digraph;
     471      bool direction;
     472    public:
     473
     474      IncEdgeIt() { }
     475
     476      IncEdgeIt(Invalid i) : Edge(i), direction(false) { }
     477
     478      IncEdgeIt(const Digraph& _graph, const Node &n) : digraph(&_graph) {
     479        _graph.firstInc(*this, direction, n);
     480      }
     481
     482      IncEdgeIt(const Digraph& _graph, const Edge &ue, const Node &n)
     483        : digraph(&_graph), Edge(ue) {
     484        direction = (_graph.source(ue) == n);
     485      }
     486
     487      IncEdgeIt& operator++() {
     488        digraph->nextInc(*this, direction);
     489        return *this;
     490      }
     491    };
     492
     493    /// \brief Base node of the iterator
     494    ///
     495    /// Returns the base node (ie. the source in this case) of the iterator
     496    Node baseNode(const OutArcIt &e) const {
     497      return Parent::source(static_cast<const Arc&>(e));
     498    }
     499    /// \brief Running node of the iterator
     500    ///
     501    /// Returns the running node (ie. the target in this case) of the
     502    /// iterator
     503    Node runningNode(const OutArcIt &e) const {
     504      return Parent::target(static_cast<const Arc&>(e));
     505    }
     506
     507    /// \brief Base node of the iterator
     508    ///
     509    /// Returns the base node (ie. the target in this case) of the iterator
     510    Node baseNode(const InArcIt &e) const {
     511      return Parent::target(static_cast<const Arc&>(e));
     512    }
     513    /// \brief Running node of the iterator
     514    ///
     515    /// Returns the running node (ie. the source in this case) of the
     516    /// iterator
     517    Node runningNode(const InArcIt &e) const {
     518      return Parent::source(static_cast<const Arc&>(e));
     519    }
     520
     521    /// Base node of the iterator
     522    ///
     523    /// Returns the base node of the iterator
     524    Node baseNode(const IncEdgeIt &e) const {
     525      return e.direction ? u(e) : v(e);
     526    }
     527    /// Running node of the iterator
     528    ///
     529    /// Returns the running node of the iterator
     530    Node runningNode(const IncEdgeIt &e) const {
     531      return e.direction ? v(e) : u(e);
     532    }
     533
     534
     535    template <typename _Value>
     536    class ArcMap
     537      : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
     538    public:
     539      typedef EdgeSetExtender Digraph;
     540      typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
     541
     542      ArcMap(const Digraph& _g)
     543        : Parent(_g) {}
     544      ArcMap(const Digraph& _g, const _Value& _v)
     545        : Parent(_g, _v) {}
     546
     547      ArcMap& operator=(const ArcMap& cmap) {
     548        return operator=<ArcMap>(cmap);
     549      }
     550
     551      template <typename CMap>
     552      ArcMap& operator=(const CMap& cmap) {
     553        Parent::operator=(cmap);
     554        return *this;
     555      }
     556
     557    };
     558
     559
     560    template <typename _Value>
     561    class EdgeMap
     562      : public MapExtender<DefaultMap<Digraph, Edge, _Value> > {
     563    public:
     564      typedef EdgeSetExtender Digraph;
     565      typedef MapExtender<DefaultMap<Digraph, Edge, _Value> > Parent;
     566
     567      EdgeMap(const Digraph& _g)
     568        : Parent(_g) {}
     569
     570      EdgeMap(const Digraph& _g, const _Value& _v)
     571        : Parent(_g, _v) {}
     572
     573      EdgeMap& operator=(const EdgeMap& cmap) {
     574        return operator=<EdgeMap>(cmap);
     575      }
     576
     577      template <typename CMap>
     578      EdgeMap& operator=(const CMap& cmap) {
     579        Parent::operator=(cmap);
     580        return *this;
     581      }
     582
     583    };
     584
     585
     586    // Alteration extension
     587
     588    Edge addEdge(const Node& from, const Node& to) {
     589      Edge edge = Parent::addEdge(from, to);
     590      notifier(Edge()).add(edge);
     591      std::vector<Arc> arcs;
     592      arcs.push_back(Parent::direct(edge, true));
     593      arcs.push_back(Parent::direct(edge, false));
     594      notifier(Arc()).add(arcs);
     595      return edge;
     596    }
     597   
     598    void clear() {
     599      notifier(Arc()).clear();
     600      notifier(Edge()).clear();
     601      Parent::clear();
     602    }
     603
     604    void erase(const Edge& edge) {
     605      std::vector<Arc> arcs;
     606      arcs.push_back(Parent::direct(edge, true));
     607      arcs.push_back(Parent::direct(edge, false));
     608      notifier(Arc()).erase(arcs);
     609      notifier(Edge()).erase(edge);
     610      Parent::erase(edge);
     611    }
     612
     613
     614    EdgeSetExtender() {
     615      arc_notifier.setContainer(*this);
     616      edge_notifier.setContainer(*this);
     617    }
     618
     619    ~EdgeSetExtender() {
     620      edge_notifier.clear();
     621      arc_notifier.clear();
     622    }
     623   
     624  };
     625
     626}
     627
     628#endif
  • new file lemon/edge_set.h

    diff -r af4e8ba94294 -r 591e8758d98b lemon/edge_set.h
    - +  
     1/* -*- C++ -*-
     2 *
     3 * This file is a part of LEMON, a generic C++ optimization library
     4 *
     5 * Copyright (C) 2003-2008
     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_EDGE_SET_H
     20#define LEMON_EDGE_SET_H
     21
     22#include <lemon/core.h>
     23#include <lemon/bits/edge_set_extender.h>
     24
     25/// \ingroup semi_adaptors
     26/// \file
     27/// \brief ArcSet and EdgeSet classes.
     28///
     29/// Graphs which use another graph's node-set as own.
     30namespace lemon {
     31
     32  template <typename _Graph>
     33  class ListArcSetBase {
     34  public:
     35
     36    typedef _Graph Graph;
     37    typedef typename Graph::Node Node;
     38    typedef typename Graph::NodeIt NodeIt;
     39
     40  protected:
     41
     42    struct NodeT {
     43      int first_out, first_in;
     44      NodeT() : first_out(-1), first_in(-1) {}
     45    };
     46
     47    typedef typename ItemSetTraits<Graph, Node>::
     48    template Map<NodeT>::Type NodesImplBase;
     49
     50    NodesImplBase* nodes;
     51
     52    struct ArcT {
     53      Node source, target;
     54      int next_out, next_in;
     55      int prev_out, prev_in;
     56      ArcT() : prev_out(-1), prev_in(-1) {}
     57    };
     58
     59    std::vector<ArcT> arcs;
     60
     61    int first_arc;
     62    int first_free_arc;
     63
     64    const Graph* graph;
     65
     66    void initalize(const Graph& _graph, NodesImplBase& _nodes) {
     67      graph = &_graph;
     68      nodes = &_nodes;
     69    }
     70   
     71  public:
     72
     73    class Arc {
     74      friend class ListArcSetBase<Graph>;
     75    protected:
     76      Arc(int _id) : id(_id) {}
     77      int id;
     78    public:
     79      Arc() {}
     80      Arc(Invalid) : id(-1) {}
     81      bool operator==(const Arc& arc) const { return id == arc.id; }
     82      bool operator!=(const Arc& arc) const { return id != arc.id; }
     83      bool operator<(const Arc& arc) const { return id < arc.id; }
     84    };
     85
     86    ListArcSetBase() : first_arc(-1), first_free_arc(-1) {}
     87
     88    Arc addArc(const Node& u, const Node& v) {
     89      int n;
     90      if (first_free_arc == -1) {
     91        n = arcs.size();
     92        arcs.push_back(ArcT());
     93      } else {
     94        n = first_free_arc;
     95        first_free_arc = arcs[first_free_arc].next_in;
     96      }
     97      arcs[n].next_in = (*nodes)[v].first_in;
     98      if ((*nodes)[v].first_in != -1) {
     99        arcs[(*nodes)[v].first_in].prev_in = n;
     100      }
     101      (*nodes)[v].first_in = n;
     102      arcs[n].next_out = (*nodes)[u].first_out;
     103      if ((*nodes)[u].first_out != -1) {
     104        arcs[(*nodes)[u].first_out].prev_out = n;
     105      }
     106      (*nodes)[u].first_out = n;
     107      arcs[n].source = u;
     108      arcs[n].target = v;
     109      return Arc(n);
     110    }
     111
     112    void erase(const Arc& arc) {
     113      int n = arc.id;
     114      if (arcs[n].prev_in != -1) {
     115        arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
     116      } else {
     117        (*nodes)[arcs[n].target].first_in = arcs[n].next_in;
     118      }
     119      if (arcs[n].next_in != -1) {
     120        arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
     121      }
     122
     123      if (arcs[n].prev_out != -1) {
     124        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
     125      } else {
     126        (*nodes)[arcs[n].source].first_out = arcs[n].next_out;
     127      }
     128      if (arcs[n].next_out != -1) {
     129        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
     130      }
     131           
     132    }
     133
     134    void clear() {
     135      Node node;
     136      for (first(node); node != INVALID; next(node)) {
     137        (*nodes)[node].first_in = -1;
     138        (*nodes)[node].first_out = -1;
     139      }
     140      arcs.clear();
     141      first_arc = -1;
     142      first_free_arc = -1;
     143    }
     144
     145    void first(Node& node) const {
     146      graph->first(node);
     147    }
     148
     149    void next(Node& node) const {
     150      graph->next(node);
     151    }
     152
     153    void first(Arc& arc) const {
     154      Node node;
     155      first(node);
     156      while (node != INVALID && (*nodes)[node].first_in == -1) {
     157        next(node);
     158      }
     159      arc.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
     160    }
     161
     162    void next(Arc& arc) const {
     163      if (arcs[arc.id].next_in != -1) {
     164        arc.id = arcs[arc.id].next_in;
     165      } else {
     166        Node node = arcs[arc.id].target;
     167        next(node);
     168        while (node != INVALID && (*nodes)[node].first_in == -1) {
     169          next(node);
     170        }
     171        arc.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
     172      }     
     173    }
     174
     175    void firstOut(Arc& arc, const Node& node) const {
     176      arc.id = (*nodes)[node].first_out;   
     177    }
     178   
     179    void nextOut(Arc& arc) const {
     180      arc.id = arcs[arc.id].next_out;       
     181    }
     182
     183    void firstIn(Arc& arc, const Node& node) const {
     184      arc.id = (*nodes)[node].first_in;         
     185    }
     186
     187    void nextIn(Arc& arc) const {
     188      arc.id = arcs[arc.id].next_in;   
     189    }
     190
     191    int id(const Node& node) const { return graph->id(node); }
     192    int id(const Arc& arc) const { return arc.id; }
     193
     194    Node nodeFromId(int ix) const { return graph->nodeFromId(ix); }
     195    Arc arcFromId(int ix) const { return Arc(ix); }
     196
     197    int maxNodeId() const { return graph->maxNodeId(); };
     198    int maxArcId() const { return arcs.size() - 1; }
     199
     200    Node source(const Arc& arc) const { return arcs[arc.id].source;}
     201    Node target(const Arc& arc) const { return arcs[arc.id].target;}
     202
     203    typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
     204
     205    NodeNotifier& notifier(Node) const {
     206      return graph->notifier(Node());
     207    }
     208
     209    template <typename _Value>
     210    class NodeMap : public Graph::template NodeMap<_Value> {
     211    public:
     212
     213      typedef typename _Graph::template NodeMap<_Value> Parent;
     214
     215      explicit NodeMap(const ListArcSetBase<Graph>& arcset)
     216        : Parent(*arcset.graph) {}
     217
     218      NodeMap(const ListArcSetBase<Graph>& arcset, const _Value& value)
     219        : Parent(*arcset.graph, value) {}
     220
     221      NodeMap& operator=(const NodeMap& cmap) {
     222        return operator=<NodeMap>(cmap);
     223      }
     224
     225      template <typename CMap>
     226      NodeMap& operator=(const CMap& cmap) {
     227        Parent::operator=(cmap);
     228        return *this;
     229      }
     230    };
     231
     232  };
     233
     234  /// \ingroup semi_adaptors
     235  ///
     236  /// \brief Digraph using a node set of another graph and an
     237  /// own arc set.
     238  ///
     239  /// This structure can be used to establish another directed graph
     240  /// over a node set of an existing one. This class uses the same
     241  /// Node type as the underlying graph, and each valid node of the
     242  /// original graph is valid in this arc set, therefore the node
     243  /// objects of the original graph can be used directly with this
     244  /// class. The node handling functions (id handling, observing, and
     245  /// iterators) works equivalently as in the original graph.
     246  ///
     247  /// This implementation is based on doubly-linked lists, from each
     248  /// node the outgoing and the incoming arcs make up lists, therefore
     249  /// one arc can be erased in constant time. It also makes possible,
     250  /// that node can be removed from the underlying graph, in this case
     251  /// all arcs incident to the given node is erased from the arc set.
     252  ///
     253  /// \param _Graph The type of the graph which shares its node set with
     254  /// this class. Its interface must conform to the \ref concepts::Digraph
     255  /// "Digraph" concept.
     256  ///
     257  /// This class is fully conform to the \ref concepts::Digraph
     258  /// "Digraph" concept.
     259  template <typename _Graph>
     260  class ListArcSet : public ArcSetExtender<ListArcSetBase<_Graph> > {
     261
     262  public:
     263
     264    typedef ArcSetExtender<ListArcSetBase<_Graph> > Parent;
     265   
     266    typedef typename Parent::Node Node;
     267    typedef typename Parent::Arc Arc;
     268   
     269    typedef _Graph Graph;
     270
     271
     272    typedef typename Parent::NodesImplBase NodesImplBase;
     273
     274    void eraseNode(const Node& node) {
     275      Arc arc;
     276      Parent::firstOut(arc, node);
     277      while (arc != INVALID ) {
     278        erase(arc);
     279        Parent::firstOut(arc, node);
     280      }
     281
     282      Parent::firstIn(arc, node);
     283      while (arc != INVALID ) {
     284        erase(arc);
     285        Parent::firstIn(arc, node);
     286      }
     287    }
     288   
     289    void clearNodes() {
     290      Parent::clear();
     291    }
     292
     293    class NodesImpl : public NodesImplBase {
     294    public:
     295      typedef NodesImplBase Parent;
     296     
     297      NodesImpl(const Graph& graph, ListArcSet& arcset)
     298        : Parent(graph), _arcset(arcset) {}
     299
     300      virtual ~NodesImpl() {}
     301     
     302    protected:
     303
     304      virtual void erase(const Node& node) {
     305        _arcset.eraseNode(node);
     306        Parent::erase(node);
     307      }
     308      virtual void erase(const std::vector<Node>& nodes) {
     309        for (int i = 0; i < int(nodes.size()); ++i) {
     310          _arcset.eraseNode(nodes[i]);
     311        }
     312        Parent::erase(nodes);
     313      }
     314      virtual void clear() {
     315        _arcset.clearNodes();
     316        Parent::clear();
     317      }
     318
     319    private:
     320      ListArcSet& _arcset;
     321    };
     322
     323    NodesImpl nodes;
     324   
     325  public:
     326
     327    /// \brief Constructor of the ArcSet.
     328    ///
     329    /// Constructor of the ArcSet.
     330    ListArcSet(const Graph& graph) : nodes(graph, *this) {
     331      Parent::initalize(graph, nodes);
     332    }
     333
     334    /// \brief Add a new arc to the digraph.
     335    ///
     336    /// Add a new arc to the digraph with source node \c s
     337    /// and target node \c t.
     338    /// \return the new arc.
     339    Arc addArc(const Node& s, const Node& t) {
     340      return Parent::addArc(s, t);
     341    }
     342
     343    /// \brief Erase an arc from the digraph.
     344    ///
     345    /// Erase the arc \c a from the digraph.
     346    void erase(const Arc& a) {
     347      return Parent::erase(a);
     348    }
     349   
     350  };
     351
     352  template <typename _Graph>
     353  class ListEdgeSetBase {
     354  public:
     355
     356    typedef _Graph Graph;
     357    typedef typename Graph::Node Node;
     358    typedef typename Graph::NodeIt NodeIt;
     359
     360  protected:
     361
     362    struct NodeT {
     363      int first_out;
     364      NodeT() : first_out(-1) {}
     365    };
     366
     367    typedef typename ItemSetTraits<Graph, Node>::
     368    template Map<NodeT>::Type NodesImplBase;
     369
     370    NodesImplBase* nodes;
     371
     372    struct ArcT {
     373      Node target;
     374      int prev_out, next_out;
     375      ArcT() : prev_out(-1), next_out(-1) {}
     376    };
     377
     378    std::vector<ArcT> arcs;
     379
     380    int first_arc;
     381    int first_free_arc;
     382
     383    const Graph* graph;
     384
     385    void initalize(const Graph& _graph, NodesImplBase& _nodes) {
     386      graph = &_graph;
     387      nodes = &_nodes;
     388    }
     389   
     390  public:
     391
     392    class Edge {
     393      friend class ListEdgeSetBase;
     394    protected:
     395
     396      int id;
     397      explicit Edge(int _id) { id = _id;}
     398
     399    public:
     400      Edge() {}
     401      Edge (Invalid) { id = -1; }
     402      bool operator==(const Edge& arc) const {return id == arc.id;}
     403      bool operator!=(const Edge& arc) const {return id != arc.id;}
     404      bool operator<(const Edge& arc) const {return id < arc.id;}
     405    };
     406
     407    class Arc {
     408      friend class ListEdgeSetBase;
     409    protected:
     410      Arc(int _id) : id(_id) {}
     411      int id;
     412    public:
     413      operator Edge() const { return edgeFromId(id / 2); }
     414
     415      Arc() {}
     416      Arc(Invalid) : id(-1) {}
     417      bool operator==(const Arc& arc) const { return id == arc.id; }
     418      bool operator!=(const Arc& arc) const { return id != arc.id; }
     419      bool operator<(const Arc& arc) const { return id < arc.id; }
     420    };
     421
     422    ListEdgeSetBase() : first_arc(-1), first_free_arc(-1) {}
     423
     424    Edge addEdge(const Node& u, const Node& v) {
     425      int n;
     426
     427      if (first_free_arc == -1) {
     428        n = arcs.size();
     429        arcs.push_back(ArcT());
     430        arcs.push_back(ArcT());
     431      } else {
     432        n = first_free_arc;
     433        first_free_arc = arcs[n].next_out;
     434      }
     435     
     436      arcs[n].target = u;
     437      arcs[n | 1].target = v;
     438
     439      arcs[n].next_out = (*nodes)[v].first_out;
     440      if ((*nodes)[v].first_out != -1) {
     441        arcs[(*nodes)[v].first_out].prev_out = n;
     442      }
     443      (*nodes)[v].first_out = n;
     444      arcs[n].prev_out = -1;
     445     
     446      if ((*nodes)[u].first_out != -1) {
     447        arcs[(*nodes)[u].first_out].prev_out = (n | 1);
     448      }
     449      arcs[n | 1].next_out = (*nodes)[u].first_out;
     450      (*nodes)[u].first_out = (n | 1);
     451      arcs[n | 1].prev_out = -1;
     452
     453      return Edge(n / 2);
     454    }
     455
     456    void erase(const Edge& arc) {
     457      int n = arc.id * 2;
     458     
     459      if (arcs[n].next_out != -1) {
     460        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
     461      }
     462
     463      if (arcs[n].prev_out != -1) {
     464        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
     465      } else {
     466        (*nodes)[arcs[n | 1].target].first_out = arcs[n].next_out;
     467      }
     468
     469      if (arcs[n | 1].next_out != -1) {
     470        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
     471      }
     472
     473      if (arcs[n | 1].prev_out != -1) {
     474        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
     475      } else {
     476        (*nodes)[arcs[n].target].first_out = arcs[n | 1].next_out;
     477      }
     478     
     479      arcs[n].next_out = first_free_arc;
     480      first_free_arc = n;     
     481           
     482    }
     483
     484    void clear() {
     485      Node node;
     486      for (first(node); node != INVALID; next(node)) {
     487        (*nodes)[node].first_out = -1;
     488      }
     489      arcs.clear();
     490      first_arc = -1;
     491      first_free_arc = -1;
     492    }
     493
     494    void first(Node& node) const {
     495      graph->first(node);
     496    }
     497
     498    void next(Node& node) const {
     499      graph->next(node);
     500    }
     501
     502    void first(Arc& arc) const {
     503      Node node;
     504      first(node);
     505      while (node != INVALID && (*nodes)[node].first_out == -1) {
     506        next(node);
     507      }
     508      arc.id = (node == INVALID) ? -1 : (*nodes)[node].first_out;
     509    }
     510
     511    void next(Arc& arc) const {
     512      if (arcs[arc.id].next_out != -1) {
     513        arc.id = arcs[arc.id].next_out;
     514      } else {
     515        Node node = arcs[arc.id ^ 1].target;
     516        next(node);
     517        while(node != INVALID && (*nodes)[node].first_out == -1) {
     518          next(node);
     519        }
     520        arc.id = (node == INVALID) ? -1 : (*nodes)[node].first_out;
     521      }     
     522    }
     523
     524    void first(Edge& edge) const {
     525      Node node;
     526      first(node);
     527      while (node != INVALID) {
     528        edge.id = (*nodes)[node].first_out;
     529        while ((edge.id & 1) != 1) {
     530          edge.id = arcs[edge.id].next_out;
     531        }
     532        if (edge.id != -1) {
     533          edge.id /= 2;
     534          return;
     535        }
     536        next(node);
     537      }
     538      edge.id = -1;
     539    }
     540
     541    void next(Edge& edge) const {
     542      Node node = arcs[edge.id * 2].target;
     543      edge.id = arcs[(edge.id * 2) | 1].next_out;
     544      while ((edge.id & 1) != 1) {
     545        edge.id = arcs[edge.id].next_out;
     546      }
     547      if (edge.id != -1) {
     548        edge.id /= 2;
     549        return;
     550      }
     551      next(node);
     552      while (node != INVALID) {
     553        edge.id = (*nodes)[node].first_out;
     554        while ((edge.id & 1) != 1) {
     555          edge.id = arcs[edge.id].next_out;
     556        }
     557        if (edge.id != -1) {
     558          edge.id /= 2;
     559          return;
     560        }
     561        next(node);
     562      }
     563      edge.id = -1;
     564    }
     565
     566    void firstOut(Arc& arc, const Node& node) const {
     567      arc.id = (*nodes)[node].first_out;
     568    }
     569   
     570    void nextOut(Arc& arc) const {
     571      arc.id = arcs[arc.id].next_out;       
     572    }
     573
     574    void firstIn(Arc& arc, const Node& node) const {
     575      arc.id = (((*nodes)[node].first_out) ^ 1);
     576      if (arc.id == -2) arc.id = -1;
     577    }
     578
     579    void nextIn(Arc& arc) const {
     580      arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
     581      if (arc.id == -2) arc.id = -1;
     582    }
     583
     584    void firstInc(Edge &arc, bool& dir, const Node& node) const {
     585      int de = (*nodes)[node].first_out;
     586      if (de != -1 ) {
     587        arc.id = de / 2;
     588        dir = ((de & 1) == 1);
     589      } else {
     590        arc.id = -1;
     591        dir = true;
     592      }
     593    }
     594    void nextInc(Edge &arc, bool& dir) const {
     595      int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
     596      if (de != -1 ) {
     597        arc.id = de / 2;
     598        dir = ((de & 1) == 1);
     599      } else {
     600        arc.id = -1;
     601        dir = true;
     602      }
     603    }
     604
     605    static bool direction(Arc arc) {
     606      return (arc.id & 1) == 1;
     607    }
     608
     609    static Arc direct(Edge edge, bool dir) {
     610      return Arc(edge.id * 2 + (dir ? 1 : 0));
     611    }
     612
     613    int id(const Node& node) const { return graph->id(node); }
     614    static int id(Arc e) { return e.id; }
     615    static int id(Edge e) { return e.id; }
     616
     617    Node nodeFromId(int id) const { return graph->nodeFromId(id); }
     618    static Arc arcFromId(int id) { return Arc(id);}
     619    static Edge edgeFromId(int id) { return Edge(id);}
     620
     621    int maxNodeId() const { return graph->maxNodeId(); };
     622    int maxEdgeId() const { return arcs.size() / 2 - 1; }
     623    int maxArcId() const { return arcs.size()-1; }
     624
     625    Node source(Arc e) const { return arcs[e.id ^ 1].target; }
     626    Node target(Arc e) const { return arcs[e.id].target; }
     627
     628    Node u(Edge e) const { return arcs[2 * e.id].target; }
     629    Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
     630
     631    typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
     632
     633    NodeNotifier& notifier(Node) const {
     634      return graph->notifier(Node());
     635    }
     636
     637    template <typename _Value>
     638    class NodeMap : public Graph::template NodeMap<_Value> {
     639    public:
     640
     641      typedef typename _Graph::template NodeMap<_Value> Parent;
     642
     643      explicit NodeMap(const ListEdgeSetBase<Graph>& arcset)
     644        : Parent(*arcset.graph) {}
     645
     646      NodeMap(const ListEdgeSetBase<Graph>& arcset, const _Value& value)
     647        : Parent(*arcset.graph, value) {}
     648
     649      NodeMap& operator=(const NodeMap& cmap) {
     650        return operator=<NodeMap>(cmap);
     651      }
     652
     653      template <typename CMap>
     654      NodeMap& operator=(const CMap& cmap) {
     655        Parent::operator=(cmap);
     656        return *this;
     657      }
     658    };
     659
     660  };
     661
     662  /// \ingroup semi_adaptors
     663  ///
     664  /// \brief Graph using a node set of another graph and an
     665  /// own edge set.
     666  ///
     667  /// This structure can be used to establish another graph over a
     668  /// node set of an existing one. This class uses the same Node type
     669  /// as the underlying graph, and each valid node of the original
     670  /// graph is valid in this arc set, therefore the node objects of
     671  /// the original graph can be used directly with this class. The
     672  /// node handling functions (id handling, observing, and iterators)
     673  /// works equivalently as in the original graph.
     674  ///
     675  /// This implementation is based on doubly-linked lists, from each
     676  /// node the incident edges make up lists, therefore one edge can be
     677  /// erased in constant time. It also makes possible, that node can
     678  /// be removed from the underlying graph, in this case all edges
     679  /// incident to the given node is erased from the arc set.
     680  ///
     681  /// \param _Graph The type of the graph which shares its node set
     682  /// with this class. Its interface must conform to the \ref
     683  /// concepts::Graph "Graph" concept.
     684  ///
     685  /// This class is fully conform to the \ref concepts::Graph "Graph"
     686  /// concept.
     687  template <typename _Graph>
     688  class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<_Graph> > {
     689
     690  public:
     691
     692    typedef EdgeSetExtender<ListEdgeSetBase<_Graph> > Parent;
     693   
     694    typedef typename Parent::Node Node;
     695    typedef typename Parent::Arc Arc;
     696    typedef typename Parent::Edge Edge;
     697   
     698    typedef _Graph Graph;
     699
     700
     701    typedef typename Parent::NodesImplBase NodesImplBase;
     702
     703    void eraseNode(const Node& node) {
     704      Arc arc;
     705      Parent::firstOut(arc, node);
     706      while (arc != INVALID ) {
     707        erase(arc);
     708        Parent::firstOut(arc, node);
     709      }
     710
     711    }
     712   
     713    void clearNodes() {
     714      Parent::clear();
     715    }
     716
     717    class NodesImpl : public NodesImplBase {
     718    public:
     719      typedef NodesImplBase Parent;
     720     
     721      NodesImpl(const Graph& graph, ListEdgeSet& arcset)
     722        : Parent(graph), _arcset(arcset) {}
     723
     724      virtual ~NodesImpl() {}
     725     
     726    protected:
     727
     728      virtual void erase(const Node& node) {
     729        _arcset.eraseNode(node);
     730        Parent::erase(node);
     731      }
     732      virtual void erase(const std::vector<Node>& nodes) {
     733        for (int i = 0; i < int(nodes.size()); ++i) {
     734          _arcset.eraseNode(nodes[i]);
     735        }
     736        Parent::erase(nodes);
     737      }
     738      virtual void clear() {
     739        _arcset.clearNodes();
     740        Parent::clear();
     741      }
     742
     743    private:
     744      ListEdgeSet& _arcset;
     745    };
     746
     747    NodesImpl nodes;
     748   
     749  public:
     750
     751    /// \brief Constructor of the EdgeSet.
     752    ///
     753    /// Constructor of the EdgeSet.
     754    ListEdgeSet(const Graph& graph) : nodes(graph, *this) {
     755      Parent::initalize(graph, nodes);
     756    }
     757
     758    /// \brief Add a new edge to the graph.
     759    ///
     760    /// Add a new edge to the graph with node \c u
     761    /// and node \c v endpoints.
     762    /// \return the new edge.
     763    Edge addEdge(const Node& u, const Node& v) {
     764      return Parent::addEdge(u, v);
     765    }
     766
     767    /// \brief Erase an edge from the graph.
     768    ///
     769    /// Erase the edge \c e from the graph.
     770    void erase(const Edge& e) {
     771      return Parent::erase(e);
     772    }
     773   
     774  };
     775
     776  template <typename _Graph>
     777  class SmartArcSetBase {
     778  public:
     779
     780    typedef _Graph Graph;
     781    typedef typename Graph::Node Node;
     782    typedef typename Graph::NodeIt NodeIt;
     783
     784  protected:
     785
     786    struct NodeT {
     787      int first_out, first_in;
     788      NodeT() : first_out(-1), first_in(-1) {}
     789    };
     790
     791    typedef typename ItemSetTraits<Graph, Node>::
     792    template Map<NodeT>::Type NodesImplBase;
     793
     794    NodesImplBase* nodes;
     795
     796    struct ArcT {
     797      Node source, target;
     798      int next_out, next_in;
     799      ArcT() {}
     800    };
     801
     802    std::vector<ArcT> arcs;
     803
     804    const Graph* graph;
     805
     806    void initalize(const Graph& _graph, NodesImplBase& _nodes) {
     807      graph = &_graph;
     808      nodes = &_nodes;
     809    }
     810   
     811  public:
     812
     813    class Arc {
     814      friend class SmartArcSetBase<Graph>;
     815    protected:
     816      Arc(int _id) : id(_id) {}
     817      int id;
     818    public:
     819      Arc() {}
     820      Arc(Invalid) : id(-1) {}
     821      bool operator==(const Arc& arc) const { return id == arc.id; }
     822      bool operator!=(const Arc& arc) const { return id != arc.id; }
     823      bool operator<(const Arc& arc) const { return id < arc.id; }
     824    };
     825
     826    SmartArcSetBase() {}
     827
     828    Arc addArc(const Node& u, const Node& v) {
     829      int n = arcs.size();
     830      arcs.push_back(ArcT());
     831      arcs[n].next_in = (*nodes)[v].first_in;
     832      (*nodes)[v].first_in = n;
     833      arcs[n].next_out = (*nodes)[u].first_out;
     834      (*nodes)[u].first_out = n;
     835      arcs[n].source = u;
     836      arcs[n].target = v;
     837      return Arc(n);
     838    }
     839
     840    void clear() {
     841      Node node;
     842      for (first(node); node != INVALID; next(node)) {
     843        (*nodes)[node].first_in = -1;
     844        (*nodes)[node].first_out = -1;
     845      }
     846      arcs.clear();
     847    }
     848
     849    void first(Node& node) const {
     850      graph->first(node);
     851    }
     852
     853    void next(Node& node) const {
     854      graph->next(node);
     855    }
     856
     857    void first(Arc& arc) const {
     858      arc.id = arcs.size() - 1;
     859    }
     860
     861    void next(Arc& arc) const {
     862      --arc.id;
     863    }
     864
     865    void firstOut(Arc& arc, const Node& node) const {
     866      arc.id = (*nodes)[node].first_out;   
     867    }
     868   
     869    void nextOut(Arc& arc) const {
     870      arc.id = arcs[arc.id].next_out;       
     871    }
     872
     873    void firstIn(Arc& arc, const Node& node) const {
     874      arc.id = (*nodes)[node].first_in;         
     875    }
     876
     877    void nextIn(Arc& arc) const {
     878      arc.id = arcs[arc.id].next_in;   
     879    }
     880
     881    int id(const Node& node) const { return graph->id(node); }
     882    int id(const Arc& arc) const { return arc.id; }
     883
     884    Node nodeFromId(int ix) const { return graph->nodeFromId(ix); }
     885    Arc arcFromId(int ix) const { return Arc(ix); }
     886
     887    int maxNodeId() const { return graph->maxNodeId(); };
     888    int maxArcId() const { return arcs.size() - 1; }
     889
     890    Node source(const Arc& arc) const { return arcs[arc.id].source;}
     891    Node target(const Arc& arc) const { return arcs[arc.id].target;}
     892
     893    typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
     894
     895    NodeNotifier& notifier(Node) const {
     896      return graph->notifier(Node());
     897    }
     898
     899    template <typename _Value>
     900    class NodeMap : public Graph::template NodeMap<_Value> {
     901    public:
     902
     903      typedef typename _Graph::template NodeMap<_Value> Parent;
     904
     905      explicit NodeMap(const SmartArcSetBase<Graph>& arcset)
     906        : Parent(*arcset.graph) { }
     907
     908      NodeMap(const SmartArcSetBase<Graph>& arcset, const _Value& value)
     909        : Parent(*arcset.graph, value) { }
     910
     911      NodeMap& operator=(const NodeMap& cmap) {
     912        return operator=<NodeMap>(cmap);
     913      }
     914
     915      template <typename CMap>
     916      NodeMap& operator=(const CMap& cmap) {
     917        Parent::operator=(cmap);
     918        return *this;
     919      }
     920    };
     921
     922  };
     923
     924
     925  /// \ingroup semi_adaptors
     926  ///
     927  /// \brief Digraph using a node set of another graph and an own arc
     928  /// set.
     929  ///
     930  /// This structure can be used to establish another directed graph
     931  /// over a node set of an existing one. This class uses the same
     932  /// Node type as the underlying graph, and each valid node of the
     933  /// original graph is valid in this arc set, therefore the node
     934  /// objects of the original graph can be used directly with this
     935  /// class. The node handling functions (id handling, observing, and
     936  /// iterators) works equivalently as in the original graph.
     937  ///
     938  /// \param _Graph The type of the graph which shares its node set with
     939  /// this class. Its interface must conform to the \ref concepts::Digraph
     940  /// "Digraph" concept.
     941  ///
     942  /// This implementation is slightly faster than the \c ListArcSet,
     943  /// because it uses continuous storage for arcs and it uses just
     944  /// single-linked lists for enumerate outgoing and incoming
     945  /// arcs. Therefore the arcs cannot be erased from the arc sets.
     946  ///
     947  /// \warning If a node is erased from the underlying graph and this
     948  /// node is the source or target of one edge in the edge set, then
     949  /// the edge set is invalidated, and it cannot be used anymore. The
     950  /// validity can be checked with the \c valid() member function.
     951  ///
     952  /// This class is fully conform to the \ref concepts::Digraph
     953  /// "Digraph" concept.
     954  template <typename _Graph>
     955  class SmartArcSet : public ArcSetExtender<SmartArcSetBase<_Graph> > {
     956
     957  public:
     958
     959    typedef ArcSetExtender<SmartArcSetBase<_Graph> > Parent;
     960   
     961    typedef typename Parent::Node Node;
     962    typedef typename Parent::Arc Arc;
     963   
     964    typedef _Graph Graph;
     965
     966  protected:
     967
     968    typedef typename Parent::NodesImplBase NodesImplBase;
     969
     970    void eraseNode(const Node& node) {
     971      if (typename Parent::InArcIt(*this, node) == INVALID &&
     972          typename Parent::OutArcIt(*this, node) == INVALID) {
     973        return;
     974      }
     975      throw typename NodesImplBase::Notifier::ImmediateDetach();
     976    }
     977   
     978    void clearNodes() {
     979      Parent::clear();
     980    }
     981
     982    class NodesImpl : public NodesImplBase {
     983    public:
     984      typedef NodesImplBase Parent;
     985     
     986      NodesImpl(const Graph& graph, SmartArcSet& arcset)
     987        : Parent(graph), _arcset(arcset) {}
     988
     989      virtual ~NodesImpl() {}
     990     
     991      bool attached() const {
     992        return Parent::attached();
     993      }
     994
     995    protected:
     996
     997      virtual void erase(const Node& node) {
     998        try {
     999          _arcset.eraseNode(node);
     1000          Parent::erase(node);
     1001        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
     1002          Parent::clear();
     1003          throw;
     1004        }
     1005      }
     1006      virtual void erase(const std::vector<Node>& nodes) {
     1007        try {
     1008          for (int i = 0; i < int(nodes.size()); ++i) {
     1009            _arcset.eraseNode(nodes[i]);
     1010          }
     1011          Parent::erase(nodes);
     1012        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
     1013          Parent::clear();
     1014          throw;
     1015        }
     1016      }
     1017      virtual void clear() {
     1018        _arcset.clearNodes();
     1019        Parent::clear();
     1020      }
     1021
     1022    private:
     1023      SmartArcSet& _arcset;
     1024    };
     1025
     1026    NodesImpl nodes;
     1027   
     1028  public:
     1029
     1030    /// \brief Constructor of the ArcSet.
     1031    ///
     1032    /// Constructor of the ArcSet.
     1033    SmartArcSet(const Graph& graph) : nodes(graph, *this) {
     1034      Parent::initalize(graph, nodes);
     1035    }
     1036
     1037    /// \brief Add a new arc to the digraph.
     1038    ///
     1039    /// Add a new arc to the digraph with source node \c s
     1040    /// and target node \c t.
     1041    /// \return the new arc.
     1042    Arc addArc(const Node& s, const Node& t) {
     1043      return Parent::addArc(s, t);
     1044    }
     1045
     1046    /// \brief Validity check
     1047    ///
     1048    /// This functions gives back false if the ArcSet is
     1049    /// invalidated. It occurs when a node in the underlying graph is
     1050    /// erased and it is not isolated in the ArcSet.
     1051    bool valid() const {
     1052      return nodes.attached();
     1053    }
     1054   
     1055  };
     1056
     1057
     1058  template <typename _Graph>
     1059  class SmartEdgeSetBase {
     1060  public:
     1061
     1062    typedef _Graph Graph;
     1063    typedef typename Graph::Node Node;
     1064    typedef typename Graph::NodeIt NodeIt;
     1065
     1066  protected:
     1067
     1068    struct NodeT {
     1069      int first_out;
     1070      NodeT() : first_out(-1) {}
     1071    };
     1072
     1073    typedef typename ItemSetTraits<Graph, Node>::
     1074    template Map<NodeT>::Type NodesImplBase;
     1075
     1076    NodesImplBase* nodes;
     1077
     1078    struct ArcT {
     1079      Node target;
     1080      int next_out;
     1081      ArcT() {}
     1082    };
     1083
     1084    std::vector<ArcT> arcs;
     1085
     1086    const Graph* graph;
     1087
     1088    void initalize(const Graph& _graph, NodesImplBase& _nodes) {
     1089      graph = &_graph;
     1090      nodes = &_nodes;
     1091    }
     1092   
     1093  public:
     1094
     1095    class Edge {
     1096      friend class SmartEdgeSetBase;
     1097    protected:
     1098
     1099      int id;
     1100      explicit Edge(int _id) { id = _id;}
     1101
     1102    public:
     1103      Edge() {}
     1104      Edge (Invalid) { id = -1; }
     1105      bool operator==(const Edge& arc) const {return id == arc.id;}
     1106      bool operator!=(const Edge& arc) const {return id != arc.id;}
     1107      bool operator<(const Edge& arc) const {return id < arc.id;}
     1108    };
     1109
     1110    class Arc {
     1111      friend class SmartEdgeSetBase;
     1112    protected:
     1113      Arc(int _id) : id(_id) {}
     1114      int id;
     1115    public:
     1116      operator Edge() const { return edgeFromId(id / 2); }
     1117
     1118      Arc() {}
     1119      Arc(Invalid) : id(-1) {}
     1120      bool operator==(const Arc& arc) const { return id == arc.id; }
     1121      bool operator!=(const Arc& arc) const { return id != arc.id; }
     1122      bool operator<(const Arc& arc) const { return id < arc.id; }
     1123    };
     1124
     1125    SmartEdgeSetBase() {}
     1126
     1127    Edge addEdge(const Node& u, const Node& v) {
     1128      int n = arcs.size();
     1129      arcs.push_back(ArcT());
     1130      arcs.push_back(ArcT());
     1131     
     1132      arcs[n].target = u;
     1133      arcs[n | 1].target = v;
     1134
     1135      arcs[n].next_out = (*nodes)[v].first_out;
     1136      (*nodes)[v].first_out = n;
     1137
     1138      arcs[n | 1].next_out = (*nodes)[u].first_out;     
     1139      (*nodes)[u].first_out = (n | 1);
     1140
     1141      return Edge(n / 2);
     1142    }
     1143
     1144    void clear() {
     1145      Node node;
     1146      for (first(node); node != INVALID; next(node)) {
     1147        (*nodes)[node].first_out = -1;
     1148      }
     1149      arcs.clear();
     1150    }
     1151
     1152    void first(Node& node) const {
     1153      graph->first(node);
     1154    }
     1155
     1156    void next(Node& node) const {
     1157      graph->next(node);
     1158    }
     1159
     1160    void first(Arc& arc) const {
     1161      arc.id = arcs.size() - 1;
     1162    }
     1163
     1164    void next(Arc& arc) const {
     1165      --arc.id;
     1166    }
     1167
     1168    void first(Edge& arc) const {
     1169      arc.id = arcs.size() / 2 - 1;
     1170    }
     1171
     1172    void next(Edge& arc) const {
     1173      --arc.id;
     1174    }
     1175
     1176    void firstOut(Arc& arc, const Node& node) const {
     1177      arc.id = (*nodes)[node].first_out;   
     1178    }
     1179   
     1180    void nextOut(Arc& arc) const {
     1181      arc.id = arcs[arc.id].next_out;       
     1182    }
     1183
     1184    void firstIn(Arc& arc, const Node& node) const {
     1185      arc.id = (((*nodes)[node].first_out) ^ 1);
     1186      if (arc.id == -2) arc.id = -1;
     1187    }
     1188
     1189    void nextIn(Arc& arc) const {
     1190      arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
     1191      if (arc.id == -2) arc.id = -1;
     1192    }
     1193
     1194    void firstInc(Edge &arc, bool& dir, const Node& node) const {
     1195      int de = (*nodes)[node].first_out;
     1196      if (de != -1 ) {
     1197        arc.id = de / 2;
     1198        dir = ((de & 1) == 1);
     1199      } else {
     1200        arc.id = -1;
     1201        dir = true;
     1202      }
     1203    }
     1204    void nextInc(Edge &arc, bool& dir) const {
     1205      int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
     1206      if (de != -1 ) {
     1207        arc.id = de / 2;
     1208        dir = ((de & 1) == 1);
     1209      } else {
     1210        arc.id = -1;
     1211        dir = true;
     1212      }
     1213    }
     1214
     1215    static bool direction(Arc arc) {
     1216      return (arc.id & 1) == 1;
     1217    }
     1218
     1219    static Arc direct(Edge edge, bool dir) {
     1220      return Arc(edge.id * 2 + (dir ? 1 : 0));
     1221    }
     1222
     1223    int id(Node node) const { return graph->id(node); }
     1224    static int id(Arc arc) { return arc.id; }
     1225    static int id(Edge arc) { return arc.id; }
     1226
     1227    Node nodeFromId(int id) const { return graph->nodeFromId(id); }
     1228    static Arc arcFromId(int id) { return Arc(id); }
     1229    static Edge edgeFromId(int id) { return Edge(id);}
     1230
     1231    int maxNodeId() const { return graph->maxNodeId(); };
     1232    int maxArcId() const { return arcs.size() - 1; }
     1233    int maxEdgeId() const { return arcs.size() / 2 - 1; }
     1234
     1235    Node source(Arc e) const { return arcs[e.id ^ 1].target; }
     1236    Node target(Arc e) const { return arcs[e.id].target; }
     1237
     1238    Node u(Edge e) const { return arcs[2 * e.id].target; }
     1239    Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
     1240
     1241    typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
     1242
     1243    NodeNotifier& notifier(Node) const {
     1244      return graph->notifier(Node());
     1245    }
     1246
     1247    template <typename _Value>
     1248    class NodeMap : public Graph::template NodeMap<_Value> {
     1249    public:
     1250
     1251      typedef typename _Graph::template NodeMap<_Value> Parent;
     1252
     1253      explicit NodeMap(const SmartEdgeSetBase<Graph>& arcset)
     1254        : Parent(*arcset.graph) { }
     1255
     1256      NodeMap(const SmartEdgeSetBase<Graph>& arcset, const _Value& value)
     1257        : Parent(*arcset.graph, value) { }
     1258
     1259      NodeMap& operator=(const NodeMap& cmap) {
     1260        return operator=<NodeMap>(cmap);
     1261      }
     1262
     1263      template <typename CMap>
     1264      NodeMap& operator=(const CMap& cmap) {
     1265        Parent::operator=(cmap);
     1266        return *this;
     1267      }
     1268    };
     1269
     1270  };
     1271
     1272  /// \ingroup semi_adaptors
     1273  ///
     1274  /// \brief Graph using a node set of another graph and an own edge
     1275  /// set.
     1276  ///
     1277  /// This structure can be used to establish another graph over a
     1278  /// node set of an existing one. This class uses the same Node type
     1279  /// as the underlying graph, and each valid node of the original
     1280  /// graph is valid in this arc set, therefore the node objects of
     1281  /// the original graph can be used directly with this class. The
     1282  /// node handling functions (id handling, observing, and iterators)
     1283  /// works equivalently as in the original graph.
     1284  ///
     1285  /// \param _Graph The type of the graph which shares its node set
     1286  /// with this class. Its interface must conform to the \ref
     1287  /// concepts::Digraph "Digraph" concept.
     1288  ///
     1289  /// This implementation is slightly faster than the \c ListEdgeSet,
     1290  /// because it uses continuous storage for arcs and it uses just
     1291  /// single-linked lists for enumerate incident edges. Therefore the
     1292  /// edges cannot be erased from the edge sets.
     1293  ///
     1294  /// \warning If a node is erased from the underlying graph and this
     1295  /// node is incident to one edge in the edge set, then the edge set
     1296  /// is invalidated, and it cannot be used anymore. The validity can
     1297  /// be checked with the \c valid() member function.
     1298  ///
     1299  /// This class is fully conform to the \ref concepts::Graph
     1300  /// "Graph" concept.
     1301  template <typename _Graph>
     1302  class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<_Graph> > {
     1303
     1304  public:
     1305
     1306    typedef EdgeSetExtender<SmartEdgeSetBase<_Graph> > Parent;
     1307   
     1308    typedef typename Parent::Node Node;
     1309    typedef typename Parent::Arc Arc;
     1310    typedef typename Parent::Edge Edge;
     1311   
     1312    typedef _Graph Graph;
     1313
     1314  protected:
     1315
     1316    typedef typename Parent::NodesImplBase NodesImplBase;
     1317
     1318    void eraseNode(const Node& node) {
     1319      if (typename Parent::IncEdgeIt(*this, node) == INVALID) {
     1320        return;
     1321      }
     1322      throw typename NodesImplBase::Notifier::ImmediateDetach();
     1323    }
     1324   
     1325    void clearNodes() {
     1326      Parent::clear();
     1327    }
     1328
     1329    class NodesImpl : public NodesImplBase {
     1330    public:
     1331      typedef NodesImplBase Parent;
     1332     
     1333      NodesImpl(const Graph& graph, SmartEdgeSet& arcset)
     1334        : Parent(graph), _arcset(arcset) {}
     1335
     1336      virtual ~NodesImpl() {}
     1337
     1338      bool attached() const {
     1339        return Parent::attached();
     1340      }
     1341     
     1342    protected:
     1343
     1344      virtual void erase(const Node& node) {
     1345        try {
     1346          _arcset.eraseNode(node);
     1347          Parent::erase(node);
     1348        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
     1349          Parent::clear();
     1350          throw;
     1351        }
     1352      }
     1353      virtual void erase(const std::vector<Node>& nodes) {
     1354        try {
     1355          for (int i = 0; i < int(nodes.size()); ++i) {
     1356            _arcset.eraseNode(nodes[i]);
     1357          }
     1358          Parent::erase(nodes);
     1359        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
     1360          Parent::clear();
     1361          throw;
     1362        }
     1363      }
     1364      virtual void clear() {
     1365        _arcset.clearNodes();
     1366        Parent::clear();
     1367      }
     1368
     1369    private:
     1370      SmartEdgeSet& _arcset;
     1371    };
     1372
     1373    NodesImpl nodes;
     1374   
     1375  public:
     1376
     1377    /// \brief Constructor of the EdgeSet.
     1378    ///
     1379    /// Constructor of the EdgeSet.
     1380    SmartEdgeSet(const Graph& graph) : nodes(graph, *this) {
     1381      Parent::initalize(graph, nodes);
     1382    }
     1383
     1384    /// \brief Add a new edge to the graph.
     1385    ///
     1386    /// Add a new edge to the graph with node \c u
     1387    /// and node \c v endpoints.
     1388    /// \return the new edge.
     1389    Edge addEdge(const Node& u, const Node& v) {
     1390      return Parent::addEdge(u, v);
     1391    }
     1392
     1393    /// \brief Validity check
     1394    ///
     1395    /// This functions gives back false if the ArcSet is
     1396    /// invalidated. It occurs when a node in the underlying graph is
     1397    /// erased and it is not isolated in the ArcSet.
     1398    bool valid() const {
     1399      return nodes.attached();
     1400    }
     1401   
     1402  };
     1403
     1404}
     1405
     1406#endif
  • test/CMakeLists.txt

    diff -r af4e8ba94294 -r 591e8758d98b test/CMakeLists.txt
    a b  
    1010  dijkstra_test
    1111  dim_test
    1212  error_test
     13  edge_set_test
    1314  graph_copy_test
    1415  graph_test
    1516  graph_utils_test
  • test/Makefile.am

    diff -r af4e8ba94294 -r 591e8758d98b test/Makefile.am
    a b  
    1212        test/digraph_test \
    1313        test/dijkstra_test \
    1414        test/dim_test \
     15        test/edge_set_test \
    1516        test/error_test \
    1617        test/graph_copy_test \
    1718        test/graph_test \
     
    3536test_digraph_test_SOURCES = test/digraph_test.cc
    3637test_dijkstra_test_SOURCES = test/dijkstra_test.cc
    3738test_dim_test_SOURCES = test/dim_test.cc
     39test_edge_set_test_SOURCES = test/edge_set_test.cc
    3840test_error_test_SOURCES = test/error_test.cc
    3941test_graph_copy_test_SOURCES = test/graph_copy_test.cc
    4042test_graph_test_SOURCES = test/graph_test.cc
  • new file test/edge_set_test.cc

    diff -r af4e8ba94294 -r 591e8758d98b test/edge_set_test.cc
    - +  
     1/* -*- C++ -*-
     2 *
     3 * This file is a part of LEMON, a generic C++ optimization library
     4 *
     5 * Copyright (C) 2003-2008
     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#include <iostream>
     20#include <vector>
     21
     22#include <lemon/concepts/digraph.h>
     23#include <lemon/concepts/graph.h>
     24#include <lemon/concept_check.h>
     25
     26#include <lemon/list_graph.h>
     27
     28#include <lemon/edge_set.h>
     29
     30#include "graph_test.h"
     31#include "test_tools.h"
     32
     33using namespace lemon;
     34
     35void checkSmartArcSet() {
     36  checkConcept<concepts::Digraph, SmartArcSet<concepts::Digraph> >();
     37 
     38  typedef ListDigraph Digraph;
     39  typedef SmartArcSet<Digraph> ArcSet;
     40
     41  Digraph digraph;
     42  Digraph::Node
     43    n1 = digraph.addNode(),
     44    n2 = digraph.addNode();
     45
     46  Digraph::Arc ga1 = digraph.addArc(n1, n2); 
     47
     48  ArcSet arc_set(digraph);
     49
     50  Digraph::Arc ga2 = digraph.addArc(n2, n1);
     51
     52  checkGraphNodeList(arc_set, 2);
     53  checkGraphArcList(arc_set, 0);
     54
     55  Digraph::Node
     56    n3 = digraph.addNode();
     57  checkGraphNodeList(arc_set, 3);
     58  checkGraphArcList(arc_set, 0);
     59
     60  ArcSet::Arc a1 = arc_set.addArc(n1, n2);
     61  check(arc_set.source(a1) == n1 && arc_set.target(a1) == n2, "Wrong arc");
     62  checkGraphNodeList(arc_set, 3);
     63  checkGraphArcList(arc_set, 1);
     64
     65  checkGraphOutArcList(arc_set, n1, 1);
     66  checkGraphOutArcList(arc_set, n2, 0);
     67  checkGraphOutArcList(arc_set, n3, 0);
     68
     69  checkGraphInArcList(arc_set, n1, 0);
     70  checkGraphInArcList(arc_set, n2, 1);
     71  checkGraphInArcList(arc_set, n3, 0);
     72
     73  checkGraphConArcList(arc_set, 1);
     74
     75  ArcSet::Arc a2 = arc_set.addArc(n2, n1),
     76    a3 = arc_set.addArc(n2, n3),
     77    a4 = arc_set.addArc(n2, n3);
     78  checkGraphNodeList(arc_set, 3);
     79  checkGraphArcList(arc_set, 4);
     80
     81  checkGraphOutArcList(arc_set, n1, 1);
     82  checkGraphOutArcList(arc_set, n2, 3);
     83  checkGraphOutArcList(arc_set, n3, 0);
     84
     85  checkGraphInArcList(arc_set, n1, 1);
     86  checkGraphInArcList(arc_set, n2, 1);
     87  checkGraphInArcList(arc_set, n3, 2);
     88
     89  checkGraphConArcList(arc_set, 4);
     90
     91  checkNodeIds(arc_set);
     92  checkArcIds(arc_set);
     93  checkGraphNodeMap(arc_set);
     94  checkGraphArcMap(arc_set);
     95
     96  check(arc_set.valid(), "Wrong validity");
     97  digraph.erase(n1);
     98  check(!arc_set.valid(), "Wrong validity");
     99}
     100
     101void checkListArcSet() {
     102  checkConcept<concepts::Digraph, SmartArcSet<concepts::Digraph> >();
     103 
     104  typedef ListDigraph Digraph;
     105  typedef ListArcSet<Digraph> ArcSet;
     106
     107  Digraph digraph;
     108  Digraph::Node
     109    n1 = digraph.addNode(),
     110    n2 = digraph.addNode();
     111
     112  Digraph::Arc ga1 = digraph.addArc(n1, n2); 
     113
     114  ArcSet arc_set(digraph);
     115
     116  Digraph::Arc ga2 = digraph.addArc(n2, n1);
     117
     118  checkGraphNodeList(arc_set, 2);
     119  checkGraphArcList(arc_set, 0);
     120
     121  Digraph::Node
     122    n3 = digraph.addNode();
     123  checkGraphNodeList(arc_set, 3);
     124  checkGraphArcList(arc_set, 0);
     125
     126  ArcSet::Arc a1 = arc_set.addArc(n1, n2);
     127  check(arc_set.source(a1) == n1 && arc_set.target(a1) == n2, "Wrong arc");
     128  checkGraphNodeList(arc_set, 3);
     129  checkGraphArcList(arc_set, 1);
     130
     131  checkGraphOutArcList(arc_set, n1, 1);
     132  checkGraphOutArcList(arc_set, n2, 0);
     133  checkGraphOutArcList(arc_set, n3, 0);
     134
     135  checkGraphInArcList(arc_set, n1, 0);
     136  checkGraphInArcList(arc_set, n2, 1);
     137  checkGraphInArcList(arc_set, n3, 0);
     138
     139  checkGraphConArcList(arc_set, 1);
     140
     141  ArcSet::Arc a2 = arc_set.addArc(n2, n1),
     142    a3 = arc_set.addArc(n2, n3),
     143    a4 = arc_set.addArc(n2, n3);
     144  checkGraphNodeList(arc_set, 3);
     145  checkGraphArcList(arc_set, 4);
     146
     147  checkGraphOutArcList(arc_set, n1, 1);
     148  checkGraphOutArcList(arc_set, n2, 3);
     149  checkGraphOutArcList(arc_set, n3, 0);
     150
     151  checkGraphInArcList(arc_set, n1, 1);
     152  checkGraphInArcList(arc_set, n2, 1);
     153  checkGraphInArcList(arc_set, n3, 2);
     154
     155  checkGraphConArcList(arc_set, 4);
     156
     157  checkNodeIds(arc_set);
     158  checkArcIds(arc_set);
     159  checkGraphNodeMap(arc_set);
     160  checkGraphArcMap(arc_set);
     161
     162  digraph.erase(n1);
     163
     164  checkGraphNodeList(arc_set, 2);
     165  checkGraphArcList(arc_set, 2);
     166
     167  checkGraphOutArcList(arc_set, n2, 2);
     168  checkGraphOutArcList(arc_set, n3, 0);
     169
     170  checkGraphInArcList(arc_set, n2, 0);
     171  checkGraphInArcList(arc_set, n3, 2);
     172
     173  checkNodeIds(arc_set);
     174  checkArcIds(arc_set);
     175  checkGraphNodeMap(arc_set);
     176  checkGraphArcMap(arc_set);
     177
     178  checkGraphConArcList(arc_set, 2);
     179}
     180
     181void checkSmartEdgeSet() {
     182  checkConcept<concepts::Digraph, SmartEdgeSet<concepts::Digraph> >();
     183 
     184  typedef ListDigraph Digraph;
     185  typedef SmartEdgeSet<Digraph> EdgeSet;
     186
     187  Digraph digraph;
     188  Digraph::Node
     189    n1 = digraph.addNode(),
     190    n2 = digraph.addNode();
     191
     192  Digraph::Arc ga1 = digraph.addArc(n1, n2); 
     193
     194  EdgeSet edge_set(digraph);
     195
     196  Digraph::Arc ga2 = digraph.addArc(n2, n1);
     197
     198  checkGraphNodeList(edge_set, 2);
     199  checkGraphArcList(edge_set, 0);
     200  checkGraphEdgeList(edge_set, 0);
     201
     202  Digraph::Node
     203    n3 = digraph.addNode();
     204  checkGraphNodeList(edge_set, 3);
     205  checkGraphArcList(edge_set, 0);
     206  checkGraphEdgeList(edge_set, 0);
     207
     208  EdgeSet::Edge e1 = edge_set.addEdge(n1, n2);
     209  check((edge_set.u(e1) == n1 && edge_set.v(e1) == n2) ||
     210        (edge_set.v(e1) == n1 && edge_set.u(e1) == n2), "Wrong edge");
     211  checkGraphNodeList(edge_set, 3);
     212  checkGraphArcList(edge_set, 2);
     213  checkGraphEdgeList(edge_set, 1);
     214
     215  checkGraphOutArcList(edge_set, n1, 1);
     216  checkGraphOutArcList(edge_set, n2, 1);
     217  checkGraphOutArcList(edge_set, n3, 0);
     218
     219  checkGraphInArcList(edge_set, n1, 1);
     220  checkGraphInArcList(edge_set, n2, 1);
     221  checkGraphInArcList(edge_set, n3, 0);
     222
     223  checkGraphIncEdgeList(edge_set, n1, 1);
     224  checkGraphIncEdgeList(edge_set, n2, 1);
     225  checkGraphIncEdgeList(edge_set, n3, 0);
     226
     227  checkGraphConEdgeList(edge_set, 1);
     228  checkGraphConArcList(edge_set, 2);
     229
     230  EdgeSet::Edge e2 = edge_set.addEdge(n2, n1),
     231    e3 = edge_set.addEdge(n2, n3),
     232    e4 = edge_set.addEdge(n2, n3);
     233  checkGraphNodeList(edge_set, 3);
     234  checkGraphEdgeList(edge_set, 4);
     235
     236  checkGraphOutArcList(edge_set, n1, 2);
     237  checkGraphOutArcList(edge_set, n2, 4);
     238  checkGraphOutArcList(edge_set, n3, 2);
     239
     240  checkGraphInArcList(edge_set, n1, 2);
     241  checkGraphInArcList(edge_set, n2, 4);
     242  checkGraphInArcList(edge_set, n3, 2);
     243
     244  checkGraphIncEdgeList(edge_set, n1, 2);
     245  checkGraphIncEdgeList(edge_set, n2, 4);
     246  checkGraphIncEdgeList(edge_set, n3, 2);
     247
     248  checkGraphConEdgeList(edge_set, 4);
     249  checkGraphConArcList(edge_set, 8);
     250
     251  checkArcDirections(edge_set);
     252
     253  checkNodeIds(edge_set);
     254  checkArcIds(edge_set);
     255  checkEdgeIds(edge_set);
     256  checkGraphNodeMap(edge_set);
     257  checkGraphArcMap(edge_set);
     258  checkGraphEdgeMap(edge_set);
     259
     260  check(edge_set.valid(), "Wrong validity");
     261  digraph.erase(n1);
     262  check(!edge_set.valid(), "Wrong validity");
     263}
     264
     265void checkListEdgeSet() {
     266  checkConcept<concepts::Digraph, ListEdgeSet<concepts::Digraph> >();
     267 
     268  typedef ListDigraph Digraph;
     269  typedef ListEdgeSet<Digraph> EdgeSet;
     270
     271  Digraph digraph;
     272  Digraph::Node
     273    n1 = digraph.addNode(),
     274    n2 = digraph.addNode();
     275
     276  Digraph::Arc ga1 = digraph.addArc(n1, n2); 
     277
     278  EdgeSet edge_set(digraph);
     279
     280  Digraph::Arc ga2 = digraph.addArc(n2, n1);
     281
     282  checkGraphNodeList(edge_set, 2);
     283  checkGraphArcList(edge_set, 0);
     284  checkGraphEdgeList(edge_set, 0);
     285
     286  Digraph::Node
     287    n3 = digraph.addNode();
     288  checkGraphNodeList(edge_set, 3);
     289  checkGraphArcList(edge_set, 0);
     290  checkGraphEdgeList(edge_set, 0);
     291
     292  EdgeSet::Edge e1 = edge_set.addEdge(n1, n2);
     293  check((edge_set.u(e1) == n1 && edge_set.v(e1) == n2) ||
     294        (edge_set.v(e1) == n1 && edge_set.u(e1) == n2), "Wrong edge");
     295  checkGraphNodeList(edge_set, 3);
     296  checkGraphArcList(edge_set, 2);
     297  checkGraphEdgeList(edge_set, 1);
     298
     299  checkGraphOutArcList(edge_set, n1, 1);
     300  checkGraphOutArcList(edge_set, n2, 1);
     301  checkGraphOutArcList(edge_set, n3, 0);
     302
     303  checkGraphInArcList(edge_set, n1, 1);
     304  checkGraphInArcList(edge_set, n2, 1);
     305  checkGraphInArcList(edge_set, n3, 0);
     306
     307  checkGraphIncEdgeList(edge_set, n1, 1);
     308  checkGraphIncEdgeList(edge_set, n2, 1);
     309  checkGraphIncEdgeList(edge_set, n3, 0);
     310
     311  checkGraphConEdgeList(edge_set, 1);
     312  checkGraphConArcList(edge_set, 2);
     313
     314  EdgeSet::Edge e2 = edge_set.addEdge(n2, n1),
     315    e3 = edge_set.addEdge(n2, n3),
     316    e4 = edge_set.addEdge(n2, n3);
     317  checkGraphNodeList(edge_set, 3);
     318  checkGraphEdgeList(edge_set, 4);
     319
     320  checkGraphOutArcList(edge_set, n1, 2);
     321  checkGraphOutArcList(edge_set, n2, 4);
     322  checkGraphOutArcList(edge_set, n3, 2);
     323
     324  checkGraphInArcList(edge_set, n1, 2);
     325  checkGraphInArcList(edge_set, n2, 4);
     326  checkGraphInArcList(edge_set, n3, 2);
     327
     328  checkGraphIncEdgeList(edge_set, n1, 2);
     329  checkGraphIncEdgeList(edge_set, n2, 4);
     330  checkGraphIncEdgeList(edge_set, n3, 2);
     331
     332  checkGraphConEdgeList(edge_set, 4);
     333  checkGraphConArcList(edge_set, 8);
     334
     335  checkArcDirections(edge_set);
     336
     337  checkNodeIds(edge_set);
     338  checkArcIds(edge_set);
     339  checkEdgeIds(edge_set);
     340  checkGraphNodeMap(edge_set);
     341  checkGraphArcMap(edge_set);
     342  checkGraphEdgeMap(edge_set);
     343
     344  digraph.erase(n1);
     345
     346  checkGraphNodeList(edge_set, 2);
     347  checkGraphArcList(edge_set, 4);
     348  checkGraphEdgeList(edge_set, 2);
     349
     350  checkGraphOutArcList(edge_set, n2, 2);
     351  checkGraphOutArcList(edge_set, n3, 2);
     352
     353  checkGraphInArcList(edge_set, n2, 2);
     354  checkGraphInArcList(edge_set, n3, 2);
     355
     356  checkGraphIncEdgeList(edge_set, n2, 2);
     357  checkGraphIncEdgeList(edge_set, n3, 2);
     358
     359  checkNodeIds(edge_set);
     360  checkArcIds(edge_set);
     361  checkEdgeIds(edge_set);
     362  checkGraphNodeMap(edge_set);
     363  checkGraphArcMap(edge_set);
     364  checkGraphEdgeMap(edge_set);
     365
     366  checkGraphConEdgeList(edge_set, 2);
     367  checkGraphConArcList(edge_set, 4);
     368
     369}
     370
     371
     372int main() {
     373
     374  checkSmartArcSet();
     375  checkListArcSet();
     376  checkSmartEdgeSet();
     377  checkListEdgeSet();
     378
     379  return 0;
     380}