# HG changeset patch # User deba # Date 1143707921 0 # Node ID 332245399dc65dd4c46d4c5b37c578e93764e074 # Parent e70c1f6849bcbb693f2d63fa2e3ddafc44f002c9 Rewritten countItems and findEdges diff -r e70c1f6849bc -r 332245399dc6 lemon/graph_utils.h --- a/lemon/graph_utils.h Mon Mar 27 16:25:14 2006 +0000 +++ b/lemon/graph_utils.h Thu Mar 30 08:38:41 2006 +0000 @@ -102,8 +102,9 @@ /// The complexity of the function is O(n) because /// it iterates on all of the items. - template + template inline int countItems(const Graph& g) { + typedef typename ItemSetTraits::ItemIt ItemIt; int num = 0; for (ItemIt it(g); it != INVALID; ++it) { ++num; @@ -113,15 +114,24 @@ // Node counting: - template - inline typename enable_if::type - _countNodes(const Graph &g) { - return g.nodeNum(); - } + namespace _graph_utils_bits { + + template + struct CountNodesSelector { + static int count(const Graph &g) { + return countItems(g); + } + }; - template - inline int _countNodes(Wrap w) { - return countItems(w.value); + template + struct CountNodesSelector< + Graph, typename + enable_if::type> + { + static int count(const Graph &g) { + return g.nodeNum(); + } + }; } /// \brief Function to count the nodes in the graph. @@ -134,20 +144,30 @@ template inline int countNodes(const Graph& g) { - return _countNodes(g); + return _graph_utils_bits::CountNodesSelector::count(g); } + // Edge counting: - template - inline typename enable_if::type - _countEdges(const Graph &g) { - return g.edgeNum(); - } + namespace _graph_utils_bits { + + template + struct CountEdgesSelector { + static int count(const Graph &g) { + return countItems(g); + } + }; - template - inline int _countEdges(Wrap w) { - return countItems(w.value); + template + struct CountEdgesSelector< + Graph, + typename enable_if::type> + { + static int count(const Graph &g) { + return g.edgeNum(); + } + }; } /// \brief Function to count the edges in the graph. @@ -158,21 +178,28 @@ template inline int countEdges(const Graph& g) { - return _countEdges(g); + return _graph_utils_bits::CountEdgesSelector::count(g); } // Undirected edge counting: + namespace _graph_utils_bits { + + template + struct CountUEdgesSelector { + static int count(const Graph &g) { + return countItems(g); + } + }; - template - inline - typename enable_if::type - _countUEdges(const Graph &g) { - return g.uEdgeNum(); - } - - template - inline int _countUEdges(Wrap w) { - return countItems(w.value); + template + struct CountUEdgesSelector< + Graph, + typename enable_if::type> + { + static int count(const Graph &g) { + return g.uEdgeNum(); + } + }; } /// \brief Function to count the undirected edges in the graph. @@ -183,11 +210,11 @@ template inline int countUEdges(const Graph& g) { - return _countUEdges(g); + return _graph_utils_bits::CountUEdgesSelector::count(g); + } - template inline int countNodeDegree(const Graph& _g, const typename Graph::Node& _n) { int num = 0; @@ -224,32 +251,36 @@ return countNodeDegree(_g, _n); } + namespace _graph_utils_bits { + + template + struct FindEdgeSelector { + typedef typename Graph::Node Node; + typedef typename Graph::Edge Edge; + static Edge find(const Graph &g, Node u, Node v, Edge e) { + if (e == INVALID) { + g.firstOut(e, u); + } else { + g.nextOut(e); + } + while (e != INVALID && g.target(e) != v) { + g.nextOut(e); + } + return e; + } + }; - template - inline - typename enable_if::type - _findEdge(const Graph &g, - typename Graph::Node u, typename Graph::Node v, - typename Graph::Edge prev = INVALID) { - return g.findEdge(u, v, prev); - } - - template - inline typename Graph::Edge - _findEdge(Wrap w, - typename Graph::Node u, - typename Graph::Node v, - typename Graph::Edge prev = INVALID) { - const Graph& g = w.value; - if (prev == INVALID) { - typename Graph::OutEdgeIt e(g, u); - while (e != INVALID && g.target(e) != v) ++e; - return e; - } else { - typename Graph::OutEdgeIt e(g, prev); ++e; - while (e != INVALID && g.target(e) != v) ++e; - return e; - } + template + struct FindEdgeSelector< + Graph, + typename enable_if::type> + { + typedef typename Graph::Node Node; + typedef typename Graph::Edge Edge; + static Edge find(const Graph &g, Node u, Node v, Edge prev) { + return g.findEdge(u, v, prev); + } + }; } /// \brief Finds an edge between two nodes of a graph. @@ -267,14 +298,12 @@ /// ... /// } ///\endcode - // /// \todo We may want to use the "GraphBase" - // /// interface here... template inline typename Graph::Edge findEdge(const Graph &g, typename Graph::Node u, typename Graph::Node v, typename Graph::Edge prev = INVALID) { - return _findEdge(g, u, v, prev); + return _graph_utils_bits::FindEdgeSelector::find(g, u, v, prev); } /// \brief Iterator for iterating on edges connected the same nodes. @@ -325,38 +354,57 @@ const Graph& graph; }; - template - inline - typename enable_if< - typename Graph::FindEdgeTag, - typename Graph::UEdge>::type - _findUEdge(const Graph &g, - typename Graph::Node u, typename Graph::Node v, - typename Graph::UEdge prev = INVALID) { - return g.findUEdge(u, v, prev); - } + namespace _graph_utils_bits { + + template + struct FindUEdgeSelector { + typedef typename Graph::Node Node; + typedef typename Graph::UEdge UEdge; + static UEdge find(const Graph &g, Node u, Node v, UEdge e) { + bool b; + if (u != v) { + if (e == INVALID) { + g.firstInc(e, u, b); + } else { + b = g.source(e) == u; + g.nextInc(e, b); + } + while (e != INVALID && g.target(e) != v) { + g.nextInc(e, b); + } + } else { + if (e == INVALID) { + g.firstInc(e, u, b); + } else { + b = true; + g.nextInc(e, b); + } + while (e != INVALID && (!b || g.target(e) != v)) { + g.nextInc(e, b); + } + } + return e; + } + }; - template - inline typename Graph::UEdge - _findUEdge(Wrap w, - typename Graph::Node u, - typename Graph::Node v, - typename Graph::UEdge prev = INVALID) { - const Graph& g = w.value; - if (prev == INVALID) { - typename Graph::OutEdgeIt e(g, u); - while (e != INVALID && g.target(e) != v) ++e; - return e; - } else { - typename Graph::OutEdgeIt e(g, g.direct(prev, u)); ++e; - while (e != INVALID && g.target(e) != v) ++e; - return e; - } + template + struct FindUEdgeSelector< + Graph, + typename enable_if::type> + { + typedef typename Graph::Node Node; + typedef typename Graph::UEdge UEdge; + static UEdge find(const Graph &g, Node u, Node v, UEdge prev) { + return g.findUEdge(u, v, prev); + } + }; } /// \brief Finds an uedge between two nodes of a graph. /// /// Finds an uedge from node \c u to node \c v in graph \c g. + /// If the node \c u and node \c v is equal then each loop edge + /// will be enumerated. /// /// If \c prev is \ref INVALID (this is the default value), then /// it finds the first edge from \c u to \c v. Otherwise it looks for @@ -370,15 +418,12 @@ /// ... /// } ///\endcode - // /// \todo We may want to use the "GraphBase" - // /// interface here... template - inline typename Graph::UEdge - findUEdge(const Graph &g, - typename Graph::Node u, - typename Graph::Node v, - typename Graph::UEdge prev = INVALID) { - return _findUEdge(g, u, v, prev); + inline typename Graph::UEdge findEdge(const Graph &g, + typename Graph::Node u, + typename Graph::Node v, + typename Graph::UEdge prev = INVALID) { + return _graph_utils_bits::FindUEdgeSelector::find(g, u, v, prev); } /// \brief Iterator for iterating on uedges connected the same nodes.