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