src/hugo/path.h
changeset 834 1dd3167db044
parent 831 b6ae3446098a
child 835 eb9587f09b42
equal deleted inserted replaced
1:f9c0374a9f54 2:63588b4333f5
    26 #include <deque>
    26 #include <deque>
    27 #include <vector>
    27 #include <vector>
    28 #include <algorithm>
    28 #include <algorithm>
    29 
    29 
    30 #include <hugo/invalid.h>
    30 #include <hugo/invalid.h>
    31 #include <hugo/error.h>
       
    32 //#include <hugo/debug.h>
       
    33 
    31 
    34 namespace hugo {
    32 namespace hugo {
    35 
    33 
    36   /// \addtogroup paths
    34   /// \addtogroup paths
    37   /// @{
    35   /// @{
    72     /// \brief Subpath constructor.
    70     /// \brief Subpath constructor.
    73     ///
    71     ///
    74     /// Subpath defined by two nodes.
    72     /// Subpath defined by two nodes.
    75     /// \warning It is an error if the two edges are not in order!
    73     /// \warning It is an error if the two edges are not in order!
    76     DirPath(const DirPath &P, const NodeIt &a, const NodeIt &b) {
    74     DirPath(const DirPath &P, const NodeIt &a, const NodeIt &b) {
    77       if(!a.valid() || !b.valid) {
       
    78 	// FIXME: this check should be more elaborate...
       
    79 	fault("DirPath, subpath ctor: invalid bounding nodes");
       
    80       }
       
    81       gr = P.gr;
    75       gr = P.gr;
    82       edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
    76       edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
    83     }
    77     }
    84 
    78 
    85     /// \brief Subpath constructor.
    79     /// \brief Subpath constructor.
    86     ///
    80     ///
    87     /// Subpath defined by two edges. Contains edges in [a,b)
    81     /// Subpath defined by two edges. Contains edges in [a,b)
    88     /// \warning It is an error if the two edges are not in order!
    82     /// \warning It is an error if the two edges are not in order!
    89     DirPath(const DirPath &P, const EdgeIt &a, const EdgeIt &b) {
    83     DirPath(const DirPath &P, const EdgeIt &a, const EdgeIt &b) {
    90       if (!a.valid() || !b.valid) {
       
    91 	// FIXME: this check should be more elaborate...
       
    92 	fault("DirPath, subpath ctor: invalid bounding nodes");
       
    93       }
       
    94       gr = P.gr;
    84       gr = P.gr;
    95       edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
    85       edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
    96     }
    86     }
    97 
    87 
    98     /// Length of the path.
    88     /// Length of the path.
   125     template<typename It>
   115     template<typename It>
   126     It& first(It &i) const { return i=It(*this); }
   116     It& first(It &i) const { return i=It(*this); }
   127 
   117 
   128     /// \brief Initializes node iterator to point to the node of a given index.
   118     /// \brief Initializes node iterator to point to the node of a given index.
   129     NodeIt& nth(NodeIt &i, int n) const {
   119     NodeIt& nth(NodeIt &i, int n) const {
   130       if(n<0 || n>int(length())) 
       
   131 	fault("DirPath::nth: index out of range");
       
   132       return i=NodeIt(*this, n);
   120       return i=NodeIt(*this, n);
   133     }
   121     }
   134 
   122 
   135     /// \brief Initializes edge iterator to point to the edge of a given index.
   123     /// \brief Initializes edge iterator to point to the edge of a given index.
   136     EdgeIt& nth(EdgeIt &i, int n) const {
   124     EdgeIt& nth(EdgeIt &i, int n) const {
   137       if(n<0 || n>=int(length())) 
       
   138 	fault("DirPath::nth: index out of range");
       
   139       return i=EdgeIt(*this, n);
   125       return i=EdgeIt(*this, n);
   140     }
   126     }
   141 
   127 
   142     /// Checks validity of a node or edge iterator.
   128     /// Checks validity of a node or edge iterator.
   143     template<typename It>
   129     template<typename It>
   146 
   132 
   147     /// Steps the given node or edge iterator.
   133     /// Steps the given node or edge iterator.
   148     template<typename It>
   134     template<typename It>
   149     static
   135     static
   150     It& next(It &e) {
   136     It& next(It &e) {
   151       if( !e.valid() )
       
   152 	fault("DirPath::next() on invalid iterator");
       
   153       return ++e;
   137       return ++e;
   154     }
   138     }
   155 
   139 
   156     /// \brief Returns node iterator pointing to the head node of the
   140     /// \brief Returns node iterator pointing to the head node of the
   157     /// given edge iterator.
   141     /// given edge iterator.
   158     NodeIt head(const EdgeIt& e) const {
   142     NodeIt head(const EdgeIt& e) const {
   159       if( !e.valid() )
       
   160 	fault("DirPath::head() on invalid iterator");
       
   161       return NodeIt(*this, e.idx+1);
   143       return NodeIt(*this, e.idx+1);
   162     }
   144     }
   163 
   145 
   164     /// \brief Returns node iterator pointing to the tail node of the
   146     /// \brief Returns node iterator pointing to the tail node of the
   165     /// given edge iterator.
   147     /// given edge iterator.
   166     NodeIt tail(const EdgeIt& e) const {
   148     NodeIt tail(const EdgeIt& e) const {
   167       if( !e.valid() )
       
   168 	fault("DirPath::tail() on invalid iterator");
       
   169       return NodeIt(*this, e.idx);
   149       return NodeIt(*this, e.idx);
   170     }
   150     }
   171 
   151 
   172 
   152 
   173     /* Iterator classes */
   153     /* Iterator classes */
   310       ///Push a new edge to the front of the path
   290       ///Push a new edge to the front of the path
   311 
   291 
   312       ///Push a new edge to the front of the path.
   292       ///Push a new edge to the front of the path.
   313       ///\sa setStartNode
   293       ///\sa setStartNode
   314       void pushFront(const GraphEdge& e) {
   294       void pushFront(const GraphEdge& e) {
   315 	if( !empty() && P.gr->head(e)!=tail() ) {
       
   316 	  fault("DirPath::Builder::pushFront: nonincident edge");
       
   317 	}
       
   318 	front.push_back(e);
   295 	front.push_back(e);
   319       }
   296       }
   320 
   297 
   321       ///Push a new edge to the back of the path
   298       ///Push a new edge to the back of the path
   322 
   299 
   323       ///Push a new edge to the back of the path.
   300       ///Push a new edge to the back of the path.
   324       ///\sa setStartNode
   301       ///\sa setStartNode
   325       void pushBack(const GraphEdge& e) {
   302       void pushBack(const GraphEdge& e) {
   326 	if( !empty() && P.gr->tail(e)!=head() ) {
       
   327 	  fault("DirPath::Builder::pushBack: nonincident edge");
       
   328 	}
       
   329 	back.push_back(e);
   303 	back.push_back(e);
   330       }
   304       }
   331 
   305 
   332       ///Commit the changes to the path.
   306       ///Commit the changes to the path.
   333       void commit() {
   307       void commit() {
   438     /// \brief Subpath constructor.
   412     /// \brief Subpath constructor.
   439     ///
   413     ///
   440     /// Subpath defined by two nodes.
   414     /// Subpath defined by two nodes.
   441     /// \warning It is an error if the two edges are not in order!
   415     /// \warning It is an error if the two edges are not in order!
   442     UndirPath(const UndirPath &P, const NodeIt &a, const NodeIt &b) {
   416     UndirPath(const UndirPath &P, const NodeIt &a, const NodeIt &b) {
   443       if(!a.valid() || !b.valid) {
       
   444 	// FIXME: this check should be more elaborate...
       
   445 	fault("UndirPath, subpath ctor: invalid bounding nodes");
       
   446       }
       
   447       gr = P.gr;
   417       gr = P.gr;
   448       edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
   418       edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
   449     }
   419     }
   450 
   420 
   451     /// \brief Subpath constructor.
   421     /// \brief Subpath constructor.
   452     ///
   422     ///
   453     /// Subpath defined by two edges. Contains edges in [a,b)
   423     /// Subpath defined by two edges. Contains edges in [a,b)
   454     /// \warning It is an error if the two edges are not in order!
   424     /// \warning It is an error if the two edges are not in order!
   455     UndirPath(const UndirPath &P, const EdgeIt &a, const EdgeIt &b) {
   425     UndirPath(const UndirPath &P, const EdgeIt &a, const EdgeIt &b) {
   456       if(!a.valid() || !b.valid) {
       
   457 	// FIXME: this check should be more elaborate...
       
   458 	fault("UndirPath, subpath ctor: invalid bounding nodes");
       
   459       }
       
   460       gr = P.gr;
   426       gr = P.gr;
   461       edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
   427       edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
   462     }
   428     }
   463 
   429 
   464     /// Length of the path.
   430     /// Length of the path.
   491     template<typename It>
   457     template<typename It>
   492     It& first(It &i) const { return i=It(*this); }
   458     It& first(It &i) const { return i=It(*this); }
   493 
   459 
   494     /// \brief Initializes node iterator to point to the node of a given index.
   460     /// \brief Initializes node iterator to point to the node of a given index.
   495     NodeIt& nth(NodeIt &i, int n) const {
   461     NodeIt& nth(NodeIt &i, int n) const {
   496       if(n<0 || n>int(length()))
       
   497 	fault("UndirPath::nth: index out of range");
       
   498       return i=NodeIt(*this, n);
   462       return i=NodeIt(*this, n);
   499     }
   463     }
   500 
   464 
   501     /// \brief Initializes edge iterator to point to the edge of a given index.
   465     /// \brief Initializes edge iterator to point to the edge of a given index.
   502     EdgeIt& nth(EdgeIt &i, int n) const {
   466     EdgeIt& nth(EdgeIt &i, int n) const {
   503       if(n<0 || n>=int(length()))
       
   504 	fault("UndirPath::nth: index out of range");
       
   505       return i=EdgeIt(*this, n);
   467       return i=EdgeIt(*this, n);
   506     }
   468     }
   507 
   469 
   508     /// Checks validity of a node or edge iterator.
   470     /// Checks validity of a node or edge iterator.
   509     template<typename It>
   471     template<typename It>
   512 
   474 
   513     /// Steps the given node or edge iterator.
   475     /// Steps the given node or edge iterator.
   514     template<typename It>
   476     template<typename It>
   515     static
   477     static
   516     It& next(It &e) {
   478     It& next(It &e) {
   517       if( !e.valid() )
       
   518 	fault("UndirPath::next() on invalid iterator");
       
   519       return ++e;
   479       return ++e;
   520     }
   480     }
   521 
   481 
   522     /// \brief Returns node iterator pointing to the head node of the
   482     /// \brief Returns node iterator pointing to the head node of the
   523     /// given edge iterator.
   483     /// given edge iterator.
   524     NodeIt head(const EdgeIt& e) const {
   484     NodeIt head(const EdgeIt& e) const {
   525       if( !e.valid() )
       
   526 	fault("UndirPath::head() on invalid iterator");
       
   527       return NodeIt(*this, e.idx+1);
   485       return NodeIt(*this, e.idx+1);
   528     }
   486     }
   529 
   487 
   530     /// \brief Returns node iterator pointing to the tail node of the
   488     /// \brief Returns node iterator pointing to the tail node of the
   531     /// given edge iterator.
   489     /// given edge iterator.
   532     NodeIt tail(const EdgeIt& e) const {
   490     NodeIt tail(const EdgeIt& e) const {
   533       if( !e.valid() )
       
   534 	fault("UndirPath::tail() on invalid iterator");
       
   535       return NodeIt(*this, e.idx);
   491       return NodeIt(*this, e.idx);
   536     }
   492     }
   537 
   493 
   538 
   494 
   539 
   495 
   674       ///Push a new edge to the front of the path
   630       ///Push a new edge to the front of the path
   675 
   631 
   676       ///Push a new edge to the front of the path.
   632       ///Push a new edge to the front of the path.
   677       ///\sa setStartNode
   633       ///\sa setStartNode
   678       void pushFront(const GraphEdge& e) {
   634       void pushFront(const GraphEdge& e) {
   679 	if( !empty() && P.gr->head(e)!=tail() ) {
       
   680 	  fault("UndirPath::Builder::pushFront: nonincident edge");
       
   681 	}
       
   682 	front.push_back(e);
   635 	front.push_back(e);
   683       }
   636       }
   684 
   637 
   685       ///Push a new edge to the back of the path
   638       ///Push a new edge to the back of the path
   686 
   639