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