2 #ifndef LEMON_ITERABLE_GRAPH_EXTENDER_H
 
     3 #define LEMON_ITERABLE_GRAPH_EXTENDER_H
 
     5 #include <lemon/invalid.h>
 
     6 #include <lemon/utility.h>
 
    10   template <typename _Base>
 
    11   class IterableGraphExtender : public _Base {
 
    14     /// Indicates that the graph is undirected.
 
    18     ///\bug Should it be here?
 
    19     typedef False UndirTag;
 
    22     typedef IterableGraphExtender<_Base> Graph;
 
    24     typedef typename Parent::Node Node;
 
    25     typedef typename Parent::Edge Edge;
 
    28     class NodeIt : public Node { 
 
    34       NodeIt(Invalid i) : Node(i) { }
 
    36       explicit NodeIt(const Graph& _graph) : graph(&_graph) {
 
    37 	_graph.first(*static_cast<Node*>(this));
 
    40       NodeIt(const Graph& _graph, const Node& node) 
 
    41 	: Node(node), graph(&_graph) {}
 
    43       NodeIt& operator++() { 
 
    51     class EdgeIt : public Edge { 
 
    57       EdgeIt(Invalid i) : Edge(i) { }
 
    59       explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
 
    60 	_graph.first(*static_cast<Edge*>(this));
 
    63       EdgeIt(const Graph& _graph, const Edge& e) : 
 
    64 	Edge(e), graph(&_graph) { }
 
    66       EdgeIt& operator++() { 
 
    74     class OutEdgeIt : public Edge { 
 
    80       OutEdgeIt(Invalid i) : Edge(i) { }
 
    82       OutEdgeIt(const Graph& _graph, const Node& node) 
 
    84 	_graph.firstOut(*this, node);
 
    87       OutEdgeIt(const Graph& _graph, const Edge& edge) 
 
    88 	: Edge(edge), graph(&_graph) {}
 
    90       OutEdgeIt& operator++() { 
 
    91 	graph->nextOut(*this);
 
    98     class InEdgeIt : public Edge { 
 
   104       InEdgeIt(Invalid i) : Edge(i) { }
 
   106       InEdgeIt(const Graph& _graph, const Node& node) 
 
   108 	_graph.firstIn(*this, node);
 
   111       InEdgeIt(const Graph& _graph, const Edge& edge) : 
 
   112 	Edge(edge), graph(&_graph) {}
 
   114       InEdgeIt& operator++() { 
 
   115 	graph->nextIn(*this);
 
   121     /// Base node of the iterator
 
   123     /// Returns the base node (ie. the source in this case) of the iterator
 
   125     /// \todo Document in the concept!
 
   126     Node baseNode(const OutEdgeIt &e) const {
 
   127       return Parent::source((Edge)e);
 
   129     /// Running node of the iterator
 
   131     /// Returns the running node (ie. the target in this case) of the
 
   134     /// \todo Document in the concept!
 
   135     Node runningNode(const OutEdgeIt &e) const {
 
   136       return Parent::target((Edge)e);
 
   139     /// Base node of the iterator
 
   141     /// Returns the base node (ie. the target in this case) of the iterator
 
   143     /// \todo Document in the concept!
 
   144     Node baseNode(const InEdgeIt &e) const {
 
   145       return Parent::target((Edge)e);
 
   147     /// Running node of the iterator
 
   149     /// Returns the running node (ie. the source in this case) of the
 
   152     /// \todo Document in the concept!
 
   153     Node runningNode(const InEdgeIt &e) const {
 
   154       return Parent::source((Edge)e);
 
   161     // /// \todo When (and if) we change the iterators concept to use operator*,
 
   162     // /// then the following shadowed methods will become superfluous.
 
   163     // /// But for now these are important safety measures.
 
   165     // void first(NodeIt &) const;
 
   166     // void first(EdgeIt &) const;
 
   167     // void first(OutEdgeIt &) const;
 
   168     // void first(InEdgeIt &) const;
 
   177   template <typename _Base>
 
   178   class IterableUndirGraphExtender : public IterableGraphExtender<_Base> {
 
   181     /// Indicates that the graph is undirected.
 
   183     ///\todo Better name?
 
   185     ///\bug Should it be here?
 
   186     ///\bug Should be tested in the concept checker whether it is defined
 
   188     typedef True UndirTag;
 
   190     typedef IterableGraphExtender<_Base> Parent;
 
   191     typedef IterableUndirGraphExtender<_Base> Graph;
 
   192     typedef typename Parent::Node Node;
 
   194     typedef typename Parent::UndirEdge UndirEdge;
 
   196     class UndirEdgeIt : public Parent::UndirEdge { 
 
   202       UndirEdgeIt(Invalid i) : UndirEdge(i) { }
 
   204       explicit UndirEdgeIt(const Graph& _graph) : graph(&_graph) {
 
   205 	_graph.first(*static_cast<UndirEdge*>(this));
 
   208       UndirEdgeIt(const Graph& _graph, const UndirEdge& e) : 
 
   209 	UndirEdge(e), graph(&_graph) { }
 
   211       UndirEdgeIt& operator++() { 
 
   218     class IncEdgeIt : public Parent::UndirEdge { 
 
   221       friend class IterableUndirGraphExtender;
 
   222       template <typename G>
 
   223       friend class UndirGraphExtender;
 
   228       IncEdgeIt(Invalid i) : UndirEdge(i), forward(false) { }
 
   230       IncEdgeIt(const Graph& _graph, const Node &n)
 
   233 	_graph._dirFirstOut(*this, n);
 
   236       IncEdgeIt(const Graph& _graph, const UndirEdge &ue, const Node &n)
 
   237 	: graph(&_graph), UndirEdge(ue)
 
   239 	forward = (_graph.source(ue) == n);
 
   242       IncEdgeIt& operator++() {
 
   243 	graph->_dirNextOut(*this);
 
   248     using Parent::baseNode;
 
   249     using Parent::runningNode;
 
   251     /// Base node of the iterator
 
   253     /// Returns the base node of the iterator
 
   254     Node baseNode(const IncEdgeIt &e) const {
 
   255       return _dirSource(e);
 
   257     /// Running node of the iterator
 
   259     /// Returns the running node of the iterator
 
   260     Node runningNode(const IncEdgeIt &e) const {
 
   261       return _dirTarget(e);
 
   267 #endif // LEMON_GRAPH_EXTENDER_H