OpenMPCD
StridedPointerIterator.hpp
Go to the documentation of this file.
1 /**
2  * @file
3  * Defines the OpenMPCD::StridedPointerIterator class.
4  */
5 
6 #ifndef OPENMPCD_STRIDEDPOINTERITERATOR_HPP
7 #define OPENMPCD_STRIDEDPOINTERITERATOR_HPP
8 
10 #include <OpenMPCD/Exceptions.hpp>
11 
12 #include <boost/static_assert.hpp>
13 #include <iterator>
14 
15 namespace OpenMPCD
16 {
17  /**
18  * Wraps a pointer in such a way that incrementing this iterator is equivalent to
19  * incrementing the underlying pointer once or more times, depending on the stride specified.
20  * @tparam Pointee The type the underlying pointer points at.
21  * @tparam stride The iteration stride, which must not be 0.
22  */
23  template<typename Pointee, unsigned int stride> class StridedPointerIterator
24  {
25  BOOST_STATIC_ASSERT(stride != 0);
26 
27  public:
28  /**
29  * The default constructor.
30  * The constructed instance is singular.
31  */
33  StridedPointerIterator() : current(NULL), pastEnd(NULL)
34  {
35  }
36 
37  /**
38  * The constructor.
39  * @param[in] start The first element to iterate over.
40  * @param[in] pastEnd_ The first element that is past the end of the array to iterate over.
41  */
43  StridedPointerIterator(Pointee* const start, const Pointee* const pastEnd_) : current(start), pastEnd(pastEnd_)
44  {
45  }
46 
47  /**
48  * The copy constructor.
49  * @param[in] rhs The right-hand-side instance.
50  */
53  : current(rhs.current), pastEnd(rhs.pastEnd)
54  {
55  }
56 
57  public:
58  /**
59  * Returns whether this instance is singular, i.e. invalid.
60  */
62  bool isSingular() const
63  {
64  return current==NULL;
65  }
66 
67  /**
68  * Returns whether this iterator is past-the-end.
69  * @throw InvalidCallException Throws if <c>isSingular()</c>.
70  */
72  bool isPastTheEnd() const
73  {
74  #ifndef __CUDA_ARCH__
75  if(isSingular())
76  OPENMPCD_THROW(InvalidCallException, "isPastTheEnd()");
77  #endif
78 
79  return current == pastEnd;
80  }
81 
82  /**
83  * Returns whether this instance can be dereferenced.
84  */
86  bool isDereferenceable() const
87  {
88  if(isSingular())
89  return false;
90 
91  if(isPastTheEnd())
92  return false;
93 
94  return true;
95  }
96 
97  /**
98  * Returns whether this instance is valid.
99  */
101  bool isValid() const
102  {
103  return isDereferenceable() || isPastTheEnd();
104  }
105 
106  /**
107  * Returns whether this instance is incrementable.
108  */
110  bool isIncrementable() const
111  {
112  if(isSingular())
113  return false;
114 
115  if(isPastTheEnd())
116  return false;
117 
118  return true;
119  }
120 
121  public:
122  /**
123  * Dereferencing operator.
124  * @throw InvalidCallException Throws if <c>!isDereferenceable()</c>.
125  */
127  Pointee& operator*()
128  {
129  #ifndef __CUDA_ARCH__
130  if(!isDereferenceable())
131  OPENMPCD_THROW(InvalidCallException, "operator*");
132  #endif
133 
134  return *current;
135  }
136 
137  /**
138  * Dereferencing operator.
139  * @throw InvalidCallException Throws if <c>!isDereferenceable()</c>.
140  */
142  const Pointee& operator*() const
143  {
144  #ifndef __CUDA_ARCH__
145  if(!isDereferenceable())
146  OPENMPCD_THROW(InvalidCallException, "operator*");
147  #endif
148 
149  return current;
150  }
151 
152  /**
153  * Member access operator.
154  * @throw InvalidCallException Throws if <c>!isDereferenceable()</c>.
155  */
157  Pointee* operator->()
158  {
159  #ifndef __CUDA_ARCH__
160  if(!isDereferenceable())
161  OPENMPCD_THROW(InvalidCallException, "operator->");
162  #endif
163 
164  return current;
165  }
166 
167  /**
168  * Member access operator.
169  * @throw InvalidCallException Throws if <c>!isDereferenceable()</c>.
170  */
172  const Pointee* operator->() const
173  {
174  #ifndef __CUDA_ARCH__
175  if(!isDereferenceable())
176  OPENMPCD_THROW(InvalidCallException, "operator->");
177  #endif
178 
179  return current;
180  }
181 
182  /**
183  * The prefix increment operator.
184  * @throw InvalidCallException Throws if <c>!isDereferenceable()</c>.
185  */
188  {
189  #ifndef __CUDA_ARCH__
190  if(!isDereferenceable())
191  OPENMPCD_THROW(InvalidCallException, "operator++");
192  #endif
193 
194  for(unsigned int i=0; i<stride; ++i)
195  {
196  ++current;
197 
198  if(current==pastEnd)
199  break;
200  }
201 
202  return *this;
203  }
204 
205  /**
206  * The postfix increment operator.
207  * @throw InvalidCallException Throws if <c>!isDereferenceable()</c>.
208  */
211  {
212  #ifndef __CUDA_ARCH__
213  if(!isDereferenceable())
214  OPENMPCD_THROW(InvalidCallException, "operator++");
215  #endif
216 
217  StridedPointerIterator ret=*this;
218 
219  for(unsigned int i=0; i<stride; ++i)
220  {
221  ++current;
222 
223  if(current==pastEnd)
224  break;
225  }
226 
227  return ret;
228  }
229 
230  /**
231  * Advances the pointer n times, or until the past-the-end iterator is reached, whichever comes first.
232  * @param[in] n The number of times to advance the pointer.
233  */
235  const StridedPointerIterator& operator+=(const unsigned int n)
236  {
237  for(unsigned int i=0; i<n; ++i)
238  {
239  operator++();
240 
241  if(isPastTheEnd())
242  break;
243  }
244 
245  return *this;
246  }
247 
248  /**
249  * Returns whether the address this instance and rhs point to the same memory.
250  * This function does not consider whether both this instance and rhs have the same iteration range.
251  * @param[in] rhs The right-hand-side instance.
252  * @throw InvalidCallException Throws if <c>!isValid()</c>.
253  */
255  bool operator==(const StridedPointerIterator& rhs) const
256  {
257  #ifndef __CUDA_ARCH__
258  if(!isValid())
259  OPENMPCD_THROW(InvalidCallException, "operator==");
260  #endif
261 
262  return current == rhs.current;
263  }
264 
265  /**
266  * Returns whether the address this instance and rhs point to different memory.
267  * This function does not consider whether both this instance and rhs have the same iteration range.
268  * @param[in] rhs The right-hand-side instance.
269  * @throw InvalidCallException Throws if <c>!isValid()</c>.
270  */
272  bool operator!=(const StridedPointerIterator& rhs) const
273  {
274  #ifndef __CUDA_ARCH__
275  if(!isValid())
276  OPENMPCD_THROW(InvalidCallException, "operator!=");
277  #endif
278 
279  return current != rhs.current;
280  }
281 
282  private:
283  Pointee* current; ///< The element this iterator points at.
284  const Pointee* pastEnd; ///< A pointer that points one element past the end of the array to iterate over.
285  };
286 }
287 
288 namespace std
289 {
290  /**
291  * Specialisation of the std::iterator_traits template for StridedPointerIterator.
292  * @tparam Pointee The type the underlying pointer points at.
293  * @tparam stride The iteration stride, which must not be 0.
294  */
295  template<typename Pointee, unsigned int stride>
296  struct iterator_traits<OpenMPCD::StridedPointerIterator<Pointee, stride> >
297  {
298  typedef std::ptrdiff_t difference_type; ///< Type for distance between iterators.
299 
300  typedef Pointee value_type; ///< Type iterated over.
301  typedef value_type* pointer; ///< Pointer to the type iterated over.
302  typedef value_type& reference; ///< Reference to the type iterated over.
303 
304  typedef std::input_iterator_tag iterator_category; ///< Specifies the iterator category.
305  };
306 }
307 
308 #endif
OpenMPCD::InvalidCallException
Exception for a forbidden function call.
Definition: Exceptions.hpp:144
Exceptions.hpp
OPENMPCD_THROW
#define OPENMPCD_THROW(ExceptionType, message)
Throws the given ExceptionType, passing the given message along with file and line number information...
Definition: Exceptions.hpp:22
OpenMPCD::StridedPointerIterator::operator!=
OPENMPCD_CUDA_HOST_AND_DEVICE bool operator!=(const StridedPointerIterator &rhs) const
Returns whether the address this instance and rhs point to different memory.
Definition: StridedPointerIterator.hpp:272
OpenMPCD::StridedPointerIterator::StridedPointerIterator
OPENMPCD_CUDA_HOST_AND_DEVICE StridedPointerIterator()
The default constructor.
Definition: StridedPointerIterator.hpp:33
OpenMPCD::StridedPointerIterator::isSingular
OPENMPCD_CUDA_HOST_AND_DEVICE bool isSingular() const
Returns whether this instance is singular, i.e.
Definition: StridedPointerIterator.hpp:62
OpenMPCD::StridedPointerIterator::operator++
OPENMPCD_CUDA_HOST_AND_DEVICE StridedPointerIterator & operator++()
The prefix increment operator.
Definition: StridedPointerIterator.hpp:187
std::iterator_traits< OpenMPCD::StridedPointerIterator< Pointee, stride > >::value_type
Pointee value_type
Type iterated over.
Definition: StridedPointerIterator.hpp:300
OpenMPCD::StridedPointerIterator::operator->
const OPENMPCD_CUDA_HOST_AND_DEVICE Pointee * operator->() const
Member access operator.
Definition: StridedPointerIterator.hpp:172
OpenMPCD::StridedPointerIterator
Wraps a pointer in such a way that incrementing this iterator is equivalent to incrementing the under...
Definition: StridedPointerIterator.hpp:23
OPENMPCD_CUDA_HOST_AND_DEVICE
#define OPENMPCD_CUDA_HOST_AND_DEVICE
Denotes a function to be callable both from the Host and from a CUDA Device.
Definition: Macros.hpp:15
std::iterator_traits< OpenMPCD::StridedPointerIterator< Pointee, stride > >::pointer
value_type * pointer
Pointer to the type iterated over.
Definition: StridedPointerIterator.hpp:301
OpenMPCD::StridedPointerIterator::operator->
OPENMPCD_CUDA_HOST_AND_DEVICE Pointee * operator->()
Member access operator.
Definition: StridedPointerIterator.hpp:157
OpenMPCD::StridedPointerIterator::operator*
const OPENMPCD_CUDA_HOST_AND_DEVICE Pointee & operator*() const
Dereferencing operator.
Definition: StridedPointerIterator.hpp:142
OpenMPCD::StridedPointerIterator::isDereferenceable
OPENMPCD_CUDA_HOST_AND_DEVICE bool isDereferenceable() const
Returns whether this instance can be dereferenced.
Definition: StridedPointerIterator.hpp:86
OpenMPCD::StridedPointerIterator::isIncrementable
OPENMPCD_CUDA_HOST_AND_DEVICE bool isIncrementable() const
Returns whether this instance is incrementable.
Definition: StridedPointerIterator.hpp:110
OpenMPCD::StridedPointerIterator::StridedPointerIterator
OPENMPCD_CUDA_HOST_AND_DEVICE StridedPointerIterator(Pointee *const start, const Pointee *const pastEnd_)
The constructor.
Definition: StridedPointerIterator.hpp:43
OpenMPCD::StridedPointerIterator::operator+=
const OPENMPCD_CUDA_HOST_AND_DEVICE StridedPointerIterator & operator+=(const unsigned int n)
Advances the pointer n times, or until the past-the-end iterator is reached, whichever comes first.
Definition: StridedPointerIterator.hpp:235
std::iterator_traits< OpenMPCD::StridedPointerIterator< Pointee, stride > >::reference
value_type & reference
Reference to the type iterated over.
Definition: StridedPointerIterator.hpp:302
OpenMPCD::StridedPointerIterator::isPastTheEnd
OPENMPCD_CUDA_HOST_AND_DEVICE bool isPastTheEnd() const
Returns whether this iterator is past-the-end.
Definition: StridedPointerIterator.hpp:72
OpenMPCD::StridedPointerIterator::operator==
OPENMPCD_CUDA_HOST_AND_DEVICE bool operator==(const StridedPointerIterator &rhs) const
Returns whether the address this instance and rhs point to the same memory.
Definition: StridedPointerIterator.hpp:255
std::iterator_traits< OpenMPCD::StridedPointerIterator< Pointee, stride > >::difference_type
std::ptrdiff_t difference_type
Type for distance between iterators.
Definition: StridedPointerIterator.hpp:298
OpenMPCD::StridedPointerIterator::StridedPointerIterator
OPENMPCD_CUDA_HOST_AND_DEVICE StridedPointerIterator(const StridedPointerIterator &rhs)
The copy constructor.
Definition: StridedPointerIterator.hpp:52
Macros.hpp
OpenMPCD::StridedPointerIterator::operator++
OPENMPCD_CUDA_HOST_AND_DEVICE StridedPointerIterator operator++(int)
The postfix increment operator.
Definition: StridedPointerIterator.hpp:210
OpenMPCD::StridedPointerIterator::operator*
OPENMPCD_CUDA_HOST_AND_DEVICE Pointee & operator*()
Dereferencing operator.
Definition: StridedPointerIterator.hpp:127
OpenMPCD::StridedPointerIterator::isValid
OPENMPCD_CUDA_HOST_AND_DEVICE bool isValid() const
Returns whether this instance is valid.
Definition: StridedPointerIterator.hpp:101
std::iterator_traits< OpenMPCD::StridedPointerIterator< Pointee, stride > >::iterator_category
std::input_iterator_tag iterator_category
Specifies the iterator category.
Definition: StridedPointerIterator.hpp:304