1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
3 * This file is a part of LEMON, a generic C++ optimization library.
5 * Copyright (C) 2003-2013
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
21 ///\brief Classes for representing paths in digraphs.
30 #include <lemon/error.h>
31 #include <lemon/core.h>
32 #include <lemon/concepts/path.h>
33 #include <lemon/bits/stl_iterators.h>
41 /// \brief A structure for representing directed paths in a digraph.
43 /// A structure for representing directed path in a digraph.
44 /// \tparam GR The digraph type in which the path is.
46 /// In a sense, a path can be treated as a list of arcs. The
47 /// LEMON path type simply stores this list. As a consequence, it
48 /// cannot enumerate the nodes in the path, and the source node of
49 /// a zero-length path is undefined.
51 /// This implementation is a back and front insertable and erasable
52 /// path type. It can be indexed in O(1) time. The front and back
53 /// insertion and erase is done in O(1) (amortized) time. The
54 /// implementation uses two vectors for storing the front and back
56 template <typename GR>
61 typedef typename Digraph::Arc Arc;
63 /// \brief Default constructor
65 /// Default constructor
68 /// \brief Copy constructor
70 Path(const Path& cpath) {
71 pathCopy(cpath, *this);
74 /// \brief Template copy constructor
76 /// This constuctor initializes the path from any other path type.
77 /// It simply makes a copy of the given path.
78 template <typename CPath>
79 Path(const CPath& cpath) {
80 pathCopy(cpath, *this);
83 /// \brief Copy assignment
85 Path& operator=(const Path& cpath) {
86 pathCopy(cpath, *this);
90 /// \brief Template copy assignment
92 /// This operator makes a copy of a path of any other type.
93 template <typename CPath>
94 Path& operator=(const CPath& cpath) {
95 pathCopy(cpath, *this);
99 /// \brief LEMON style iterator for path arcs
101 /// This class is used to iterate on the arcs of the paths.
105 /// \brief Default constructor
107 /// \brief Invalid constructor
108 ArcIt(Invalid) : path(0), idx(-1) {}
109 /// \brief Initializate the iterator to the first arc of path
110 ArcIt(const Path &_path)
111 : path(&_path), idx(_path.empty() ? -1 : 0) {}
115 ArcIt(const Path &_path, int _idx)
116 : path(&_path), idx(_idx) {}
120 /// \brief Conversion to Arc
121 operator const Arc&() const {
122 return path->nth(idx);
126 ArcIt& operator++() {
128 if (idx >= path->length()) idx = -1;
132 /// \brief Comparison operator
133 bool operator==(const ArcIt& e) const { return idx==e.idx; }
134 /// \brief Comparison operator
135 bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
136 /// \brief Comparison operator
137 bool operator<(const ArcIt& e) const { return idx<e.idx; }
144 /// \brief Gets the collection of the arcs of the path.
146 /// This function can be used for iterating on the
147 /// arcs of the path. It returns a wrapped
148 /// ArcIt, which looks like an STL container
149 /// (by having begin() and end()) which you can use in range-based
150 /// for loops, STL algorithms, etc.
151 /// For example you can write:
153 /// for(auto a: p.arcs())
156 LemonRangeWrapper1<ArcIt, Path> arcs() const {
157 return LemonRangeWrapper1<ArcIt, Path>(*this);
161 /// \brief Length of the path.
162 int length() const { return head.size() + tail.size(); }
163 /// \brief Return whether the path is empty.
164 bool empty() const { return head.empty() && tail.empty(); }
166 /// \brief Reset the path to an empty one.
167 void clear() { head.clear(); tail.clear(); }
169 /// \brief The n-th arc.
171 /// Gives back the n-th arc. This function runs in O(1) time.
172 /// \pre \c n is in the range <tt>[0..length() - 1]</tt>.
173 const Arc& nth(int n) const {
174 return n < int(head.size()) ? *(head.rbegin() + n) :
175 *(tail.begin() + (n - head.size()));
178 /// \brief Initialize arc iterator to point to the n-th arc
180 /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
181 ArcIt nthIt(int n) const {
182 return ArcIt(*this, n);
185 /// \brief The n-th arc.
187 /// Gives back the n-th arc. This operator is just an alias for \ref nth(),
188 /// it runs in O(1) time.
189 /// \pre \c n is in the range <tt>[0..length() - 1]</tt>.
190 const Arc& operator[](int n) const {
194 /// \brief The first arc of the path
195 const Arc& front() const {
196 return head.empty() ? tail.front() : head.back();
199 /// \brief Add a new arc before the current path
200 void addFront(const Arc& arc) {
204 /// \brief Erase the first arc of the path
210 int halfsize = tail.size() / 2;
211 head.resize(halfsize);
212 std::copy(tail.begin() + 1, tail.begin() + halfsize + 1,
214 std::copy(tail.begin() + halfsize + 1, tail.end(), tail.begin());
215 tail.resize(tail.size() - halfsize - 1);
219 /// \brief The last arc of the path
220 const Arc& back() const {
221 return tail.empty() ? head.front() : tail.back();
224 /// \brief Add a new arc behind the current path
225 void addBack(const Arc& arc) {
229 /// \brief Erase the last arc of the path
234 int halfsize = head.size() / 2;
235 tail.resize(halfsize);
236 std::copy(head.begin() + 1, head.begin() + halfsize + 1,
238 std::copy(head.begin() + halfsize + 1, head.end(), head.begin());
239 head.resize(head.size() - halfsize - 1);
243 typedef True BuildTag;
245 template <typename CPath>
246 void build(const CPath& path) {
247 int len = path.length();
249 for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
254 template <typename CPath>
255 void buildRev(const CPath& path) {
256 int len = path.length();
258 for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
264 typedef std::vector<Arc> Container;
265 Container head, tail;
269 /// \brief A structure for representing directed paths in a digraph.
271 /// A structure for representing directed path in a digraph.
272 /// \tparam GR The digraph type in which the path is.
274 /// In a sense, a path can be treated as a list of arcs. The
275 /// LEMON path type simply stores this list. As a consequence, it
276 /// cannot enumerate the nodes in the path, and the source node of
277 /// a zero-length path is undefined.
279 /// This implementation is a just back insertable and erasable path
280 /// type. It can be indexed in O(1) time. The back insertion and
281 /// erasure is amortized O(1) time. This implementation is faster
282 /// than the \c Path type because it use just one vector for the
284 template <typename GR>
289 typedef typename Digraph::Arc Arc;
291 /// \brief Default constructor
293 /// Default constructor
296 /// \brief Copy constructor
298 SimplePath(const SimplePath& cpath) {
299 pathCopy(cpath, *this);
302 /// \brief Template copy constructor
304 /// This path can be initialized with any other path type. It just
305 /// makes a copy of the given path.
306 template <typename CPath>
307 SimplePath(const CPath& cpath) {
308 pathCopy(cpath, *this);
311 /// \brief Copy assignment
313 SimplePath& operator=(const SimplePath& cpath) {
314 pathCopy(cpath, *this);
318 /// \brief Template copy assignment
320 /// This path can be initialized with any other path type. It just
321 /// makes a copy of the given path.
322 template <typename CPath>
323 SimplePath& operator=(const CPath& cpath) {
324 pathCopy(cpath, *this);
328 /// \brief Iterator class to iterate on the arcs of the paths
330 /// This class is used to iterate on the arcs of the paths
332 /// Of course it converts to Digraph::Arc
334 friend class SimplePath;
336 /// Default constructor
338 /// Invalid constructor
339 ArcIt(Invalid) : path(0), idx(-1) {}
340 /// \brief Initializate the constructor to the first arc of path
341 ArcIt(const SimplePath &_path)
342 : path(&_path), idx(_path.empty() ? -1 : 0) {}
346 /// Constructor with starting point
347 ArcIt(const SimplePath &_path, int _idx)
348 : path(&_path), idx(_idx) {}
352 ///Conversion to Digraph::Arc
353 operator const Arc&() const {
354 return path->nth(idx);
358 ArcIt& operator++() {
360 if (idx >= path->length()) idx = -1;
364 /// Comparison operator
365 bool operator==(const ArcIt& e) const { return idx==e.idx; }
366 /// Comparison operator
367 bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
368 /// Comparison operator
369 bool operator<(const ArcIt& e) const { return idx<e.idx; }
372 const SimplePath *path;
376 /// \brief Gets the collection of the arcs of the path.
378 /// This function can be used for iterating on the
379 /// arcs of the path. It returns a wrapped
380 /// ArcIt, which looks like an STL container
381 /// (by having begin() and end()) which you can use in range-based
382 /// for loops, STL algorithms, etc.
383 /// For example you can write:
385 /// for(auto a: p.arcs())
388 LemonRangeWrapper1<ArcIt, SimplePath> arcs() const {
389 return LemonRangeWrapper1<ArcIt, SimplePath>(*this);
393 /// \brief Length of the path.
394 int length() const { return data.size(); }
395 /// \brief Return true if the path is empty.
396 bool empty() const { return data.empty(); }
398 /// \brief Reset the path to an empty one.
399 void clear() { data.clear(); }
401 /// \brief The n-th arc.
403 /// Gives back the n-th arc. This function runs in O(1) time.
404 /// \pre \c n is in the range <tt>[0..length() - 1]</tt>.
405 const Arc& nth(int n) const {
409 /// \brief Initializes arc iterator to point to the n-th arc.
410 ArcIt nthIt(int n) const {
411 return ArcIt(*this, n);
414 /// \brief The n-th arc.
416 /// Gives back the n-th arc. This operator is just an alias for \ref nth(),
417 /// it runs in O(1) time.
418 /// \pre \c n is in the range <tt>[0..length() - 1]</tt>.
419 const Arc& operator[](int n) const {
423 /// \brief The first arc of the path.
424 const Arc& front() const {
428 /// \brief The last arc of the path.
429 const Arc& back() const {
433 /// \brief Add a new arc behind the current path.
434 void addBack(const Arc& arc) {
438 /// \brief Erase the last arc of the path
443 typedef True BuildTag;
445 template <typename CPath>
446 void build(const CPath& path) {
447 int len = path.length();
450 for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
456 template <typename CPath>
457 void buildRev(const CPath& path) {
458 int len = path.length();
461 for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
468 typedef std::vector<Arc> Container;
473 /// \brief A structure for representing directed paths in a digraph.
475 /// A structure for representing directed path in a digraph.
476 /// \tparam GR The digraph type in which the path is.
478 /// In a sense, a path can be treated as a list of arcs. The
479 /// LEMON path type simply stores this list. As a consequence, it
480 /// cannot enumerate the nodes in the path, and the source node of
481 /// a zero-length path is undefined.
483 /// This implementation is a back and front insertable and erasable
484 /// path type. It can be indexed in O(k) time, where k is the rank
485 /// of the arc in the path. The length can be computed in O(n)
486 /// time. The front and back insertion and erasure is O(1) time
487 /// and it can be splited and spliced in O(1) time.
488 template <typename GR>
493 typedef typename Digraph::Arc Arc;
497 // the std::list<> is incompatible
498 // hard to create invalid iterator
506 std::allocator<Node> alloc;
510 /// \brief Default constructor
512 /// Default constructor
513 ListPath() : first(0), last(0) {}
515 /// \brief Copy constructor
517 ListPath(const ListPath& cpath) : first(0), last(0) {
518 pathCopy(cpath, *this);
521 /// \brief Template copy constructor
523 /// This path can be initialized with any other path type. It just
524 /// makes a copy of the given path.
525 template <typename CPath>
526 ListPath(const CPath& cpath) : first(0), last(0) {
527 pathCopy(cpath, *this);
530 /// \brief Destructor of the path
532 /// Destructor of the path
537 /// \brief Copy assignment
539 ListPath& operator=(const ListPath& cpath) {
540 pathCopy(cpath, *this);
544 /// \brief Template copy assignment
546 /// This path can be initialized with any other path type. It just
547 /// makes a copy of the given path.
548 template <typename CPath>
549 ListPath& operator=(const CPath& cpath) {
550 pathCopy(cpath, *this);
554 /// \brief Iterator class to iterate on the arcs of the paths
556 /// This class is used to iterate on the arcs of the paths
558 /// Of course it converts to Digraph::Arc
560 friend class ListPath;
562 /// Default constructor
564 /// Invalid constructor
565 ArcIt(Invalid) : path(0), node(0) {}
566 /// \brief Initializate the constructor to the first arc of path
567 ArcIt(const ListPath &_path)
568 : path(&_path), node(_path.first) {}
572 ArcIt(const ListPath &_path, Node *_node)
573 : path(&_path), node(_node) {}
578 ///Conversion to Digraph::Arc
579 operator const Arc&() const {
584 ArcIt& operator++() {
589 /// Comparison operator
590 bool operator==(const ArcIt& e) const { return node==e.node; }
591 /// Comparison operator
592 bool operator!=(const ArcIt& e) const { return node!=e.node; }
593 /// Comparison operator
594 bool operator<(const ArcIt& e) const { return node<e.node; }
597 const ListPath *path;
601 /// \brief Gets the collection of the arcs of the path.
603 /// This function can be used for iterating on the
604 /// arcs of the path. It returns a wrapped
605 /// ArcIt, which looks like an STL container
606 /// (by having begin() and end()) which you can use in range-based
607 /// for loops, STL algorithms, etc.
608 /// For example you can write:
610 /// for(auto a: p.arcs())
613 LemonRangeWrapper1<ArcIt, ListPath> arcs() const {
614 return LemonRangeWrapper1<ArcIt, ListPath>(*this);
618 /// \brief The n-th arc.
620 /// This function looks for the n-th arc in O(n) time.
621 /// \pre \c n is in the range <tt>[0..length() - 1]</tt>.
622 const Arc& nth(int n) const {
624 for (int i = 0; i < n; ++i) {
630 /// \brief Initializes arc iterator to point to the n-th arc.
631 ArcIt nthIt(int n) const {
633 for (int i = 0; i < n; ++i) {
636 return ArcIt(*this, node);
639 /// \brief The n-th arc.
641 /// Looks for the n-th arc in O(n) time. This operator is just an alias
643 /// \pre \c n is in the range <tt>[0..length() - 1]</tt>.
644 const Arc& operator[](int n) const {
648 /// \brief Length of the path.
659 /// \brief Return true if the path is empty.
660 bool empty() const { return first == 0; }
662 /// \brief Reset the path to an empty one.
666 alloc.destroy(first);
667 alloc.deallocate(first, 1);
672 /// \brief The first arc of the path
673 const Arc& front() const {
677 /// \brief Add a new arc before the current path
678 void addFront(const Arc& arc) {
679 Node *node = alloc.allocate(1);
680 alloc.construct(node, Node());
692 /// \brief Erase the first arc of the path
702 alloc.deallocate(node, 1);
705 /// \brief The last arc of the path.
706 const Arc& back() const {
710 /// \brief Add a new arc behind the current path.
711 void addBack(const Arc& arc) {
712 Node *node = alloc.allocate(1);
713 alloc.construct(node, Node());
725 /// \brief Erase the last arc of the path
735 alloc.deallocate(node, 1);
738 /// \brief Splice a path to the back of the current path.
740 /// It splices \c tpath to the back of the current path and \c
741 /// tpath becomes empty. The time complexity of this function is
743 void spliceBack(ListPath& tpath) {
746 last->next = tpath.first;
747 tpath.first->prev = last;
754 tpath.first = tpath.last = 0;
757 /// \brief Splice a path to the front of the current path.
759 /// It splices \c tpath before the current path and \c tpath
760 /// becomes empty. The time complexity of this function
762 void spliceFront(ListPath& tpath) {
765 first->prev = tpath.last;
766 tpath.last->next = first;
773 tpath.first = tpath.last = 0;
776 /// \brief Splice a path into the current path.
778 /// It splices the \c tpath into the current path before the
779 /// position of \c it iterator and \c tpath becomes empty. The
780 /// time complexity of this function is O(1). If the \c it is
781 /// \c INVALID then it will splice behind the current path.
782 void splice(ArcIt it, ListPath& tpath) {
785 tpath.first->prev = it.node->prev;
787 it.node->prev->next = tpath.first;
791 it.node->prev = tpath.last;
792 tpath.last->next = it.node;
797 last->next = tpath.first;
798 tpath.first->prev = last;
806 tpath.first = tpath.last = 0;
809 /// \brief Split the current path.
811 /// It splits the current path into two parts. The part before
812 /// the iterator \c it will remain in the current path and the part
814 /// \c it will put into \c tpath. If \c tpath have arcs
815 /// before the operation they are removed first. The time
816 /// complexity of this function is O(1) plus the time of emtying
817 /// \c tpath. If \c it is \c INVALID then it just clears \c tpath
818 void split(ArcIt it, ListPath& tpath) {
821 tpath.first = it.node;
824 last = it.node->prev;
834 typedef True BuildTag;
836 template <typename CPath>
837 void build(const CPath& path) {
838 for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
843 template <typename CPath>
844 void buildRev(const CPath& path) {
845 for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
852 /// \brief A structure for representing directed paths in a digraph.
854 /// A structure for representing directed path in a digraph.
855 /// \tparam GR The digraph type in which the path is.
857 /// In a sense, a path can be treated as a list of arcs. The
858 /// LEMON path type simply stores this list. As a consequence, it
859 /// cannot enumerate the nodes in the path, and the source node of
860 /// a zero-length path is undefined.
862 /// This implementation is completly static, i.e. it can be copy constucted
863 /// or copy assigned from another path, but otherwise it cannot be
866 /// Being the most memory-efficient path type in LEMON, it is
867 /// intented to be used when you want to store a large number of paths.
868 template <typename GR>
873 typedef typename Digraph::Arc Arc;
875 /// \brief Default constructor
877 /// Default constructor
878 StaticPath() : len(0), _arcs(0) {}
880 /// \brief Copy constructor
882 StaticPath(const StaticPath& cpath) : _arcs(0) {
883 pathCopy(cpath, *this);
886 /// \brief Template copy constructor
888 /// This path can be initialized from any other path type.
889 template <typename CPath>
890 StaticPath(const CPath& cpath) : _arcs(0) {
891 pathCopy(cpath, *this);
894 /// \brief Destructor of the path
896 /// Destructor of the path
898 if (_arcs) delete[] _arcs;
901 /// \brief Copy assignment
903 StaticPath& operator=(const StaticPath& cpath) {
904 pathCopy(cpath, *this);
908 /// \brief Template copy assignment
910 /// This path can be made equal to any other path type. It simply
911 /// makes a copy of the given path.
912 template <typename CPath>
913 StaticPath& operator=(const CPath& cpath) {
914 pathCopy(cpath, *this);
918 /// \brief Iterator class to iterate on the arcs of the paths
920 /// This class is used to iterate on the arcs of the paths
922 /// Of course it converts to Digraph::Arc
924 friend class StaticPath;
926 /// Default constructor
928 /// Invalid constructor
929 ArcIt(Invalid) : path(0), idx(-1) {}
930 /// Initializate the constructor to the first arc of path
931 ArcIt(const StaticPath &_path)
932 : path(&_path), idx(_path.empty() ? -1 : 0) {}
936 /// Constructor with starting point
937 ArcIt(const StaticPath &_path, int _idx)
938 : idx(_idx), path(&_path) {}
942 ///Conversion to Digraph::Arc
943 operator const Arc&() const {
944 return path->nth(idx);
948 ArcIt& operator++() {
950 if (idx >= path->length()) idx = -1;
954 /// Comparison operator
955 bool operator==(const ArcIt& e) const { return idx==e.idx; }
956 /// Comparison operator
957 bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
958 /// Comparison operator
959 bool operator<(const ArcIt& e) const { return idx<e.idx; }
962 const StaticPath *path;
966 /// \brief Gets the collection of the arcs of the path.
968 /// This function can be used for iterating on the
969 /// arcs of the path. It returns a wrapped
970 /// ArcIt, which looks like an STL container
971 /// (by having begin() and end()) which you can use in range-based
972 /// for loops, STL algorithms, etc.
973 /// For example you can write:
975 /// for(auto a: p.arcs())
978 LemonRangeWrapper1<ArcIt, StaticPath> arcs() const {
979 return LemonRangeWrapper1<ArcIt, StaticPath>(*this);
983 /// \brief The n-th arc.
985 /// Gives back the n-th arc. This function runs in O(1) time.
986 /// \pre \c n is in the range <tt>[0..length() - 1]</tt>.
987 const Arc& nth(int n) const {
991 /// \brief The arc iterator pointing to the n-th arc.
992 ArcIt nthIt(int n) const {
993 return ArcIt(*this, n);
996 /// \brief The n-th arc.
998 /// Gives back the n-th arc. This operator is just an alias for \ref nth(),
999 /// it runs in O(1) time.
1000 /// \pre \c n is in the range <tt>[0..length() - 1]</tt>.
1001 const Arc& operator[](int n) const {
1005 /// \brief The length of the path.
1006 int length() const { return len; }
1008 /// \brief Return true when the path is empty.
1009 int empty() const { return len == 0; }
1011 /// \brief Reset the path to an empty one.
1014 if (_arcs) delete[] _arcs;
1018 /// \brief The first arc of the path.
1019 const Arc& front() const {
1023 /// \brief The last arc of the path.
1024 const Arc& back() const {
1025 return _arcs[len - 1];
1029 typedef True BuildTag;
1031 template <typename CPath>
1032 void build(const CPath& path) {
1033 len = path.length();
1034 _arcs = new Arc[len];
1036 for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
1042 template <typename CPath>
1043 void buildRev(const CPath& path) {
1044 len = path.length();
1045 _arcs = new Arc[len];
1047 for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
1058 ///////////////////////////////////////////////////////////////////////
1059 // Additional utilities
1060 ///////////////////////////////////////////////////////////////////////
1062 namespace _path_bits {
1064 template <typename Path, typename Enable = void>
1065 struct RevPathTagIndicator {
1066 static const bool value = false;
1069 template <typename Path>
1070 struct RevPathTagIndicator<
1072 typename enable_if<typename Path::RevPathTag, void>::type
1074 static const bool value = true;
1077 template <typename Path, typename Enable = void>
1078 struct BuildTagIndicator {
1079 static const bool value = false;
1082 template <typename Path>
1083 struct BuildTagIndicator<
1085 typename enable_if<typename Path::BuildTag, void>::type
1087 static const bool value = true;
1090 template <typename From, typename To,
1091 bool buildEnable = BuildTagIndicator<To>::value>
1092 struct PathCopySelectorForward {
1093 static void copy(const From& from, To& to) {
1095 for (typename From::ArcIt it(from); it != INVALID; ++it) {
1101 template <typename From, typename To>
1102 struct PathCopySelectorForward<From, To, true> {
1103 static void copy(const From& from, To& to) {
1109 template <typename From, typename To,
1110 bool buildEnable = BuildTagIndicator<To>::value>
1111 struct PathCopySelectorBackward {
1112 static void copy(const From& from, To& to) {
1114 for (typename From::RevArcIt it(from); it != INVALID; ++it) {
1120 template <typename From, typename To>
1121 struct PathCopySelectorBackward<From, To, true> {
1122 static void copy(const From& from, To& to) {
1129 template <typename From, typename To,
1130 bool revEnable = RevPathTagIndicator<From>::value>
1131 struct PathCopySelector {
1132 static void copy(const From& from, To& to) {
1133 PathCopySelectorForward<From, To>::copy(from, to);
1137 template <typename From, typename To>
1138 struct PathCopySelector<From, To, true> {
1139 static void copy(const From& from, To& to) {
1140 PathCopySelectorBackward<From, To>::copy(from, to);
1147 /// \brief Make a copy of a path.
1149 /// This function makes a copy of a path.
1150 template <typename From, typename To>
1151 void pathCopy(const From& from, To& to) {
1152 checkConcept<concepts::PathDumper<typename From::Digraph>, From>();
1153 _path_bits::PathCopySelector<From, To>::copy(from, to);
1156 /// \brief Deprecated version of \ref pathCopy().
1158 /// Deprecated version of \ref pathCopy() (only for reverse compatibility).
1159 template <typename To, typename From>
1160 void copyPath(To& to, const From& from) {
1164 /// \brief Check the consistency of a path.
1166 /// This function checks that the target of each arc is the same
1167 /// as the source of the next one.
1169 template <typename Digraph, typename Path>
1170 bool checkPath(const Digraph& digraph, const Path& path) {
1171 typename Path::ArcIt it(path);
1172 if (it == INVALID) return true;
1173 typename Digraph::Node node = digraph.target(it);
1175 while (it != INVALID) {
1176 if (digraph.source(it) != node) return false;
1177 node = digraph.target(it);
1183 /// \brief The source of a path
1185 /// This function returns the source node of the given path.
1186 /// If the path is empty, then it returns \c INVALID.
1187 template <typename Digraph, typename Path>
1188 typename Digraph::Node pathSource(const Digraph& digraph, const Path& path) {
1189 return path.empty() ? INVALID : digraph.source(path.front());
1192 /// \brief The target of a path
1194 /// This function returns the target node of the given path.
1195 /// If the path is empty, then it returns \c INVALID.
1196 template <typename Digraph, typename Path>
1197 typename Digraph::Node pathTarget(const Digraph& digraph, const Path& path) {
1198 return path.empty() ? INVALID : digraph.target(path.back());
1201 /// \brief Class for iterating through the nodes of a path
1203 /// Class for iterating through the nodes of a path.
1205 /// In a sense, a path can be treated as a list of arcs. The
1206 /// LEMON path type simply stores this list. As a consequence, it
1207 /// cannot enumerate the nodes in the path, and the source node of
1208 /// a zero-length path is undefined.
1210 /// However, this class implements a node iterator for path structures.
1211 /// To provide this feature, the underlying digraph should be passed to
1212 /// the constructor of the iterator.
1213 template <typename Path>
1216 const typename Path::Digraph *_digraph;
1217 typename Path::ArcIt _it;
1218 typename Path::Digraph::Node _nd;
1222 typedef typename Path::Digraph Digraph;
1223 typedef typename Digraph::Node Node;
1225 /// Default constructor
1227 /// Invalid constructor
1229 : _digraph(0), _it(INVALID), _nd(INVALID) {}
1231 PathNodeIt(const Digraph& digraph, const Path& path)
1232 : _digraph(&digraph), _it(path) {
1233 _nd = (_it != INVALID ? _digraph->source(_it) : INVALID);
1236 PathNodeIt(const Digraph& digraph, const Path& path, const Node& src)
1237 : _digraph(&digraph), _it(path), _nd(src) {}
1239 ///Conversion to Digraph::Node
1240 operator Node() const {
1245 PathNodeIt& operator++() {
1246 if (_it == INVALID) _nd = INVALID;
1248 _nd = _digraph->target(_it);
1254 /// Comparison operator
1255 bool operator==(const PathNodeIt& n) const {
1256 return _it == n._it && _nd == n._nd;
1258 /// Comparison operator
1259 bool operator!=(const PathNodeIt& n) const {
1260 return _it != n._it || _nd != n._nd;
1262 /// Comparison operator
1263 bool operator<(const PathNodeIt& n) const {
1264 return (_it < n._it && _nd != INVALID);
1269 /// \brief Gets the collection of the nodes of the path.
1271 /// This function can be used for iterating on the
1272 /// nodes of the path. It returns a wrapped
1273 /// PathNodeIt, which looks like an STL container
1274 /// (by having begin() and end()) which you can use in range-based
1275 /// for loops, STL algorithms, etc.
1276 /// For example you can write:
1278 /// for(auto u: pathNodes(g,p))
1281 template<typename Path>
1282 LemonRangeWrapper2<PathNodeIt<Path>, typename Path::Digraph, Path>
1283 pathNodes(const typename Path::Digraph &g, const Path &p) {
1285 LemonRangeWrapper2<PathNodeIt<Path>, typename Path::Digraph, Path>(g,p);
1290 } // namespace lemon
1292 #endif // LEMON_PATH_H