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  int rank,
41  template<int> class CheckingPolicy = ArrayNoArgCheck
42 >
43 class Range {
44  public:
46  private:
48  LimitType lo, hi;
49  public:
51  Range() : lo(0), hi(0) {};
52 
54 
55  template<template<int> class ArrayCheckingPolicy>
57  : lo(lo_), hi(hi_) {}
58 
60  template<template<int> class ArrayCheckingPolicy>
62  : lo(domain.getLo()), hi(domain.getHi()) {}
63 
65  Range &operator=(const Range &domain)
66  {
67  lo = domain.lo;
68  hi = domain.hi;
69  return *this;
70  }
71 
73  const LimitType &getLo() const {
74  return lo;
75  }
77  const LimitType &getHi() const {
78  return hi;
79  }
80 
82  LimitType &getLo() {return lo;}
84  LimitType &getHi() {return hi;}
85 
87  bool inside(const LimitType &p)
88  {
89  for (int i=0; i<rank; ++i)
90  if ((p[i]<lo[i]) || (p[i]>hi[i])) return false;
91 
92  return true;
93  }
95  template<int destLength>
97  {
98  return Range<T,destLength,CheckingPolicy>(lo.template project<destLength>(), hi.template project<destLength>());
99  }
100 
101  Range<T,rank-1,CheckingPolicy> projectDim(int dim) const
102  {
103  return Range<T,rank-1,CheckingPolicy>(lo.projectDim(dim), hi.projectDim(dim));
104  }
105 
106  void grow(const T &s)
107  {
108  for (int i=0; i<rank; ++i)
109  {
110  lo[i] -= s;
111  hi[i] += s;
112  }
113  }
114 
115  void grow(const T &d0, const T &d1)
116  {
117  BOOST_STATIC_ASSERT(2==rank);
118  lo[0] -= d0;
119  hi[0] += d0;
120  lo[1] -= d1;
121  hi[1] += d1;
122  }
123 
124  void grow(const T &d0, const T &d1, const T &d2)
125  {
126  BOOST_STATIC_ASSERT(3==rank);
127  lo[0] -= d0;
128  hi[0] += d0;
129  lo[1] -= d1;
130  hi[1] += d1;
131  lo[2] -= d2;
132  hi[2] += d2;
133  }
134 
135  void grow(const T &d0, const T &d1, const T &d2, const T &d3)
136  {
137  BOOST_STATIC_ASSERT(4==rank);
138  lo[0] -= d0;
139  hi[0] += d0;
140  lo[1] -= d1;
141  hi[1] += d1;
142  lo[2] -= d2;
143  hi[2] += d2;
144  lo[3] -= d3;
145  hi[3] += d3;
146  }
147 
148  void grow(const T &d0, const T &d1, const T &d2, const T &d3, const T &d4)
149  {
150  BOOST_STATIC_ASSERT(5==rank);
151  lo[0] -= d0;
152  hi[0] += d0;
153  lo[1] -= d1;
154  hi[1] += d1;
155  lo[2] -= d2;
156  hi[2] += d2;
157  lo[3] -= d3;
158  hi[3] += d3;
159  lo[4] -= d4;
160  hi[4] += d4;
161  }
162 
163  void grow(const T &d0, const T &d1, const T &d2, const T &d3, const T &d4,
164  const T &d5)
165  {
166  BOOST_STATIC_ASSERT(6==rank);
167  lo[0] -= d0;
168  hi[0] += d0;
169  lo[1] -= d1;
170  hi[1] += d1;
171  lo[2] -= d2;
172  hi[2] += d2;
173  lo[3] -= d3;
174  hi[3] += d3;
175  lo[4] -= d4;
176  hi[4] += d4;
177  lo[5] -= d5;
178  hi[5] += d5;
179  }
180 
181  void grow(const T &d0, const T &d1, const T &d2, const T &d3, const T &d4,
182  const T &d5, const T &d6)
183  {
184  BOOST_STATIC_ASSERT(7==rank);
185  lo[0] -= d0;
186  hi[0] += d0;
187  lo[1] -= d1;
188  hi[1] += d1;
189  lo[2] -= d2;
190  hi[2] += d2;
191  lo[3] -= d3;
192  hi[3] += d3;
193  lo[4] -= d4;
194  hi[4] += d4;
195  lo[5] -= d5;
196  hi[5] += d5;
197  lo[6] -= d6;
198  hi[6] += d6;
199  }
200 
201  void grow(const T &d0, const T &d1, const T &d2, const T &d3, const T &d4,
202  const T &d5, const T &d6, const T &d7)
203  {
204  BOOST_STATIC_ASSERT(8==rank);
205  lo[0] -= d0;
206  hi[0] += d0;
207  lo[1] -= d1;
208  hi[1] += d1;
209  lo[2] -= d2;
210  hi[2] += d2;
211  lo[3] -= d3;
212  hi[3] += d3;
213  lo[4] -= d4;
214  hi[4] += d4;
215  lo[5] -= d5;
216  hi[5] += d5;
217  lo[6] -= d6;
218  hi[6] += d6;
219  lo[7] -= d7;
220  hi[7] += d7;
221  }
222 
223  void grow(const T &d0, const T &d1, const T &d2, const T &d3, const T &d4,
224  const T &d5, const T &d6, const T &d7, const T &d8)
225  {
226  BOOST_STATIC_ASSERT(9==rank);
227  lo[0] -= d0;
228  hi[0] += d0;
229  lo[1] -= d1;
230  hi[1] += d1;
231  lo[2] -= d2;
232  hi[2] += d2;
233  lo[3] -= d3;
234  hi[3] += d3;
235  lo[4] -= d4;
236  hi[4] += d4;
237  lo[5] -= d5;
238  hi[5] += d5;
239  lo[6] -= d6;
240  hi[6] += d6;
241  lo[7] -= d7;
242  hi[7] += d7;
243  lo[8] -= d8;
244  hi[8] += d8;
245  }
246 
247  void grow(const T &d0, const T &d1, const T &d2, const T &d3, const T &d4,
248  const T &d5, const T &d6, const T &d7, const T &d8, const T &d9)
249  {
250  BOOST_STATIC_ASSERT(10==rank);
251  lo[0] -= d0;
252  hi[0] += d0;
253  lo[1] -= d1;
254  hi[1] += d1;
255  lo[2] -= d2;
256  hi[2] += d2;
257  lo[3] -= d3;
258  hi[3] += d3;
259  lo[4] -= d4;
260  hi[4] += d4;
261  lo[5] -= d5;
262  hi[5] += d5;
263  lo[6] -= d6;
264  hi[6] += d6;
265  lo[7] -= d7;
266  hi[7] += d7;
267  lo[8] -= d8;
268  hi[8] += d8;
269  lo[9] -= d9;
270  hi[9] += d9;
271  }
272 
276  class iterator : public std::iterator<std::forward_iterator_tag, LimitType> {
277  private:
278  BOOST_CONCEPT_ASSERT((boost::Integer<T>));
279  friend class Range;
281  LimitType pos;
283  const Range &domain;
285  bool atEnd;
286 
288  iterator(const Range &domain_, const LimitType &pos_, bool atEnd_=false)
289  : pos(pos_), domain(domain_), atEnd(atEnd_) {}
291  iterator();
292 
294  void increment()
295  {
296  int d = rank;
297  while (d>0)
298  {
299  --d;
300  if (++pos[d] > domain.getHi()[d])
301  {
302  pos[d] = domain.getLo()[d];
303  }
304  else
305  return;
306  }
307  atEnd = true;
308  }
309  public:
311  iterator(const iterator &it) : pos(it.pos), domain(it.domain), atEnd(it.atEnd) {}
312 
315  {
316  increment();
317  return *this;
318  }
320  const iterator operator++(int)
321  {
322  iterator it(*this);
323  increment();
324  return it;
325  }
327  bool operator==(const iterator &it)
328  {
329  return (atEnd==it.atEnd) && (pos==it.pos);
330  }
331 
333  bool operator!=(const iterator &it) { return !(operator==(it)); }
334 
336  const LimitType& operator*() { return pos; }
337 
339  const LimitType& getPos() { return pos; }
340  };
341 
343  iterator begin() {
344  return iterator(*this, this->getLo());
345  }
346 
348  iterator end() {
349  return iterator(*this, this->getLo(), true);
350  }
351 };
352 
353 } // namespace
354 
355 #endif // RANGE_HPP_
const iterator operator++(int)
Postfix increment. Increments the iterator by one position.
Definition: range.hpp:320
Definition: range.hpp:43
Definition: algo.hpp:30
bool operator==(const iterator &it)
Equality test.
Definition: range.hpp:327
iterator(const iterator &it)
Copy constructor.
Definition: range.hpp:311
Definition: range.hpp:276
const LimitType & getHi() const
Return rectangle maximum.
Definition: range.hpp:77
iterator & operator++()
Prefix increment. Increments the iterator by one position.
Definition: range.hpp:314
LimitType & getLo()
Return rectangle minimum.
Definition: range.hpp:82
const LimitType & getPos()
Returns the current iterator position.
Definition: range.hpp:339
bool inside(const LimitType &p)
Returns true if the argument lies within the range.
Definition: range.hpp:87
LimitType & getHi()
Return rectangle maximum.
Definition: range.hpp:84
Range(const Array< T, rank, ArrayCheckingPolicy > &lo_, const Array< T, rank, ArrayCheckingPolicy > &hi_)
Construct with rectangle minimum and maximum.
Definition: range.hpp:56
Range()
Default constructor.
Definition: range.hpp:51
iterator end()
Creates an iterator pointing to a position after the end of the rectangle.
Definition: range.hpp:348
const LimitType & operator*()
Returns the current iterator position.
Definition: range.hpp:336
Range< T, destLength, CheckingPolicy > project() const
projects the Array onto an Array of shorter length
Definition: range.hpp:96
Range & operator=(const Range &domain)
Assignment operator.
Definition: range.hpp:65
bool operator!=(const iterator &it)
Equality test.
Definition: range.hpp:333
iterator begin()
Creates an iterator pointing to the beginning of the rectangle.
Definition: range.hpp:343
const LimitType & getLo() const
Return rectangle minimum.
Definition: range.hpp:73
Range(const Range< T, rank, ArrayCheckingPolicy > &domain)
Copy constructor.
Definition: range.hpp:61