DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
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 "DGtal/base/Common.h"
49 //#include <iterator> // Bug for operator * => dangling reference !!!
50 // Class allowing to build a reverse iterator of a given iterator.
51 template<typename _Iterator>
53  : public iterator<typename iterator_traits<_Iterator>::iterator_category,
54  typename iterator_traits<_Iterator>::value_type,
55  typename iterator_traits<_Iterator>::difference_type,
56  typename iterator_traits<_Iterator>::pointer,
57  typename iterator_traits<_Iterator>::reference>
58 {
59 protected:
60  _Iterator current;
61  _Iterator prev;
62 
63 public:
64  typedef _Iterator iterator_type;
65  typedef typename iterator_traits<_Iterator>::difference_type
67  typedef typename iterator_traits<_Iterator>::reference reference;
68  typedef typename iterator_traits<_Iterator>::pointer pointer;
69 
70 public:
71  explicit
73  prev(current)
74  { --prev; }
75 
77  : current(__x.current), prev(__x.prev) { }
78 
80  { return current; }
81 
82  /*const*/ reference operator*() const
83  { return *prev; }
84 
86  { return *prev; }
87 
89  { return &(operator*()); }
90 
92  { --current; --prev;
93  return *this;
94  }
95 
97  {
98  myreverse_iterator __tmp = *this;
99  operator++();
100  return __tmp;
101  }
102 
104  {
105  ++current; ++prev;
106  return *this;
107  }
108 
110  {
111  myreverse_iterator __tmp = *this;
112  operator--();
113  return __tmp;
114  }
115 
117  { return myreverse_iterator(current - __n); }
118 
120  {
121  current -= __n; prev = current; --prev;
122  return *this;
123  }
124 
126  { return myreverse_iterator(current + __n); }
127 
129  {
130  current += __n; prev = current; --prev;
131  return *this;
132  }
133 
135  { return *(*this + __n); }
136 };
137 template<typename _Iterator>
138 inline bool
141 { return __x.base() == __y.base(); }
142 template<typename _Iterator>
143 inline bool
146 { return !(__x == __y); }
147 
148 //******************************************************************************
149 namespace DGtal
150 {
152  // class HyperRectDomain_Iterator
157  template<typename TPoint>
159  {
160  public:
161  typedef std::bidirectional_iterator_tag iterator_category;
162  typedef TPoint value_type;
163  typedef ptrdiff_t difference_type;
164  typedef TPoint* pointer;
165  typedef TPoint& reference;
166  typedef typename TPoint::Dimension Dimension;
167 
168 
169  HyperRectDomain_Iterator( const TPoint & p, const TPoint& lower, const TPoint &upper )
170  : myPoint( p ), mylower( lower ), myupper( upper ), myCurrentPos( 0 )
171  {
172  ASSERT( lower <= upper );
173  ASSERT( lower <= p && p <= upper );
174  }
175 
176  const TPoint & operator*() const
177  {
178  ASSERT(mylower<=myPoint && myPoint<=myupper); // we must be between [begin,end]
179  return myPoint;
180  }
181  TPoint & operator*()
182  {
183  ASSERT(mylower<=myPoint && myPoint<=myupper); // we must be between [begin,end]
184  return myPoint;
185  }
186 
192  {
193  return ( myPoint==it.myPoint );
194  }
195 
201  {
202  return ( myPoint!=aIt.myPoint );
203  }
204 
210  {
212  if (( myCurrentPos < TPoint::dimension - 1 ) &&
214  {
215  do
216  {
218  myCurrentPos++;
219  if ( myCurrentPos < TPoint::dimension )
221  }
222  while (( myCurrentPos < TPoint::dimension - 1 ) &&
223  ( myPoint[myCurrentPos] > myupper[ myCurrentPos ] ) );
224  myCurrentPos = 0;
225  }
226  }
227 
232  {
234  return *this;
235  }
236 
242  {
245  return tmp;
246  }
247 
253  {
254  --myPoint[ myCurrentPos ];
255  if (( myCurrentPos < TPoint::dimension - 1 ) &&
257  {
258  do
259  {
261  ++myCurrentPos;
262  if ( myCurrentPos < TPoint::dimension )
263  --myPoint[ myCurrentPos ];
264  }
265  while (( myCurrentPos < TPoint::dimension - 1 ) &&
266  ( myPoint[ myCurrentPos ] < mylower[ myCurrentPos ] ) );
267  myCurrentPos = 0;
268  }
269  }
270 
276  {
278  return *this;
279  }
280 
285  {
288  return tmp;
289  }
290 
291  private:
293  TPoint myPoint;
295  TPoint mylower, myupper;
298  };
300  // class HyperRectDomain_Iterator
305  template<typename TPoint>
307  {
308  public:
309  typedef std::bidirectional_iterator_tag iterator_category;
310  typedef TPoint value_type;
311  typedef ptrdiff_t difference_type;
312  typedef TPoint* pointer;
313  typedef TPoint& reference;
314  typedef typename TPoint::Dimension Dimension;
315 
316 #ifdef CPP11_INITIALIZER_LIST
317  HyperRectDomain_subIterator(const TPoint & p, const TPoint& lower,
318  const TPoint &upper,
319  std::initializer_list<Dimension> subDomain)
320  : myPoint( p ), mylower( lower ), myupper( upper ), myCurrentPos( 0 )
321  {
322  ASSERT( lower <= upper );
323  ASSERT( lower <= p && p <= upper );
324  ASSERT( subDomain.size() <= TPoint::dimension );
325  mySubDomain.reserve( subDomain.size() );
326  for ( const unsigned int *c = subDomain.begin();
327  c != subDomain.end(); ++c )
328  {
329  ASSERT( *c <= TPoint::dimension );
330  mySubDomain.push_back( *c );
331  }
332 
333  // TODO: check the validity of the subDomain ?
334  }
335 #endif
336  HyperRectDomain_subIterator(const TPoint & p, const TPoint& lower,
337  const TPoint &upper,
338  const std::vector<Dimension> &subDomain)
339  : myPoint( p ), mylower( lower ), myupper( upper ), myCurrentPos( 0 )
340  {
341  ASSERT( lower <= upper );
342  ASSERT( lower <= p && p <= upper );
343  ASSERT( subDomain.size() <= TPoint::dimension );
344  mySubDomain.reserve( subDomain.size() );
345  for ( typename std::vector<Dimension>::const_iterator it = subDomain.begin();
346  it != subDomain.end(); ++it )
347  {
348  ASSERT( *it <= TPoint::dimension );
349  mySubDomain.push_back( *it );
350  }
351 
352  // TODO: check the validity of the subDomain ?
353  }
354 
355 
356  const TPoint & operator*() const
357  {
358  ASSERT(mylower<=myPoint && myPoint<=myupper); // we must be between [begin,end]
359  return myPoint;
360  }
361  TPoint & operator*()
362  {
363  ASSERT(mylower<=myPoint && myPoint<=myupper); // we must be between [begin,end]
364  return myPoint;
365  }
366 
372  {
373  for (unsigned int i=0; i<mySubDomain.size(); ++i)
374  if ( myPoint[mySubDomain[i]]!=it.myPoint[mySubDomain[i]]) return false;
375  return true;
376  // return ( myPoint==it.myPoint );
377  }
378 
384  {
385  return !operator==(aIt);
386  // ( myPoint!=aIt.myPoint );
387  }
388 
394  {
395  ASSERT( myCurrentPos < mySubDomain.size() );
397 
398  if ( myCurrentPos < mySubDomain.size() - 1 &&
399  myPoint[ mySubDomain[myCurrentPos] ] >
400  myupper[ mySubDomain[myCurrentPos] ] )
401  {
402  do
403  {
404  myPoint[ mySubDomain[myCurrentPos] ] =
405  mylower[ mySubDomain[myCurrentPos] ];
406  ++myCurrentPos;
407  if ( myCurrentPos < mySubDomain.size() )
408  ++myPoint[ mySubDomain[myCurrentPos] ];
409  }
410  while (( myCurrentPos < mySubDomain.size() - 1 ) &&
411  ( myPoint[ mySubDomain[myCurrentPos] ] >
412  myupper[ mySubDomain[myCurrentPos] ] ) );
413  myCurrentPos = 0;
414  }
415  }
416 
421  {
423  return *this;
424  }
425 
431  {
434  return tmp;
435  }
436 
442  {
443  ASSERT( myCurrentPos < mySubDomain.size() );
445 
446  if ( myCurrentPos < mySubDomain.size() - 1 &&
447  myPoint[ mySubDomain[myCurrentPos] ] <
448  mylower[ mySubDomain[myCurrentPos] ] )
449  {
450  do
451  {
452  myPoint[ mySubDomain[myCurrentPos] ] =
453  myupper[ mySubDomain[myCurrentPos] ];
454  ++myCurrentPos;
455  if ( myCurrentPos < mySubDomain.size() )
456  --myPoint[ mySubDomain[myCurrentPos] ];
457  }
458  while (( myCurrentPos < mySubDomain.size() - 1 ) &&
459  ( myPoint[ mySubDomain[myCurrentPos] ] <
460  mylower[ mySubDomain[myCurrentPos] ] ) );
461  myCurrentPos = 0;
462  }
463  }
464 
470  {
472  return *this;
473  }
474 
479  {
482  return tmp;
483  }
484 
485  private:
487  TPoint myPoint;
489  TPoint mylower, myupper;
494  std::vector<Dimension> mySubDomain;
495  };
496 
497 } //namespace
498 // //
500 
501 #endif // !defined HyperRectDomain_Iterator_h
502 
503 #undef HyperRectDomain_Iterator_RECURSES
504 #endif // else defined(HyperRectDomain_Iterator_RECURSES)