DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
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/IteratorTraits.h"
46 
47 namespace DGtal
48 {
49 
50 
52  // template class Circulator
76  template <typename TIterator>
77  class Circulator
78  {
79 
80  // ----------------------- Types ------------------------------
81  public:
82 
83  typedef TIterator Iterator;
85 
86  typedef CirculatorType Type;
87 
88  typedef typename boost::iterator_category<TIterator>::type
90 
91  typedef typename iterator_traits<TIterator>::value_type value_type;
92  typedef typename iterator_traits<TIterator>::difference_type difference_type;
93  typedef typename iterator_traits<TIterator>::pointer pointer;
94  typedef typename iterator_traits<TIterator>::reference reference;
95 
96 
97 
98  // ----------------------- Standard services ------------------------------
99  public:
100 
107 
108 
117  explicit
119  const Iterator& itb,
120  const Iterator& ite)
121  : myCurrentIt(i), myBeginIt(itb), myEndIt(ite), myFlagIsValid(true)
122  { if (myBeginIt == myEndIt) myFlagIsValid = false; }
123 
128 
133  Circulator ( const Circulator & other )
134  : myCurrentIt(other.myCurrentIt),
135  myBeginIt(other.myBeginIt), myEndIt(other.myEndIt),
137  {}
138 
143  template<typename other_Iterator>
145  : myCurrentIt(other.base()),
146  myBeginIt(other.begin()), myEndIt(other.end()),
147  myFlagIsValid(other.isValid())
148  {}
149 
155  Circulator & operator= ( const Circulator & other )
156  {
157  if ( this != &other )
158  {
159  myCurrentIt = other.myCurrentIt;
160  myBeginIt = other.myBeginIt;
161  myEndIt = other.myEndIt;
162  if (myBeginIt != myEndIt)
163  myFlagIsValid = true;
164  else
165  myFlagIsValid = false;
166  }
167  return *this;
168  }
169 
175  template<typename other_Iterator>
177  {
178  if ( this != &other )
179  {
180  myCurrentIt = other.base();
181  myBeginIt = other.begin();
182  myEndIt = other.end();
183  if (myBeginIt != myEndIt)
184  myFlagIsValid = true;
185  else
186  myFlagIsValid = false;
187  }
188  return *this;
189  }
190 
195  bool isValid() const
196  { return myFlagIsValid; }
197 
198 
199  // ----------------------- Interface --------------------------------------
200  public:
201 
205  Iterator base() const
206  { return myCurrentIt; }
207 
211  Iterator begin() const
212  { return myBeginIt; }
213 
217  Iterator end() const
218  { return myEndIt; }
219 
223  reference operator*() const {
224  //ASSERT( myCurrentIt != myEndIt ); //myCurrentIt == myEndIt when using reverse iterators on circulators
225  ASSERT( isValid() );
226  return *myCurrentIt;
227  }
228 
232  pointer operator->() const {
233  //ASSERT( myCurrentIt != myEndIt ); //myCurrentIt == myEndIt when using reverse iterators on circulators
234  ASSERT( isValid() );
235  return myCurrentIt.operator->();
236  }
237 
238 
239  // ----------------------- Incrementation/Decrementation --------------------------------------
240  public:
241 
246  {
247  ASSERT( isValid() );
248  ++myCurrentIt;
250  return *this;
251  }
252 
257  {
258  Self tmp = *this;
259  operator++();
260  return tmp;
261  }
262 
263 
268  {
269  ASSERT( isValid() );
271  --myCurrentIt;
272  return *this;
273  }
274 
279  {
280  Self tmp = *this;
281  operator--();
282  return tmp;
283  }
284 
285  // ----------------------- Equality operators --------------------------------------
286  public:
287 
288  //'true' if their three underlying iterators are equal
289  //or if their underlying ranges are both empty,
290  //'false' otherwise
291  bool operator==( const Self& other) const {
292  return ( ( (myBeginIt == other.begin())
293  &&(myEndIt == other.end())
294  &&(myCurrentIt == other.base()) )
295  ||( (!isValid())&&(!other.isValid()) ) );
296  }
297  bool operator!=( const Self& other) const { return !(*this == other); }
298 
299  template<typename OtherIterator>
300  bool operator==( const OtherIterator& other) const {
301  return ( ( (myBeginIt == other.begin())
302  &&(myEndIt == other.end())
303  &&(myCurrentIt == other.base()) )
304  ||( (!isValid())&&(!other.isValid()) ) );
305  }
306  template<typename OtherIterator>
307  bool operator!=( const OtherIterator& other) const { return !(*this == other); }
308 
309 
310  // ----------------------- Random access operators --------------------------------------
311  public:
312 
314  ASSERT( isValid() );
315  typename Iterator::difference_type j = myCurrentIt - myBeginIt;
316  typename Iterator::difference_type n = myEndIt - myBeginIt;
317  ASSERT( n > 0 );
318  ASSERT( (j >= 0) && (j < n) );
319  typename Iterator::difference_type e = n - j;
320  if (d < e) j += d;
321  else j = d - e;
322  ASSERT( (j >= 0) && (j < n) );
323  myCurrentIt = myBeginIt + j;
324  return *this;
325  }
327  Self tmp = *this;
328  return tmp += d;
329  }
331  Self tmp = *this;
332  return tmp += -d;
333  }
335 
336  difference_type operator-( const Self& c) const {
337  ASSERT( isValid() );
338  ASSERT( c.isValid() );
339  return myCurrentIt - c.myCurrentIt;
340  }
342  Self tmp = *this;
343  tmp += d;
344  return *tmp;
345  }
346 
347  // ----------------------- Comparisons operators --------------------------------------
348  // Contrary to iterators, random access circulators have no comparison operators.
349 
350 
351  // ------------------------- Protected Datas --------------------------------
352  protected:
353 
358 
359  // ------------------------- Private Datas --------------------------------
360  private:
361 
362 
363 
364  // ------------------------- Hidden services ------------------------------
365  protected:
366 
367 
368 
369  private:
370 
371 
372  }; // end of class Circulator
373 
374 
375 } // namespace DGtal
376 
377 #include "DGtal/base/IteratorFunctions.h"
378 
380 // Includes inline functions.
381 //#include "DGtal/base/Circulator.ih"
382 
383 // //
385 
386 #endif // !defined Circulator_h
387 
388 #undef Circulator_RECURSES
389 #endif // else defined(Circulator_RECURSES)