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; |
---|
59 | It _begin; |
---|
60 | |
---|
61 | public: |
---|
62 | LemonRangeWrapper1(const P &p) : _begin(LIT(p)) {} |
---|
63 | It begin() const { |
---|
64 | return _begin; |
---|
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 { |
---|
84 | typedef LemonItWrapper<LIT> It; |
---|
85 | It _begin; |
---|
86 | public: |
---|
87 | LemonRangeWrapper2(const P1 &p1, const P2 &p2) : _begin(LIT(p1, p2)) {} |
---|
88 | It begin() const { |
---|
89 | return _begin; |
---|
90 | } |
---|
91 | It end() const { |
---|
92 | return It(lemon::INVALID); |
---|
93 | } |
---|
94 | }; |
---|
95 | |
---|
96 | |
---|
97 | } |
---|
98 | |
---|
99 | #endif /* STL_ITERATORS_H_ */ |
---|