COIN-OR::LEMON - Graph Library

source: lemon/lemon/bits/edge_set_extender.h

Last change on this file was 1337:4add05447ca0, checked in by Alpar Juttner <alpar@…>, 9 years ago

Tests and bugfixes for the STL style iterators (#325)

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