DGtal 1.4.2
Loading...
Searching...
No Matches
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
47namespace DGtal
48{
49
50
52 // template class Circulator
84 template <typename TIterator>
86 {
87
88 BOOST_STATIC_ASSERT(( boost::is_same<
90 IteratorType >::value ));
91
92 // ----------------------- Types ------------------------------
93 public:
94
95 typedef TIterator Iterator;
97
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
217 { return myCurrentIt; }
218
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) );
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
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
Circulator(const Circulator &other)
Definition Circulator.h:144
Self operator-(difference_type d) const
Definition Circulator.h:383
bool operator<(const Self &) const
Definition Circulator.h:409
bool operator<=(const Self &) const
Definition Circulator.h:413
bool operator>=(const Self &c) const
Definition Circulator.h:421
CirculatorType Type
Definition Circulator.h:98
bool operator!=(const OtherIterator &other) const
Definition Circulator.h:334
std::iterator_traits< TIterator >::reference reference
Definition Circulator.h:106
Self & operator--()
Definition Circulator.h:280
Self & operator+=(difference_type d)
Definition Circulator.h:340
pointer operator->() const
Definition Circulator.h:244
BOOST_STATIC_ASSERT((boost::is_same< typename IteratorCirculatorTraits< TIterator >::Type, IteratorType >::value))
Circulator & operator=(const Circulator &other)
Definition Circulator.h:166
bool isValid() const
Definition Circulator.h:206
Iterator base() const
Definition Circulator.h:216
reference operator*() const
Definition Circulator.h:234
Self operator--(int)
Definition Circulator.h:291
TIterator Iterator
Definition Circulator.h:95
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
Self & operator++()
Definition Circulator.h:258
Iterator end() const
Definition Circulator.h:228
std::iterator_traits< TIterator >::value_type value_type
Definition Circulator.h:103
Circulator(const Iterator &i, const Iterator &itb, const Iterator &ite)
Definition Circulator.h:129
Iterator begin() const
Definition Circulator.h:222
Self operator+(difference_type d) const
Definition Circulator.h:377
Self & operator-=(difference_type d)
Definition Circulator.h:375
std::iterator_traits< TIterator >::pointer pointer
Definition Circulator.h:105
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
boost::iterator_category< TIterator >::type iterator_category
Definition Circulator.h:101
std::iterator_traits< TIterator >::difference_type difference_type
Definition Circulator.h:104
Circulator< TIterator > Self
Definition Circulator.h:96
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