00001 
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   
00019   std::bidirectional_iterator_tag,
00020   
00021   typename 
00022   Loki::Select<Const, typename _Mesh::ConstEdge,
00023                typename _Mesh::Edge>::Result,
00024   
00025   std::ptrdiff_t, 
00026   
00027   typename 
00028   Loki::Select<Const, const typename _Mesh::ConstEdge*,
00029                typename _Mesh::Edge*>::Result,
00030   
00031   typename 
00032   Loki::Select<Const, const typename _Mesh::ConstEdge&,
00033                typename _Mesh::Edge&>::Result> {
00034   
00035   
00036   
00037 
00038 private:
00039 
00041   enum {M = _Mesh::M};
00042 
00043   
00044   
00045   
00046 
00047 private:
00048 
00050   typedef std::iterator< 
00051     
00052     std::bidirectional_iterator_tag,
00053     
00054     typename 
00055     Loki::Select<Const, typename _Mesh::ConstEdge,
00056                  typename _Mesh::Edge>::Result,
00057     
00058     std::ptrdiff_t, 
00059     
00060     typename 
00061     Loki::Select<Const, const typename _Mesh::ConstEdge*,
00062                  typename _Mesh::Edge*>::Result,
00063     
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   
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   
00113   
00114 
00115 private:
00116   
00118   Edge _edge;
00120   CellIterator _cellsEnd;
00121 
00122   
00123   
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     
00211     return _edge;
00212   }
00213 
00215   pointer
00216   operator->() const {
00217     
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   
00271   
00272 
00274   bool
00275   operator==(const EdgeIterator& x) {
00276 #ifdef DEBUG_EdgeIterator
00277     
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   
00295   
00296   bool
00297   isValid() {
00298     if (_edge.first != _cellsEnd) {
00299       
00300       NodeIterator a = _edge.first->getNode(_edge.second);
00301       
00302       NodeIterator b = _edge.first->getNode(_edge.third);
00303       
00304       for (CellIncidentToNodeIterator c = a->getCellsBeginning(); 
00305            c != a->getCellsEnd(); ++c) {
00306         
00307         
00308         if (c->hasNode(b) && 
00309             c->getIdentifier() < _edge.first->getIdentifier()) {
00310           return false;
00311         }
00312       }
00313     }
00314     return true;
00315   }
00316 
00317   
00318   void
00319   increment() {
00320     
00321     while (_edge.first != _cellsEnd) {
00322       
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       
00334       if (isValid()) {
00335         
00336         break;
00337       }
00338     }
00339   }
00340 
00341   
00342   void
00343   decrement() {
00344     
00345     do {
00346       
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       
00358       if (isValid()) {
00359         
00360         break;
00361       }
00362     } while (_edge.first != _cellsEnd);
00363   }
00364 
00365 };
00366 
00367 END_NAMESPACE_GEOM
00368 
00369 #endif