Improve findEdge interface
authordeba
Mon, 18 Jul 2005 15:07:28 +0000
changeset 156596244ea562a3
parent 1564 16d316199cf6
child 1566 12a3101cf3ab
Improve findEdge interface
ConEdgeIt is a high level replacement of findEdge
lemon/graph_utils.h
     1.1 --- a/lemon/graph_utils.h	Mon Jul 18 15:05:50 2005 +0000
     1.2 +++ b/lemon/graph_utils.h	Mon Jul 18 15:07:28 2005 +0000
     1.3 @@ -160,8 +160,35 @@
     1.4    }
     1.5  
     1.6  
     1.7 -  /// Finds an edge between two nodes of a graph.
     1.8 +  template <typename Graph>
     1.9 +  inline
    1.10 +  typename enable_if<typename Graph::FindEdgeTag, typename Graph::Edge>::type 
    1.11 +  _findEdge(const Graph &g,
    1.12 +	    typename Graph::Node u, typename Graph::Node v,
    1.13 +	    typename Graph::Edge prev = INVALID) {
    1.14 +    return g.findEdge(u, v, prev);
    1.15 +  }
    1.16  
    1.17 +  template <typename Graph>
    1.18 +  inline typename Graph::Edge 
    1.19 +  _findEdge(Wrap<Graph> w,
    1.20 +	    typename Graph::Node u, 
    1.21 +	    typename Graph::Node v,
    1.22 +	    typename Graph::Edge prev = INVALID) {
    1.23 +    const Graph& g = w.value;
    1.24 +    if (prev == INVALID) {
    1.25 +      typename Graph::OutEdgeIt e(g, u);
    1.26 +      while (e != INVALID && g.target(e) != v) ++e;
    1.27 +      return e;
    1.28 +    } else {
    1.29 +      typename Graph::OutEdgeIt e(g, prev); ++e;
    1.30 +      while (e != INVALID && g.target(e) != v) ++e;
    1.31 +      return e;
    1.32 +    }
    1.33 +  }
    1.34 +
    1.35 +  /// \brief Finds an edge between two nodes of a graph.
    1.36 +  ///
    1.37    /// Finds an edge from node \c u to node \c v in graph \c g.
    1.38    ///
    1.39    /// If \c prev is \ref INVALID (this is the default value), then
    1.40 @@ -175,22 +202,65 @@
    1.41    ///   ...
    1.42    /// }
    1.43    /// \endcode
    1.44 -  /// \todo We may want to use the "GraphBase"
    1.45 -  /// interface here...
    1.46 -  /// \bug Untested ...
    1.47 +  // /// \todo We may want to use the "GraphBase" 
    1.48 +  // /// interface here...
    1.49 +  // /// It would not work with the undirected graphs.
    1.50    template <typename Graph>
    1.51 -  typename Graph::Edge findEdge(const Graph &g,
    1.52 -				typename Graph::Node u, typename Graph::Node v,
    1.53 -				typename Graph::Edge prev = INVALID) 
    1.54 -  {
    1.55 -    typename Graph::OutEdgeIt e(g,prev);
    1.56 -    //    if(prev==INVALID) g.first(e,u);
    1.57 -    if(prev==INVALID) e=typename Graph::OutEdgeIt(g,u);
    1.58 -    else ++e;
    1.59 -    while(e!=INVALID && g.target(e)!=v) ++e;
    1.60 -    return e;
    1.61 +  inline typename Graph::Edge findEdge(const Graph &g,
    1.62 +				       typename Graph::Node u, 
    1.63 +				       typename Graph::Node v,
    1.64 +				       typename Graph::Edge prev = INVALID) {
    1.65 +    return _findEdge<Graph>(g, u, v, prev);
    1.66    }
    1.67  
    1.68 +  /// \brief Iterator for iterating on edges connected the same nodes.
    1.69 +  ///
    1.70 +  /// Iterator for iterating on edges connected the same nodes. It is 
    1.71 +  /// higher level interface for the findEdge() function. You can
    1.72 +  /// use it the next way:
    1.73 +  /// \code
    1.74 +  /// for (ConEdgeIt<Graph> it(g, src, trg); it != INVALID; ++it) {
    1.75 +  ///   ...
    1.76 +  /// }
    1.77 +  /// \endcode
    1.78 +  ///
    1.79 +  /// \author Balazs Dezso 
    1.80 +  template <typename _Graph>
    1.81 +  class ConEdgeIt : public _Graph::Edge {
    1.82 +  public:
    1.83 +
    1.84 +    typedef _Graph Graph;
    1.85 +    typedef typename Graph::Edge Parent;
    1.86 +
    1.87 +    typedef typename Graph::Edge Edge;
    1.88 +    typedef typename Graph::Node Node;
    1.89 +
    1.90 +    /// \brief Constructor.
    1.91 +    ///
    1.92 +    /// Construct a new ConEdgeIt iterating on the edges which
    1.93 +    /// connects the \c u and \c v node.
    1.94 +    ConEdgeIt(const Graph& g, Node u, Node v) : graph(g) {
    1.95 +      Parent::operator=(findEdge(graph, u, v));
    1.96 +    }
    1.97 +
    1.98 +    /// \brief Constructor.
    1.99 +    ///
   1.100 +    /// Construct a new ConEdgeIt which continues the iterating from 
   1.101 +    /// the \c e edge.
   1.102 +    ConEdgeIt(const Graph& g, Edge e) : Parent(e), graph(g) {}
   1.103 +    
   1.104 +    /// \brief Increment operator.
   1.105 +    ///
   1.106 +    /// It increments the iterator and gives back the next edge.
   1.107 +    ConEdgeIt& operator++() {
   1.108 +      Parent::operator=(findEdge(graph, graph.source(*this), 
   1.109 +				 graph.target(*this), *this));
   1.110 +      return *this;
   1.111 +    }
   1.112 +  private:
   1.113 +    const Graph& graph;
   1.114 +  };
   1.115 +
   1.116    /// \brief Copy a map.
   1.117    ///
   1.118    /// This function copies the \c source map to the \c target map. It uses the