Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE) 00002 // 00003 // This file is part of Olena. 00004 // 00005 // Olena is free software: you can redistribute it and/or modify it under 00006 // the terms of the GNU General Public License as published by the Free 00007 // Software Foundation, version 2 of the License. 00008 // 00009 // Olena is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 // As a special exception, you may use this file as part of a free 00018 // software project without restriction. Specifically, if other files 00019 // instantiate templates or use macros or inline functions from this 00020 // file, or you compile this file and link it with other files to produce 00021 // an executable, this file does not by itself cause the resulting 00022 // executable to be covered by the GNU General Public License. This 00023 // exception does not however invalidate any other reasons why the 00024 // executable file might be covered by the GNU General Public License. 00025 00026 #ifndef MLN_TOPO_ADJ_M_FACE_ITER_HH 00027 # define MLN_TOPO_ADJ_M_FACE_ITER_HH 00028 00034 00035 # include <set> 00036 # include <vector> 00037 00038 # include <mln/topo/internal/complex_relative_iterator_base.hh> 00039 # include <mln/topo/face.hh> 00040 00041 00042 namespace mln 00043 { 00044 00045 namespace topo 00046 { 00047 00048 // Forward declarations. 00049 template <unsigned D> class complex; 00050 namespace internal 00051 { 00052 template <unsigned D> class adj_m_face_iterator; 00053 } 00054 00055 00056 /*-------------------------------. 00057 | topo::adj_m_face_fwd_iter<D>. | 00058 `-------------------------------*/ 00059 00069 template <unsigned D> 00070 class adj_m_face_fwd_iter 00071 : public internal::forward_complex_relative_iterator_base< topo::face<D>, 00072 algebraic_face<D>, 00073 adj_m_face_fwd_iter<D> >, 00074 public internal::adj_m_face_iterator<D> 00075 { 00076 // Tech note: we use topo::face to help g++-2.95. 00077 private: 00078 typedef adj_m_face_fwd_iter<D> self_; 00079 typedef internal::forward_complex_relative_iterator_base< topo::face<D>, 00080 algebraic_face<D>, 00081 self_ > super_; 00082 typedef internal::adj_m_face_iterator<D> impl_; 00083 00084 public: 00089 adj_m_face_fwd_iter(); 00092 template <typename Fref> 00093 adj_m_face_fwd_iter(const Fref& f_ref, unsigned m); 00095 00100 void update_adj_faces_(); 00101 }; 00102 00103 00104 /*-------------------------------. 00105 | topo::adj_m_face_bkd_iter<D>. | 00106 `-------------------------------*/ 00107 00117 template <unsigned D> 00118 class adj_m_face_bkd_iter 00119 : public internal::backward_complex_relative_iterator_base< topo::face<D>, 00120 algebraic_face<D>, 00121 adj_m_face_bkd_iter<D> >, 00122 public internal::adj_m_face_iterator<D> 00123 { 00124 // Tech note: we use topo::face to help g++-2.95. 00125 private: 00126 typedef adj_m_face_bkd_iter<D> self_; 00127 typedef internal::backward_complex_relative_iterator_base< topo::face<D>, 00128 algebraic_face<D>, 00129 self_ > super_; 00130 typedef internal::adj_m_face_iterator<D> impl_; 00131 00132 public: 00137 adj_m_face_bkd_iter(); 00140 template <typename Fref> 00141 adj_m_face_bkd_iter(const Fref& f_ref, unsigned m); 00143 00148 void update_adj_faces_(); 00149 }; 00150 00151 00152 /*-----------------------------------------. 00153 | topo::internal::adj_m_face_iterator<D>. | 00154 `-----------------------------------------*/ 00155 00156 namespace internal 00157 { 00158 00159 template <unsigned D> 00160 class adj_m_face_iterator 00161 { 00162 protected: 00163 adj_m_face_iterator(); 00164 adj_m_face_iterator(unsigned m); 00165 00166 public: 00168 unsigned m() const; 00170 void set_m(unsigned m); 00171 00172 protected: 00175 void update_adj_faces__(const topo::face<D>& center, 00176 std::vector< algebraic_face<D> >& adj_faces); 00177 00179 unsigned m_; 00180 }; 00181 00182 } // end of namespace mln::topo::internal 00183 00184 00185 00186 # ifndef MLN_INCLUDE_ONLY 00187 00188 /*-------------------------------. 00189 | topo::adj_m_face_fwd_iter<D>. | 00190 `-------------------------------*/ 00191 00192 template <unsigned D> 00193 inline 00194 adj_m_face_fwd_iter<D>::adj_m_face_fwd_iter() 00195 { 00196 } 00197 00198 template <unsigned D> 00199 template <typename Fref> 00200 inline 00201 adj_m_face_fwd_iter<D>::adj_m_face_fwd_iter(const Fref& f_ref, unsigned m) 00202 : super_(f_ref), impl_(m) 00203 { 00204 } 00205 00206 template <unsigned D> 00207 inline 00208 void 00209 adj_m_face_fwd_iter<D>::update_adj_faces_() 00210 { 00211 mln_precondition(this->c_); 00212 // Delegate computation to base class. 00213 this->update_adj_faces__(*this->c_, this->adj_faces_); 00214 } 00215 00216 00217 /*-------------------------------. 00218 | topo::adj_m_face_bkd_iter<D>. | 00219 `-------------------------------*/ 00220 00221 template <unsigned D> 00222 inline 00223 adj_m_face_bkd_iter<D>::adj_m_face_bkd_iter() 00224 { 00225 } 00226 00227 template <unsigned D> 00228 template <typename Fref> 00229 inline 00230 adj_m_face_bkd_iter<D>::adj_m_face_bkd_iter(const Fref& f_ref, unsigned m) 00231 : super_(f_ref), impl_(m) 00232 { 00233 } 00234 00235 template <unsigned D> 00236 inline 00237 void 00238 adj_m_face_bkd_iter<D>::update_adj_faces_() 00239 { 00240 mln_precondition(this->c_); 00241 // Delegate computation to base class. 00242 this->update_adj_faces__(*this->c_, this->adj_faces_); 00243 } 00244 00245 00246 /*-----------------------------------------. 00247 | topo::internal::adj_m_face_iterator<D>. | 00248 `-----------------------------------------*/ 00249 00250 namespace internal 00251 { 00252 00253 template <unsigned D> 00254 inline 00255 adj_m_face_iterator<D>::adj_m_face_iterator() 00256 : m_(0) 00257 { 00258 } 00259 00260 template <unsigned D> 00261 inline 00262 adj_m_face_iterator<D>::adj_m_face_iterator(unsigned m) 00263 : m_(m) 00264 { 00265 mln_precondition(m <= D); 00266 } 00267 00268 template <unsigned D> 00269 unsigned 00270 adj_m_face_iterator<D>::m() const 00271 { 00272 return m_; 00273 } 00274 00275 template <unsigned D> 00276 void 00277 adj_m_face_iterator<D>::set_m(unsigned m) 00278 { 00279 m_ = m; 00280 } 00281 00282 template <unsigned D> 00283 inline 00284 void 00285 adj_m_face_iterator<D>::update_adj_faces__(const topo::face<D>& center, 00286 std::vector< algebraic_face<D> >& adj_faces) 00287 { 00288 adj_faces.clear(); 00289 00290 if (center.n() == m_) 00291 return; 00292 00293 typedef std::vector < topo::algebraic_face<D> > faces_t; 00294 typedef std::set < topo::algebraic_face<D> > faces_set_t; 00295 00296 /* FIXME: p_faces is redundant; we could use adj_faces 00297 directly. */ 00298 /* The adjacent p-faces being built; initialized with CENTER, 00299 and filled with q-faces at each step, until q reaches 00300 m_. */ 00301 faces_t p_faces(1, 00302 make_algebraic_face(center, true)); 00303 // The set of faces being built. 00304 /* FIXME: This pattern is recurring in Milena---using an 00305 std::set (or any fast associative container) to improve 00306 the lookup speed of an std::vector; we should create a 00307 class for this, a bit like mln::util::set, but with a 00308 garantee on the order of insertion. */ 00309 faces_t work_faces; 00310 faces_set_t work_faces_set; 00311 00312 // Iteratively compute the set of locations. 00313 for (unsigned p = center.n(); p != m_; (p < m_ ? ++p : --p) ) 00314 { 00315 mln_invariant (p != m_); 00316 for (typename faces_t::const_iterator g = p_faces.begin(); 00317 g != p_faces.end(); ++g) 00318 { 00319 mln_invariant (g->n() != m_); 00320 faces_t q_faces = g->n() < m_ ? 00321 g->higher_dim_adj_faces() : 00322 g->lower_dim_adj_faces(); 00323 /* Traverse the higher- or lower-dimension adjacent 00324 faces of G in the natural order if G's sign is 00325 positive, or in the reverse order if G's sign is 00326 negative. */ 00327 /* FIXME: Factor; the code if the two branches is the 00328 same, except for the iteration order. */ 00329 if (g->sign()) 00330 { 00331 for (typename faces_t::const_iterator h = q_faces.begin(); 00332 h != q_faces.end(); ++h) 00333 // Don't insert a face twice. 00334 if (work_faces_set.find(*h) == work_faces_set.end()) 00335 { 00336 work_faces.push_back(*h); 00337 work_faces_set.insert(*h); 00338 } 00339 } 00340 else 00341 { 00342 for (typename faces_t::const_reverse_iterator h = 00343 q_faces.rbegin(); 00344 /* This is crazy. With Apple g++ 4.0, this 00345 code won't compile without this cast! 00346 This is solved in MacPorts g++ 4.3. */ 00347 h != (typename faces_t::const_reverse_iterator) q_faces.rend(); 00348 ++h) 00349 // Don't insert a face twice. 00350 if (work_faces_set.find(*h) == work_faces_set.end()) 00351 { 00352 work_faces.push_back(*h); 00353 work_faces_set.insert(*h); 00354 } 00355 } 00356 } 00357 work_faces.swap(p_faces); 00358 work_faces.clear(); 00359 work_faces_set.clear(); 00360 } 00361 00362 adj_faces = p_faces; 00363 } 00364 00365 } // end of namespace mln::topo::internal 00366 00367 # endif // ! MLN_INCLUDE_ONLY 00368 00369 } // end of namespace mln::topo 00370 00371 } // end of namespace mln 00372 00373 #endif // ! MLN_TOPO_ADJ_M_FACE_ITER_HH