Schnek
range.hpp
1 /*
2  * range.hpp
3  *
4  * Created on: 31 Aug 2012
5  * Author: Holger Schmitz
6  * Email: holger@notjustphysics.com
7  *
8  * Copyright 2012 Holger Schmitz
9  *
10  * This file is part of Schnek.
11  *
12  * Schnek is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation, either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * Schnek is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with Schnek. If not, see <http://www.gnu.org/licenses/>.
24  *
25  */
26 
27 #ifndef SCHNEK_RANGE_HPP_
28 #define SCHNEK_RANGE_HPP_
29 
30 #include "array.hpp"
31 #include "boost/concept/assert.hpp"
32 #include "boost/concept_check.hpp"
33 
34 namespace schnek {
35 
38 template<
39  class T,
40  size_t rank,
41  template<size_t> class CheckingPolicy = ArrayNoArgCheck
42 >
43 class Range {
44  public:
46  typedef T value_type;
47  private:
49  LimitType lo, hi;
50  public:
52  Range() : lo(0), hi(0) {}
53  Range(const Range &domain): lo(domain.lo), hi(domain.hi) {}
54 
56  template<template<size_t> class ArrayCheckingPolicy>
58  : lo(lo_), hi(hi_) {}
59 
61  template<template<size_t> class ArrayCheckingPolicy>
63  : lo(domain.getLo()), hi(domain.getHi()) {}
64 
66  Range &operator=(const Range &domain)
67  {
68  lo = domain.lo;
69  hi = domain.hi;
70  return *this;
71  }
72 
74  SCHNEK_INLINE const LimitType &getLo() const { return lo; }
76  SCHNEK_INLINE const LimitType &getHi() const { return hi; }
77 
79  SCHNEK_INLINE LimitType &getLo() {return lo;}
81  SCHNEK_INLINE LimitType &getHi() {return hi;}
82 
84  SCHNEK_INLINE T &getLo(size_t i) { return lo[i]; }
86  SCHNEK_INLINE T &getHi(size_t i) { return hi[i]; }
87 
89  SCHNEK_INLINE const T getLo(size_t i) const { return lo[i]; }
91  SCHNEK_INLINE const T getHi(size_t i) const { return hi[i]; }
92 
94  bool inside(const LimitType &p)
95  {
96  for (int i=0; i<rank; ++i)
97  if ((p[i]<lo[i]) || (p[i]>hi[i])) return false;
98 
99  return true;
100  }
102  template<int destLength>
104  {
105  return Range<T,destLength,CheckingPolicy>(lo.template project<destLength>(), hi.template project<destLength>());
106  }
107 
108  Range<T,rank-1,CheckingPolicy> projectDim(int dim) const
109  {
110  return Range<T,rank-1,CheckingPolicy>(lo.projectDim(dim), hi.projectDim(dim));
111  }
112 
113  void grow(const T &s)
114  {
115  for (int i=0; i<rank; ++i)
116  {
117  lo[i] -= s;
118  hi[i] += s;
119  }
120  }
121 
122  void grow(const T &d0, const T &d1)
123  {
124  BOOST_STATIC_ASSERT(2==rank);
125  lo[0] -= d0;
126  hi[0] += d0;
127  lo[1] -= d1;
128  hi[1] += d1;
129  }
130 
131  void grow(const T &d0, const T &d1, const T &d2)
132  {
133  BOOST_STATIC_ASSERT(3==rank);
134  lo[0] -= d0;
135  hi[0] += d0;
136  lo[1] -= d1;
137  hi[1] += d1;
138  lo[2] -= d2;
139  hi[2] += d2;
140  }
141 
142  void grow(const T &d0, const T &d1, const T &d2, const T &d3)
143  {
144  BOOST_STATIC_ASSERT(4==rank);
145  lo[0] -= d0;
146  hi[0] += d0;
147  lo[1] -= d1;
148  hi[1] += d1;
149  lo[2] -= d2;
150  hi[2] += d2;
151  lo[3] -= d3;
152  hi[3] += d3;
153  }
154 
155  void grow(const T &d0, const T &d1, const T &d2, const T &d3, const T &d4)
156  {
157  BOOST_STATIC_ASSERT(5==rank);
158  lo[0] -= d0;
159  hi[0] += d0;
160  lo[1] -= d1;
161  hi[1] += d1;
162  lo[2] -= d2;
163  hi[2] += d2;
164  lo[3] -= d3;
165  hi[3] += d3;
166  lo[4] -= d4;
167  hi[4] += d4;
168  }
169 
170  void grow(const T &d0, const T &d1, const T &d2, const T &d3, const T &d4,
171  const T &d5)
172  {
173  BOOST_STATIC_ASSERT(6==rank);
174  lo[0] -= d0;
175  hi[0] += d0;
176  lo[1] -= d1;
177  hi[1] += d1;
178  lo[2] -= d2;
179  hi[2] += d2;
180  lo[3] -= d3;
181  hi[3] += d3;
182  lo[4] -= d4;
183  hi[4] += d4;
184  lo[5] -= d5;
185  hi[5] += d5;
186  }
187 
188  void grow(const T &d0, const T &d1, const T &d2, const T &d3, const T &d4,
189  const T &d5, const T &d6)
190  {
191  BOOST_STATIC_ASSERT(7==rank);
192  lo[0] -= d0;
193  hi[0] += d0;
194  lo[1] -= d1;
195  hi[1] += d1;
196  lo[2] -= d2;
197  hi[2] += d2;
198  lo[3] -= d3;
199  hi[3] += d3;
200  lo[4] -= d4;
201  hi[4] += d4;
202  lo[5] -= d5;
203  hi[5] += d5;
204  lo[6] -= d6;
205  hi[6] += d6;
206  }
207 
208  void grow(const T &d0, const T &d1, const T &d2, const T &d3, const T &d4,
209  const T &d5, const T &d6, const T &d7)
210  {
211  BOOST_STATIC_ASSERT(8==rank);
212  lo[0] -= d0;
213  hi[0] += d0;
214  lo[1] -= d1;
215  hi[1] += d1;
216  lo[2] -= d2;
217  hi[2] += d2;
218  lo[3] -= d3;
219  hi[3] += d3;
220  lo[4] -= d4;
221  hi[4] += d4;
222  lo[5] -= d5;
223  hi[5] += d5;
224  lo[6] -= d6;
225  hi[6] += d6;
226  lo[7] -= d7;
227  hi[7] += d7;
228  }
229 
230  void grow(const T &d0, const T &d1, const T &d2, const T &d3, const T &d4,
231  const T &d5, const T &d6, const T &d7, const T &d8)
232  {
233  BOOST_STATIC_ASSERT(9==rank);
234  lo[0] -= d0;
235  hi[0] += d0;
236  lo[1] -= d1;
237  hi[1] += d1;
238  lo[2] -= d2;
239  hi[2] += d2;
240  lo[3] -= d3;
241  hi[3] += d3;
242  lo[4] -= d4;
243  hi[4] += d4;
244  lo[5] -= d5;
245  hi[5] += d5;
246  lo[6] -= d6;
247  hi[6] += d6;
248  lo[7] -= d7;
249  hi[7] += d7;
250  lo[8] -= d8;
251  hi[8] += d8;
252  }
253 
254  void grow(const T &d0, const T &d1, const T &d2, const T &d3, const T &d4,
255  const T &d5, const T &d6, const T &d7, const T &d8, const T &d9)
256  {
257  BOOST_STATIC_ASSERT(10==rank);
258  lo[0] -= d0;
259  hi[0] += d0;
260  lo[1] -= d1;
261  hi[1] += d1;
262  lo[2] -= d2;
263  hi[2] += d2;
264  lo[3] -= d3;
265  hi[3] += d3;
266  lo[4] -= d4;
267  hi[4] += d4;
268  lo[5] -= d5;
269  hi[5] += d5;
270  lo[6] -= d6;
271  hi[6] += d6;
272  lo[7] -= d7;
273  hi[7] += d7;
274  lo[8] -= d8;
275  hi[8] += d8;
276  lo[9] -= d9;
277  hi[9] += d9;
278  }
279 
285  class iterator : public std::iterator<std::forward_iterator_tag, LimitType> {
286  private:
287  BOOST_CONCEPT_ASSERT((boost::Integer<T>));
288  friend class Range;
290  LimitType pos;
292  const Range &domain;
294  bool atEnd;
295 
297  iterator(const Range &domain_, const LimitType &pos_, bool atEnd_=false)
298  : pos(pos_), domain(domain_), atEnd(atEnd_) {}
300  iterator();
301 
303  void increment()
304  {
305  int d = rank;
306  while (d>0)
307  {
308  --d;
309  if (++pos[d] > domain.getHi()[d])
310  {
311  pos[d] = domain.getLo()[d];
312  }
313  else
314  return;
315  }
316  atEnd = true;
317  }
318  public:
320  iterator(const iterator &it) : pos(it.pos), domain(it.domain), atEnd(it.atEnd) {}
321 
324  {
325  increment();
326  return *this;
327  }
329  const iterator operator++(int)
330  {
331  iterator it(*this);
332  increment();
333  return it;
334  }
336  bool operator==(const iterator &it)
337  {
338  return (atEnd==it.atEnd) && (pos==it.pos);
339  }
340 
342  bool operator!=(const iterator &it) { return !(operator==(it)); }
343 
345  const LimitType& operator*() { return pos; }
346 
348  const LimitType& getPos() { return pos; }
349  };
350 
352  iterator begin() {
353  return iterator(*this, this->getLo());
354  }
355 
357  iterator end() {
358  return iterator(*this, this->getLo(), true);
359  }
360 };
361 
362 } // namespace
363 
364 #endif // RANGE_HPP_
SCHNEK_INLINE T & getLo(size_t i)
Return the i-th coordinate of the rectangle minimum.
Definition: range.hpp:84
const iterator operator++(int)
Postfix increment. Increments the iterator by one position.
Definition: range.hpp:329
Definition: range.hpp:43
SCHNEK_INLINE const LimitType & getLo() const
Return rectangle minimum.
Definition: range.hpp:74
Definition: algo.hpp:30
bool operator==(const iterator &it)
Equality test.
Definition: range.hpp:336
SCHNEK_INLINE LimitType & getHi()
Return rectangle maximum.
Definition: range.hpp:81
iterator(const iterator &it)
Copy constructor.
Definition: range.hpp:320
Forward iterator over the rectangular domain.
Definition: range.hpp:285
SCHNEK_INLINE const T getLo(size_t i) const
Return the i-th coordinate of the rectangle minimum.
Definition: range.hpp:89
iterator & operator++()
Prefix increment. Increments the iterator by one position.
Definition: range.hpp:323
SCHNEK_INLINE LimitType & getLo()
Return rectangle minimum.
Definition: range.hpp:79
const LimitType & getPos()
Returns the current iterator position.
Definition: range.hpp:348
bool inside(const LimitType &p)
Returns true if the argument lies within the range.
Definition: range.hpp:94
Range(const Array< T, rank, ArrayCheckingPolicy > &lo_, const Array< T, rank, ArrayCheckingPolicy > &hi_)
Construct with rectangle minimum and maximum.
Definition: range.hpp:57
Range()
Default constructor.
Definition: range.hpp:52
iterator end()
Creates an iterator pointing to a position after the end of the rectangle.
Definition: range.hpp:357
const LimitType & operator*()
Returns the current iterator position.
Definition: range.hpp:345
Range< T, destLength, CheckingPolicy > project() const
projects the Array onto an Array of shorter length
Definition: range.hpp:103
Range & operator=(const Range &domain)
Assignment operator.
Definition: range.hpp:66
bool operator!=(const iterator &it)
Equality test.
Definition: range.hpp:342
iterator begin()
Creates an iterator pointing to the beginning of the rectangle.
Definition: range.hpp:352
SCHNEK_INLINE T & getHi(size_t i)
Return the i-th coordinate of the rectangle maximum.
Definition: range.hpp:86
SCHNEK_INLINE const T getHi(size_t i) const
Return the i-th coordinate of the rectangle maximum.
Definition: range.hpp:91
SCHNEK_INLINE const LimitType & getHi() const
Return rectangle maximum.
Definition: range.hpp:76
Range(const Range< T, rank, ArrayCheckingPolicy > &domain)
Copy constructor.
Definition: range.hpp:62