[1336] | 1 | /* -*- mode: C++; indent-tabs-mode: nil; -*- |
---|
| 2 | */ |
---|
| 3 | |
---|
| 4 | #ifndef STL_ITERATORS_H_ |
---|
| 5 | #define STL_ITERATORS_H_ |
---|
| 6 | |
---|
| 7 | #include <lemon/core.h> |
---|
| 8 | |
---|
| 9 | namespace lemon { |
---|
| 10 | |
---|
| 11 | /// \brief Template to make STL iterators from Lemon iterators. |
---|
| 12 | /// |
---|
| 13 | /// This template makes an STL iterator from a Lemon iterator |
---|
| 14 | /// by adding the missing features. |
---|
| 15 | /// It inherits from \c std::iterator to make \c iterator_concept work |
---|
| 16 | /// (so that STL algorithms work). |
---|
| 17 | /// \c T should be the lemon iterator to be decorated. |
---|
| 18 | template<class T> |
---|
| 19 | struct LemonItWrapper |
---|
| 20 | : public T, public std::iterator<std::input_iterator_tag, T> { |
---|
| 21 | |
---|
| 22 | LemonItWrapper(const T &x) : T(x) {} |
---|
| 23 | |
---|
| 24 | //Lemon iterators don't have operator*, (because they rather |
---|
| 25 | //inherit from their "value_type"), |
---|
| 26 | //so we add one that just returns the object. |
---|
| 27 | const T& operator*() const { |
---|
| 28 | return static_cast<const T&>(*this); |
---|
| 29 | } |
---|
| 30 | |
---|
| 31 | //I can't think of any use case for this with Lemon iterators, |
---|
| 32 | //but maybe it should be included for completeness. |
---|
| 33 | const T* operator->() { |
---|
| 34 | return static_cast<const T*>(this); |
---|
| 35 | } |
---|
| 36 | |
---|
| 37 | //Lemon iterators don't have postincrement. |
---|
| 38 | void operator++(int) { |
---|
| 39 | T::operator++(); |
---|
| 40 | } |
---|
| 41 | |
---|
| 42 | using T::operator++; |
---|
| 43 | |
---|
| 44 | }; |
---|
| 45 | |
---|
| 46 | |
---|
| 47 | /// \brief A generic wrapper for Lemon iterators for range-based for loops. |
---|
| 48 | /// |
---|
| 49 | /// This template can be used to create a class |
---|
| 50 | /// that has begin() and end() from a Lemon iterator |
---|
| 51 | /// (with a 1-parameter constructor) |
---|
| 52 | /// to make range-based for loops and STL algorithms work. |
---|
| 53 | /// |
---|
| 54 | /// \c LIT is the Lemon iterator that will be wrapped |
---|
| 55 | /// \c P is the type of the parameter of the constructor of \c LIT. |
---|
| 56 | template<class LIT, class P> |
---|
| 57 | class LemonRangeWrapper1 { |
---|
| 58 | typedef LemonItWrapper<LIT> It; |
---|
[1339] | 59 | It _begin; |
---|
| 60 | |
---|
[1336] | 61 | public: |
---|
[1339] | 62 | LemonRangeWrapper1(const P &p) : _begin(LIT(p)) {} |
---|
[1336] | 63 | It begin() const { |
---|
[1339] | 64 | return _begin; |
---|
[1336] | 65 | } |
---|
| 66 | It end() const { |
---|
| 67 | return It(lemon::INVALID); |
---|
| 68 | } |
---|
| 69 | }; |
---|
| 70 | |
---|
| 71 | |
---|
| 72 | /// \brief A generic wrapper for Lemon iterators for range-based for loops. |
---|
| 73 | /// |
---|
| 74 | /// This template can be used to create a class |
---|
| 75 | /// that has begin() and end() from a Lemon iterator |
---|
| 76 | /// (with a 2-parameter constructor) |
---|
| 77 | /// to make range-based for loops and STL algorithms work. |
---|
| 78 | /// |
---|
| 79 | /// \c LIT is the Lemon iterator that will be wrapped |
---|
| 80 | /// \c P1 and \c P2 are the types of the parameters |
---|
| 81 | /// of the constructor of \c LIT. |
---|
| 82 | template<class LIT, class P1, class P2> |
---|
| 83 | class LemonRangeWrapper2 { |
---|
[1339] | 84 | typedef LemonItWrapper<LIT> It; |
---|
| 85 | It _begin; |
---|
| 86 | public: |
---|
| 87 | LemonRangeWrapper2(const P1 &p1, const P2 &p2) : _begin(LIT(p1, p2)) {} |
---|
[1336] | 88 | It begin() const { |
---|
[1339] | 89 | return _begin; |
---|
[1336] | 90 | } |
---|
| 91 | It end() const { |
---|
| 92 | return It(lemon::INVALID); |
---|
| 93 | } |
---|
| 94 | }; |
---|
| 95 | |
---|
| 96 | |
---|
| 97 | } |
---|
| 98 | |
---|
| 99 | #endif /* STL_ITERATORS_H_ */ |
---|