# 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 |