DGtal 0.3.0

HyperRectDomain_Iterator.h

Go to the documentation of this file.
00001 
00017 #pragma once
00018 
00032 #if defined(HyperRectDomain_Iterator_RECURSES)
00033 #error Recursive header files inclusion detected in HyperRectDomain_Iterator.h
00034 #else // defined(HyperRectDomain_Iterator_RECURSES)
00035 
00036 #define HyperRectDomain_Iterator_RECURSES
00037 
00038 #if !defined HyperRectDomain_Iterator_h
00039 
00040 #define HyperRectDomain_Iterator_h
00041 
00043 // Inclusions
00044 #include <iostream>
00045 #include <vector>
00046 #include "DGtal/base/Common.h"
00049 //#include <iterator> // Bug for operator * => dangling reference !!!
00050 // Class allowing to build a reverse iterator of a given iterator.
00051 template<typename _Iterator>
00052 class myreverse_iterator
00053         : public iterator<typename iterator_traits<_Iterator>::iterator_category,
00054         typename iterator_traits<_Iterator>::value_type,
00055         typename iterator_traits<_Iterator>::difference_type,
00056         typename iterator_traits<_Iterator>::pointer,
00057         typename iterator_traits<_Iterator>::reference>
00058 {
00059 protected:
00060         _Iterator current;
00061         _Iterator prev;
00062 
00063 public:
00064   typedef _Iterator                                            iterator_type;
00065   typedef typename iterator_traits<_Iterator>::difference_type
00066       difference_type;
00067   typedef typename iterator_traits<_Iterator>::reference   reference;
00068   typedef typename iterator_traits<_Iterator>::pointer     pointer;
00069 
00070 public:
00071   explicit
00072       myreverse_iterator(iterator_type __x) : current(__x),
00073       prev(current)
00074   { --prev; }
00075 
00076   myreverse_iterator(const myreverse_iterator& __x)
00077     : current(__x.current), prev(__x.prev) { }
00078 
00079   iterator_type base() const
00080   { return current; }
00081 
00082   const reference operator*() const
00083   { return *prev; }
00084 
00085   reference operator*()
00086   { return *prev; }
00087 
00088   pointer operator->() const
00089   { return &(operator*()); }
00090 
00091   myreverse_iterator& operator++()
00092   { --current; --prev;
00093     return *this;
00094   }
00095 
00096   myreverse_iterator operator++(int)
00097   {
00098     myreverse_iterator __tmp = *this;
00099     operator++();
00100     return __tmp;
00101   }
00102 
00103   myreverse_iterator& operator--()
00104   {
00105     ++current; ++prev;
00106     return *this;
00107   }
00108 
00109   myreverse_iterator operator--(int)
00110   {
00111     myreverse_iterator __tmp = *this;
00112     operator--();
00113     return __tmp;
00114   }
00115 
00116   myreverse_iterator operator+(difference_type __n) const
00117   { return myreverse_iterator(current - __n); }
00118 
00119   myreverse_iterator& operator+=(difference_type __n)
00120                                 {
00121     current -= __n; prev = current; --prev;
00122     return *this;
00123   }
00124 
00125   myreverse_iterator operator-(difference_type __n) const
00126   { return myreverse_iterator(current + __n); }
00127 
00128   myreverse_iterator& operator-=(difference_type __n)
00129                                 {
00130     current += __n; prev = current; --prev;
00131     return *this;
00132   }
00133 
00134   reference operator[](difference_type __n) const
00135   { return *(*this + __n); }
00136 };
00137 template<typename _Iterator>
00138 inline bool
00139     operator==(const myreverse_iterator<_Iterator>& __x,
00140                const myreverse_iterator<_Iterator>& __y)
00141 { return __x.base() == __y.base(); }
00142 template<typename _Iterator>
00143 inline bool
00144     operator!=(const myreverse_iterator<_Iterator>& __x,
00145                const myreverse_iterator<_Iterator>& __y)
00146 { return !(__x == __y); }
00147 
00148 //******************************************************************************
00149 namespace DGtal
00150 {
00152   // class HyperRectDomain_Iterator
00157   template<typename TPoint>
00158   class HyperRectDomain_Iterator
00159   {
00160   public:
00161     typedef std::bidirectional_iterator_tag iterator_category; 
00162     typedef TPoint value_type;
00163     typedef ptrdiff_t difference_type;
00164     typedef TPoint* pointer;
00165     typedef TPoint& reference;
00166     typedef typename TPoint::Dimension Dimension;
00167 
00168 
00169     HyperRectDomain_Iterator( const TPoint & p, const TPoint& lower, const TPoint &upper )
00170       : myPoint( p ), mylower( lower ), myupper( upper ),  myCurrentPos( 0 )
00171     {
00172       ASSERT( lower <= upper );
00173       ASSERT( lower <= p && p <= upper );
00174     }
00175 
00176     const TPoint & operator*() const
00177     {
00178       ASSERT(mylower<=myPoint && myPoint<=myupper); // we must be between [begin,end]
00179       return myPoint;
00180     }
00181     TPoint & operator*()
00182     {
00183       ASSERT(mylower<=myPoint && myPoint<=myupper); // we must be between [begin,end]
00184       return myPoint;
00185       }
00186 
00191     bool operator== ( const HyperRectDomain_Iterator<TPoint> &it ) const
00192     {
00193       return ( myPoint==it.myPoint );
00194     }
00195 
00200     bool operator!= ( const HyperRectDomain_Iterator<TPoint> &aIt ) const
00201     {
00202       return ( myPoint!=aIt.myPoint );
00203     }
00204 
00209     void nextLexicographicOrder()
00210     {
00211       ++myPoint[myCurrentPos];
00212       if (( myCurrentPos < TPoint::dimension - 1 ) &&
00213           ( myPoint[myCurrentPos] > myupper[myCurrentPos] ) )
00214         {
00215           do
00216             {
00217               myPoint[myCurrentPos] = mylower[myCurrentPos];
00218               myCurrentPos++;
00219               if ( myCurrentPos < TPoint::dimension )
00220                 ++myPoint[myCurrentPos];
00221             }
00222           while (( myCurrentPos < TPoint::dimension - 1 ) &&
00223                  ( myPoint[myCurrentPos]  >  myupper[ myCurrentPos ] ) );
00224           myCurrentPos = 0;
00225         }
00226     }
00227 
00231     HyperRectDomain_Iterator<TPoint> &operator++()
00232     {
00233       nextLexicographicOrder();
00234       return *this;
00235     }
00236 
00241     HyperRectDomain_Iterator<TPoint> operator++ ( int )
00242     {
00243       HyperRectDomain_Iterator<TPoint> tmp = *this;
00244       nextLexicographicOrder();
00245       return tmp;
00246     }
00247 
00252     void prevLexicographicOrder()
00253     {
00254       --myPoint[ myCurrentPos ];
00255       if (( myCurrentPos < TPoint::dimension - 1 ) &&
00256           ( myPoint[ myCurrentPos ]  <  mylower[ myCurrentPos ] ) )
00257         {
00258           do
00259             {
00260               myPoint[ myCurrentPos ] = myupper[ myCurrentPos ];
00261               ++myCurrentPos;
00262               if ( myCurrentPos < TPoint::dimension )
00263                 --myPoint[ myCurrentPos ];
00264             }
00265           while (( myCurrentPos < TPoint::dimension - 1 ) &&
00266                  ( myPoint[ myCurrentPos ]  <  mylower[ myCurrentPos ] ) );
00267           myCurrentPos = 0;
00268         }
00269     }
00270 
00275     HyperRectDomain_Iterator<TPoint> &operator--()
00276     {
00277       prevLexicographicOrder();
00278       return *this;
00279     }
00280 
00284     HyperRectDomain_Iterator<TPoint> operator-- ( int )
00285     {
00286       HyperRectDomain_Iterator<TPoint> tmp = *this;
00287       prevLexicographicOrder();
00288       return tmp;
00289     }
00290 
00291   private:
00293     TPoint myPoint;
00295     TPoint mylower, myupper;
00297     Dimension myCurrentPos;
00298   };
00300   // class HyperRectDomain_Iterator
00305   template<typename TPoint>
00306   class HyperRectDomain_subIterator
00307   {
00308   public:
00309     typedef std::bidirectional_iterator_tag iterator_category; 
00310     typedef TPoint value_type;
00311     typedef ptrdiff_t difference_type;
00312     typedef TPoint* pointer;
00313     typedef TPoint& reference;
00314     typedef typename TPoint::Dimension Dimension;
00315 
00316 #ifdef CPP0X_INITIALIZER_LIST
00317     HyperRectDomain_subIterator(const TPoint & p, const TPoint& lower,
00318                                 const TPoint &upper,
00319                                 std::initializer_list<Dimension> subDomain)
00320       : myPoint( p ), mylower( lower ), myupper( upper ),  myCurrentPos( 0 )
00321     {
00322       ASSERT( lower <= upper );
00323       ASSERT( lower <= p && p <= upper );
00324       ASSERT( subDomain.size() <= TPoint::dimension );
00325       mySubDomain.reserve( subDomain.size() );
00326       for ( const unsigned int *c = subDomain.begin();
00327             c != subDomain.end(); ++c )
00328         {
00329           ASSERT( *c <= TPoint::dimension );
00330           mySubDomain.push_back( *c );
00331         }
00332 
00333       // TODO: check the validity of the subDomain ?
00334     }
00335 #endif
00336     HyperRectDomain_subIterator(const TPoint & p, const TPoint& lower,
00337                              const TPoint &upper,
00338                              const std::vector<Dimension> &subDomain)
00339       : myPoint( p ), mylower( lower ), myupper( upper ),  myCurrentPos( 0 )
00340     {
00341       ASSERT( lower <= upper );
00342       ASSERT( lower <= p && p <= upper );
00343       ASSERT( subDomain.size() <= TPoint::dimension );
00344       mySubDomain.reserve( subDomain.size() );
00345       for ( typename std::vector<Dimension>::const_iterator it = subDomain.begin();
00346             it != subDomain.end(); ++it )
00347         {
00348           ASSERT( *it <= TPoint::dimension );
00349           mySubDomain.push_back( *it );
00350         }
00351 
00352       // TODO: check the validity of the subDomain ?
00353     }
00354 
00355 
00356     const TPoint & operator*() const
00357     {
00358       ASSERT(mylower<=myPoint && myPoint<=myupper); // we must be between [begin,end]
00359       return myPoint;
00360     }
00361     TPoint & operator*()
00362     {
00363       ASSERT(mylower<=myPoint && myPoint<=myupper); // we must be between [begin,end]
00364       return myPoint;
00365     }
00366 
00371     bool operator== ( const HyperRectDomain_subIterator<TPoint> &it ) const
00372     {
00373       return ( myPoint==it.myPoint );
00374     }
00375 
00380     bool operator!= ( const HyperRectDomain_subIterator<TPoint> &aIt ) const
00381     {
00382       return ( myPoint!=aIt.myPoint );
00383     }
00384 
00389     void nextSubDomainOrder()
00390     {
00391       ASSERT( myCurrentPos < mySubDomain.size() );
00392       ++myPoint[ mySubDomain[myCurrentPos] ];
00393 
00394       if ( myCurrentPos < mySubDomain.size() - 1 &&
00395            myPoint[ mySubDomain[myCurrentPos] ] >
00396            myupper[ mySubDomain[myCurrentPos] ] )
00397         {
00398           do
00399             {
00400               myPoint[ mySubDomain[myCurrentPos] ] =
00401                 mylower[ mySubDomain[myCurrentPos] ];
00402               ++myCurrentPos;
00403               if ( myCurrentPos < mySubDomain.size() )
00404                 ++myPoint[ mySubDomain[myCurrentPos] ];
00405             }
00406           while (( myCurrentPos < mySubDomain.size() - 1  ) &&
00407                  ( myPoint[ mySubDomain[myCurrentPos] ]  >
00408                    myupper[ mySubDomain[myCurrentPos] ] ) );
00409           myCurrentPos = 0;
00410         }
00411     }
00412 
00416     HyperRectDomain_subIterator<TPoint> &operator++()
00417     {
00418       nextSubDomainOrder();
00419       return *this;
00420     }
00421 
00426     HyperRectDomain_subIterator<TPoint> operator++ ( int )
00427     {
00428       HyperRectDomain_subIterator<TPoint> tmp = *this;
00429       nextSubDomainOrder();
00430       return tmp;
00431     }
00432 
00437     void prevSubDomainOrder()
00438     {
00439       ASSERT( myCurrentPos < mySubDomain.size() );
00440       --myPoint[ mySubDomain[myCurrentPos] ];
00441 
00442       if (  myCurrentPos < mySubDomain.size() - 1 &&
00443             myPoint[ mySubDomain[myCurrentPos] ]  <
00444             mylower[ mySubDomain[myCurrentPos] ] )
00445         {
00446           do
00447             {
00448               myPoint[ mySubDomain[myCurrentPos] ] =
00449                 myupper[ mySubDomain[myCurrentPos] ];
00450               ++myCurrentPos;
00451               if ( myCurrentPos < mySubDomain.size() )
00452                 --myPoint[ mySubDomain[myCurrentPos] ];
00453             }
00454           while (( myCurrentPos < mySubDomain.size() - 1 ) &&
00455                  ( myPoint[ mySubDomain[myCurrentPos] ]  <
00456                    mylower[ mySubDomain[myCurrentPos] ] ) );
00457           myCurrentPos = 0;
00458         }
00459     }
00460 
00465     HyperRectDomain_subIterator<TPoint> &operator--()
00466     {
00467       prevSubDomainOrder();
00468       return *this;
00469     }
00470 
00474     HyperRectDomain_subIterator<TPoint> operator-- ( int )
00475     {
00476       HyperRectDomain_subIterator<TPoint> tmp = *this;
00477       prevSubDomainOrder();
00478       return tmp;
00479     }
00480 
00481   private:
00483     TPoint myPoint;
00485     TPoint mylower, myupper;
00487     Dimension myCurrentPos;
00490     std::vector<Dimension> mySubDomain;
00491   };
00492 
00493 } //namespace
00494 //                                                                           //
00496 
00497 #endif // !defined HyperRectDomain_Iterator_h
00498 
00499 #undef HyperRectDomain_Iterator_RECURSES
00500 #endif // else defined(HyperRectDomain_Iterator_RECURSES)
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines