vtf-logo

IssiaFaceIterator.h

00001 // -*- C++ -*-
00002 
00003 #if !defined(__geom_mesh_iss_IssiaFaceIterator_h__)
00004 #define __geom_mesh_iss_IssiaFaceIterator_h__
00005 
00006 #if defined(DEBUG_geom) && !defined(DEBUG_IssiaFaceIterator)
00007 #define DEBUG_IssiaFaceIterator
00008 #endif
00009 
00010 
00011 BEGIN_NAMESPACE_GEOM
00012 
00014 
00018 template<class ISSIA>
00019 class 
00020 IssiaFaceIterator  :
00021   public std::iterator<std::bidirectional_iterator_tag, // Iterator tag.
00022                        std::pair<int,int>, // Value type.
00023                        std::ptrdiff_t, // Pointer difference type.
00024                        const std::pair<int,int>*, // Pointer type.
00025                        const std::pair<int,int>&> { // Reference type.
00026   //
00027   // Private types.
00028   //
00029 
00030 private:
00031 
00033   typedef std::iterator<std::bidirectional_iterator_tag,
00034                         std::pair<int,int>,
00035                         std::ptrdiff_t,
00036                         const std::pair<int,int>*,
00037                         const std::pair<int,int>&> Base;
00038   
00039   //
00040   // Public types.
00041   //
00042 
00043 public:
00044 
00046   typedef typename Base::iterator_category iterator_category;
00048   typedef typename Base::value_type value_type;
00050   typedef typename Base::difference_type difference_type;
00052   typedef typename Base::pointer pointer;
00054   typedef typename Base::reference reference;
00055 
00056   //
00057   // Member data.
00058   //
00059 
00060 private:
00061   
00063   const ISSIA* _mesh;
00065   value_type _face;
00066 
00067   //
00068   // Not implemented.
00069   //
00070 
00071 private:
00072 
00074   IssiaFaceIterator();
00075 
00076 public:
00077 
00078   //--------------------------------------------------------------------------
00080 
00081 
00083   IssiaFaceIterator(const ISSIA* mesh, const int simplexIndex) :
00084     Base(),
00085     _mesh(mesh),
00086     _face(simplexIndex, 0) {
00087     // We allow it to be equal to simplices_size for the past-the-end iterator.
00088     assert(0 <= simplexIndex && simplexIndex <= _mesh->getSimplicesSize());
00089     if (simplexIndex != _mesh->getSimplicesSize() && ! isValid()) {
00090       increment();
00091     }
00092   }
00093 
00095 
00096 public:
00097 
00098   //--------------------------------------------------------------------------
00100 
00101 
00103   IssiaFaceIterator(const IssiaFaceIterator& other) :
00104     Base(),
00105     _mesh(other._mesh),
00106     _face(other._face)
00107   {}    
00108 
00110   IssiaFaceIterator&
00111   operator=(const IssiaFaceIterator& other) {
00112     if (&other != this) {
00113       _mesh = other._mesh;
00114       _face = other._face;
00115     }
00116     return *this;
00117   }
00118 
00120   ~IssiaFaceIterator()
00121   {}
00122 
00124   //--------------------------------------------------------------------------
00126 
00127 
00129   reference
00130   operator*() const {
00131     // Return a constant reference to the face.
00132     return _face;
00133   }
00134 
00136   pointer
00137   operator->() const {
00138     // Return a constant pointer to the face.
00139     return &_face;
00140   }
00141   
00143   IssiaFaceIterator&
00144   operator++() { 
00145     increment();
00146     return *this; 
00147   }
00148       
00150 
00154   IssiaFaceIterator
00155   operator++(int) {
00156     IssiaFaceIterator x(*this); 
00157     ++*this;
00158     return x;
00159   }
00160       
00162   //--------------------------------------------------------------------------
00164 
00165 
00167   IssiaFaceIterator&
00168   operator--() { 
00169     decrement();
00170     return *this; 
00171   }
00172       
00174 
00178   IssiaFaceIterator
00179   operator--(int) {
00180     IssiaFaceIterator x(*this); 
00181     --*this;
00182     return x;
00183   }
00184 
00186   //--------------------------------------------------------------------------
00188 
00189       
00190   //
00191   // Forward iterator requirements
00192   //
00193 
00195   bool
00196   operator==(const IssiaFaceIterator& x) {
00197 #ifdef DEBUG_IssiaFaceIterator
00198     // These must be iterators over the same mesh.
00199     assert(_mesh == x._mesh);
00200 #endif
00201     return _face == x._face;
00202   }
00203 
00205   bool
00206   operator!=(const IssiaFaceIterator& x) {
00207     return ! operator==(x);
00208   }
00209 
00211 
00212 
00213 private:
00214 
00215   // If there is no adjacent cell through the face or
00216   // if the address of this cell is less than the address of the 
00217   // adjacent cell through the face.
00218   bool
00219   isValid() {
00220     // The index of the adjacent neighbor.
00221     int neighbor = _mesh->getAdjacent(_face.first, _face.second);
00222     // Return true if there is no neighbor or if our index is less than 
00223     // the neighbor.
00224     return (neighbor == -1 || _face.first < neighbor);
00225   }
00226 
00227   // Increment the iterator.
00228   void
00229   increment() {
00230     assert(0 <= _face.first && _face.first < _mesh->getSimplicesSize());
00231     assert(0 <= _face.second && _face.second <= ISSIA::M);
00232     // While we have not gone through all of the cells.
00233     while (_face.first != _mesh->getSimplicesSize()) {
00234       // Advance to the next face.
00235 
00236       // If we have not gone through all the faces of this cell.
00237       if (_face.second != ISSIA::M) {
00238         // Advance to the next face within the cell.
00239         ++_face.second;
00240       }
00241       else {
00242         // Advance to the next cell.
00243         ++_face.first;
00244         _face.second = 0;
00245       }
00246       
00247       // First check that we have not gone through all of the cells.
00248       // If there is no adjacent cell through the face or
00249       // if the index of this cell is less than the index of the 
00250       // adjacent cell through the face.
00251       if (_face.first != _mesh->getSimplicesSize() && isValid()) {
00252         // Then we have a face.  Break out of the loop and return.
00253         break;
00254       }
00255     }
00256   }
00257 
00258   // Decrement the iterator.
00259   void
00260   decrement() {
00261     // While we have not gone through all of the cells.
00262     while (_face.first != -1) {
00263 
00264       // Move to the previous face.
00265 
00266       // If we have not gone through all the faces of this cell.
00267       if (_face.second != 0) {
00268         // Go to the previous face within the cell.
00269         --_face.second;
00270       }
00271       else {
00272         // Go to the previous cell.
00273         --_face.first;
00274         _face.second = ISSIA::M;
00275       }
00276 
00277       // First check that we have not gone through all of the cells.
00278       // If there is no adjacent cell through the face or
00279       // if the index of this cell is less than the index of the 
00280       // adjacent cell through the face.
00281       if (_face.first != -1 && isValid()) {
00282         // Then we have a face.  Break out of the loop and return.
00283         break;
00284       }
00285     }
00286   }
00287 
00288 };
00289 
00290 END_NAMESPACE_GEOM
00291 
00292 #endif

Generated on Fri Aug 24 12:55:55 2007 for Computational Geometry Package by  doxygen 1.4.7