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_N_FACE_HH 00027 # define MLN_TOPO_N_FACE_HH 00028 00032 00033 # include <iostream> 00034 # include <vector> 00035 00036 # include <mln/value/internal/limits.hh> 00037 # include <mln/core/contract.hh> 00038 # include <mln/metal/bool.hh> 00039 00040 namespace mln 00041 { 00042 00043 namespace topo 00044 { 00045 00046 // Forward declaration. 00047 template <unsigned D> class complex; 00048 template <unsigned N, unsigned D> class face_data; 00049 template <unsigned N, unsigned D> class algebraic_n_face; 00050 00051 00052 /*---------. 00053 | n-Face. | 00054 `---------*/ 00055 00060 template <unsigned N, unsigned D> 00061 class n_face 00062 { 00063 public: 00064 // The type of the complex this handle points to. 00065 typedef complex<D> complex_type; 00066 00068 n_face(); 00070 n_face(complex<D>& complex, unsigned face_id); 00071 00073 bool is_valid() const; 00075 void invalidate(); 00076 00080 complex<D> cplx() const; 00082 // FIXME: Rename as `id'? 00083 unsigned face_id() const; 00084 00086 void set_cplx(const complex<D>& cplx); 00088 // FIXME: Rename as `dim'? 00089 unsigned n() const; 00091 void set_face_id(unsigned face_id); 00093 void inc_face_id(); 00095 void dec_face_id(); 00096 00098 face_data<N, D>& data() const; 00099 00100 /* FIXME: We should not provide lower_dim_adj_faces() when N == 00101 0 nor higher_dim_adj_faces() when N == D. */ 00103 std::vector< algebraic_n_face<N - 1, D> > lower_dim_adj_faces() const; 00105 std::vector< algebraic_n_face<N + 1, D> > higher_dim_adj_faces() const; 00107 00108 private: 00112 mutable complex<D> cplx_; 00114 // FIXME: Rename as `id_'? 00115 unsigned face_id_; 00116 }; 00117 00118 00121 00126 template <unsigned N, unsigned D> 00127 bool operator==(const n_face<N, D>& lhs, const n_face<N, D>& rhs); 00128 00133 template <unsigned N, unsigned D> 00134 bool operator!=(const n_face<N, D>& lhs, const n_face<N, D>& rhs); 00135 00142 template <unsigned N, unsigned D> 00143 bool operator< (const n_face<N, D>& lhs, const n_face<N, D>& rhs); 00144 00146 00147 00149 template <unsigned N, unsigned D> 00150 std::ostream& 00151 operator<<(std::ostream& ostr, const n_face<N, D>& f); 00152 00153 00154 00155 # ifndef MLN_INCLUDE_ONLY 00156 00157 template <unsigned N, unsigned D> 00158 inline 00159 n_face<N, D>::n_face() 00160 : cplx_(), face_id_(value::internal::limits<unsigned>::max()) 00161 { 00162 // Ensure N is compatible with D. 00163 metal::bool_< N <= D >::check(); 00164 mln_postcondition(!is_valid()); 00165 } 00166 00167 template <unsigned N, unsigned D> 00168 inline 00169 n_face<N, D>::n_face(complex<D>& c, unsigned face_id) 00170 : cplx_(c), face_id_(face_id) 00171 { 00172 // Ensure N is compatible with D. 00173 metal::bool_< N <= D >::check(); 00174 } 00175 00176 template <unsigned N, unsigned D> 00177 inline 00178 bool 00179 n_face<N, D>::is_valid() const 00180 { 00181 return face_id_ < cplx_.template nfaces_of_static_dim<N>(); 00182 } 00183 00184 template <unsigned N, unsigned D> 00185 inline 00186 void 00187 n_face<N, D>::invalidate() 00188 { 00189 set_face_id(value::internal::limits<unsigned>::max()); 00190 } 00191 00192 template <unsigned N, unsigned D> 00193 inline 00194 complex<D> 00195 n_face<N, D>::cplx() const 00196 { 00197 return cplx_; 00198 } 00199 00200 template <unsigned N, unsigned D> 00201 inline 00202 unsigned 00203 n_face<N, D>::n() const 00204 { 00205 return N; 00206 } 00207 00208 template <unsigned N, unsigned D> 00209 inline 00210 unsigned 00211 n_face<N, D>::face_id() const 00212 { 00213 return face_id_; 00214 } 00215 00216 template <unsigned N, unsigned D> 00217 inline 00218 void 00219 n_face<N, D>::set_cplx(const complex<D>& cplx) 00220 { 00221 cplx_ = cplx; 00222 } 00223 00224 template <unsigned N, unsigned D> 00225 inline 00226 void 00227 n_face<N, D>::set_face_id(unsigned face_id) 00228 { 00229 face_id_ = face_id; 00230 } 00231 00232 template <unsigned N, unsigned D> 00233 inline 00234 void 00235 n_face<N, D>::inc_face_id() 00236 { 00237 ++face_id_; 00238 } 00239 00240 template <unsigned N, unsigned D> 00241 inline 00242 void 00243 n_face<N, D>::dec_face_id() 00244 { 00245 --face_id_; 00246 } 00247 00248 template <unsigned N, unsigned D> 00249 inline 00250 face_data<N, D>& 00251 n_face<N, D>::data() const 00252 { 00253 mln_precondition(is_valid()); 00254 return cplx_.template face_data_<N>(face_id_); 00255 } 00256 00257 template <unsigned N, unsigned D> 00258 inline 00259 std::vector< algebraic_n_face<N - 1, D> > 00260 n_face<N, D>::lower_dim_adj_faces() const 00261 { 00262 mln_precondition(N > 0); 00263 mln_precondition(is_valid()); 00264 return cplx_.template face_data_<N>(face_id_).lower_dim_faces_; 00265 } 00266 00267 template <unsigned N, unsigned D> 00268 inline 00269 std::vector< algebraic_n_face<N + 1, D> > 00270 n_face<N, D>::higher_dim_adj_faces() const 00271 { 00272 mln_precondition(N <= D); 00273 mln_precondition(is_valid()); 00274 return cplx_.template face_data_<N>(face_id_).higher_dim_faces_; 00275 } 00276 00277 00278 template <unsigned N, unsigned D> 00279 inline 00280 bool 00281 operator==(const n_face<N, D>& lhs, const n_face<N, D>& rhs) 00282 { 00283 // Ensure LHS and RHS belong to the same complex. 00284 mln_precondition(lhs.cplx() == rhs.cplx()); 00285 return lhs.face_id() == rhs.face_id(); 00286 } 00287 00288 template <unsigned N, unsigned D> 00289 inline 00290 bool 00291 operator!=(const n_face<N, D>& lhs, const n_face<N, D>& rhs) 00292 { 00293 // Ensure LHS and RHS belong to the same complex. 00294 mln_precondition(lhs.cplx() == rhs.cplx()); 00295 return !(lhs == rhs); 00296 } 00297 00298 template <unsigned N, unsigned D> 00299 inline 00300 bool 00301 operator< (const n_face<N, D>& lhs, const n_face<N, D>& rhs) 00302 { 00303 // Ensure LHS and RHS belong to the same complex. 00304 mln_precondition(lhs.cplx() == rhs.cplx()); 00305 return lhs.face_id() < rhs.face_id(); 00306 } 00307 00308 00309 template <unsigned N, unsigned D> 00310 inline 00311 std::ostream& 00312 operator<<(std::ostream& ostr, const n_face<N, D>& f) 00313 { 00314 return ostr << "(cplx = " << f.cplx().addr() << ", dim = " << f.n() 00315 << ", id = " << f.face_id() << ')'; 00316 } 00317 00318 # endif // ! MLN_INCLUDE_ONLY 00319 00320 } // end of namespace mln::topo 00321 00322 } // end of namespace mln 00323 00324 #endif // ! MLN_TOPO_N_FACE_HH