Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008, 2009, 2010, 2011 EPITA Research and Development 00002 // Laboratory (LRDE) 00003 // 00004 // This file is part of Olena. 00005 // 00006 // Olena is free software: you can redistribute it and/or modify it under 00007 // the terms of the GNU General Public License as published by the Free 00008 // Software Foundation, version 2 of the License. 00009 // 00010 // Olena is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00017 // 00018 // As a special exception, you may use this file as part of a free 00019 // software project without restriction. Specifically, if other files 00020 // instantiate templates or use macros or inline functions from this 00021 // file, or you compile this file and link it with other files to produce 00022 // an executable, this file does not by itself cause the resulting 00023 // executable to be covered by the GNU General Public License. This 00024 // exception does not however invalidate any other reasons why the 00025 // executable file might be covered by the GNU General Public License. 00026 00027 #ifndef MLN_TOPO_FACE_HH 00028 # define MLN_TOPO_FACE_HH 00029 00033 00034 # include <iostream> 00035 # include <vector> 00036 00037 # include <mln/value/internal/limits.hh> 00038 # include <mln/core/contract.hh> 00039 # include <mln/metal/bool.hh> 00040 00041 00042 namespace mln 00043 { 00044 00045 namespace topo 00046 { 00047 00048 // Forward declarations. 00049 template <unsigned D> class complex; 00050 template <unsigned N, unsigned D> class n_face; 00051 template <unsigned N, unsigned D> class face_data; 00052 template <unsigned N> class algebraic_face; 00053 00054 00055 /*-------. 00056 | Face. | 00057 `-------*/ 00058 00063 template <unsigned D> 00064 class face 00065 { 00066 public: 00067 // The type of the complex this handle points to. 00068 typedef complex<D> complex_type; 00069 00071 face(); 00073 face(complex<D>& complex, unsigned n, unsigned face_id); 00074 00076 template <unsigned N> 00077 face(const n_face<N, D>& f); 00078 00080 bool is_valid() const; 00082 void invalidate(); 00083 00087 complex<D> cplx() const; 00089 // FIXME: Rename as `dim'? 00090 unsigned n() const; 00092 // FIXME: Rename as `id'? 00093 unsigned face_id() const; 00094 00096 void set_cplx(const complex<D>& cplx); 00097 00099 void set_n(unsigned n); 00101 void inc_n(); 00103 void dec_n(); 00104 00106 void set_face_id(unsigned face_id); 00108 void inc_face_id(); 00110 void dec_face_id(); 00111 00113 template <unsigned N> 00114 face_data<N, D>& data() const; 00115 00116 // FIXME: To be overhauled. 00118 std::vector< algebraic_face<D> > lower_dim_adj_faces() const; 00120 std::vector< algebraic_face<D> > higher_dim_adj_faces() const; 00122 00123 private: 00127 mutable complex<D> cplx_; 00129 // FIXME: Rename as `dim_'? 00130 unsigned n_; 00132 // FIXME: Rename as `id_'? 00133 unsigned face_id_; 00134 }; 00135 00136 00139 00144 template <unsigned D> 00145 bool operator==(const face<D>& lhs, const face<D>& rhs); 00146 00151 template <unsigned D> 00152 bool operator!=(const face<D>& lhs, const face<D>& rhs); 00153 00161 template <unsigned D> 00162 bool operator< (const face<D>& lhs, const face<D>& rhs); 00163 00165 00166 00168 template <unsigned D> 00169 std::ostream& 00170 operator<<(std::ostream& ostr, const face<D>& f); 00171 00172 00173 00174 # ifndef MLN_INCLUDE_ONLY 00175 00176 template <unsigned D> 00177 inline 00178 face<D>::face() 00179 : cplx_(), 00180 n_(value::internal::limits<unsigned>::max()), 00181 face_id_(value::internal::limits<unsigned>::max()) 00182 { 00183 } 00184 00185 template <unsigned D> 00186 inline 00187 face<D>::face(complex<D>& c, unsigned n, unsigned face_id) 00188 : cplx_(c), n_(n), face_id_(face_id) 00189 { 00190 // Ensure N is compatible with D. 00191 mln_precondition(n <= D); 00192 } 00193 00194 template <unsigned D> 00195 template <unsigned N> 00196 inline 00197 face<D>::face(const n_face<N, D>& f) 00198 : cplx_(f.cplx()), n_(N), face_id_(f.face_id()) 00199 { 00200 // Ensure N is compatible with D. 00201 metal::bool_< N <= D >::check(); 00202 } 00203 00204 template <unsigned D> 00205 inline 00206 bool 00207 face<D>::is_valid() const 00208 { 00209 return n_ <= D && face_id_ < cplx_.nfaces_of_dim(n_); 00210 } 00211 00212 template <unsigned D> 00213 inline 00214 void 00215 face<D>::invalidate() 00216 { 00217 set_n(value::internal::limits<unsigned>::max()); 00218 set_face_id(value::internal::limits<unsigned>::max()); 00219 } 00220 00221 template <unsigned D> 00222 inline 00223 complex<D> 00224 face<D>::cplx() const 00225 { 00226 return cplx_; 00227 } 00228 00229 template <unsigned D> 00230 inline 00231 unsigned 00232 face<D>::n() const 00233 { 00234 return n_; 00235 } 00236 00237 template <unsigned D> 00238 inline 00239 unsigned 00240 face<D>::face_id() const 00241 { 00242 return face_id_; 00243 } 00244 00245 template <unsigned D> 00246 inline 00247 void 00248 face<D>::set_cplx(const complex<D>& cplx) 00249 { 00250 cplx_ = cplx; 00251 } 00252 00253 template <unsigned D> 00254 inline 00255 void 00256 face<D>::set_n(unsigned n) 00257 { 00258 n_ = n; 00259 } 00260 00261 template <unsigned D> 00262 inline 00263 void 00264 face<D>::inc_n() 00265 { 00266 ++n_; 00267 } 00268 00269 template <unsigned D> 00270 inline 00271 void 00272 face<D>::dec_n() 00273 { 00274 --n_; 00275 } 00276 00277 template <unsigned D> 00278 inline 00279 void 00280 face<D>::set_face_id(unsigned face_id) 00281 { 00282 face_id_ = face_id; 00283 } 00284 00285 template <unsigned D> 00286 inline 00287 void 00288 face<D>::inc_face_id() 00289 { 00290 ++face_id_; 00291 } 00292 00293 template <unsigned D> 00294 inline 00295 void 00296 face<D>::dec_face_id() 00297 { 00298 --face_id_; 00299 } 00300 00301 template <unsigned D> 00302 template <unsigned N> 00303 inline 00304 face_data<N, D>& 00305 face<D>::data() const 00306 { 00307 mln_precondition(n_ == N); 00308 mln_precondition(is_valid()); 00309 return cplx_.template face_data_<N>(face_id_); 00310 } 00311 00312 00313 /*-----------------------------------------------. 00314 | Helpers for face<D>::lower_dim_adj_faces() and | 00315 | face<D>::higher_dim_adj_faces(). | 00316 `-----------------------------------------------*/ 00317 00318 /* FIXME: This is way too complicated; should disappear when the 00319 implementation of complexes is simplified (see 00320 https://trac.lrde.org/olena/ticket/168). */ 00321 00322 // Implementation is in mln/topo/algebraic_face.hh. 00323 00324 namespace internal 00325 { 00326 00327 template <unsigned N, unsigned D> 00328 struct lower_dim_adj_faces_if_dim_matches_ 00329 { 00330 std::vector< algebraic_face<D> > operator()(const face<D>& face); 00331 }; 00332 00333 template <unsigned D> 00334 struct lower_dim_adj_faces_if_dim_matches_<1, D> 00335 { 00336 std::vector< algebraic_face<D> > operator()(const face<D>& face); 00337 }; 00338 00339 template <unsigned N, unsigned D> 00340 struct higher_dim_adj_faces_if_dim_matches_ 00341 { 00342 std::vector< algebraic_face<D> > operator()(const face<D>& face); 00343 }; 00344 00345 template <unsigned D> 00346 struct higher_dim_adj_faces_if_dim_matches_<0, D> 00347 { 00348 std::vector< algebraic_face<D> > operator()(const face<D>& face); 00349 }; 00350 00351 } // end of namespace mln::topo::internal 00352 00353 00354 template <unsigned D> 00355 inline 00356 std::vector< algebraic_face<D> > 00357 face<D>::lower_dim_adj_faces() const 00358 { 00359 // FIXME: Warning: might prevent any attempt to build a complex<0>. 00360 metal::bool_<( D != 0 )>::check(); 00361 00362 return n_ > 0 ? 00363 internal::lower_dim_adj_faces_if_dim_matches_<D, D>()(*this) : 00364 std::vector< algebraic_face<D> >(); 00365 } 00366 00367 template <unsigned D> 00368 inline 00369 std::vector< algebraic_face<D> > 00370 face<D>::higher_dim_adj_faces() const 00371 { 00372 // FIXME: Warning: might prevent any attempt to build a complex<0>. 00373 metal::bool_<( D != 0 )>::check(); 00374 00375 return n_ < D ? 00376 internal::higher_dim_adj_faces_if_dim_matches_<D - 1, D>()(*this) : 00377 std::vector< algebraic_face<D> >(); 00378 } 00379 00380 00381 template <unsigned D> 00382 inline 00383 bool 00384 operator==(const face<D>& lhs, const face<D>& rhs) 00385 { 00386 // Ensure LHS and RHS belong to the same complex. 00387 mln_precondition(lhs.cplx() == rhs.cplx()); 00388 return lhs.n() == rhs.n() && lhs.face_id() == rhs.face_id(); 00389 } 00390 00391 template <unsigned D> 00392 inline 00393 bool 00394 operator!=(const face<D>& lhs, const face<D>& rhs) 00395 { 00396 // Ensure LHS and RHS belong to the same complex. 00397 mln_precondition(lhs.cplx() == rhs.cplx()); 00398 return !(lhs == rhs); 00399 } 00400 00401 template <unsigned D> 00402 inline 00403 bool 00404 operator< (const face<D>& lhs, const face<D>& rhs) 00405 { 00406 // Ensure LHS and RHS belong to the same complex. 00407 mln_precondition(lhs.cplx() == rhs.cplx()); 00408 return lhs.n() < rhs.n() || 00409 (lhs.n() == rhs.n() && lhs.face_id() < rhs.face_id()); 00410 } 00411 00412 00413 template <unsigned D> 00414 inline 00415 std::ostream& 00416 operator<<(std::ostream& ostr, const face<D>& f) 00417 { 00418 return ostr << "(cplx = " << f.cplx().addr() << ", dim = " << f.n() 00419 << ", id = " << f.face_id() << ')'; 00420 } 00421 00422 # endif // ! MLN_INCLUDE_ONLY 00423 00424 } // end of namespace mln::topo 00425 00426 } // end of namespace mln 00427 00428 #endif // ! MLN_TOPO_FACE_HH