Iterators.h
Go to the documentation of this file.
1/*!
2 *
3 *
4 * \brief Small Iterator collection.
5 *
6 *
7 *
8 *
9 * \author Oswin Krause
10 * \date 2012
11 *
12 *
13 * \par Copyright 1995-2017 Shark Development Team
14 *
15 * <BR><HR>
16 * This file is part of Shark.
17 * <https://shark-ml.github.io/Shark/>
18 *
19 * Shark is free software: you can redistribute it and/or modify
20 * it under the terms of the GNU Lesser General Public License as published
21 * by the Free Software Foundation, either version 3 of the License, or
22 * (at your option) any later version.
23 *
24 * Shark is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU Lesser General Public License for more details.
28 *
29 * You should have received a copy of the GNU Lesser General Public License
30 * along with Shark. If not, see <http://www.gnu.org/licenses/>.
31 *
32 */
33#ifndef SHARK_CORE_ITERATORS_H
34#define SHARK_CORE_ITERATORS_H
35
36#include <boost/version.hpp>
37#include "Impl/boost_iterator_facade_fixed.hpp"//thanks, boost.
38
39#include <boost/range/iterator.hpp>
40namespace shark{
41
42///\brief creates an Indexed Iterator, an Iterator which also carries index information using index()
43///
44///The underlying Iterator must be a random access iterator
45template<class Iterator>
46class IndexedIterator: public SHARK_ITERATOR_FACADE<
47 IndexedIterator<Iterator>,
48 typename boost::iterator_value<Iterator>::type,
49 std::random_access_iterator_tag,
50 typename boost::iterator_reference<Iterator>::type
51>
52{
53public:
55 :m_index(0){}
56
57 ///\brief Copy-Constructs this iterator from some other IndexedIterator convertible to this.
58 template<class I>
60 : m_iterator(iterator.m_iterator),m_index(iterator.index){}
61
62 ///\brief Constructs the iterator from another iterator plus a starting index.
63 template<class IteratorT>
64 IndexedIterator(IteratorT const& iterator, std::size_t startIndex)
65 : m_iterator(Iterator(iterator)),m_index(startIndex){}
66
67 std::size_t index()const{
68 return m_index;
69 }
70private:
71 typedef SHARK_ITERATOR_FACADE<
73 typename boost::iterator_value<Iterator>::type,
74 boost::random_access_traversal_tag,
75 typename boost::iterator_reference<Iterator>::type
76 > base_type;
77
79
80 typename base_type::reference dereference() const {
81 return *m_iterator;
82 }
83
84 void increment() {
85 ++m_index;
86 ++m_iterator;
87 }
88 void decrement() {
89 --m_index;
90 --m_iterator;
91 }
92
93 void advance(std::ptrdiff_t n){
94 m_index += n;
95 m_iterator += n;
96 }
97
98 template<class I>
99 std::ptrdiff_t distance_to(IndexedIterator<I> const& other) const{
100 return other.m_iterator - m_iterator;
101 }
102
103 template<class I>
104 bool equal(IndexedIterator<I> const& other) const{
105 return m_iterator == other.m_iterator;
106 }
107
108 Iterator m_iterator;
109 std::size_t m_index;
110};
111
112/// \brief Creates an iterator which reinterpretes an object as a range
113///
114/// The second template argument represents the elements by the proxy reference type. it must offer
115/// a constructor Reference(sequence,i) which constructs a reference to the i-th proxy-element
116template<class Sequence, class ValueType, class Reference>
117class ProxyIterator: public SHARK_ITERATOR_FACADE<
118 ProxyIterator<Sequence,ValueType,Reference>,
119 ValueType,
120 //boost::random_access_traversal_tag,
121 std::random_access_iterator_tag,//keep VC quiet.
122 Reference
123>{
124public:
125 ProxyIterator() : m_position(0) {}
126
127 ProxyIterator(Sequence& seq, std::size_t position)
128 : m_sequence(&seq),m_position(position) {}
129
130 template<class S, class V, class R>
132 : m_sequence(other.m_sequence),m_position(other.m_position) {}
133
134private:
136 template <class,class,class> friend class ProxyIterator;
137
138 void increment() {
139 ++m_position;
140 }
141 void decrement() {
142 --m_position;
143 }
144
145 void advance(std::ptrdiff_t n){
146 m_position += n;
147 }
148
149 template<class Iter>
150 std::ptrdiff_t distance_to(const Iter& other) const{
151 return (std::ptrdiff_t)other.m_position - (std::ptrdiff_t)m_position;
152 }
153
154 template<class Iter>
155 bool equal(Iter const& other) const{
156 return (m_position == other.m_position);
157 }
158 Reference dereference() const {
159 return Reference(*m_sequence,m_position);
160 }
161
162 Sequence* m_sequence;
163 std::size_t m_position;
164};
165
166template<class Container>
167class IndexingIterator: public SHARK_ITERATOR_FACADE<
168 IndexingIterator<Container>,
169 typename Container::value_type,
170 std::random_access_iterator_tag,
171 typename boost::mpl::if_<
172 std::is_const<Container>,
173 typename Container::const_reference,
174 typename Container::reference
175 >::type
176>{
177private:
178 template<class> friend class IndexingIterator;
179public:
181 IndexingIterator(Container& container, std::size_t pos):m_container(&container), m_index(std::ptrdiff_t(pos)){}
182
183 template<class C>
185 : m_container(iterator.m_container){}
186
187private:
189
190 void increment() {
191 ++m_index;
192 }
193 void decrement() {
194 --m_index;
195 }
196
197 void advance(std::ptrdiff_t n){
198 m_index += n;
199 }
200
201 template<class C>
202 std::ptrdiff_t distance_to(IndexingIterator<C> const& other) const{
203 return other.m_index - m_index;
204 }
205
206 template<class C>
207 bool equal(IndexingIterator<C> const& other) const{
208 return m_index == other.m_index;
209 }
210 typename IndexingIterator::reference dereference() const {
211 return (*m_container)[m_index];
212 }
213
214 Container* m_container;
215 std::ptrdiff_t m_index;
216};
217
218}
219#endif