DGtal  1.1.0
HyperRectDomain_Iterator.h
1 
17 #pragma once
18 
32 #if defined(HyperRectDomain_Iterator_RECURSES)
33 #error Recursive header files inclusion detected in HyperRectDomain_Iterator.h
34 #else // defined(HyperRectDomain_Iterator_RECURSES)
35 
36 #define HyperRectDomain_Iterator_RECURSES
37 
38 #if !defined HyperRectDomain_Iterator_h
39 
40 #define HyperRectDomain_Iterator_h
41 
43 // Inclusions
44 #include <iostream>
45 #include <vector>
46 #include <iterator>
47 #include <type_traits>
48 
49 #include <boost/iterator/iterator_facade.hpp>
50 
51 #include "DGtal/base/Common.h"
53 
54 namespace DGtal
55 {
65  template <typename TIterator>
67  : public boost::iterator_facade <
68  HyperRectDomain_ReverseIterator<TIterator>,
69  typename TIterator::Point const,
70  std::random_access_iterator_tag,
71  typename TIterator::Point const&,
72  typename std::iterator_traits<TIterator>::difference_type
73  >
74  {
75  public:
76  using Iterator = TIterator;
78  using Point = typename Iterator::Point;
79  using Dimension = typename Point::Dimension;
80  using DifferenceType = typename std::iterator_traits<Self>::difference_type;
81 
82  public:
85  : current(it)
86  , prev(it)
87  {
88  --prev;
89  }
90 
92  const Point& dereference() const
93  {
94  return *prev;
95  }
96 
98  bool equal( const Self &other ) const
99  {
100  return current == other.current;
101  }
102 
104  void increment()
105  {
106  --current;
107  --prev;
108  }
109 
111  void decrement()
112  {
113  ++current;
114  ++prev;
115  }
116 
118  void advance( DifferenceType const& n )
119  {
120  current -= n;
121  prev -= n;
122  }
123 
125  DifferenceType distance_to( const Self& other ) const
126  {
127  return std::distance(other.current, current);
128  }
129 
130  private:
132 
133  };
134 
136  // class HyperRectDomain_Iterator
141  template <typename TPoint>
143  : public boost::iterator_facade <
144  HyperRectDomain_Iterator<TPoint>,
145  TPoint const,
146  std::random_access_iterator_tag,
147  TPoint const&,
148 #ifdef WITH_BIGINTEGER
149  typename std::conditional<std::is_same<typename TPoint::Component, BigInteger>::value, BigInteger, std::ptrdiff_t>::type
150 #else
151  std::ptrdiff_t
152 #endif
153  >
154  {
155  public:
156  using Point = TPoint;
158  using Dimension = typename Point::Dimension;
159  using DifferenceType = typename std::iterator_traits<Self>::difference_type;
160 
161 
171  HyperRectDomain_Iterator( const Point & p, const Point& lower, const Point &upper )
172  : myPoint( p ), mylower( lower ), myupper( upper )
173  {
174  ASSERT_MSG( // For an empty domain, lower = upper + diag(1) so that begin() == end().
175  lower.isLower(upper) || lower == upper + TPoint::diagonal(1),
176  "The lower bound must be lower than the upper bound or, for an empty domain, be equal to the upper bound + diagonal(1)."
177  );
178 
179  ASSERT_MSG(
180  ( lower.isLower(p) && p.isLower(upper) ) || p == lower || p == upper,
181  "The point must be inside the domain or be equal to one of his bound."
182  );
183 
184  // Calculating iterator position in the sequence
185  pos = 0;
186  DifferenceType delta = 1;
187  for ( Dimension i = 0; i < Point::dimension; ++i )
188  {
189  pos += delta * (myPoint[i] - mylower[i]);
190  delta *= myupper[i] - mylower[i] + 1;
191  }
192  }
193 
194  private:
196 
198  const Point& dereference() const
199  {
200  ASSERT_MSG( // we must be between [begin,end]
201  mylower.isLower(myPoint) && myPoint.isLower(myupper),
202  "The iterator points outside the domain."
203  );
204 
205  return myPoint;
206 
207  }
208 
213  bool equal( const Self &other ) const
214  {
215  ASSERT_MSG( // we should only compare iterators on the same domain
216  mylower == other.mylower && myupper == other.myupper,
217  "The compared iterators iterate on different domains."
218  );
219 
220  return pos == other.pos;
221  }
222 
227  void increment()
228  {
229  ++pos;
230  ++myPoint[0];
231  for ( Dimension i = 0; myPoint[i] > myupper[i] && i < Point::dimension - 1; ++i )
232  {
233  ++myPoint[i+1];
234  myPoint[i] = mylower[i];
235  }
236  }
237 
242  void decrement()
243  {
244  --pos;
245  --myPoint[0];
246  for ( Dimension i = 0; myPoint[i] < mylower[i] && i < Point::dimension - 1; ++i )
247  {
248  --myPoint[i+1];
249  myPoint[i] = myupper[i];
250  }
251  }
252 
257  void advance( DifferenceType const& n )
258  {
259  pos += n;
260  if (n > 0)
261  {
262  myPoint[0] += n;
263  for ( Dimension i = 0; myPoint[i] > myupper[i] && i < Point::dimension - 1; ++i )
264  {
265  typename Point::Component const shift = myPoint[i] - mylower[i];
266  typename Point::Component const length = myupper[i] - mylower[i] + 1;
267  myPoint[i+1] += shift / length;
268  myPoint[i] = mylower[i] + (shift % length);
269  }
270  }
271  else if (n < 0)
272  {
273  myPoint[0] += n;
274  for ( Dimension i = 0; myPoint[i] < mylower[i] && i < Point::dimension - 1; ++i )
275  {
276  typename Point::Component const shift = myupper[i] - myPoint[i];
277  typename Point::Component const length = myupper[i] - mylower[i] + 1;
278  myPoint[i+1] -= shift / length;
279  myPoint[i] = myupper[i] - (shift % length);
280  }
281  }
282  }
283 
287  DifferenceType distance_to( const Self& other ) const
288  {
289  ASSERT_MSG( // we should only compare iterators on the same domain
290  mylower == other.mylower && myupper == other.myupper,
291  "The compared iterators iterate on different domains."
292  );
293 
294  return other.pos - pos;
295  }
296 
297  private:
299  TPoint myPoint;
300 
302  TPoint mylower, myupper;
303 
306 
307  }; // End of class HyperRectDomain_Iterator
308 
310  // class HyperRectDomain_subIterator
315  template<typename TPoint>
317  : public boost::iterator_facade <
318  HyperRectDomain_subIterator<TPoint>,
319  const TPoint,
320  std::random_access_iterator_tag,
321  TPoint const&,
322 #ifdef WITH_BIGINTEGER
323  typename std::conditional<std::is_same<typename TPoint::Component, BigInteger>::value, BigInteger, std::ptrdiff_t>::type
324 #else
325  std::ptrdiff_t
326 #endif
327  >
328  {
329  public:
330  using Point = TPoint;
332  using Dimension = typename Point::Dimension;
333  using DifferenceType = typename std::iterator_traits<Self>::difference_type;
334 
335  HyperRectDomain_subIterator(const TPoint & p, const TPoint& lower,
336  const TPoint &upper,
337  const std::vector<Dimension> &subDomain)
338  : myPoint( p ), mylower( lower ), myupper( upper )
339  {
340  ASSERT_MSG( // For an empty domain, lower = upper + diag(1) so that begin() == end().
341  lower.isLower(upper) || lower == upper + TPoint::diagonal(0).partialCopy( TPoint::diagonal(1), subDomain ),
342  "The lower bound must be lower than the upper bound or, for an empty domain, be equal to the upper bound + diagonal(1)."
343  );
344 
345  ASSERT_MSG(
346  ( lower.isLower(p) && p.isLower(upper) ) || p == lower || p == upper,
347  "The point must be inside the domain or be equal to one of his bound."
348  );
349 
350  ASSERT_MSG(
351  subDomain.size() <= TPoint::dimension,
352  "The sub-range cannot have more dimensions than the ambiant space."
353  );
354 
355  mySubDomain.reserve( subDomain.size() );
356  for ( typename std::vector<Dimension>::const_iterator it = subDomain.begin();
357  it != subDomain.end(); ++it )
358  {
359  ASSERT_MSG(
360  *it <= TPoint::dimension,
361  "Invalid dimension in the sub-range."
362  );
363  mySubDomain.push_back( *it );
364  }
365 
366  // Calculating iterator position in the sequence
367  pos = 0;
368  DifferenceType delta = 1;
369  for ( Dimension i = 0; i < mySubDomain.size(); ++i )
370  {
371  auto const ii = mySubDomain[i];
372  pos += delta * (myPoint[ii] - mylower[ii]);
373  delta *= myupper[ii] - mylower[ii] + 1;
374  }
375  }
376 
377  private:
379 
381  const Point& dereference() const
382  {
383  ASSERT_MSG( // we must be between [begin,end]
384  mylower.isLower(myPoint) && myPoint.isLower(myupper),
385  "The iterator points outside the domain."
386  );
387 
388  return myPoint;
389 
390  }
391 
396  bool equal( const Self &other ) const
397  {
398  ASSERT_MSG( // we should only compare iterators on the same domain and same dimensions
399  mylower == other.mylower && myupper == other.myupper && mySubDomain == other.mySubDomain,
400  "The compared iterators iterate on different domains or different dimensions."
401  );
402 
403  return pos == other.pos;
404  }
405 
406 
411  void increment()
412  {
413  ++pos;
414  ++myPoint[mySubDomain[0]];
415  for ( Dimension i = 0; myPoint[mySubDomain[i]] > myupper[mySubDomain[i]] && i < mySubDomain.size() - 1; ++i )
416  {
417  ++myPoint[mySubDomain[i+1]];
419  }
420  }
421 
426  void decrement()
427  {
428  --pos;
429  --myPoint[mySubDomain[0]];
430  for ( Dimension i = 0; myPoint[mySubDomain[i]] < mylower[mySubDomain[i]] && i < mySubDomain.size() - 1; ++i )
431  {
432  --myPoint[mySubDomain[i+1]];
434  }
435  }
436 
441  void advance( DifferenceType const& n )
442  {
443  pos += n;
444  if (n > 0)
445  {
446  myPoint[mySubDomain[0]] += n;
447  for ( Dimension i = 0; myPoint[mySubDomain[i]] > myupper[mySubDomain[i]] && i < mySubDomain.size() - 1; ++i )
448  {
449  auto const ii = mySubDomain[i];
450  typename Point::Component const shift = myPoint[ii] - mylower[ii];
451  typename Point::Component const length = myupper[ii] - mylower[ii] + 1;
452  myPoint[mySubDomain[i+1]] += shift / length;
453  myPoint[ii] = mylower[ii] + (shift % length);
454  }
455  }
456  else if (n < 0)
457  {
458  myPoint[mySubDomain[0]] += n;
459  for ( Dimension i = 0; myPoint[mySubDomain[i]] < mylower[mySubDomain[i]] && i < mySubDomain.size() - 1; ++i )
460  {
461  auto const ii = mySubDomain[i];
462  typename Point::Component const shift = myupper[ii] - myPoint[ii];
463  typename Point::Component const length = myupper[ii] - mylower[ii] + 1;
464  myPoint[mySubDomain[i+1]] -= shift / length;
465  myPoint[ii] = myupper[ii] - (shift % length);
466  }
467  }
468  }
469 
474  DifferenceType distance_to( const Self& other ) const
475  {
476  ASSERT_MSG( // we should only compare iterators on the same domain and same dimensions
477  mylower == other.mylower && myupper == other.myupper && mySubDomain == other.mySubDomain,
478  "The compared iterators iterate on different domains or different dimensions."
479  );
480 
481  return other.pos - pos;
482  }
483 
484  private:
486  TPoint myPoint;
487 
489  TPoint mylower, myupper;
490 
494  std::vector<Dimension> mySubDomain;
495 
498 
499  }; // End of class HyperRectDomain_subIterator
500 
501 } //namespace
502 // //
504 
505 #endif // !defined HyperRectDomain_Iterator_h
506 
507 #undef HyperRectDomain_Iterator_RECURSES
508 #endif // else defined(HyperRectDomain_Iterator_RECURSES)
DGtal::HyperRectDomain_subIterator::advance
void advance(DifferenceType const &n)
Advances the iterator in order to scan the domain points dimension by dimension (by using the subDoma...
Definition: HyperRectDomain_Iterator.h:441
DGtal::HyperRectDomain_subIterator::DifferenceType
typename std::iterator_traits< Self >::difference_type DifferenceType
Type of the difference between two iterators (usually std::ptrdiff_t except for BigInteger).
Definition: HyperRectDomain_Iterator.h:333
DGtal::HyperRectDomain_Iterator::Point
TPoint Point
Definition: HyperRectDomain_Iterator.h:156
DGtal::HyperRectDomain_ReverseIterator::distance_to
DifferenceType distance_to(const Self &other) const
Distance between two iterators on the same domain.
Definition: HyperRectDomain_Iterator.h:125
DGtal::HyperRectDomain_ReverseIterator
Reverse iterator for HyperRectDomain.
Definition: HyperRectDomain_Iterator.h:74
DGtal::HyperRectDomain_subIterator::Point
TPoint Point
Definition: HyperRectDomain_Iterator.h:330
lower
Vector lower(const Vector &z, unsigned int k)
Definition: viewDualSurface.cpp:190
DGtal::HyperRectDomain_subIterator::HyperRectDomain_subIterator
HyperRectDomain_subIterator(const TPoint &p, const TPoint &lower, const TPoint &upper, const std::vector< Dimension > &subDomain)
Definition: HyperRectDomain_Iterator.h:335
DGtal::HyperRectDomain_subIterator::increment
void increment()
Increments the iterator in order to scan the domain points dimension by dimension (by using the subDo...
Definition: HyperRectDomain_Iterator.h:411
DGtal::HyperRectDomain_Iterator::iterator_core_access
friend class boost::iterator_core_access
Definition: HyperRectDomain_Iterator.h:195
DGtal::HyperRectDomain_ReverseIterator::equal
bool equal(const Self &other) const
Compare iterators.
Definition: HyperRectDomain_Iterator.h:98
DGtal::HyperRectDomain_ReverseIterator::Iterator
TIterator Iterator
Definition: HyperRectDomain_Iterator.h:76
DGtal::HyperRectDomain_Iterator::myPoint
TPoint myPoint
Current Point in the domain.
Definition: HyperRectDomain_Iterator.h:299
DGtal::HyperRectDomain_subIterator::myupper
TPoint myupper
Definition: HyperRectDomain_Iterator.h:489
DGtal::HyperRectDomain_Iterator::myupper
TPoint myupper
Definition: HyperRectDomain_Iterator.h:302
DGtal::HyperRectDomain_subIterator::equal
bool equal(const Self &other) const
Compare iterators.
Definition: HyperRectDomain_Iterator.h:396
DGtal::HyperRectDomain_subIterator
Definition: HyperRectDomain_Iterator.h:328
DGtal::HyperRectDomain_Iterator::DifferenceType
typename std::iterator_traits< Self >::difference_type DifferenceType
Type of the difference between two iterators (usually std::ptrdiff_t except for BigInteger).
Definition: HyperRectDomain_Iterator.h:159
DGtal::HyperRectDomain_ReverseIterator::current
Iterator current
Definition: HyperRectDomain_Iterator.h:131
DGtal::HyperRectDomain_subIterator::mySubDomain
std::vector< Dimension > mySubDomain
Definition: HyperRectDomain_Iterator.h:494
DGtal::HyperRectDomain_Iterator::dereference
const Point & dereference() const
Dereference.
Definition: HyperRectDomain_Iterator.h:198
DGtal::HyperRectDomain_Iterator::decrement
void decrement()
Decrements the iterator in order to scan the domain points dimension by dimension (lexicographic orde...
Definition: HyperRectDomain_Iterator.h:242
DGtal
DGtal is the top-level namespace which contains all DGtal functions and types.
Definition: ClosedIntegerHalfPlane.h:49
DGtal::HyperRectDomain_ReverseIterator::advance
void advance(DifferenceType const &n)
Advance iterator by given steps.
Definition: HyperRectDomain_Iterator.h:118
DGtal::HyperRectDomain_ReverseIterator::prev
Iterator prev
Definition: HyperRectDomain_Iterator.h:131
DGtal::HyperRectDomain_subIterator::mylower
TPoint mylower
Copies of the Domain limits.
Definition: HyperRectDomain_Iterator.h:489
DGtal::HyperRectDomain_subIterator::Dimension
typename Point::Dimension Dimension
Definition: HyperRectDomain_Iterator.h:332
DGtal::HyperRectDomain_Iterator::increment
void increment()
Increments the iterator in order to scan the domain points dimension by dimension (lexicographic orde...
Definition: HyperRectDomain_Iterator.h:227
DGtal::HyperRectDomain_ReverseIterator::increment
void increment()
Increment iterator.
Definition: HyperRectDomain_Iterator.h:104
DGtal::HyperRectDomain_Iterator::equal
bool equal(const Self &other) const
Compare iterators.
Definition: HyperRectDomain_Iterator.h:213
DGtal::HyperRectDomain_ReverseIterator::DifferenceType
typename std::iterator_traits< Self >::difference_type DifferenceType
Type of the difference between two iterators (usually std::ptrdiff_t except for BigInteger).
Definition: HyperRectDomain_Iterator.h:80
DGtal::HyperRectDomain_Iterator::distance_to
DifferenceType distance_to(const Self &other) const
Distance between two iterators on the same domain (lexicographic order).
Definition: HyperRectDomain_Iterator.h:287
DGtal::HyperRectDomain_Iterator::HyperRectDomain_Iterator
HyperRectDomain_Iterator(const Point &p, const Point &lower, const Point &upper)
HyperRectDomain iterator constructor.
Definition: HyperRectDomain_Iterator.h:171
DGtal::HyperRectDomain_ReverseIterator::decrement
void decrement()
Decrement iterator.
Definition: HyperRectDomain_Iterator.h:111
DGtal::HyperRectDomain_Iterator
Iterator for HyperRectDomain.
Definition: HyperRectDomain_Iterator.h:154
upper
Vector upper(const Vector &z, unsigned int k)
Definition: viewDualSurface.cpp:197
DGtal::HyperRectDomain_ReverseIterator::dereference
const Point & dereference() const
Dereference.
Definition: HyperRectDomain_Iterator.h:92
DGtal::HyperRectDomain_ReverseIterator::HyperRectDomain_ReverseIterator
HyperRectDomain_ReverseIterator(Iterator it)
Constructor from a HyperRectDomain iterator.
Definition: HyperRectDomain_Iterator.h:84
DGtal::HyperRectDomain_ReverseIterator::Dimension
typename Point::Dimension Dimension
Definition: HyperRectDomain_Iterator.h:79
DGtal::HyperRectDomain_subIterator::myPoint
TPoint myPoint
Current Point in the domain.
Definition: HyperRectDomain_Iterator.h:486
DGtal::HyperRectDomain_subIterator::iterator_core_access
friend class boost::iterator_core_access
Definition: HyperRectDomain_Iterator.h:378
DGtal::HyperRectDomain_Iterator::Dimension
typename Point::Dimension Dimension
Definition: HyperRectDomain_Iterator.h:158
DGtal::HyperRectDomain_Iterator::advance
void advance(DifferenceType const &n)
Advances the iterator in order to scan the domain points dimension by dimension (lexicographic order)...
Definition: HyperRectDomain_Iterator.h:257
DGtal::HyperRectDomain_subIterator::dereference
const Point & dereference() const
Dereference.
Definition: HyperRectDomain_Iterator.h:381
DGtal::HyperRectDomain_subIterator::pos
DifferenceType pos
Iterator position in the current sequence.
Definition: HyperRectDomain_Iterator.h:497
DGtal::HyperRectDomain_Iterator::pos
DifferenceType pos
Iterator position in the current sequence.
Definition: HyperRectDomain_Iterator.h:305
Point
MyPointD Point
Definition: testClone2.cpp:383
DGtal::HyperRectDomain_subIterator::decrement
void decrement()
Decrements the iterator in order to scan the domain points dimension by dimension (by using the subDo...
Definition: HyperRectDomain_Iterator.h:426
DGtal::HyperRectDomain_Iterator::mylower
TPoint mylower
Copies of the Domain limits.
Definition: HyperRectDomain_Iterator.h:302
DGtal::HyperRectDomain_ReverseIterator::Point
typename Iterator::Point Point
Definition: HyperRectDomain_Iterator.h:78
DGtal::HyperRectDomain_subIterator::distance_to
DifferenceType distance_to(const Self &other) const
Distance between two iterators on the same domain (by using the subDomain order given by the user).
Definition: HyperRectDomain_Iterator.h:474