# HG changeset patch
# User Gabor Gevay <ggab90@gmail.com>
# Date 1390047445 -3600
# Sat Jan 18 13:17:25 2014 +0100
# Node ID fe4d0623659c53def73f443f989632de7ae96520
# Parent 7111be01ce588ac18d555c061a7b551ba470ab39
STL style iterators for paths.
diff --git a/contrib/stlit_test/stlit_test.cc b/contrib/stlit_test/stlit_test.cc
a
|
b
|
|
6 | 6 | #include <lemon/bits/stl_iterators.h> |
7 | 7 | #include <lemon/list_graph.h> |
8 | 8 | #include <lemon/smart_graph.h> |
| 9 | #include <lemon/path.h> |
| 10 | #include <lemon/bfs.h> |
9 | 11 | |
10 | 12 | |
11 | 13 | using namespace std; |
… |
… |
|
125 | 127 | for(auto u: g3.blueNodes()) |
126 | 128 | cout<<g3.id(u)<<endl; |
127 | 129 | |
| 130 | cout<<endl; |
| 131 | |
| 132 | { |
| 133 | SmartGraph g4; |
| 134 | auto u1 = g4.addNode(), u2 = g4.addNode(); |
| 135 | g4.addEdge(u1, u2); |
| 136 | Path<SmartGraph> p; |
| 137 | bfs(g4).path(p).run(u1,u2); |
| 138 | for(auto u: pathNodes(g4, p)) |
| 139 | cout<<g4.id(u)<<endl; |
| 140 | for(auto a: p.arcs()) |
| 141 | cout<<g4.id(g4.target(a))<<endl; |
| 142 | } |
| 143 | |
128 | 144 | return 0; |
129 | 145 | } |
diff --git a/lemon/concepts/path.h b/lemon/concepts/path.h
a
|
b
|
|
115 | 115 | |
116 | 116 | }; |
117 | 117 | |
| 118 | /// \brief Gets the collection of the arcs of the path. |
| 119 | /// |
| 120 | /// This function can be used for iterating on the |
| 121 | /// arcs of the path. It returns a wrapped |
| 122 | /// ArcIt, which looks like an STL container |
| 123 | /// (by having begin() and end()) which you can use in range-based |
| 124 | /// for loops, stl algorithms, etc. |
| 125 | /// For example you can write: |
| 126 | ///\code |
| 127 | /// for(auto a: p.arcs()) |
| 128 | /// doSomething(a); |
| 129 | ///\endcode |
| 130 | LemonRangeWrapper1<ArcIt, Path> arcs() const { |
| 131 | return LemonRangeWrapper1<ArcIt, Path>(*this); |
| 132 | } |
| 133 | |
| 134 | |
118 | 135 | template <typename _Path> |
119 | 136 | struct Constraints { |
120 | 137 | void constraints() { |
… |
… |
|
264 | 281 | |
265 | 282 | }; |
266 | 283 | |
| 284 | /// \brief Gets the collection of the arcs of the path. |
| 285 | /// |
| 286 | /// This function can be used for iterating on the |
| 287 | /// arcs of the path. It returns a wrapped |
| 288 | /// ArcIt, which looks like an STL container |
| 289 | /// (by having begin() and end()) which you can use in range-based |
| 290 | /// for loops, stl algorithms, etc. |
| 291 | /// For example you can write: |
| 292 | ///\code |
| 293 | /// for(auto a: p.arcs()) |
| 294 | /// doSomething(a); |
| 295 | ///\endcode |
| 296 | LemonRangeWrapper1<ArcIt, PathDumper> arcs() const { |
| 297 | return LemonRangeWrapper1<ArcIt, PathDumper>(*this); |
| 298 | } |
| 299 | |
| 300 | |
267 | 301 | /// \brief LEMON style iterator for enumerating the arcs of a path |
268 | 302 | /// in reverse direction. |
269 | 303 | /// |
… |
… |
|
293 | 327 | |
294 | 328 | }; |
295 | 329 | |
| 330 | /// \brief Gets the collection of the arcs of the path |
| 331 | /// in reverse direction. |
| 332 | /// |
| 333 | /// This function can be used for iterating on the |
| 334 | /// arcs of the path in reverse direction. It returns a wrapped |
| 335 | /// RevArcIt, which looks like an STL container |
| 336 | /// (by having begin() and end()) which you can use in range-based |
| 337 | /// for loops, stl algorithms, etc. |
| 338 | /// For example you can write: |
| 339 | ///\code |
| 340 | /// for(auto a: p.revArcs()) |
| 341 | /// doSomething(a); |
| 342 | ///\endcode |
| 343 | LemonRangeWrapper1<RevArcIt, PathDumper> revArcs() const { |
| 344 | return LemonRangeWrapper1<RevArcIt, PathDumper>(*this); |
| 345 | } |
| 346 | |
| 347 | |
296 | 348 | template <typename _Path> |
297 | 349 | struct Constraints { |
298 | 350 | void constraints() { |
diff --git a/lemon/path.h b/lemon/path.h
a
|
b
|
|
140 | 140 | int idx; |
141 | 141 | }; |
142 | 142 | |
| 143 | /// \brief Gets the collection of the arcs of the path. |
| 144 | /// |
| 145 | /// This function can be used for iterating on the |
| 146 | /// arcs of the path. It returns a wrapped |
| 147 | /// ArcIt, which looks like an STL container |
| 148 | /// (by having begin() and end()) which you can use in range-based |
| 149 | /// for loops, stl algorithms, etc. |
| 150 | /// For example you can write: |
| 151 | ///\code |
| 152 | /// for(auto a: p.arcs()) |
| 153 | /// doSomething(a); |
| 154 | ///\endcode |
| 155 | LemonRangeWrapper1<ArcIt, Path> arcs() const { |
| 156 | return LemonRangeWrapper1<ArcIt, Path>(*this); |
| 157 | } |
| 158 | |
| 159 | |
143 | 160 | /// \brief Length of the path. |
144 | 161 | int length() const { return head.size() + tail.size(); } |
145 | 162 | /// \brief Return whether the path is empty. |
… |
… |
|
345 | 362 | int idx; |
346 | 363 | }; |
347 | 364 | |
| 365 | /// \brief Gets the collection of the arcs of the path. |
| 366 | /// |
| 367 | /// This function can be used for iterating on the |
| 368 | /// arcs of the path. It returns a wrapped |
| 369 | /// ArcIt, which looks like an STL container |
| 370 | /// (by having begin() and end()) which you can use in range-based |
| 371 | /// for loops, stl algorithms, etc. |
| 372 | /// For example you can write: |
| 373 | ///\code |
| 374 | /// for(auto a: p.arcs()) |
| 375 | /// doSomething(a); |
| 376 | ///\endcode |
| 377 | LemonRangeWrapper1<ArcIt, SimplePath> arcs() const { |
| 378 | return LemonRangeWrapper1<ArcIt, SimplePath>(*this); |
| 379 | } |
| 380 | |
| 381 | |
348 | 382 | /// \brief Length of the path. |
349 | 383 | int length() const { return data.size(); } |
350 | 384 | /// \brief Return true if the path is empty. |
… |
… |
|
543 | 577 | Node *node; |
544 | 578 | }; |
545 | 579 | |
| 580 | /// \brief Gets the collection of the arcs of the path. |
| 581 | /// |
| 582 | /// This function can be used for iterating on the |
| 583 | /// arcs of the path. It returns a wrapped |
| 584 | /// ArcIt, which looks like an STL container |
| 585 | /// (by having begin() and end()) which you can use in range-based |
| 586 | /// for loops, stl algorithms, etc. |
| 587 | /// For example you can write: |
| 588 | ///\code |
| 589 | /// for(auto a: p.arcs()) |
| 590 | /// doSomething(a); |
| 591 | ///\endcode |
| 592 | LemonRangeWrapper1<ArcIt, ListPath> arcs() const { |
| 593 | return LemonRangeWrapper1<ArcIt, ListPath>(*this); |
| 594 | } |
| 595 | |
| 596 | |
546 | 597 | /// \brief The n-th arc. |
547 | 598 | /// |
548 | 599 | /// This function looks for the n-th arc in O(n) time. |
… |
… |
|
795 | 846 | /// \brief Default constructor |
796 | 847 | /// |
797 | 848 | /// Default constructor |
798 | | StaticPath() : len(0), arcs(0) {} |
| 849 | StaticPath() : len(0), _arcs(0) {} |
799 | 850 | |
800 | 851 | /// \brief Copy constructor |
801 | 852 | /// |
802 | | StaticPath(const StaticPath& cpath) : arcs(0) { |
| 853 | StaticPath(const StaticPath& cpath) : _arcs(0) { |
803 | 854 | pathCopy(cpath, *this); |
804 | 855 | } |
805 | 856 | |
… |
… |
|
807 | 858 | /// |
808 | 859 | /// This path can be initialized from any other path type. |
809 | 860 | template <typename CPath> |
810 | | StaticPath(const CPath& cpath) : arcs(0) { |
| 861 | StaticPath(const CPath& cpath) : _arcs(0) { |
811 | 862 | pathCopy(cpath, *this); |
812 | 863 | } |
813 | 864 | |
… |
… |
|
815 | 866 | /// |
816 | 867 | /// Destructor of the path |
817 | 868 | ~StaticPath() { |
818 | | if (arcs) delete[] arcs; |
| 869 | if (_arcs) delete[] _arcs; |
819 | 870 | } |
820 | 871 | |
821 | 872 | /// \brief Copy assignment |
… |
… |
|
882 | 933 | const StaticPath *path; |
883 | 934 | int idx; |
884 | 935 | }; |
| 936 | |
| 937 | /// \brief Gets the collection of the arcs of the path. |
| 938 | /// |
| 939 | /// This function can be used for iterating on the |
| 940 | /// arcs of the path. It returns a wrapped |
| 941 | /// ArcIt, which looks like an STL container |
| 942 | /// (by having begin() and end()) which you can use in range-based |
| 943 | /// for loops, stl algorithms, etc. |
| 944 | /// For example you can write: |
| 945 | ///\code |
| 946 | /// for(auto a: p.arcs()) |
| 947 | /// doSomething(a); |
| 948 | ///\endcode |
| 949 | LemonRangeWrapper1<ArcIt, StaticPath> arcs() const { |
| 950 | return LemonRangeWrapper1<ArcIt, StaticPath>(*this); |
| 951 | } |
| 952 | |
885 | 953 | |
886 | 954 | /// \brief The n-th arc. |
887 | 955 | /// |
888 | 956 | /// \pre \c n is in the <tt>[0..length() - 1]</tt> range. |
889 | 957 | const Arc& nth(int n) const { |
890 | | return arcs[n]; |
| 958 | return _arcs[n]; |
891 | 959 | } |
892 | 960 | |
893 | 961 | /// \brief The arc iterator pointing to the n-th arc. |
… |
… |
|
904 | 972 | /// \brief Erase all arcs in the digraph. |
905 | 973 | void clear() { |
906 | 974 | len = 0; |
907 | | if (arcs) delete[] arcs; |
908 | | arcs = 0; |
| 975 | if (_arcs) delete[] _arcs; |
| 976 | _arcs = 0; |
909 | 977 | } |
910 | 978 | |
911 | 979 | /// \brief The first arc of the path. |
912 | 980 | const Arc& front() const { |
913 | | return arcs[0]; |
| 981 | return _arcs[0]; |
914 | 982 | } |
915 | 983 | |
916 | 984 | /// \brief The last arc of the path. |
917 | 985 | const Arc& back() const { |
918 | | return arcs[len - 1]; |
| 986 | return _arcs[len - 1]; |
919 | 987 | } |
920 | 988 | |
921 | 989 | |
… |
… |
|
924 | 992 | template <typename CPath> |
925 | 993 | void build(const CPath& path) { |
926 | 994 | len = path.length(); |
927 | | arcs = new Arc[len]; |
| 995 | _arcs = new Arc[len]; |
928 | 996 | int index = 0; |
929 | 997 | for (typename CPath::ArcIt it(path); it != INVALID; ++it) { |
930 | | arcs[index] = it; |
| 998 | _arcs[index] = it; |
931 | 999 | ++index; |
932 | 1000 | } |
933 | 1001 | } |
… |
… |
|
935 | 1003 | template <typename CPath> |
936 | 1004 | void buildRev(const CPath& path) { |
937 | 1005 | len = path.length(); |
938 | | arcs = new Arc[len]; |
| 1006 | _arcs = new Arc[len]; |
939 | 1007 | int index = len; |
940 | 1008 | for (typename CPath::RevArcIt it(path); it != INVALID; ++it) { |
941 | 1009 | --index; |
942 | | arcs[index] = it; |
| 1010 | _arcs[index] = it; |
943 | 1011 | } |
944 | 1012 | } |
945 | 1013 | |
946 | 1014 | private: |
947 | 1015 | int len; |
948 | | Arc* arcs; |
| 1016 | Arc* _arcs; |
949 | 1017 | }; |
950 | 1018 | |
951 | 1019 | /////////////////////////////////////////////////////////////////////// |
… |
… |
|
1157 | 1225 | |
1158 | 1226 | }; |
1159 | 1227 | |
| 1228 | /// \brief Gets the collection of the nodes of the path. |
| 1229 | /// |
| 1230 | /// This function can be used for iterating on the |
| 1231 | /// nodes of the path. It returns a wrapped |
| 1232 | /// PathNodeIt, which looks like an STL container |
| 1233 | /// (by having begin() and end()) which you can use in range-based |
| 1234 | /// for loops, stl algorithms, etc. |
| 1235 | /// For example you can write: |
| 1236 | ///\code |
| 1237 | /// for(auto u: pathNodes(g,p)) |
| 1238 | /// doSomething(u); |
| 1239 | ///\endcode |
| 1240 | template<typename Path> |
| 1241 | LemonRangeWrapper2<PathNodeIt<Path>, typename Path::Digraph, Path> |
| 1242 | pathNodes(const typename Path::Digraph &g, const Path &p) { |
| 1243 | return |
| 1244 | LemonRangeWrapper2<PathNodeIt<Path>, typename Path::Digraph, Path>(g,p); |
| 1245 | } |
| 1246 | |
1160 | 1247 | ///@} |
1161 | 1248 | |
1162 | 1249 | } // namespace lemon |