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  * <http://shark-ml.org/>
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>
40 namespace 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
45 template<class Iterator>
46 class 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 {
53 public:
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  }
70 private:
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
116 template<class Sequence, class ValueType, class Reference>
117 class 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 >{
124 public:
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 
134 private:
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 
166 template<class Container>
167 class 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 >{
177 private:
178  template<class> friend class IndexingIterator;
179 public:
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 
187 private:
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