Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008, 2009, 2010 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_ALGEBRAIC_FACE_HH 00028 # define MLN_TOPO_ALGEBRAIC_FACE_HH 00029 00033 00034 #include <mln/topo/face.hh> 00035 #include <mln/topo/algebraic_n_face.hh> 00036 00037 00038 namespace mln 00039 { 00040 00041 namespace topo 00042 { 00043 00044 // Forward declarations. 00045 template <unsigned D> class complex; 00046 template <unsigned N, unsigned D> class n_face; 00047 template <unsigned N, unsigned D> class face_data; 00048 00049 00050 /*-------. 00051 | Face. | 00052 `-------*/ 00053 00059 template <unsigned D> 00060 class algebraic_face : public face<D> 00061 { 00062 typedef face<D> super_; 00063 00064 public: 00065 // The type of the complex this handle points to. 00066 typedef complex<D> complex_type; 00067 00069 algebraic_face(); 00071 algebraic_face(complex<D>& complex, unsigned n, unsigned face_id, 00072 bool sign); 00074 algebraic_face(const face<D>& f, bool sign); 00075 00077 template <unsigned N> 00078 algebraic_face(const algebraic_n_face<N, D>& f); 00079 00083 bool sign() const; 00085 void set_sign(bool sign); 00087 00088 private: 00090 bool sign_; 00091 }; 00092 00093 00095 template <unsigned D> 00096 algebraic_face<D> 00097 make_algebraic_face(const face<D>& f, bool sign); 00098 00099 00102 template <unsigned D> 00103 algebraic_face<D> 00104 operator-(const face<D>& f); 00105 00106 template <unsigned D> 00107 algebraic_face<D> 00108 operator-(const algebraic_face<D>& f); 00110 00111 00114 00119 template <unsigned D> 00120 bool operator==(const algebraic_face<D>& lhs, 00121 const algebraic_face<D>& rhs); 00122 00127 template <unsigned D> 00128 bool operator!=(const algebraic_face<D>& lhs, 00129 const algebraic_face<D>& rhs); 00130 00139 template <unsigned D> 00140 bool operator< (const algebraic_face<D>& lhs, 00141 const algebraic_face<D>& rhs); 00142 00144 00145 00147 template <unsigned D> 00148 std::ostream& 00149 operator<<(std::ostream& ostr, const algebraic_face<D>& f); 00150 00151 00152 00153 # ifndef MLN_INCLUDE_ONLY 00154 00155 template <unsigned D> 00156 inline 00157 algebraic_face<D>::algebraic_face() 00158 : super_(), sign_(true) 00159 { 00160 } 00161 00162 template <unsigned D> 00163 inline 00164 algebraic_face<D>::algebraic_face(complex<D>& c, unsigned n, 00165 unsigned face_id, bool sign) 00166 : super_(c, n, face_id), sign_(sign) 00167 { 00168 // Ensure N is compatible with D. 00169 mln_precondition(n <= D); 00170 } 00171 00172 template <unsigned D> 00173 inline 00174 algebraic_face<D>::algebraic_face(const face<D>& f, bool sign) 00175 : super_(f), sign_(sign) 00176 { 00177 // Ensure N is compatible with D. 00178 mln_precondition(f.n() <= D); 00179 } 00180 00181 template <unsigned D> 00182 template <unsigned N> 00183 inline 00184 algebraic_face<D>::algebraic_face(const algebraic_n_face<N, D>& f) 00185 : super_(f), sign_(f.sign()) 00186 { 00187 // Ensure N is compatible with D. 00188 metal::bool_< N <= D >::check(); 00189 } 00190 00191 00192 template <unsigned D> 00193 inline 00194 bool 00195 algebraic_face<D>::sign() const 00196 { 00197 return sign_; 00198 } 00199 00200 template <unsigned D> 00201 inline 00202 void 00203 algebraic_face<D>::set_sign(bool sign) 00204 { 00205 sign_ = sign; 00206 } 00207 00208 00209 template <unsigned D> 00210 algebraic_face<D> 00211 make_algebraic_face(const face<D>& f, bool sign) 00212 { 00213 return algebraic_face<D>(f, sign); 00214 } 00215 00216 00217 template <unsigned D> 00218 algebraic_face<D> 00219 operator-(const face<D>& f) 00220 { 00221 return algebraic_face<D>(f, false); 00222 } 00223 00224 template <unsigned D> 00225 algebraic_face<D> 00226 operator-(const algebraic_face<D>& f) 00227 { 00228 algebraic_face<D> f2(f); 00229 f2.set_sign(!f.sign()); 00230 return f2; 00231 } 00232 00233 00234 template <unsigned D> 00235 inline 00236 bool 00237 operator==(const algebraic_face<D>& lhs, const algebraic_face<D>& rhs) 00238 { 00239 // Ensure LHS and RHS belong to the same complex. 00240 mln_precondition(lhs.cplx() == rhs.cplx()); 00241 return 00242 lhs.n() == rhs.n() && 00243 lhs.face_id() == rhs.face_id() && 00244 lhs.sign() == rhs.sign(); 00245 } 00246 00247 template <unsigned D> 00248 inline 00249 bool 00250 operator!=(const algebraic_face<D>& lhs, const algebraic_face<D>& rhs) 00251 { 00252 // Ensure LHS and RHS belong to the same complex. 00253 mln_precondition(lhs.cplx() == rhs.cplx()); 00254 return !(lhs == rhs); 00255 } 00256 00257 template <unsigned D> 00258 inline 00259 bool 00260 operator< (const algebraic_face<D>& lhs, const algebraic_face<D>& rhs) 00261 { 00262 // Ensure LHS and RHS belong to the same complex. 00263 mln_precondition(lhs.cplx() == rhs.cplx()); 00264 // Ensure LHS and RHS have the same dimension. 00265 mln_precondition(lhs.n() == rhs.n()); 00266 return lhs.face_id() < rhs.face_id(); 00267 } 00268 00269 00270 template <unsigned D> 00271 inline 00272 std::ostream& 00273 operator<<(std::ostream& ostr, const algebraic_face<D>& f) 00274 { 00275 return 00276 ostr << "(cplx = " << f.cplx().addr() << ", dim = " << f.n() 00277 << ", id = " << f.face_id() << ", sign = " << f.sign()<< ')'; 00278 } 00279 00280 00281 /*-----------------------------------------------. 00282 | Helpers for face<D>::lower_dim_adj_faces() and | 00283 | face<D>::higher_dim_adj_faces(). | 00284 `-----------------------------------------------*/ 00285 00286 /* FIXME: This is way too complicated; should disappear when the 00287 implementation of complexes is simplified (see 00288 https://trac.lrde.org/olena/ticket/168). */ 00289 00290 namespace internal 00291 { 00292 00293 template <unsigned N, unsigned D> 00294 std::vector< algebraic_face<D> > 00295 lower_dim_adj_faces_if_dim_matches_<N, D>::operator()(const face<D>& face) 00296 { 00297 metal::bool_< (N <= D) >::check(); 00298 metal::bool_< (N > 1) >::check(); 00299 00300 if (face.n() == N) 00301 { 00302 face_data<N, D>& data = face.template data<N>(); 00303 std::vector< algebraic_n_face<N - 1, D> > lower_dim_faces = 00304 data.lower_dim_faces_; 00305 std::vector< topo::algebraic_face<D> > result; 00306 for (typename std::vector< algebraic_n_face<N - 1, D> >::const_iterator f = 00307 lower_dim_faces.begin(); f != lower_dim_faces.end(); ++f) 00308 result.push_back(*f); 00309 return result; 00310 } 00311 else 00312 return internal::lower_dim_adj_faces_if_dim_matches_<N - 1, D>()(face); 00313 } 00314 00315 template <unsigned D> 00316 std::vector< algebraic_face<D> > 00317 lower_dim_adj_faces_if_dim_matches_<1, D>::operator()(const face<D>& face) 00318 { 00321 mln_precondition(face.n() == 1); 00322 face_data<1, D>& data = face.template data<1>(); 00323 std::vector< algebraic_n_face<0, D> > lower_dim_faces = 00324 data.lower_dim_faces_; 00325 std::vector< topo::algebraic_face<D> > result; 00326 for (typename std::vector< algebraic_n_face<0, D> >::const_iterator f = 00327 lower_dim_faces.begin(); f != lower_dim_faces.end(); ++f) 00328 result.push_back(*f); 00329 return result; 00330 } 00331 00332 template <unsigned N, unsigned D> 00333 std::vector< algebraic_face<D> > 00334 higher_dim_adj_faces_if_dim_matches_<N, D>::operator()(const face<D>& face) 00335 { 00336 metal::bool_< (N < D) >::check(); 00337 00338 if (face.n() == N) 00339 { 00340 face_data<N, D>& data = face.template data<N>(); 00341 std::vector< algebraic_n_face<N + 1, D> > higher_dim_faces = 00342 data.higher_dim_faces_; 00343 std::vector< topo::algebraic_face<D> > result; 00344 for (typename std::vector< algebraic_n_face<N + 1, D> >::const_iterator f = 00345 higher_dim_faces.begin(); f != higher_dim_faces.end(); ++f) 00346 result.push_back(*f); 00347 return result; 00348 } 00349 else 00350 return 00351 internal::higher_dim_adj_faces_if_dim_matches_<N - 1, D>()(face); 00352 } 00353 00354 template <unsigned D> 00355 std::vector< algebraic_face<D> > 00356 higher_dim_adj_faces_if_dim_matches_<0, D>::operator()(const face<D>& face) 00357 { 00360 mln_precondition(face.n() == 0); 00361 face_data<0, D>& data = face.template data<0>(); 00362 std::vector< algebraic_n_face<1, D> > higher_dim_faces = 00363 data.higher_dim_faces_; 00364 std::vector< topo::algebraic_face<D> > result; 00365 for (typename std::vector< algebraic_n_face<1, D> >::const_iterator f = 00366 higher_dim_faces.begin(); f != higher_dim_faces.end(); ++f) 00367 result.push_back(*f); 00368 return result; 00369 } 00370 00371 } // end of namespace mln::topo::internal 00372 00373 00374 # endif // ! MLN_INCLUDE_ONLY 00375 00376 } // end of namespace mln::topo 00377 00378 } // end of namespace mln 00379 00380 #endif // ! MLN_TOPO_ALGEBRAIC_FACE_HH