DGtal  1.4.beta
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)
35 #define Circulator_RECURSES
36 
37 #if !defined Circulator_h
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 
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 
235  {
236  //ASSERT( myCurrentIt != myEndIt ); //myCurrentIt == myEndIt when using reverse iterators on circulators
237  ASSERT( isValid() );
238  return *myCurrentIt;
239  }
240 
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 
259  {
260  ASSERT( isValid() );
261  ++myCurrentIt;
263  return *this;
264  }
265 
270  {
271  Self tmp = *this;
272  operator++();
273  return tmp;
274  }
275 
276 
281  {
282  ASSERT( isValid() );
284  --myCurrentIt;
285  return *this;
286  }
287 
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 
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 
376 
378  {
379  Self tmp = *this;
380  return tmp += d;
381  }
382 
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  }
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 
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)
Aim: Provides an adapter for classical iterators that can iterate through the underlying data structu...
Definition: Circulator.h:86
Self & operator-=(difference_type d)
Definition: Circulator.h:375
CirculatorType Type
Definition: Circulator.h:98
Circulator(const Circulator &other)
Definition: Circulator.h:144
Self operator-(difference_type d) const
Definition: Circulator.h:383
TIterator Iterator
Definition: Circulator.h:95
std::iterator_traits< TIterator >::difference_type difference_type
Definition: Circulator.h:104
bool operator<(const Self &) const
Definition: Circulator.h:409
bool operator<=(const Self &) const
Definition: Circulator.h:413
std::iterator_traits< TIterator >::value_type value_type
Definition: Circulator.h:103
bool operator>=(const Self &c) const
Definition: Circulator.h:421
bool operator!=(const OtherIterator &other) const
Definition: Circulator.h:334
Circulator & operator=(const Circulator &other)
Definition: Circulator.h:166
pointer operator->() const
Definition: Circulator.h:244
BOOST_STATIC_ASSERT((boost::is_same< typename IteratorCirculatorTraits< TIterator >::Type, IteratorType >::value))
bool isValid() const
Definition: Circulator.h:206
Iterator base() const
Definition: Circulator.h:216
reference operator*() const
Definition: Circulator.h:234
Self & operator+=(difference_type d)
Definition: Circulator.h:340
Self operator--(int)
Definition: Circulator.h:291
std::iterator_traits< TIterator >::reference reference
Definition: Circulator.h:106
Circulator< TIterator > Self
Definition: Circulator.h:96
reference operator[](difference_type d) const
Definition: Circulator.h:401
Circulator(const Circulator< other_Iterator > &other)
Definition: Circulator.h:155
difference_type operator-(const Self &c) const
Definition: Circulator.h:389
Iterator end() const
Definition: Circulator.h:228
Iterator myBeginIt
Definition: Circulator.h:431
boost::iterator_category< TIterator >::type iterator_category
Definition: Circulator.h:101
Circulator(const Iterator &i, const Iterator &itb, const Iterator &ite)
Definition: Circulator.h:129
Self & operator--()
Definition: Circulator.h:280
Iterator begin() const
Definition: Circulator.h:222
Self & operator++()
Definition: Circulator.h:258
Self operator+(difference_type d) const
Definition: Circulator.h:377
Iterator myEndIt
Definition: Circulator.h:432
Iterator myCurrentIt
Definition: Circulator.h:430
Self operator++(int)
Definition: Circulator.h:269
bool operator>(const Self &c) const
Definition: Circulator.h:417
bool operator!=(const Self &other) const
Definition: Circulator.h:317
bool operator==(const Self &other) const
Definition: Circulator.h:304
std::iterator_traits< TIterator >::pointer pointer
Definition: Circulator.h:105
bool operator==(const OtherIterator &other) const
Definition: Circulator.h:320
DGtal is the top-level namespace which contains all DGtal functions and types.
Circulator< TIterator > operator+(typename IteratorCirculatorTraits< TIterator >::Difference d, Circulator< TIterator > &object)
Definition: Circulator.h:453