Line data Source code
1 :
2 : /* Copyright (c) 2011-2014, Stefan.Eilemann@epfl.ch
3 : *
4 : * This file is part of Lunchbox <https://github.com/Eyescale/Lunchbox>
5 : *
6 : * This library is free software; you can redistribute it and/or modify it under
7 : * the terms of the GNU Lesser General Public License version 3.0 as published
8 : * by the Free Software Foundation.
9 : *
10 : * This library is distributed in the hope that it will be useful, but WITHOUT
11 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 : * details.
14 : *
15 : * You should have received a copy of the GNU Lesser General Public License
16 : * along with this library; if not, write to the Free Software Foundation, Inc.,
17 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 : */
19 :
20 : #ifndef LUNCHBOX_INDEXITERATOR_H
21 : #define LUNCHBOX_INDEXITERATOR_H
22 :
23 : namespace lunchbox
24 : {
25 :
26 : /**
27 : * Counter-based, as opposed to pointer-based, iterator for any container.
28 : *
29 : * Uses curiously recurring template pattern to return proper type from
30 : * assignment and other operators. Access methods are to be implemented by a
31 : * subclass using container_ and i_. Furthermore subclasses need to implement
32 : * the necessary constructors (see LFVectorIterator for example).
33 : *
34 : * @param S CRTP Subclass type
35 : * @param C The container type
36 : * @param T The element type
37 : */
38 : template< class S, class C, class T > class IndexIterator
39 : : public std::iterator< std::random_access_iterator_tag, T >
40 : {
41 : public:
42 : /** Construct an iterator for a given container and position. @version 1.8*/
43 2002281 : IndexIterator( C* container, const size_t i )
44 2002281 : : container_( container ), i_(i) {}
45 :
46 : /** Copy-construct an iterator. @version 1.8 */
47 : explicit IndexIterator( const S& from )
48 : : container_( from.container_ ), i_( from.i_ ) {}
49 :
50 : /** Copy-construct an iterator. @version 1.8 */
51 : template< class U, class V, class W >
52 2000002 : IndexIterator( const IndexIterator< U, V, W >& from )
53 2000002 : : container_( from.container_ ), i_( from.i_ ) {}
54 :
55 : /** Assign the container and position from another iterator. @version 1.8 */
56 : // cppcheck-suppress operatorEq
57 3 : S& operator = ( const IndexIterator& rhs )
58 : {
59 3 : container_ = rhs.container_;
60 3 : i_ = rhs.i_;
61 3 : return *static_cast< S* >( this );
62 : }
63 :
64 : /** Assign the container and position from another iterator. @version 1.8 */
65 : template< class U, class W >
66 : S& operator = ( const IndexIterator< S, U, W >& rhs )
67 : {
68 : container_ = rhs.container_;
69 : i_ = rhs.i_;
70 : return *static_cast< S* >( this );
71 : }
72 :
73 : /** Increment the iterator position. @version 1.8 */
74 79600866 : S& operator ++() { ++i_; return *static_cast< S* >( this ); }
75 :
76 : /** Decrement the iterator position. @version 1.8 */
77 : S& operator --() { --i_; return *static_cast< S* >( this ); }
78 :
79 : /** Increment the iterator position. @version 1.8 */
80 : S operator ++ (int) { return S( container_, i_++ ); }
81 :
82 : /** Decrement the iterator position. @version 1.8 */
83 : S operator -- (int) { return S( container_, i_-- ); }
84 :
85 : /** Increment the iterator position by a given amount. @version 1.8 */
86 1139 : S operator + ( const size_t& n ) const
87 1139 : { return S( container_, i_+n ); }
88 :
89 : /** Increment the iterator position by a given amount. @version 1.8 */
90 : S& operator += ( const size_t& n )
91 : { i_ += n; return *static_cast< S* >( this ); }
92 :
93 : /** Decrement the iterator position by a given amount. @version 1.8 */
94 : S operator - ( const size_t& n ) const
95 : { return S( container_, i_-n ); }
96 :
97 : /** Decrement the iterator position by a given amount. @version 1.8 */
98 : S& operator -= ( const size_t& n )
99 : { i_ -= n; return *static_cast< S* >( this ); }
100 :
101 : /** Compute the distance between this and another iterator. @version 1.8 */
102 380 : ssize_t operator- ( const S& n ) const { return i_ - n.i_; }
103 :
104 : /** @return true if both iterators are equal. @version 1.8 */
105 2000379 : bool operator == ( const S& rhs ) const
106 2000379 : { return container_ == rhs.container_ && i_ == rhs.i_; }
107 :
108 : /** @return true if both iterators are not equal. @version 1.8 */
109 379 : bool operator != ( const S& rhs ) const
110 379 : { return container_ != rhs.container_ || i_ != rhs.i_; }
111 :
112 : /** @return true if this iterator is before the given one. @version 1.8 */
113 : bool operator < ( const S& rhs ) const
114 : { return container_ <= rhs.container_ && i_ < rhs.i_; }
115 :
116 : /** @return true if this iterator is after the given one. @version 1.8 */
117 : bool operator > ( const S& rhs ) const
118 : { return container_ >= rhs.container_ && i_ > rhs.i_; }
119 :
120 : /**
121 : * @return true if this iterator is before or equal to the given one.
122 : * @version 1.8
123 : */
124 : bool operator <= ( const S& rhs ) const
125 : { return container_ <= rhs.container_ && i_ <= rhs.i_; }
126 :
127 : /**
128 : * @return true if this iterator is after or equal to the given one.
129 : * @version 1.8
130 : */
131 : bool operator >= ( const S& rhs ) const
132 : { return container_ >= rhs.container_ && i_ >= rhs.i_; }
133 :
134 : /** @return the position of this iterator. @version 1.8 */
135 0 : size_t getPosition() const { return i_; }
136 :
137 : protected:
138 : C* container_;
139 : size_t i_;
140 :
141 : // template copy ctor
142 : template< class, class, class > friend class IndexIterator;
143 :
144 : private:
145 : IndexIterator();
146 : };
147 :
148 : }
149 :
150 : #endif // LUNCHBOX_INDEXITERATOR_H
|