00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
00042
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
00229
00232
00233
00234
00235
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