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 |