106 /// \brief Starting point of the path. |
106 /// \brief Starting point of the path. |
107 /// |
107 /// |
108 /// Starting point of the path. |
108 /// Starting point of the path. |
109 /// Returns INVALID if the path is empty. |
109 /// Returns INVALID if the path is empty. |
110 GraphNode from() const { |
110 GraphNode from() const { |
111 return empty() ? INVALID : gr->tail(edges[0]); |
111 return empty() ? INVALID : gr->source(edges[0]); |
112 } |
112 } |
113 /// \brief End point of the path. |
113 /// \brief End point of the path. |
114 /// |
114 /// |
115 /// End point of the path. |
115 /// End point of the path. |
116 /// Returns INVALID if the path is empty. |
116 /// Returns INVALID if the path is empty. |
117 GraphNode to() const { |
117 GraphNode to() const { |
118 return empty() ? INVALID : gr->head(edges[length()-1]); |
118 return empty() ? INVALID : gr->target(edges[length()-1]); |
119 } |
119 } |
120 |
120 |
121 /// \brief Initializes node or edge iterator to point to the first |
121 /// \brief Initializes node or edge iterator to point to the first |
122 /// node or edge. |
122 /// node or edge. |
123 /// |
123 /// |
151 if( DM::range_check && !e.valid() ) |
151 if( DM::range_check && !e.valid() ) |
152 fault("DirPath::next() on invalid iterator"); |
152 fault("DirPath::next() on invalid iterator"); |
153 return ++e; |
153 return ++e; |
154 } |
154 } |
155 |
155 |
156 /// \brief Returns node iterator pointing to the head node of the |
156 /// \brief Returns node iterator pointing to the target node of the |
157 /// given edge iterator. |
157 /// given edge iterator. |
158 NodeIt head(const EdgeIt& e) const { |
158 NodeIt target(const EdgeIt& e) const { |
159 if( DM::range_check && !e.valid() ) |
159 if( DM::range_check && !e.valid() ) |
160 fault("DirPath::head() on invalid iterator"); |
160 fault("DirPath::target() on invalid iterator"); |
161 return NodeIt(*this, e.idx+1); |
161 return NodeIt(*this, e.idx+1); |
162 } |
162 } |
163 |
163 |
164 /// \brief Returns node iterator pointing to the tail node of the |
164 /// \brief Returns node iterator pointing to the source node of the |
165 /// given edge iterator. |
165 /// given edge iterator. |
166 NodeIt tail(const EdgeIt& e) const { |
166 NodeIt source(const EdgeIt& e) const { |
167 if( DM::range_check && !e.valid() ) |
167 if( DM::range_check && !e.valid() ) |
168 fault("DirPath::tail() on invalid iterator"); |
168 fault("DirPath::source() on invalid iterator"); |
169 return NodeIt(*this, e.idx); |
169 return NodeIt(*this, e.idx); |
170 } |
170 } |
171 |
171 |
172 |
172 |
173 /* Iterator classes */ |
173 /* Iterator classes */ |
252 ///Conversion to Graph::Node |
252 ///Conversion to Graph::Node |
253 operator const GraphNode& () const { |
253 operator const GraphNode& () const { |
254 if(idx >= p->length()) |
254 if(idx >= p->length()) |
255 return p->to(); |
255 return p->to(); |
256 else if(idx >= 0) |
256 else if(idx >= 0) |
257 return p->gr->tail(p->edges[idx]); |
257 return p->gr->source(p->edges[idx]); |
258 else |
258 else |
259 return INVALID; |
259 return INVALID; |
260 } |
260 } |
261 /// Next node |
261 /// Next node |
262 NodeIt& operator++() { ++idx; validate(); return *this; } |
262 NodeIt& operator++() { ++idx; validate(); return *this; } |
310 ///Push a new edge to the front of the path |
310 ///Push a new edge to the front of the path |
311 |
311 |
312 ///Push a new edge to the front of the path. |
312 ///Push a new edge to the front of the path. |
313 ///\sa setStartNode |
313 ///\sa setStartNode |
314 void pushFront(const GraphEdge& e) { |
314 void pushFront(const GraphEdge& e) { |
315 if( DM::consistensy_check && !empty() && P.gr->head(e)!=from() ) { |
315 if( DM::consistensy_check && !empty() && P.gr->target(e)!=from() ) { |
316 fault("DirPath::Builder::pushFront: nonincident edge"); |
316 fault("DirPath::Builder::pushFront: nonincident edge"); |
317 } |
317 } |
318 front.push_back(e); |
318 front.push_back(e); |
319 } |
319 } |
320 |
320 |
321 ///Push a new edge to the back of the path |
321 ///Push a new edge to the back of the path |
322 |
322 |
323 ///Push a new edge to the back of the path. |
323 ///Push a new edge to the back of the path. |
324 ///\sa setStartNode |
324 ///\sa setStartNode |
325 void pushBack(const GraphEdge& e) { |
325 void pushBack(const GraphEdge& e) { |
326 if( DM::consistensy_check && !empty() && P.gr->tail(e)!=to() ) { |
326 if( DM::consistensy_check && !empty() && P.gr->source(e)!=to() ) { |
327 fault("DirPath::Builder::pushBack: nonincident edge"); |
327 fault("DirPath::Builder::pushBack: nonincident edge"); |
328 } |
328 } |
329 back.push_back(e); |
329 back.push_back(e); |
330 } |
330 } |
331 |
331 |
360 return front.empty() && back.empty() && P.empty(); |
360 return front.empty() && back.empty() && P.empty(); |
361 } |
361 } |
362 |
362 |
363 GraphNode from() const { |
363 GraphNode from() const { |
364 if( ! front.empty() ) |
364 if( ! front.empty() ) |
365 return P.gr->tail(front[front.size()-1]); |
365 return P.gr->source(front[front.size()-1]); |
366 else if( ! P.empty() ) |
366 else if( ! P.empty() ) |
367 return P.gr->tail(P.edges[0]); |
367 return P.gr->source(P.edges[0]); |
368 else if( ! back.empty() ) |
368 else if( ! back.empty() ) |
369 return P.gr->tail(back[0]); |
369 return P.gr->source(back[0]); |
370 else |
370 else |
371 return INVALID; |
371 return INVALID; |
372 } |
372 } |
373 GraphNode to() const { |
373 GraphNode to() const { |
374 if( ! back.empty() ) |
374 if( ! back.empty() ) |
375 return P.gr->head(back[back.size()-1]); |
375 return P.gr->target(back[back.size()-1]); |
376 else if( ! P.empty() ) |
376 else if( ! P.empty() ) |
377 return P.gr->head(P.edges[P.length()-1]); |
377 return P.gr->target(P.edges[P.length()-1]); |
378 else if( ! front.empty() ) |
378 else if( ! front.empty() ) |
379 return P.gr->head(front[0]); |
379 return P.gr->target(front[0]); |
380 else |
380 else |
381 return INVALID; |
381 return INVALID; |
382 } |
382 } |
383 |
383 |
384 }; |
384 }; |
469 /// \brief Starting point of the path. |
469 /// \brief Starting point of the path. |
470 /// |
470 /// |
471 /// Starting point of the path. |
471 /// Starting point of the path. |
472 /// Returns INVALID if the path is empty. |
472 /// Returns INVALID if the path is empty. |
473 GraphNode from() const { |
473 GraphNode from() const { |
474 return empty() ? INVALID : gr->tail(edges[0]); |
474 return empty() ? INVALID : gr->source(edges[0]); |
475 } |
475 } |
476 /// \brief End point of the path. |
476 /// \brief End point of the path. |
477 /// |
477 /// |
478 /// End point of the path. |
478 /// End point of the path. |
479 /// Returns INVALID if the path is empty. |
479 /// Returns INVALID if the path is empty. |
480 GraphNode to() const { |
480 GraphNode to() const { |
481 return empty() ? INVALID : gr->head(edges[length()-1]); |
481 return empty() ? INVALID : gr->target(edges[length()-1]); |
482 } |
482 } |
483 |
483 |
484 /// \brief Initializes node or edge iterator to point to the first |
484 /// \brief Initializes node or edge iterator to point to the first |
485 /// node or edge. |
485 /// node or edge. |
486 /// |
486 /// |
514 if( DM::range_check && !e.valid() ) |
514 if( DM::range_check && !e.valid() ) |
515 fault("UndirPath::next() on invalid iterator"); |
515 fault("UndirPath::next() on invalid iterator"); |
516 return ++e; |
516 return ++e; |
517 } |
517 } |
518 |
518 |
519 /// \brief Returns node iterator pointing to the head node of the |
519 /// \brief Returns node iterator pointing to the target node of the |
520 /// given edge iterator. |
520 /// given edge iterator. |
521 NodeIt head(const EdgeIt& e) const { |
521 NodeIt target(const EdgeIt& e) const { |
522 if( DM::range_check && !e.valid() ) |
522 if( DM::range_check && !e.valid() ) |
523 fault("UndirPath::head() on invalid iterator"); |
523 fault("UndirPath::target() on invalid iterator"); |
524 return NodeIt(*this, e.idx+1); |
524 return NodeIt(*this, e.idx+1); |
525 } |
525 } |
526 |
526 |
527 /// \brief Returns node iterator pointing to the tail node of the |
527 /// \brief Returns node iterator pointing to the source node of the |
528 /// given edge iterator. |
528 /// given edge iterator. |
529 NodeIt tail(const EdgeIt& e) const { |
529 NodeIt source(const EdgeIt& e) const { |
530 if( DM::range_check && !e.valid() ) |
530 if( DM::range_check && !e.valid() ) |
531 fault("UndirPath::tail() on invalid iterator"); |
531 fault("UndirPath::source() on invalid iterator"); |
532 return NodeIt(*this, e.idx); |
532 return NodeIt(*this, e.idx); |
533 } |
533 } |
534 |
534 |
535 |
535 |
536 |
536 |
613 ///Conversion to Graph::Node |
613 ///Conversion to Graph::Node |
614 operator const GraphNode& () const { |
614 operator const GraphNode& () const { |
615 if(idx >= p->length()) |
615 if(idx >= p->length()) |
616 return p->to(); |
616 return p->to(); |
617 else if(idx >= 0) |
617 else if(idx >= 0) |
618 return p->gr->tail(p->edges[idx]); |
618 return p->gr->source(p->edges[idx]); |
619 else |
619 else |
620 return INVALID; |
620 return INVALID; |
621 } |
621 } |
622 /// Next node |
622 /// Next node |
623 NodeIt& operator++() { ++idx; validate(); return *this; } |
623 NodeIt& operator++() { ++idx; validate(); return *this; } |
671 ///Push a new edge to the front of the path |
671 ///Push a new edge to the front of the path |
672 |
672 |
673 ///Push a new edge to the front of the path. |
673 ///Push a new edge to the front of the path. |
674 ///\sa setStartNode |
674 ///\sa setStartNode |
675 void pushFront(const GraphEdge& e) { |
675 void pushFront(const GraphEdge& e) { |
676 if( DM::consistensy_check && !empty() && P.gr->head(e)!=from() ) { |
676 if( DM::consistensy_check && !empty() && P.gr->target(e)!=from() ) { |
677 fault("UndirPath::Builder::pushFront: nonincident edge"); |
677 fault("UndirPath::Builder::pushFront: nonincident edge"); |
678 } |
678 } |
679 front.push_back(e); |
679 front.push_back(e); |
680 } |
680 } |
681 |
681 |
682 ///Push a new edge to the back of the path |
682 ///Push a new edge to the back of the path |
683 |
683 |
684 ///Push a new edge to the back of the path. |
684 ///Push a new edge to the back of the path. |
685 ///\sa setStartNode |
685 ///\sa setStartNode |
686 void pushBack(const GraphEdge& e) { |
686 void pushBack(const GraphEdge& e) { |
687 if( DM::consistensy_check && !empty() && P.gr->tail(e)!=to() ) { |
687 if( DM::consistensy_check && !empty() && P.gr->source(e)!=to() ) { |
688 fault("UndirPath::Builder::pushBack: nonincident edge"); |
688 fault("UndirPath::Builder::pushBack: nonincident edge"); |
689 } |
689 } |
690 back.push_back(e); |
690 back.push_back(e); |
691 } |
691 } |
692 |
692 |
721 return front.empty() && back.empty() && P.empty(); |
721 return front.empty() && back.empty() && P.empty(); |
722 } |
722 } |
723 |
723 |
724 GraphNode from() const { |
724 GraphNode from() const { |
725 if( ! front.empty() ) |
725 if( ! front.empty() ) |
726 return P.gr->tail(front[front.size()-1]); |
726 return P.gr->source(front[front.size()-1]); |
727 else if( ! P.empty() ) |
727 else if( ! P.empty() ) |
728 return P.gr->tail(P.edges[0]); |
728 return P.gr->source(P.edges[0]); |
729 else if( ! back.empty() ) |
729 else if( ! back.empty() ) |
730 return P.gr->tail(back[0]); |
730 return P.gr->source(back[0]); |
731 else |
731 else |
732 return INVALID; |
732 return INVALID; |
733 } |
733 } |
734 GraphNode to() const { |
734 GraphNode to() const { |
735 if( ! back.empty() ) |
735 if( ! back.empty() ) |
736 return P.gr->head(back[back.size()-1]); |
736 return P.gr->target(back[back.size()-1]); |
737 else if( ! P.empty() ) |
737 else if( ! P.empty() ) |
738 return P.gr->head(P.edges[P.length()-1]); |
738 return P.gr->target(P.edges[P.length()-1]); |
739 else if( ! front.empty() ) |
739 else if( ! front.empty() ) |
740 return P.gr->head(front[0]); |
740 return P.gr->target(front[0]); |
741 else |
741 else |
742 return INVALID; |
742 return INVALID; |
743 } |
743 } |
744 |
744 |
745 }; |
745 }; |
838 bool pushFront(const GraphEdge &e); |
838 bool pushFront(const GraphEdge &e); |
839 bool pushBack(const GraphEdge &e); |
839 bool pushBack(const GraphEdge &e); |
840 bool setFrom(const GraphNode &n); |
840 bool setFrom(const GraphNode &n); |
841 bool setTo(const GraphNode &n); |
841 bool setTo(const GraphNode &n); |
842 |
842 |
843 // WARNING: these two functions return the head/tail of an edge with |
843 // WARNING: these two functions return the target/source of an edge with |
844 // respect to the direction of the path! |
844 // respect to the direction of the path! |
845 // So G.head(P.graphEdge(e)) == P.graphNode(P.head(e)) holds only if |
845 // So G.target(P.graphEdge(e)) == P.graphNode(P.target(e)) holds only if |
846 // P.forward(e) is true (or the edge is a loop)! |
846 // P.forward(e) is true (or the edge is a loop)! |
847 NodeIt head(const EdgeIt& e) const; |
847 NodeIt target(const EdgeIt& e) const; |
848 NodeIt tail(const EdgeIt& e) const; |
848 NodeIt source(const EdgeIt& e) const; |
849 |
849 |
850 // FIXME: ezeknek valami jobb nev kellene!!! |
850 // FIXME: ezeknek valami jobb nev kellene!!! |
851 GraphEdge graphEdge(const EdgeIt& e) const; |
851 GraphEdge graphEdge(const EdgeIt& e) const; |
852 GraphNode graphNode(const NodeIt& n) const; |
852 GraphNode graphNode(const NodeIt& n) const; |
853 |
853 |
894 typename DynamicPath<Gr>::EdgeIt& |
894 typename DynamicPath<Gr>::EdgeIt& |
895 DynamicPath<Gr>::next(DynamicPath::EdgeIt &e) const { |
895 DynamicPath<Gr>::next(DynamicPath::EdgeIt &e) const { |
896 if( e.it == edges.end() ) |
896 if( e.it == edges.end() ) |
897 return e; |
897 return e; |
898 |
898 |
899 GraphNode common_node = ( e.forw ? G.head(*e.it) : G.tail(*e.it) ); |
899 GraphNode common_node = ( e.forw ? G.target(*e.it) : G.source(*e.it) ); |
900 ++e.it; |
900 ++e.it; |
901 |
901 |
902 // Invalid edgeit is always forward :) |
902 // Invalid edgeit is always forward :) |
903 if( e.it == edges.end() ) { |
903 if( e.it == edges.end() ) { |
904 e.forw = true; |
904 e.forw = true; |
905 return e; |
905 return e; |
906 } |
906 } |
907 |
907 |
908 e.forw = ( G.tail(*e.it) == common_node ); |
908 e.forw = ( G.source(*e.it) == common_node ); |
909 return e; |
909 return e; |
910 } |
910 } |
911 |
911 |
912 template<typename Gr> |
912 template<typename Gr> |
913 typename DynamicPath<Gr>::NodeIt& DynamicPath<Gr>::next(NodeIt &n) const { |
913 typename DynamicPath<Gr>::NodeIt& DynamicPath<Gr>::next(NodeIt &n) const { |
916 n.idx = length()+1; |
916 n.idx = length()+1; |
917 return n; |
917 return n; |
918 } |
918 } |
919 |
919 |
920 |
920 |
921 GraphNode next_node = ( n.tail ? G.head(edges[n.idx]) : |
921 GraphNode next_node = ( n.source ? G.target(edges[n.idx]) : |
922 G.tail(edges[n.idx]) ); |
922 G.source(edges[n.idx]) ); |
923 ++n.idx; |
923 ++n.idx; |
924 if( n.idx < length() ) { |
924 if( n.idx < length() ) { |
925 n.tail = ( next_node == G.tail(edges[n.idx]) ); |
925 n.source = ( next_node == G.source(edges[n.idx]) ); |
926 } |
926 } |
927 else { |
927 else { |
928 n.tail = true; |
928 n.source = true; |
929 } |
929 } |
930 |
930 |
931 return n; |
931 return n; |
932 } |
932 } |
933 |
933 |
934 template<typename Gr> |
934 template<typename Gr> |
935 bool DynamicPath<Gr>::edgeIncident(const GraphEdge &e, const GraphNode &a, |
935 bool DynamicPath<Gr>::edgeIncident(const GraphEdge &e, const GraphNode &a, |
936 GraphNode &b) { |
936 GraphNode &b) { |
937 if( G.tail(e) == a ) { |
937 if( G.source(e) == a ) { |
938 b=G.head(e); |
938 b=G.target(e); |
939 return true; |
939 return true; |
940 } |
940 } |
941 if( G.head(e) == a ) { |
941 if( G.target(e) == a ) { |
942 b=G.tail(e); |
942 b=G.source(e); |
943 return true; |
943 return true; |
944 } |
944 } |
945 return false; |
945 return false; |
946 } |
946 } |
947 |
947 |
948 template<typename Gr> |
948 template<typename Gr> |
949 bool DynamicPath<Gr>::connectTwoEdges(const GraphEdge &e, |
949 bool DynamicPath<Gr>::connectTwoEdges(const GraphEdge &e, |
950 const GraphEdge &f) { |
950 const GraphEdge &f) { |
951 if( edgeIncident(f, G.tail(e), _last) ) { |
951 if( edgeIncident(f, G.source(e), _last) ) { |
952 _first = G.head(e); |
952 _first = G.target(e); |
953 return true; |
953 return true; |
954 } |
954 } |
955 if( edgeIncident(f, G.head(e), _last) ) { |
955 if( edgeIncident(f, G.target(e), _last) ) { |
956 _first = G.tail(e); |
956 _first = G.source(e); |
957 return true; |
957 return true; |
958 } |
958 } |
959 return false; |
959 return false; |
960 } |
960 } |
961 |
961 |
1037 } |
1037 } |
1038 |
1038 |
1039 |
1039 |
1040 template<typename Gr> |
1040 template<typename Gr> |
1041 typename DynamicPath<Gr>::NodeIt |
1041 typename DynamicPath<Gr>::NodeIt |
1042 DynamicPath<Gr>::tail(const EdgeIt& e) const { |
1042 DynamicPath<Gr>::source(const EdgeIt& e) const { |
1043 NodeIt n; |
1043 NodeIt n; |
1044 |
1044 |
1045 if( e.it == edges.end() ) { |
1045 if( e.it == edges.end() ) { |
1046 // FIXME: invalid-> invalid |
1046 // FIXME: invalid-> invalid |
1047 n.idx = length() + 1; |
1047 n.idx = length() + 1; |
1048 n.tail = true; |
1048 n.source = true; |
1049 return n; |
1049 return n; |
1050 } |
1050 } |
1051 |
1051 |
1052 n.idx = e.it-edges.begin(); |
1052 n.idx = e.it-edges.begin(); |
1053 n.tail = e.forw; |
1053 n.source = e.forw; |
1054 return n; |
1054 return n; |
1055 } |
1055 } |
1056 |
1056 |
1057 template<typename Gr> |
1057 template<typename Gr> |
1058 typename DynamicPath<Gr>::NodeIt |
1058 typename DynamicPath<Gr>::NodeIt |
1059 DynamicPath<Gr>::head(const EdgeIt& e) const { |
1059 DynamicPath<Gr>::target(const EdgeIt& e) const { |
1060 if( e.it == edges.end()-1 ) { |
1060 if( e.it == edges.end()-1 ) { |
1061 return _last; |
1061 return _last; |
1062 } |
1062 } |
1063 |
1063 |
1064 EdgeIt next_edge = e; |
1064 EdgeIt next_edge = e; |
1065 next(next_edge); |
1065 next(next_edge); |
1066 return tail(next_edge); |
1066 return source(next_edge); |
1067 } |
1067 } |
1068 |
1068 |
1069 template<typename Gr> |
1069 template<typename Gr> |
1070 typename DynamicPath<Gr>::GraphEdge |
1070 typename DynamicPath<Gr>::GraphEdge |
1071 DynamicPath<Gr>::graphEdge(const EdgeIt& e) const { |
1071 DynamicPath<Gr>::graphEdge(const EdgeIt& e) const { |
1079 |
1079 |
1080 template<typename Gr> |
1080 template<typename Gr> |
1081 typename DynamicPath<Gr>::GraphNode |
1081 typename DynamicPath<Gr>::GraphNode |
1082 DynamicPath<Gr>::graphNode(const NodeIt& n) const { |
1082 DynamicPath<Gr>::graphNode(const NodeIt& n) const { |
1083 if( n.idx < length() ) { |
1083 if( n.idx < length() ) { |
1084 return n.tail ? G.tail(edges[n.idx]) : G.head(edges[n.idx]); |
1084 return n.source ? G.source(edges[n.idx]) : G.target(edges[n.idx]); |
1085 } |
1085 } |
1086 else if( n.idx == length() ) { |
1086 else if( n.idx == length() ) { |
1087 return _last; |
1087 return _last; |
1088 } |
1088 } |
1089 else { |
1089 else { |
1101 return e; |
1101 return e; |
1102 } |
1102 } |
1103 |
1103 |
1104 e.it = edges.begin()+k; |
1104 e.it = edges.begin()+k; |
1105 if(k==0) { |
1105 if(k==0) { |
1106 e.forw = ( G.tail(*e.it) == _first ); |
1106 e.forw = ( G.source(*e.it) == _first ); |
1107 } |
1107 } |
1108 else { |
1108 else { |
1109 e.forw = ( G.tail(*e.it) == G.tail(edges[k-1]) || |
1109 e.forw = ( G.source(*e.it) == G.source(edges[k-1]) || |
1110 G.tail(*e.it) == G.head(edges[k-1]) ); |
1110 G.source(*e.it) == G.target(edges[k-1]) ); |
1111 } |
1111 } |
1112 return e; |
1112 return e; |
1113 } |
1113 } |
1114 |
1114 |
1115 template<typename Gr> |
1115 template<typename Gr> |
1116 typename DynamicPath<Gr>::NodeIt& |
1116 typename DynamicPath<Gr>::NodeIt& |
1117 DynamicPath<Gr>::nth(NodeIt &n, size_t k) const { |
1117 DynamicPath<Gr>::nth(NodeIt &n, size_t k) const { |
1118 if( k>length() ) { |
1118 if( k>length() ) { |
1119 // FIXME: invalid NodeIt |
1119 // FIXME: invalid NodeIt |
1120 n.idx = length()+1; |
1120 n.idx = length()+1; |
1121 n.tail = true; |
1121 n.source = true; |
1122 return n; |
1122 return n; |
1123 } |
1123 } |
1124 if( k==length() ) { |
1124 if( k==length() ) { |
1125 n.idx = length(); |
1125 n.idx = length(); |
1126 n.tail = true; |
1126 n.source = true; |
1127 return n; |
1127 return n; |
1128 } |
1128 } |
1129 n = tail(nth<EdgeIt>(k)); |
1129 n = source(nth<EdgeIt>(k)); |
1130 return n; |
1130 return n; |
1131 } |
1131 } |
1132 |
1132 |
1133 // Reszut konstruktorok: |
1133 // Reszut konstruktorok: |
1134 |
1134 |
1137 DynamicPath<Gr>::DynamicPath(const DynamicPath &P, const EdgeIt &a, |
1137 DynamicPath<Gr>::DynamicPath(const DynamicPath &P, const EdgeIt &a, |
1138 const EdgeIt &b) : |
1138 const EdgeIt &b) : |
1139 G(P.G), edges(a.it, b.it) // WARNING: if b.it < a.it this will blow up! |
1139 G(P.G), edges(a.it, b.it) // WARNING: if b.it < a.it this will blow up! |
1140 { |
1140 { |
1141 if( G.valid(P._first) && a.it < P.edges.end() ) { |
1141 if( G.valid(P._first) && a.it < P.edges.end() ) { |
1142 _first = ( a.forw ? G.tail(*a.it) : G.head(*a.it) ); |
1142 _first = ( a.forw ? G.source(*a.it) : G.target(*a.it) ); |
1143 if( b.it < P.edges.end() ) { |
1143 if( b.it < P.edges.end() ) { |
1144 _last = ( b.forw ? G.tail(*b.it) : G.head(*b.it) ); |
1144 _last = ( b.forw ? G.source(*b.it) : G.target(*b.it) ); |
1145 } |
1145 } |
1146 else { |
1146 else { |
1147 _last = P._last; |
1147 _last = P._last; |
1148 } |
1148 } |
1149 } |
1149 } |