|
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 const P &_p; |
|
59 typedef LemonItWrapper<LIT> It; |
|
60 public: |
|
61 LemonRangeWrapper1(const P &p) : _p(p) {} |
|
62 It begin() const { |
|
63 return It(LIT(_p)); |
|
64 } |
|
65 It end() const { |
|
66 return It(lemon::INVALID); |
|
67 } |
|
68 }; |
|
69 |
|
70 |
|
71 /// \brief A generic wrapper for Lemon iterators for range-based for loops. |
|
72 /// |
|
73 /// This template can be used to create a class |
|
74 /// that has begin() and end() from a Lemon iterator |
|
75 /// (with a 2-parameter constructor) |
|
76 /// to make range-based for loops and STL algorithms work. |
|
77 /// |
|
78 /// \c LIT is the Lemon iterator that will be wrapped |
|
79 /// \c P1 and \c P2 are the types of the parameters |
|
80 /// of the constructor of \c LIT. |
|
81 template<class LIT, class P1, class P2> |
|
82 class LemonRangeWrapper2 { |
|
83 const P1 &_p1; |
|
84 const P2 &_p2; |
|
85 typedef LemonItWrapper<LIT> It; |
|
86 public: |
|
87 LemonRangeWrapper2(const P1 &p1, const P2 &p2) : _p1(p1), _p2(p2) {} |
|
88 It begin() const { |
|
89 return It(LIT(_p1, _p2)); |
|
90 } |
|
91 It end() const { |
|
92 return It(lemon::INVALID); |
|
93 } |
|
94 }; |
|
95 |
|
96 |
|
97 } |
|
98 |
|
99 #endif /* STL_ITERATORS_H_ */ |