00001
00002 #ifndef LEMON_ITERABLE_GRAPH_EXTENDER_H
00003 #define LEMON_ITERABLE_GRAPH_EXTENDER_H
00004
00005 #include <lemon/invalid.h>
00006 #include <lemon/utility.h>
00007
00008 namespace lemon {
00009
00010 template <typename _Base>
00011 class IterableGraphExtender : public _Base {
00012 public:
00013
00015
00019 typedef False UndirTag;
00020
00021 typedef _Base Parent;
00022 typedef IterableGraphExtender<_Base> Graph;
00023
00024 typedef typename Parent::Node Node;
00025 typedef typename Parent::Edge Edge;
00026
00027
00028 class NodeIt : public Node {
00029 const Graph* graph;
00030 public:
00031
00032 NodeIt() {}
00033
00034 NodeIt(Invalid i) : Node(i) { }
00035
00036 explicit NodeIt(const Graph& _graph) : graph(&_graph) {
00037 _graph.first(*static_cast<Node*>(this));
00038 }
00039
00040 NodeIt(const Graph& _graph, const Node& node)
00041 : Node(node), graph(&_graph) {}
00042
00043 NodeIt& operator++() {
00044 graph->next(*this);
00045 return *this;
00046 }
00047
00048 };
00049
00050
00051 class EdgeIt : public Edge {
00052 const Graph* graph;
00053 public:
00054
00055 EdgeIt() { }
00056
00057 EdgeIt(Invalid i) : Edge(i) { }
00058
00059 explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
00060 _graph.first(*static_cast<Edge*>(this));
00061 }
00062
00063 EdgeIt(const Graph& _graph, const Edge& e) :
00064 Edge(e), graph(&_graph) { }
00065
00066 EdgeIt& operator++() {
00067 graph->next(*this);
00068 return *this;
00069 }
00070
00071 };
00072
00073
00074 class OutEdgeIt : public Edge {
00075 const Graph* graph;
00076 public:
00077
00078 OutEdgeIt() { }
00079
00080 OutEdgeIt(Invalid i) : Edge(i) { }
00081
00082 OutEdgeIt(const Graph& _graph, const Node& node)
00083 : graph(&_graph) {
00084 _graph.firstOut(*this, node);
00085 }
00086
00087 OutEdgeIt(const Graph& _graph, const Edge& edge)
00088 : Edge(edge), graph(&_graph) {}
00089
00090 OutEdgeIt& operator++() {
00091 graph->nextOut(*this);
00092 return *this;
00093 }
00094
00095 };
00096
00097
00098 class InEdgeIt : public Edge {
00099 const Graph* graph;
00100 public:
00101
00102 InEdgeIt() { }
00103
00104 InEdgeIt(Invalid i) : Edge(i) { }
00105
00106 InEdgeIt(const Graph& _graph, const Node& node)
00107 : graph(&_graph) {
00108 _graph.firstIn(*this, node);
00109 }
00110
00111 InEdgeIt(const Graph& _graph, const Edge& edge) :
00112 Edge(edge), graph(&_graph) {}
00113
00114 InEdgeIt& operator++() {
00115 graph->nextIn(*this);
00116 return *this;
00117 }
00118
00119 };
00120
00124 Node baseNode(const OutEdgeIt &e) const {
00125 return Parent::source((Edge)e);
00126 }
00131 Node runningNode(const OutEdgeIt &e) const {
00132 return Parent::target((Edge)e);
00133 }
00134
00138 Node baseNode(const InEdgeIt &e) const {
00139 return Parent::target((Edge)e);
00140 }
00145 Node runningNode(const InEdgeIt &e) const {
00146 return Parent::source((Edge)e);
00147 }
00148
00149 using Parent::first;
00150
00154 Node oppositeNode(const Node& n, const Edge& e) const {
00155 if (Parent::source(e) == n) {
00156 return Parent::target(e);
00157 } else {
00158 return Parent::source(e);
00159 }
00160 }
00161
00162 private:
00163
00164
00165
00166
00167
00168
00169 };
00170
00171
00172
00173
00174
00175
00176 template <typename _Base>
00177 class IterableUndirGraphExtender : public IterableGraphExtender<_Base> {
00178 public:
00179
00181
00187 typedef True UndirTag;
00188
00189 typedef IterableGraphExtender<_Base> Parent;
00190 typedef IterableUndirGraphExtender<_Base> Graph;
00191 typedef typename Parent::Node Node;
00192 typedef typename Parent::Edge Edge;
00193 typedef typename Parent::UndirEdge UndirEdge;
00194
00195 class UndirEdgeIt : public Parent::UndirEdge {
00196 const Graph* graph;
00197 public:
00198
00199 UndirEdgeIt() { }
00200
00201 UndirEdgeIt(Invalid i) : UndirEdge(i) { }
00202
00203 explicit UndirEdgeIt(const Graph& _graph) : graph(&_graph) {
00204 _graph.first(*static_cast<UndirEdge*>(this));
00205 }
00206
00207 UndirEdgeIt(const Graph& _graph, const UndirEdge& e) :
00208 UndirEdge(e), graph(&_graph) { }
00209
00210 UndirEdgeIt& operator++() {
00211 graph->next(*this);
00212 return *this;
00213 }
00214
00215 };
00216
00217 class IncEdgeIt : public Parent::UndirEdge {
00218 const Graph* graph;
00219 bool forward;
00220 friend class IterableUndirGraphExtender;
00221 template <typename G>
00222 friend class UndirGraphExtender;
00223 public:
00224
00225 IncEdgeIt() { }
00226
00227 IncEdgeIt(Invalid i) : UndirEdge(i), forward(false) { }
00228
00229 IncEdgeIt(const Graph& _graph, const Node &n)
00230 : graph(&_graph)
00231 {
00232 _graph._dirFirstOut(*this, n);
00233 }
00234
00235 IncEdgeIt(const Graph& _graph, const UndirEdge &ue, const Node &n)
00236 : graph(&_graph), UndirEdge(ue)
00237 {
00238 forward = (_graph.source(ue) == n);
00239 }
00240
00241 IncEdgeIt& operator++() {
00242 graph->_dirNextOut(*this);
00243 return *this;
00244 }
00245 };
00246
00247 using Parent::baseNode;
00248 using Parent::runningNode;
00249
00253 Node baseNode(const IncEdgeIt &e) const {
00254 return _dirSource(e);
00255 }
00259 Node runningNode(const IncEdgeIt &e) const {
00260 return _dirTarget(e);
00261 }
00262
00266 Node oppositeNode(const Node& n, const UndirEdge& e) const {
00267 if (Parent::source(e) == n) {
00268 return Parent::target(e);
00269 } else {
00270 return Parent::source(e);
00271 }
00272 }
00273
00274 };
00275 }
00276
00277 #endif // LEMON_GRAPH_EXTENDER_H