Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

undir_graph_extender.h

00001 /* -*- C++ -*-
00002  *
00003  * lemon/undir_graph_extender.h - Part of LEMON, a generic C++
00004  * optimization library
00005  *
00006  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi
00007  * Kutatocsoport (Egervary Research Group on Combinatorial Optimization,
00008  * EGRES).
00009  *
00010  * Permission to use, modify and distribute this software is granted
00011  * provided that this copyright notice appears in all copies. For
00012  * precise terms see the accompanying LICENSE file.
00013  *
00014  * This software is provided "AS IS" with no warranty of any kind,
00015  * express or implied, and with no claim as to its suitability for any
00016  * purpose.
00017  *
00018  */
00019 
00020 #ifndef LEMON_UNDIR_GRAPH_EXTENDER_H
00021 #define LEMON_UNDIR_GRAPH_EXTENDER_H
00022 
00023 #include <lemon/invalid.h>
00024 
00025 namespace lemon {
00026 
00027   template <typename _Base>
00028   class UndirGraphExtender : public _Base {
00029     typedef _Base Parent;
00030     typedef UndirGraphExtender Graph;
00031 
00032   public:
00033 
00034     typedef typename Parent::Edge UndirEdge;
00035     typedef typename Parent::Node Node;
00036 
00037     class Edge : public UndirEdge {
00038       friend class UndirGraphExtender;
00039 
00040     protected:
00041       // FIXME: Marci use opposite logic in his graph adaptors. It would
00042       // be reasonable to syncronize...
00043       bool forward;
00044 
00045       Edge(const UndirEdge &ue, bool _forward) :
00046         UndirEdge(ue), forward(_forward) {}
00047 
00048     public:
00049       Edge() {}
00050 
00052       Edge(Invalid i) : UndirEdge(i), forward(true) {}
00053 
00054       bool operator==(const Edge &that) const {
00055         return forward==that.forward && UndirEdge(*this)==UndirEdge(that);
00056       }
00057       bool operator!=(const Edge &that) const {
00058         return forward!=that.forward || UndirEdge(*this)!=UndirEdge(that);
00059       }
00060       bool operator<(const Edge &that) const {
00061         return forward<that.forward ||
00062           (!(that.forward<forward) && UndirEdge(*this)<UndirEdge(that));
00063       }
00064     };
00065 
00066 
00070     Edge oppositeEdge(const Edge &e) const {
00071       return Edge(e,!e.forward);
00072     }
00073 
00074   protected:
00075 
00076     template <typename E>
00077     Node _dirSource(const E &e) const {
00078       return e.forward ? Parent::source(e) : Parent::target(e);
00079     }
00080 
00081     template <typename E>
00082     Node _dirTarget(const E &e) const {
00083       return e.forward ? Parent::target(e) : Parent::source(e);
00084     }
00085 
00086   public:
00089     using Parent::source;
00090 
00092     Node source(const Edge &e) const {
00093       return _dirSource(e);
00094     }
00095 
00098     using Parent::target;
00099 
00101     Node target(const Edge &e) const {
00102       return _dirTarget(e);
00103     }
00104 
00105     Node oppositeNode(const Node &n, const UndirEdge &e) const {
00106       if( n == Parent::source(e))
00107         return Parent::target(e);
00108       else if( n == Parent::target(e))
00109         return Parent::source(e);
00110       else
00111         return INVALID;
00112     }
00113 
00119     Edge direct(const UndirEdge &ue, const Node &s) const {
00120       return Edge(ue, s == source(ue));
00121     }
00122 
00128     Edge direct(const UndirEdge &ue, bool d) const {
00129       return Edge(ue, d);
00130     }
00131 
00137     bool direction(const Edge &e) const { return e.forward; }
00138 
00139 
00140     using Parent::first;
00141     void first(Edge &e) const {
00142       Parent::first(e);
00143       e.forward=true;
00144     }
00145 
00146     using Parent::next;
00147     void next(Edge &e) const {
00148       if( e.forward ) {
00149         e.forward = false;
00150       }
00151       else {
00152         Parent::next(e);
00153         e.forward = true;
00154       }
00155     }
00156 
00157     
00158   protected:
00159 
00160     template <typename E>
00161     void _dirFirstOut(E &e, const Node &n) const {
00162       Parent::firstIn(e,n);
00163       if( UndirEdge(e) != INVALID ) {
00164         e.forward = false;
00165       }
00166       else {
00167         Parent::firstOut(e,n);
00168         e.forward = true;
00169       }
00170     }
00171     template <typename E>
00172     void _dirFirstIn(E &e, const Node &n) const {
00173       Parent::firstOut(e,n);
00174       if( UndirEdge(e) != INVALID ) {
00175         e.forward = false;
00176       }
00177       else {
00178         Parent::firstIn(e,n);
00179         e.forward = true;
00180       }
00181     }
00182 
00183     template <typename E>
00184     void _dirNextOut(E &e) const {
00185       if( ! e.forward ) {
00186         Node n = Parent::target(e);
00187         Parent::nextIn(e);
00188         if( UndirEdge(e) == INVALID ) {
00189           Parent::firstOut(e, n);
00190           e.forward = true;
00191         }
00192       }
00193       else {
00194         Parent::nextOut(e);
00195       }
00196     }
00197     template <typename E>
00198     void _dirNextIn(E &e) const {
00199       if( ! e.forward ) {
00200         Node n = Parent::source(e);
00201         Parent::nextOut(e);
00202         if( UndirEdge(e) == INVALID ) {
00203           Parent::firstIn(e, n);
00204           e.forward = true;
00205         }
00206       }
00207       else {
00208         Parent::nextIn(e);
00209       }
00210     }
00211 
00212   public:
00213 
00214     void firstOut(Edge &e, const Node &n) const {
00215       _dirFirstOut(e, n);
00216     }
00217     void firstIn(Edge &e, const Node &n) const {
00218       _dirFirstIn(e, n);
00219     }
00220 
00221     void nextOut(Edge &e) const {
00222       _dirNextOut(e);
00223     }
00224     void nextIn(Edge &e) const {
00225       _dirNextIn(e);
00226     }
00227 
00228     // Miscellaneous stuff:
00229 
00232 
00233     // using Parent::id;
00234     // Using "using" is not a good idea, cause it could be that there is
00235     // no "id" in Parent...
00236 
00237     int id(const Node &n) const {
00238       return Parent::id(n);
00239     }
00240 
00241     int id(const UndirEdge &e) const {
00242       return Parent::id(e);
00243     }
00244 
00245     int id(const Edge &e) const {
00246       return 2 * Parent::id(e) + int(e.forward);
00247     }
00248 
00249 
00250     int maxId(Node) const {
00251       return Parent::maxId(Node());
00252     }
00253 
00254     int maxId(Edge) const {
00255       return 2 * Parent::maxId(typename Parent::Edge()) + 1;
00256     }
00257     int maxId(UndirEdge) const {
00258       return Parent::maxId(typename Parent::Edge());
00259     }
00260 
00261 
00262     int edgeNum() const {
00263       return 2 * Parent::edgeNum();
00264     }
00265     int undirEdgeNum() const {
00266       return Parent::edgeNum();
00267     }
00268 
00269   };
00270 
00271 }
00272 
00273 #endif // LEMON_UNDIR_GRAPH_EXTENDER_H

Generated on Sat Aug 27 14:14:50 2005 for LEMON by  doxygen 1.4.4