DGtal  0.9.4beta
Circulator.h
1 
17 #pragma once
18 
31 #if defined(Circulator_RECURSES)
32 #error Recursive header files inclusion detected in Circulator.h
33 #else // defined(Circulator_RECURSES)
34 
35 #define Circulator_RECURSES
36 
37 #if !defined Circulator_h
38 
39 #define Circulator_h
40 
42 // Inclusions
43 #include<iterator>
44 #include "DGtal/base/IteratorCirculatorTraits.h"
46 
47 namespace DGtal
48 {
49 
50 
52  // template class Circulator
84  template <typename TIterator>
85  class Circulator
86  {
87 
88  BOOST_STATIC_ASSERT(( boost::is_same<
90  IteratorType >::value ));
91 
92  // ----------------------- Types ------------------------------
93  public:
94 
95  typedef TIterator Iterator;
97 
98  typedef CirculatorType Type;
99 
100  typedef typename boost::iterator_category<TIterator>::type
102 
103  typedef typename std::iterator_traits<TIterator>::value_type value_type;
104  typedef typename std::iterator_traits<TIterator>::difference_type difference_type;
105  typedef typename std::iterator_traits<TIterator>::pointer pointer;
106  typedef typename std::iterator_traits<TIterator>::reference reference;
107 
108 
109 
110  // ----------------------- Standard services ------------------------------
111  public:
112 
119 
120 
129  Circulator(const Iterator& i,
130  const Iterator& itb,
131  const Iterator& ite)
132  : myCurrentIt(i), myBeginIt(itb), myEndIt(ite), myFlagIsValid(true)
133  { if (myBeginIt == myEndIt) myFlagIsValid = false; }
134 
139 
144  Circulator ( const Circulator & other )
145  : myCurrentIt(other.myCurrentIt),
146  myBeginIt(other.myBeginIt), myEndIt(other.myEndIt),
148  {}
149 
154  template<typename other_Iterator>
156  : myCurrentIt(other.base()),
157  myBeginIt(other.begin()), myEndIt(other.end()),
158  myFlagIsValid(other.isValid())
159  {}
160 
166  Circulator & operator= ( const Circulator & other )
167  {
168  if ( this != &other )
169  {
170  myCurrentIt = other.myCurrentIt;
171  myBeginIt = other.myBeginIt;
172  myEndIt = other.myEndIt;
173  if (myBeginIt != myEndIt)
174  myFlagIsValid = true;
175  else
176  myFlagIsValid = false;
177  }
178  return *this;
179  }
180 
186  template<typename other_Iterator>
188  {
189  if ( this != &other )
190  {
191  myCurrentIt = other.base();
192  myBeginIt = other.begin();
193  myEndIt = other.end();
194  if (myBeginIt != myEndIt)
195  myFlagIsValid = true;
196  else
197  myFlagIsValid = false;
198  }
199  return *this;
200  }
201 
206  bool isValid() const
207  { return myFlagIsValid; }
208 
209 
210  // ----------------------- Interface --------------------------------------
211  public:
212 
216  Iterator base() const
217  { return myCurrentIt; }
218 
222  Iterator begin() const
223  { return myBeginIt; }
224 
228  Iterator end() const
229  { return myEndIt; }
230 
234  reference operator*() const
235  {
236  //ASSERT( myCurrentIt != myEndIt ); //myCurrentIt == myEndIt when using reverse iterators on circulators
237  ASSERT( isValid() );
238  return *myCurrentIt;
239  }
240 
244  pointer operator->() const
245  {
246  //ASSERT( myCurrentIt != myEndIt ); //myCurrentIt == myEndIt when using reverse iterators on circulators
247  ASSERT( isValid() );
248  return myCurrentIt.operator->();
249  }
250 
251 
252  // ----------------------- Incrementation/Decrementation --------------------------------------
253  public:
254 
258  Self& operator++()
259  {
260  ASSERT( isValid() );
261  ++myCurrentIt;
263  return *this;
264  }
265 
269  Self operator++(int)
270  {
271  Self tmp = *this;
272  operator++();
273  return tmp;
274  }
275 
276 
280  Self& operator--()
281  {
282  ASSERT( isValid() );
284  --myCurrentIt;
285  return *this;
286  }
287 
291  Self operator--(int)
292  {
293  Self tmp = *this;
294  operator--();
295  return tmp;
296  }
297 
298  // ----------------------- Equality operators --------------------------------------
299  public:
300 
301  //'true' if their three underlying iterators are equal
302  //or if their underlying ranges are both empty,
303  //'false' otherwise
304  bool operator==( const Self& other) const
305  {
306  return ( ( (!isValid())&&(!other.isValid()) )
307  ||
308  ( ( isValid() && other.isValid())
309  &&
310  ( (myBeginIt == other.begin())
311  &&(myEndIt == other.end())
312  &&(myCurrentIt == other.base())
313  )
314  )
315  );
316  }
317  bool operator!=( const Self& other) const { return !(*this == other); }
318 
319  template<typename OtherIterator>
320  bool operator==( const OtherIterator& other) const
321  {
322  return ( ( (!isValid())&&(!other.isValid()) )
323  ||
324  ( ( isValid() && other.isValid())
325  &&
326  ( (myBeginIt == other.begin())
327  &&(myEndIt == other.end())
328  &&(myCurrentIt == other.base())
329  )
330  )
331  );
332  }
333  template<typename OtherIterator>
334  bool operator!=( const OtherIterator& other) const { return !(*this == other); }
335 
336 
337  // ----------------------- Random access operators --------------------------------------
338  public:
339 
340  Self& operator+=( difference_type d )
341  {
342  if ( isValid() )
343  {
344  //size range
345  typename Iterator::difference_type n = myEndIt - myBeginIt;
346  ASSERT( n > 0 );
347  //difference modulo n
348  if ( (d >= n)||(-d >= n) )
349  d = d%n;
350  ASSERT( (d < n)&&(-d < n) );
351  //position of the current iterator
352  typename Iterator::difference_type j = myCurrentIt - myBeginIt;
353  ASSERT( (j >= 0) && (j < n) );
354  //deviation between the position of the past-the-end value
355  //and the current iterator
356  typename Iterator::difference_type e = n - j;
357  if (d >= 0)
358  { //in case of positive distance
359  if (d < e) j += d;
360  else j = d - e;
361  }
362  else
363  { //in case of negative distance
364  if (-d <= j) j += d;
365  else j = j + d + n;
366  }
367  ASSERT( (j >= 0) && (j < n) );
368  myCurrentIt = myBeginIt + j;
369  return *this;
370  }
371  else
372  return *this;
373  }
374 
375  Self& operator-=( difference_type d) { return operator+=( -d); }
376 
377  Self operator+( difference_type d) const
378  {
379  Self tmp = *this;
380  return tmp += d;
381  }
382 
383  Self operator-( difference_type d) const
384  {
385  Self tmp = *this;
386  return tmp += -d;
387  }
388 
389  difference_type operator-( const Self& c) const
390  {
391  typename Iterator::difference_type d = (myCurrentIt - c.myCurrentIt);
392  if (d >= 0)
393  return d;
394  else
395  {
396  typename Iterator::difference_type n = myEndIt - myBeginIt;
397  ASSERT( n > 0 );
398  return (n + d);
399  }
400  }
401  reference operator[]( difference_type d) const
402  {
403  Self tmp = *this;
404  tmp += d;
405  return *tmp;
406  }
407 
408  // ----------------------- Comparisons operators --------------------------------------
409  bool operator<( const Self& /*c*/) const
410  {
411  return true;
412  }
413  bool operator<=( const Self& /*c*/) const
414  {
415  return true;
416  }
417  bool operator>( const Self& c) const
418  {
419  return !operator<=(c);
420  }
421  bool operator>=( const Self& c) const
422  {
423  return !operator>(c);
424  }
425 
426 
427  // ------------------------- Protected Datas --------------------------------
428  protected:
429 
430  Iterator myCurrentIt;
431  Iterator myBeginIt;
432  Iterator myEndIt;
434 
435  // ------------------------- Private Datas --------------------------------
436  private:
437 
438 
439 
440  // ------------------------- Hidden services ------------------------------
441  protected:
442 
443 
444 
445  private:
446 
447 
448  }; // end of class Circulator
449 
450 
451  template <typename TIterator>
454  Circulator<TIterator> & object )
455  {
456  Circulator<TIterator> tmp = object;
457  return tmp += d;
458  }
459 
460 
461 } // namespace DGtal
462 
463 #include "DGtal/base/IteratorFunctions.h"
464 
466 // Includes inline functions.
467 //#include "DGtal/base/Circulator.ih"
468 
469 // //
471 
472 #endif // !defined Circulator_h
473 
474 #undef Circulator_RECURSES
475 #endif // else defined(Circulator_RECURSES)
Circulator< TIterator > Self
Definition: Circulator.h:96
std::iterator_traits< TIterator >::pointer pointer
Definition: Circulator.h:105
std::iterator_traits< TIterator >::value_type value_type
Definition: Circulator.h:103
BOOST_STATIC_ASSERT((boost::is_same< typename IteratorCirculatorTraits< TIterator >::Type, IteratorType >::value))
Iterator end() const
Definition: Circulator.h:228
reference operator[](difference_type d) const
Definition: Circulator.h:401
Self operator--(int)
Definition: Circulator.h:291
Iterator myBeginIt
Definition: Circulator.h:431
bool operator<(const Self &) const
Definition: Circulator.h:409
bool operator>=(const Self &c) const
Definition: Circulator.h:421
bool isValid() const
Definition: Circulator.h:206
Circulator(const Circulator< other_Iterator > &other)
Definition: Circulator.h:155
bool operator==(const Self &other) const
Definition: Circulator.h:304
Circulator(const Iterator &i, const Iterator &itb, const Iterator &ite)
Definition: Circulator.h:129
Iterator myCurrentIt
Definition: Circulator.h:430
bool operator>(const Self &c) const
Definition: Circulator.h:417
Iterator myEndIt
Definition: Circulator.h:432
Self operator+(difference_type d) const
Definition: Circulator.h:377
reference operator*() const
Definition: Circulator.h:234
bool operator<=(const Self &) const
Definition: Circulator.h:413
Circulator(const Circulator &other)
Definition: Circulator.h:144
bool operator!=(const OtherIterator &other) const
Definition: Circulator.h:334
Circulator< TIterator > operator+(typename IteratorCirculatorTraits< TIterator >::Difference d, Circulator< TIterator > &object)
Definition: Circulator.h:453
Self & operator--()
Definition: Circulator.h:280
difference_type operator-(const Self &c) const
Definition: Circulator.h:389
Self operator-(difference_type d) const
Definition: Circulator.h:383
Aim: Provides an adapter for classical iterators that can iterate through the underlying data structu...
Definition: Circulator.h:85
Iterator base() const
Definition: Circulator.h:216
DGtal is the top-level namespace which contains all DGtal functions and types.
Self & operator+=(difference_type d)
Definition: Circulator.h:340
CirculatorType Type
Definition: Circulator.h:98
TIterator Iterator
Definition: Circulator.h:95
Circulator & operator=(const Circulator &other)
Definition: Circulator.h:166
boost::iterator_category< TIterator >::type iterator_category
Definition: Circulator.h:101
Self & operator++()
Definition: Circulator.h:258
Self & operator-=(difference_type d)
Definition: Circulator.h:375
Iterator begin() const
Definition: Circulator.h:222
pointer operator->() const
Definition: Circulator.h:244
bool operator!=(const Self &other) const
Definition: Circulator.h:317
Self operator++(int)
Definition: Circulator.h:269
std::iterator_traits< TIterator >::reference reference
Definition: Circulator.h:106
std::iterator_traits< TIterator >::difference_type difference_type
Definition: Circulator.h:104
bool operator==(const OtherIterator &other) const
Definition: Circulator.h:320