Advances in UndirGraph.
authorklao
Thu, 25 Nov 2004 14:48:24 +0000
changeset 1021fd1d073b6557
parent 1020 f42cb3146ed4
child 1022 567f392d1d2e
Advances in UndirGraph.
* IterableExtender is complete
src/lemon/concept/graph_component.h
src/lemon/concept/undir_graph.h
src/lemon/iterable_graph_extender.h
src/lemon/undir_graph_extender.h
     1.1 --- a/src/lemon/concept/graph_component.h	Mon Nov 22 17:50:26 2004 +0000
     1.2 +++ b/src/lemon/concept/graph_component.h	Thu Nov 25 14:48:24 2004 +0000
     1.3 @@ -505,62 +505,66 @@
     1.4      /// base class, the _selector is a additional template parameter. For 
     1.5      /// InEdgeIt you should instantiate it with character 'i' and for 
     1.6      /// OutEdgeIt with 'o'.
     1.7 -    /// \todo check the name of the concept GraphIncEdgeIterator
     1.8 -    template <typename _Graph, char _selector>
     1.9 -    class GraphIncEdgeIterator : public _Graph::Edge {
    1.10 +    /// \todo Is this a good name for this concept?
    1.11 +    template <typename Graph,
    1.12 +	      typename Edge = typename Graph::Edge,
    1.13 +	      char _selector = '0'>
    1.14 +    class GraphIncIterator : public Edge {
    1.15      public:
    1.16        /// Default constructor.
    1.17        
    1.18        /// @warning The default constructor sets the iterator
    1.19        /// to an undefined value.
    1.20 -      GraphIncEdgeIterator() {}
    1.21 +      GraphIncIterator() {}
    1.22        /// Copy constructor.
    1.23        
    1.24        /// Copy constructor.
    1.25        ///
    1.26 -      GraphIncEdgeIterator(GraphIncEdgeIterator const&) {}
    1.27 +      GraphIncIterator(GraphIncIterator const&) {}
    1.28        /// Sets the iterator to the first edge incoming into or outgoing from the node.
    1.29        
    1.30        /// Sets the iterator to the first edge incoming into or outgoing from the node.
    1.31        ///
    1.32 -      explicit GraphIncEdgeIterator(const _Graph&, const typename _Graph::Node&) {}
    1.33 +      explicit GraphIncIterator(const Graph&, const typename Graph::Node&) {}
    1.34        /// Invalid constructor \& conversion.
    1.35  
    1.36        /// This constructor initializes the item to be invalid.
    1.37        /// \sa Invalid for more details.
    1.38 -      GraphIncEdgeIterator(Invalid) {}
    1.39 +      GraphIncIterator(Invalid) {}
    1.40        /// Assign operator for nodes.
    1.41  
    1.42        /// The nodes are assignable. 
    1.43        ///
    1.44 -      GraphIncEdgeIterator& operator=(GraphIncEdgeIterator const&) { return *this; }      
    1.45 +      GraphIncIterator& operator=(GraphIncIterator const&) { return *this; }      
    1.46        /// Next edge.
    1.47  
    1.48        /// Assign the iterator to the next node.
    1.49        ///
    1.50 -      GraphIncEdgeIterator& operator++() { return *this; }
    1.51 +      GraphIncIterator& operator++() { return *this; }
    1.52 +
    1.53        //	Node operator*() const { return INVALID; }
    1.54 +
    1.55        /// Equality operator
    1.56  
    1.57        /// Two iterators are equal if and only if they point to the
    1.58        /// same object or both are invalid.
    1.59 -      bool operator==(const GraphIncEdgeIterator&) const { return true;}
    1.60 +      bool operator==(const GraphIncIterator&) const { return true;}
    1.61 +
    1.62        /// Inequality operator
    1.63  	
    1.64        /// \sa operator==(Node n)
    1.65        ///
    1.66 -      bool operator!=(const GraphIncEdgeIterator&) const { return true;}
    1.67 +      bool operator!=(const GraphIncIterator&) const { return true;}
    1.68  
    1.69 -      template <typename _GraphIncEdgeIterator>
    1.70 +      template <typename _GraphIncIterator>
    1.71        struct Constraints {
    1.72 -	typedef typename _Graph::Node Node;
    1.73 -	typedef typename _Graph::Edge Edge;
    1.74 +	typedef typename Graph::Node Node;
    1.75  	void constraints() {
    1.76 -	  checkConcept<GraphItem<'e'>, _GraphIncEdgeIterator>();
    1.77 -	  _GraphIncEdgeIterator it1(graph, node);
    1.78 +	  checkConcept<GraphItem<'e'>, _GraphIncIterator>();
    1.79 +	  _GraphIncIterator it1(graph, node);
    1.80  	  /// \todo Do we need OutEdgeIt(Edge) kind of constructor?
    1.81 -	  //	_GraphIncEdgeIterator it2(edge);
    1.82 -	  _GraphIncEdgeIterator it2;
    1.83 +	  //	_GraphIncIterator it2(edge);
    1.84 +	  _GraphIncIterator it2;
    1.85  
    1.86  	  it2 = ++it1;
    1.87  	  ++it2 = it1;
    1.88 @@ -571,9 +575,11 @@
    1.89  
    1.90  	Edge& edge;
    1.91  	Node& node;
    1.92 -	_Graph& graph;
    1.93 +	Graph& graph;
    1.94        };
    1.95      };
    1.96 +
    1.97 +
    1.98      /// An empty iterable base graph class.
    1.99    
   1.100      /// This class provides beside the core graph features
   1.101 @@ -602,12 +608,12 @@
   1.102  
   1.103        /// This iterator goes trough the \e inccoming edges of a certain node
   1.104        /// of a graph.
   1.105 -      typedef GraphIncEdgeIterator<Graph, 'i'> InEdgeIt;
   1.106 +      typedef GraphIncIterator<Graph, Edge, 'i'> InEdgeIt;
   1.107        /// This iterator goes trough the outgoing edges of a node.
   1.108  
   1.109        /// This iterator goes trough the \e outgoing edges of a certain node
   1.110        /// of a graph.
   1.111 -      typedef GraphIncEdgeIterator<Graph, 'o'> OutEdgeIt;
   1.112 +      typedef GraphIncIterator<Graph, Edge, 'o'> OutEdgeIt;
   1.113      };
   1.114      
   1.115      template <typename _Graph> 
   1.116 @@ -617,8 +623,8 @@
   1.117  
   1.118  	checkConcept<GraphIterator<_Graph, typename _Graph::Edge>, typename _Graph::EdgeIt >();
   1.119  	checkConcept<GraphIterator<_Graph, typename _Graph::Node>, typename _Graph::NodeIt >();
   1.120 -	checkConcept<GraphIncEdgeIterator<_Graph, 'i'>, typename _Graph::InEdgeIt >();
   1.121 -	checkConcept<GraphIncEdgeIterator<_Graph, 'o'>, typename _Graph::OutEdgeIt >();
   1.122 +	checkConcept<GraphIncIterator<_Graph>, typename _Graph::InEdgeIt >();
   1.123 +	checkConcept<GraphIncIterator<_Graph>, typename _Graph::OutEdgeIt >();
   1.124        }
   1.125      };
   1.126  
     2.1 --- a/src/lemon/concept/undir_graph.h	Mon Nov 22 17:50:26 2004 +0000
     2.2 +++ b/src/lemon/concept/undir_graph.h	Thu Nov 25 14:48:24 2004 +0000
     2.3 @@ -67,8 +67,13 @@
     2.4  
     2.5  	typedef typename Graph::UndirEdge UndirEdge;
     2.6  	typedef typename Graph::UndirEdgeIt UndirEdgeIt;
     2.7 +	typedef typename Graph::UndirIncEdgeIt UndirIncEdgeIt;
     2.8  
     2.9  	checkConcept< GraphIterator<Graph, UndirEdge>, UndirEdgeIt >();
    2.10 +
    2.11 +	checkConcept<
    2.12 +	  GraphIncIterator<Graph, UndirEdge>,
    2.13 +	  UndirIncEdgeIt >();
    2.14        }
    2.15      };
    2.16  
     3.1 --- a/src/lemon/iterable_graph_extender.h	Mon Nov 22 17:50:26 2004 +0000
     3.2 +++ b/src/lemon/iterable_graph_extender.h	Thu Nov 25 14:48:24 2004 +0000
     3.3 @@ -131,6 +131,7 @@
     3.4  
     3.5      typedef IterableGraphExtender<_Base> Parent;
     3.6      typedef IterableUndirGraphExtender<_Base> Graph;
     3.7 +    typedef typename Parent::Node Node;
     3.8  
     3.9      typedef typename Parent::UndirEdge UndirEdge;
    3.10  
    3.11 @@ -156,6 +157,50 @@
    3.12  
    3.13      };
    3.14  
    3.15 +    class UndirIncEdgeIt : public UndirEdge { 
    3.16 +      const Graph* graph;
    3.17 +      bool forward;
    3.18 +      friend class IterableUndirGraphExtender;
    3.19 +      template <typename G>
    3.20 +      friend class UndirGraphExtender;
    3.21 +    public:
    3.22 +
    3.23 +      UndirIncEdgeIt() { }
    3.24 +
    3.25 +      UndirIncEdgeIt(Invalid i) : UndirEdge(i), forward(false) { }
    3.26 +
    3.27 +      explicit UndirIncEdgeIt(const Graph& _graph, const Node &n)
    3.28 +	: graph(&_graph)
    3.29 +      {
    3.30 +	_graph._dirFirstOut(*this, n);
    3.31 +      }
    3.32 +
    3.33 +      // FIXME: Do we need this type of constructor here?
    3.34 +      // UndirIncEdgeIt(const Graph& _graph, const UndirEdge& e) : 
    3.35 +      //   UndirEdge(e), graph(&_graph) { }
    3.36 +
    3.37 +      UndirIncEdgeIt& operator++() {
    3.38 +	graph->_dirNextOut(*this);
    3.39 +	return *this; 
    3.40 +      }
    3.41 +    };
    3.42 +
    3.43 +    Node source(const UndirIncEdgeIt &e) const {
    3.44 +      return _dirSource(e);
    3.45 +    }
    3.46 +
    3.47 +    /// \todo Shouldn't the "source" of an undirected edge be called "aNode"
    3.48 +    /// or something???
    3.49 +    using Parent::source;
    3.50 +
    3.51 +    /// Target of the given Edge.
    3.52 +    Node target(const UndirIncEdgeIt &e) const {
    3.53 +      return _dirTarget(e);
    3.54 +    }
    3.55 +
    3.56 +    /// \todo Shouldn't the "target" of an undirected edge be called "bNode"
    3.57 +    /// or something???
    3.58 +    using Parent::target;
    3.59  
    3.60    };
    3.61  }
     4.1 --- a/src/lemon/undir_graph_extender.h	Mon Nov 22 17:50:26 2004 +0000
     4.2 +++ b/src/lemon/undir_graph_extender.h	Thu Nov 25 14:48:24 2004 +0000
     4.3 @@ -70,24 +70,37 @@
     4.4        return Edge(e,!e.forward);
     4.5      }
     4.6  
     4.7 -    /// Source of the given Edge.
     4.8 -    Node source(const Edge &e) const {
     4.9 +  protected:
    4.10 +
    4.11 +    template <typename E>
    4.12 +    Node _dirSource(const E &e) const {
    4.13        return e.forward ? Parent::source(e) : Parent::target(e);
    4.14      }
    4.15  
    4.16 +    template <typename E>
    4.17 +    Node _dirTarget(const E &e) const {
    4.18 +      return e.forward ? Parent::target(e) : Parent::source(e);
    4.19 +    }
    4.20 +
    4.21 +  public:
    4.22      /// \todo Shouldn't the "source" of an undirected edge be called "aNode"
    4.23      /// or something???
    4.24      using Parent::source;
    4.25  
    4.26 -    /// Target of the given Edge.
    4.27 -    Node target(const Edge &e) const {
    4.28 -      return e.forward ? Parent::target(e) : Parent::source(e);
    4.29 +    /// Source of the given Edge.
    4.30 +    Node source(const Edge &e) const {
    4.31 +      return _dirSource(e);
    4.32      }
    4.33  
    4.34      /// \todo Shouldn't the "target" of an undirected edge be called "bNode"
    4.35      /// or something???
    4.36      using Parent::target;
    4.37  
    4.38 +    /// Target of the given Edge.
    4.39 +    Node target(const Edge &e) const {
    4.40 +      return _dirTarget(e);
    4.41 +    }
    4.42 +
    4.43      /// Returns whether the given directed edge is same orientation as the
    4.44      /// corresponding undirected edge.
    4.45      ///
    4.46 @@ -122,7 +135,11 @@
    4.47        }
    4.48      }
    4.49  
    4.50 -    void firstOut(Edge &e, const Node &n) const {
    4.51 +    
    4.52 +  protected:
    4.53 +
    4.54 +    template <typename E>
    4.55 +    void _dirFirstOut(E &e, const Node &n) const {
    4.56        Parent::firstOut(e,n);
    4.57        if( UndirEdge(e) != INVALID ) {
    4.58  	e.forward = true;
    4.59 @@ -132,7 +149,8 @@
    4.60  	e.forward = false;
    4.61        }
    4.62      }
    4.63 -    void firstIn(Edge &e, const Node &n) const {
    4.64 +    template <typename E>
    4.65 +    void _dirFirstIn(E &e, const Node &n) const {
    4.66        Parent::firstIn(e,n);
    4.67        if( UndirEdge(e) != INVALID ) {
    4.68  	e.forward = true;
    4.69 @@ -143,7 +161,8 @@
    4.70        }
    4.71      }
    4.72  
    4.73 -    void nextOut(Edge &e) const {
    4.74 +    template <typename E>
    4.75 +    void _dirNextOut(E &e) const {
    4.76        if( e.forward ) {
    4.77  	Parent::nextOut(e);
    4.78  	if( UndirEdge(e) == INVALID ) {
    4.79 @@ -155,7 +174,8 @@
    4.80  	Parent::nextIn(e);
    4.81        }
    4.82      }
    4.83 -    void nextIn(Edge &e) const {
    4.84 +    template <typename E>
    4.85 +    void _dirNextIn(E &e) const {
    4.86        if( e.forward ) {
    4.87  	Parent::nextIn(e);
    4.88  	if( UndirEdge(e) == INVALID ) {
    4.89 @@ -168,21 +188,52 @@
    4.90        }
    4.91      }
    4.92  
    4.93 +  public:
    4.94 +
    4.95 +    void firstOut(Edge &e, const Node &n) const {
    4.96 +      _dirFirstOut(e, n);
    4.97 +    }
    4.98 +    void firstIn(Edge &e, const Node &n) const {
    4.99 +      _dirFirstIn(e, n);
   4.100 +    }
   4.101 +
   4.102 +    void nextOut(Edge &e) const {
   4.103 +      _dirNextOut(e);
   4.104 +    }
   4.105 +    void nextIn(Edge &e) const {
   4.106 +      _dirNextIn(e);
   4.107 +    }
   4.108 +
   4.109      // Miscellaneous stuff:
   4.110  
   4.111      /// \todo these methods (id, maxEdgeId) should be moved into separate
   4.112      /// Extender
   4.113  
   4.114 -    using Parent::id;
   4.115 +    // using Parent::id;
   4.116 +    // Using "using" is not a good idea, cause it could be that there is
   4.117 +    // no "id" in Parent...
   4.118 +
   4.119 +    int id(const Node &n) const {
   4.120 +      return Parent::id(n);
   4.121 +    }
   4.122 +
   4.123 +    int id(const UndirEdge &e) const {
   4.124 +      return Parent::id(e);
   4.125 +    }
   4.126  
   4.127      int id(const Edge &e) const {
   4.128        return 2 * Parent::id(e) + int(e.forward);
   4.129      }
   4.130  
   4.131 -    int maxId(Edge = INVALID) const {
   4.132 +
   4.133 +    int maxId(Node n) const {
   4.134 +      return Parent::maxId(Node());
   4.135 +    }
   4.136 +
   4.137 +    int maxId(Edge) const {
   4.138        return 2 * Parent::maxId(typename Parent::Edge()) + 1;
   4.139      }
   4.140 -    int maxId(UndirEdge = INVALID) const {
   4.141 +    int maxId(UndirEdge) const {
   4.142        return Parent::maxId(typename Parent::Edge());
   4.143      }
   4.144