Index: src/work/klao/path.h
===================================================================
--- src/work/klao/path.h	(revision 227)
+++ src/work/klao/path.h	(revision 369)
@@ -11,4 +11,5 @@
 
 #include <deque>
+#include <vector>
 #include <algorithm>
 
@@ -16,4 +17,190 @@
 
 namespace hugo {
+
+  template<typename Graph>
+  class DirPath {
+  public:
+    typedef typename Graph::Edge GraphEdge;
+    typedef typename Graph::Node GraphNode;
+    class NodeIt;
+    class EdgeIt;
+
+  protected:
+    const Graph *gr;
+    typedef std::vector<GraphEdge> Container;
+    Container edges;
+
+  public:
+
+    DirPath(const Graph &_G) : gr(&_G) {}
+
+    /// Subpath defined by two nodes.
+    /// It is an error if the two edges are not in order!
+    DirPath(const DirPath &P, const NodeIt &a, const NodeIt &b);
+    /// Subpath defined by two edges. Contains edges in [a,b)
+    /// It is an error if the two edges are not in order!
+    DirPath(const DirPath &P, const EdgeIt &a, const EdgeIt &b);
+
+    size_t length() const { return edges.size(); }
+    bool empty() const { return edges.empty(); }
+    GraphNode from() const {
+      return empty() ? INVALID : gr->tail(edges[0]);
+    }
+    GraphNode to() const {
+      return empty() ? INVALID : gr->head(edges[length()-1]);
+    }
+
+    template<typename It>
+    It& first(It &i) const { return i=It(*this); }
+
+    template<typename It>
+    It& nth(It &i, int n) const { return i=It(*this, n); }
+
+    template<typename It>
+    bool valid(const It &i) const { return i.valid(); }
+
+    template<typename It>
+    It& next(It &e) const { return ++e; }
+
+    /// \todo !
+    NodeIt head(const EdgeIt& e) const;
+    NodeIt tail(const EdgeIt& e) const;
+
+
+    /*** Iterator classes ***/
+    class EdgeIt {
+      friend class DirPath;
+
+      int idx;
+      const DirPath *p;
+    public:
+      EdgeIt() {}
+      EdgeIt(Invalid) : idx(-1), p(0) {}
+      EdgeIt(const DirPath &_p, int _idx = 0) :
+	idx(_idx), p(&_p) { validate(); }
+
+      bool valid() const { return idx!=-1; }
+
+      operator GraphEdge () const {
+	return valid() ? p->edges[idx] : INVALID;
+      }
+      EdgeIt& operator++() { ++idx; validate(); return *this; }
+
+      bool operator==(const EdgeIt& e) const { return idx==e.idx; }
+      bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
+      bool operator<(const EdgeIt& e) const { return idx<e.idx; }
+
+    private:
+      // FIXME: comparison between signed and unsigned...
+      // Jo ez igy? Vagy esetleg legyen a length() int?
+      void validate() { if( size_t(idx) >= p->length() ) idx=-1; }
+    };
+
+    class NodeIt {
+      friend class DirPath;
+
+      int idx;
+      const DirPath *p;
+    public:
+      NodeIt() {}
+      NodeIt(Invalid) : idx(-1), p(0) {}
+      NodeIt(const DirPath &_p, int _idx = 0) :
+	idx(_idx), p(&_p) { validate(); }
+
+      bool valid() const { return idx!=-1; }
+
+      operator const GraphEdge& () const {
+	if(idx >= p->length())
+	  return p->to();
+	else if(idx >= 0)
+	  return p->gr->tail(p->edges[idx]);
+	else
+	  return INVALID;
+      }
+      NodeIt& operator++() { ++idx; validate(); return *this; }
+
+      bool operator==(const NodeIt& e) const { return idx==e.idx; }
+      bool operator!=(const NodeIt& e) const { return idx!=e.idx; }
+      bool operator<(const NodeIt& e) const { return idx<e.idx; }
+
+    private:
+      void validate() { if( size_t(idx) > p->length() ) idx=-1; }
+    };
+
+    friend class Builder;    
+    class Builder {
+      DirPath &P;
+      Container d;
+
+    public:
+      Builder(DirPath &_P) : P(_P) {}
+
+      bool pushFront(const GraphEdge& e) {
+	if( empty() || P.gr->head(e)==from() ) {
+	  d.push_back(e);
+	  return true;
+	}
+	return false;
+      }
+      bool pushBack(const GraphEdge& e) {
+	if( empty() || P.gr->tail(e)==to() ) {
+	  P.edges.push_back(e);
+	  return true;
+	}
+	return false;
+      }
+
+      void commit() {
+	if( !d.empty() ) {
+	  P.edges.insert(P.edges.begin(), d.rbegin(), d.rend());
+	  d.clear();
+	}
+      }
+
+      ~Builder() { commit(); }
+
+      // FIXME: Hmm, pontosan hogy is kene ezt csinalni?
+      // Hogy kenyelmes egy ilyet hasznalni?
+      void reserve(size_t r) {
+	d.reserve(r);
+	P.edges.reserve(P.length()+r);
+      }
+
+    private:
+      bool empty() { return d.empty() && P.empty(); }
+
+      GraphNode from() const {
+	if( ! d.empty() )
+	  return P.gr->tail(d[d.size()-1]);
+	else if( ! P.empty() )
+	  return P.gr->tail(P.edges[0]);
+	else
+	  return INVALID;
+      }
+      GraphNode to() const {
+	if( ! P.empty() )
+	  return P.gr->head(P.edges[P.length()-1]);
+	else if( ! d.empty() )
+	  return P.gr->head(d[0]);
+	else
+	  return INVALID;
+      }
+
+    };
+
+  };
+
+
+
+
+
+
+
+
+
+
+
+  /**********************************************************************/
+
 
   /* Ennek az allocatorosdinak sokkal jobban utana kene nezni a hasznalata
@@ -21,5 +208,5 @@
 
   template<typename Graph>
-  class Path {
+  class DynamicPath {
 
   public:
@@ -39,13 +226,13 @@
   public:
 
-    Path(Graph &_G) : G(_G), _first(INVALID), _last(INVALID) {}
+    DynamicPath(Graph &_G) : G(_G), _first(INVALID), _last(INVALID) {}
 
     /// Subpath defined by two nodes.
     /// Nodes may be in reversed order, then
     /// we contstruct the reversed path.
-    Path(const Path &P, const NodeIt &a, const NodeIt &b);
+    DynamicPath(const DynamicPath &P, const NodeIt &a, const NodeIt &b);
     /// Subpath defined by two edges. Contains edges in [a,b)
     /// It is an error if the two edges are not in order!
-    Path(const Path &P, const EdgeIt &a, const EdgeIt &b);
+    DynamicPath(const DynamicPath &P, const EdgeIt &a, const EdgeIt &b);
     
     size_t length() const { return edges.size(); }
@@ -113,5 +300,5 @@
     /*** Iterator classes ***/
     class EdgeIt {
-      friend class Path;
+      friend class DynamicPath;
 
       typename Container::const_iterator it;
@@ -129,6 +316,5 @@
 
     class NodeIt {
-      friend class Path;
-      friend class EdgeIt;
+      friend class DynamicPath;
 
       size_t idx;
@@ -151,6 +337,6 @@
 
   template<typename Gr>
-  typename Path<Gr>::EdgeIt&
-  Path<Gr>::next(Path::EdgeIt &e) const {
+  typename DynamicPath<Gr>::EdgeIt&
+  DynamicPath<Gr>::next(DynamicPath::EdgeIt &e) const {
     if( e.it == edges.end() ) 
       return e;
@@ -170,5 +356,5 @@
 
   template<typename Gr>
-  typename Path<Gr>::NodeIt& Path<Gr>::next(NodeIt &n) const {
+  typename DynamicPath<Gr>::NodeIt& DynamicPath<Gr>::next(NodeIt &n) const {
     if( n.idx >= length() ) {
       // FIXME: invalid
@@ -192,5 +378,5 @@
 
   template<typename Gr>
-  bool Path<Gr>::edgeIncident(const GraphEdge &e, const GraphNode &a,
+  bool DynamicPath<Gr>::edgeIncident(const GraphEdge &e, const GraphNode &a,
 			  GraphNode &b) {
     if( G.tail(e) == a ) {
@@ -206,5 +392,5 @@
 
   template<typename Gr>
-  bool Path<Gr>::connectTwoEdges(const GraphEdge &e,
+  bool DynamicPath<Gr>::connectTwoEdges(const GraphEdge &e,
 			     const GraphEdge &f) {
     if( edgeIncident(f, G.tail(e), _last) ) {
@@ -220,5 +406,5 @@
 
   template<typename Gr>
-  bool Path<Gr>::pushFront(const GraphEdge &e) {
+  bool DynamicPath<Gr>::pushFront(const GraphEdge &e) {
     if( G.valid(_first) ) {
 	if( edgeIncident(e, _first, _first) ) {
@@ -238,5 +424,5 @@
 
   template<typename Gr>
-  bool Path<Gr>::pushBack(const GraphEdge &e) {
+  bool DynamicPath<Gr>::pushBack(const GraphEdge &e) {
     if( G.valid(_last) ) {
 	if( edgeIncident(e, _last, _last) ) {
@@ -257,5 +443,5 @@
 
   template<typename Gr>
-  bool Path<Gr>::setFrom(const GraphNode &n) {
+  bool DynamicPath<Gr>::setFrom(const GraphNode &n) {
     if( G.valid(_first) ) {
       return _first == n;
@@ -277,5 +463,5 @@
 
   template<typename Gr>
-  bool Path<Gr>::setTo(const GraphNode &n) {
+  bool DynamicPath<Gr>::setTo(const GraphNode &n) {
     if( G.valid(_last) ) {
       return _last == n;
@@ -298,6 +484,6 @@
 
   template<typename Gr>
-  typename Path<Gr>::NodeIt
-  Path<Gr>::tail(const EdgeIt& e) const {
+  typename DynamicPath<Gr>::NodeIt
+  DynamicPath<Gr>::tail(const EdgeIt& e) const {
     NodeIt n;
 
@@ -315,6 +501,6 @@
 
   template<typename Gr>
-  typename Path<Gr>::NodeIt
-  Path<Gr>::head(const EdgeIt& e) const {
+  typename DynamicPath<Gr>::NodeIt
+  DynamicPath<Gr>::head(const EdgeIt& e) const {
     if( e.it == edges.end()-1 ) {
       return _last;
@@ -327,6 +513,6 @@
       
   template<typename Gr>
-  typename Path<Gr>::GraphEdge
-  Path<Gr>::graphEdge(const EdgeIt& e) const {
+  typename DynamicPath<Gr>::GraphEdge
+  DynamicPath<Gr>::graphEdge(const EdgeIt& e) const {
     if( e.it != edges.end() ) {
       return *e.it;
@@ -338,6 +524,6 @@
   
   template<typename Gr>
-  typename Path<Gr>::GraphNode
-  Path<Gr>::graphNode(const NodeIt& n) const {
+  typename DynamicPath<Gr>::GraphNode
+  DynamicPath<Gr>::graphNode(const NodeIt& n) const {
     if( n.idx < length() ) {
       return n.tail ? G.tail(edges[n.idx]) : G.head(edges[n.idx]);
@@ -352,5 +538,6 @@
 
   template<typename Gr>
-  typename Path<Gr>::EdgeIt& Path<Gr>::nth(EdgeIt &e, size_t k) const {
+  typename DynamicPath<Gr>::EdgeIt&
+  DynamicPath<Gr>::nth(EdgeIt &e, size_t k) const {
     if( k<0 || k>=length() ) {
       // FIXME: invalid EdgeIt
@@ -372,5 +559,6 @@
     
   template<typename Gr>
-  typename Path<Gr>::NodeIt& Path<Gr>::nth(NodeIt &n, size_t k) const {
+  typename DynamicPath<Gr>::NodeIt&
+  DynamicPath<Gr>::nth(NodeIt &n, size_t k) const {
     if( k<0 || k>length() ) {
       // FIXME: invalid NodeIt
@@ -392,5 +580,6 @@
 
   template<typename Gr>
-  Path<Gr>::Path(const Path &P, const EdgeIt &a, const EdgeIt &b) :
+  DynamicPath<Gr>::DynamicPath(const DynamicPath &P, const EdgeIt &a,
+			       const EdgeIt &b) :
     G(P.G), edges(a.it, b.it)    // WARNING: if b.it < a.it this will blow up! 
   {
@@ -407,6 +596,6 @@
 
   template<typename Gr>
-  Path<Gr>::Path(const Path &P, const NodeIt &a, const NodeIt &b) :
-    G(P.G)
+  DynamicPath<Gr>::DynamicPath(const DynamicPath &P, const NodeIt &a,
+			       const NodeIt &b) : G(P.G)
   {
     if( !P.valid(a) || !P.valid(b) )
