vtf-logo

EdgeIterator.h

00001 // -*- C++ -*-
00002 
00003 #if !defined(__geom_mesh_simplicial_EdgeIterator_h__)
00004 #define __geom_mesh_simplicial_EdgeIterator_h__
00005 
00006 #if defined(DEBUG_geom) && !defined(DEBUG_EdgeIterator)
00007 #define DEBUG_EdgeIterator
00008 #endif
00009 
00010 
00011 BEGIN_NAMESPACE_GEOM
00012 
00014 template<class _Mesh, bool Const = true>
00015 class 
00016 EdgeIterator :
00017   public std::iterator< 
00018   // Iterator tag.
00019   std::bidirectional_iterator_tag,
00020   // Value type.
00021   typename 
00022   Loki::Select<Const, typename _Mesh::ConstEdge,
00023                typename _Mesh::Edge>::Result,
00024   // Pointer difference type.
00025   std::ptrdiff_t, 
00026   // Pointer type.
00027   typename 
00028   Loki::Select<Const, const typename _Mesh::ConstEdge*,
00029                typename _Mesh::Edge*>::Result,
00030   // Reference type.
00031   typename 
00032   Loki::Select<Const, const typename _Mesh::ConstEdge&,
00033                typename _Mesh::Edge&>::Result> {
00034   //
00035   // Enumerations.
00036   //
00037 
00038 private:
00039 
00041   enum {M = _Mesh::M};
00042 
00043   //
00044   // Private types.
00045   //
00046 
00047 private:
00048 
00050   typedef std::iterator< 
00051     // Iterator tag.
00052     std::bidirectional_iterator_tag,
00053     // Value type.
00054     typename 
00055     Loki::Select<Const, typename _Mesh::ConstEdge,
00056                  typename _Mesh::Edge>::Result,
00057     // Pointer difference type.
00058     std::ptrdiff_t, 
00059     // Pointer type.
00060     typename 
00061     Loki::Select<Const, const typename _Mesh::ConstEdge*,
00062                  typename _Mesh::Edge*>::Result,
00063     // Reference type.
00064     typename 
00065     Loki::Select<Const, const typename _Mesh::ConstEdge&,
00066                  typename _Mesh::Edge&>::Result> 
00067   Base;
00068 
00070   typedef _Mesh Mesh;
00072   typedef typename Mesh::Node Node;
00074   typedef typename Loki::Select<Const,
00075                                 typename Mesh::NodeConstIterator,
00076                                 typename Mesh::NodeIterator>::Result
00077   NodeIterator;
00078 
00080   typedef 
00081   typename Loki::Select<Const,
00082                         typename Node::CellIncidentToNodeConstIterator,
00083                         typename Node::CellIncidentToNodeIterator>::Result
00084   CellIncidentToNodeIterator;
00085 
00086   //
00087   // Public types.
00088   //
00089 
00090 public:
00091 
00093   typedef typename Base::iterator_category iterator_category;
00095   typedef typename Base::value_type value_type;
00097   typedef typename Base::difference_type difference_type;
00099   typedef typename Base::pointer pointer;
00101   typedef typename Base::reference reference;
00102 
00104   typedef value_type Edge;
00106   typedef typename Loki::Select<Const,
00107                                 typename Mesh::CellConstIterator,
00108                                 typename Mesh::CellIterator>::Result
00109   CellIterator;
00110 
00111   //
00112   // Member data.
00113   //
00114 
00115 private:
00116   
00118   Edge _edge;
00120   CellIterator _cellsEnd;
00121 
00122   //
00123   // Not implemented.
00124   //
00125 
00126 private:
00127 
00129   EdgeIterator();
00130 
00131 public:
00132 
00133   //--------------------------------------------------------------------------
00135 
00136 
00138   EdgeIterator(const CellIterator c, const CellIterator cellsEnd) :
00139     Base(),
00140     _edge(c, 0, 1),
00141     _cellsEnd(cellsEnd) {
00142     if (c != cellsEnd && ! isValid()) {
00143       increment();
00144     }
00145   }
00146 
00148 
00149 public:
00150 
00151   //--------------------------------------------------------------------------
00153 
00154 
00156   EdgeIterator(const EdgeIterator& other) :
00157     Base(),
00158     _edge(other._edge),
00159     _cellsEnd(other._cellsEnd)
00160   {}    
00161 
00163   EdgeIterator&
00164   operator=(const EdgeIterator& other) {
00165     if (&other != this) {
00166       _edge = other._edge;
00167       _cellsEnd = other._cellsEnd;
00168     }
00169     return *this;
00170   }
00171 
00173   ~EdgeIterator()
00174   {}
00175 
00177 
00180   const Edge&
00181   getEdge() const {
00182     return _edge;
00183   }
00184 
00186 
00189   const CellIterator&
00190   getCellsEnd() const {
00191     return _cellsEnd;
00192   }
00193 
00195   template<bool _Const>
00196   EdgeIterator(const EdgeIterator<Mesh,_Const>& other) :
00197     Base(),
00198     _edge(other.getEdge()),
00199     _cellsEnd(other.getCellsEnd())
00200   {}    
00201 
00203   //--------------------------------------------------------------------------
00205 
00206 
00208   reference
00209   operator*() const {
00210     // Return a constant reference to the edge.
00211     return _edge;
00212   }
00213 
00215   pointer
00216   operator->() const {
00217     // Return a constant pointer to the edge.
00218     return &_edge;
00219   }
00220   
00222   EdgeIterator&
00223   operator++() { 
00224     increment();
00225     return *this; 
00226   }
00227       
00229 
00233   EdgeIterator
00234   operator++(int) {
00235     EdgeIterator x(*this); 
00236     ++*this;
00237     return x;
00238   }
00239       
00241   //--------------------------------------------------------------------------
00243 
00244 
00246   EdgeIterator&
00247   operator--() { 
00248     decrement();
00249     return *this; 
00250   }
00251       
00253 
00257   EdgeIterator
00258   operator--(int) {
00259     EdgeIterator x(*this); 
00260     --*this;
00261     return x;
00262   }
00263 
00265   //--------------------------------------------------------------------------
00267 
00268       
00269   //
00270   // Forward iterator requirements
00271   //
00272 
00274   bool
00275   operator==(const EdgeIterator& x) {
00276 #ifdef DEBUG_EdgeIterator
00277     // These must be iterators over the same mesh.
00278     assert(_cellsEnd == x._cellsEnd);
00279 #endif
00280     return _edge == x._edge;
00281   }
00282 
00284   bool
00285   operator!=(const EdgeIterator& x) {
00286     return ! operator==(x);
00287   }
00288 
00290 
00291 
00292 private:
00293 
00294   // If the address of this cell is less than the addresses of the other
00295   // cells incident to the edge.
00296   bool
00297   isValid() {
00298     if (_edge.first != _cellsEnd) {
00299       // The source node of the edge.
00300       NodeIterator a = _edge.first->getNode(_edge.second);
00301       // The target node of the edge.
00302       NodeIterator b = _edge.first->getNode(_edge.third);
00303       // For each incident cell of the source node.
00304       for (CellIncidentToNodeIterator c = a->getCellsBeginning(); 
00305            c != a->getCellsEnd(); ++c) {
00306         // If this cell is incident to the edge and its identifier is less 
00307         // than this cell's identifier.
00308         if (c->hasNode(b) && 
00309             c->getIdentifier() < _edge.first->getIdentifier()) {
00310           return false;
00311         }
00312       }
00313     }
00314     return true;
00315   }
00316 
00317   // Increment the iterator.
00318   void
00319   increment() {
00320     // While we have not gone through all of the cells.
00321     while (_edge.first != _cellsEnd) {
00322       // Go to the next edge.
00323       ++_edge.third;
00324       if (_edge.third == M + 1) {
00325         ++_edge.second;
00326         _edge.third = _edge.second + 1;
00327       }
00328       if (_edge.second == M) {
00329         ++_edge.first;
00330         _edge.second = 0;
00331         _edge.third = 1;
00332       }
00333       // If this edge is valid.
00334       if (isValid()) {
00335         // Then we have a edge.  Break out of the loop and return.
00336         break;
00337       }
00338     }
00339   }
00340 
00341   // Decrement the iterator.
00342   void
00343   decrement() {
00344     // While we have not gone through all of the cells.
00345     do {
00346       // Go to the previous edge.
00347       --_edge.third;
00348       if (_edge.third == _edge.second) {
00349         --_edge.second;
00350         _edge.third = M;
00351       }
00352       if (_edge.second == -1) {
00353         --_edge.first;
00354         _edge.second = M-1;
00355         _edge.third = M;
00356       }
00357       // If this edge is valid.
00358       if (isValid()) {
00359         // Then we have a edge.  Break out of the loop and return.
00360         break;
00361       }
00362     } while (_edge.first != _cellsEnd);
00363   }
00364 
00365 };
00366 
00367 END_NAMESPACE_GEOM
00368 
00369 #endif

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