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_CORE_SITE_SET_COMPLEX_PSITE_HH 00027 # define MLN_CORE_SITE_SET_COMPLEX_PSITE_HH 00028 00032 00033 # include <mln/core/internal/pseudo_site_base.hh> 00034 00035 # include <mln/topo/complex.hh> 00036 00037 // FIXME: There's a circular dependency issue between complex_psite 00038 // and p_complex (likewise for faces_psite and p_faces): they have to 00039 // know their interfaces one another. I have disabled some 00040 // preconditions and invariants to have the code compile, but we must 00041 // find a real solution. 00042 00043 // FIXME: Factor complex_psite and faces_psite? 00044 00045 // FIXME: Rename complex_psite as p_complex_psite, and move this file to 00046 // core/site_set. 00047 00048 00049 namespace mln 00050 { 00051 // Forward declaration. 00052 template <unsigned D, typename G> class p_complex; 00053 00054 00059 template <unsigned D, typename G> 00060 class complex_psite 00061 : public internal::pseudo_site_base_< const mln_site(G)&, complex_psite<D, G> > 00062 { 00063 public: 00064 // This associated type is important to know that this particular 00065 // pseudo site knows the site set it refers to. 00066 typedef p_complex<D, G> target; 00067 00068 typedef p_complex<D, G> target_t; // To please g++-2.95. 00069 00070 // FIXME: Document. 00073 complex_psite(); 00075 complex_psite(const p_complex<D, G>& pc, 00076 const topo::face<D>& face); 00077 complex_psite(const p_complex<D, G>& pc, unsigned n, unsigned face_id); 00079 00083 bool is_valid() const; 00085 void invalidate(); 00087 00093 const target& site_set() const; 00094 00096 const target* target_() const; 00098 void change_target(const target& new_target); 00100 00104 const mln_site(G)& subj_(); 00106 00110 const topo::face<D>& face() const; 00111 00113 unsigned n() const; 00115 unsigned face_id() const; 00117 00118 private: 00122 void update_(); 00123 // The site corresponding to this psite. 00124 mln_site(G) p_; 00126 00127 /* FIXME: Attributes pc_ and face_ share a common information: the 00128 address of their complex. 00129 00130 This is both a loss of space and time (we must ensure 00131 synchronization), but this design issue is not trivial: we 00132 actually introduced (any-)face handles to pack together the 00133 location information (n, face_id) with the support (the 00134 complex), to avoid what we did with graphs --- where location 00135 (edge id or vertex id) is separated from the support (the 00136 graph). 00137 00138 Think about it, and adjust faces_psite as well. */ 00139 private: 00143 const target* pc_; 00145 topo::face<D> face_; 00147 }; 00148 00149 00152 /* FIXME: Shouldn't those comparisons be part of a much general 00153 mechanism? */ 00154 00159 /* FIXME: We probably want to relax this precondition: p_complex 00160 equality is too strong; prefer complex equality. */ 00161 template <unsigned D, typename G> 00162 bool 00163 operator==(const complex_psite<D, G>& lhs, 00164 const complex_psite<D, G>& rhs); 00165 00170 /* FIXME: We probably want to relax this precondition: p_complex 00171 equality is too strong; prefer complex equality. */ 00172 template <unsigned D, typename G> 00173 bool 00174 operator!=(const complex_psite<D, G>& lhs, 00175 const complex_psite<D, G>& rhs); 00176 00183 /* FIXME: We probably want to relax this precondition: p_complex 00184 equality is too strong; prefer complex equality. */ 00185 template <unsigned D, typename G> 00186 bool 00187 operator< (const complex_psite<D, G>& lhs, 00188 const complex_psite<D, G>& rhs); 00190 00191 00192 template <unsigned D, typename G> 00193 inline 00194 std::ostream& 00195 operator<<(std::ostream& ostr, const complex_psite<D, G>& p); 00196 00197 00198 00199 # ifndef MLN_INCLUDE_ONLY 00200 00201 template <unsigned D, typename G> 00202 inline 00203 complex_psite<D, G>::complex_psite() 00204 : pc_(0) 00205 { 00206 invalidate(); 00207 } 00208 00209 template <unsigned D, typename G> 00210 inline 00211 complex_psite<D, G>::complex_psite(const p_complex<D, G>& pc, 00212 const topo::face<D>& face) 00213 : pc_(&pc), 00214 face_(face) 00215 { 00216 // Check arguments consistency. 00217 // FIXME: Re-enable when the cyclic dependencies are fixed. 00218 #if 0 00219 mln_precondition(pc.cplx() == face.cplx()); 00220 #endif 00221 if (is_valid()) 00222 update_(); 00223 } 00224 00225 template <unsigned D, typename G> 00226 inline 00227 complex_psite<D, G>::complex_psite(const p_complex<D, G>& pc, 00228 unsigned n, unsigned face_id) 00229 : pc_(&pc), 00230 face_(pc.cplx(), n, face_id) 00231 { 00232 if (is_valid()) 00233 update_(); 00234 } 00235 00236 template <unsigned D, typename G> 00237 inline 00238 bool 00239 complex_psite<D, G>::is_valid() const 00240 { 00241 // FIXME: Re-enable when the cyclic dependencies are fixed. 00242 #if 0 00243 mln_invariant(!pc_ || pc_.cplx() == face_.cplx()); 00244 #endif 00245 return face_.is_valid(); 00246 } 00247 00248 template <unsigned D, typename G> 00249 inline 00250 void 00251 complex_psite<D, G>::invalidate() 00252 { 00253 return face_.invalidate(); 00254 } 00255 00256 template <unsigned D, typename G> 00257 inline 00258 const p_complex<D, G>& 00259 complex_psite<D, G>::site_set() const 00260 { 00261 mln_precondition(target_()); 00262 return *target_(); 00263 } 00264 00265 template <unsigned D, typename G> 00266 inline 00267 const p_complex<D, G>* 00268 complex_psite<D, G>::target_() const 00269 { 00270 // FIXME: Re-enable when the cyclic dependencies are fixed. 00271 #if 0 00272 mln_invariant(!pc_ || pc_.cplx() == face_.cplx()); 00273 #endif 00274 return pc_; 00275 } 00276 00277 template <unsigned D, typename G> 00278 inline 00279 void 00280 complex_psite<D, G>::change_target(const target& new_target) 00281 { 00282 // Update both pc_ and face_. 00283 pc_ = &new_target; 00284 face_.set_cplx(new_target.cplx()); 00285 invalidate(); 00286 } 00287 00288 // FIXME: Write or extend a test to exercise this method (when the 00289 // handling of G is done, i.e., when update_ is complete). 00290 template <unsigned D, typename G> 00291 inline 00292 const mln_site(G)& 00293 complex_psite<D, G>::subj_() 00294 { 00295 return p_; 00296 } 00297 00298 template <unsigned D, typename G> 00299 inline 00300 const topo::face<D>& 00301 complex_psite<D, G>::face() const 00302 { 00303 return face_; 00304 } 00305 00306 template <unsigned D, typename G> 00307 inline 00308 unsigned 00309 complex_psite<D, G>::n() const 00310 { 00311 return face_.n(); 00312 } 00313 00314 template <unsigned D, typename G> 00315 inline 00316 unsigned 00317 complex_psite<D, G>::face_id() const 00318 { 00319 return face_.face_id(); 00320 } 00321 00322 template <unsigned D, typename G> 00323 inline 00324 void 00325 complex_psite<D, G>::update_() 00326 { 00327 mln_precondition(is_valid()); 00328 // FIXME: Re-enable when the cyclic dependencies are fixed. 00329 #if 0 00330 mln_invariant(!pc_ || pc_.cplx() == face_.cplx()); 00331 #endif 00332 // FIXME: Simplify? (I.e., add accessors to shorten the following 00333 // line?) 00334 p_ = site_set().geom()(face_); 00335 } 00336 00337 00338 /*--------------. 00339 | Comparisons. | 00340 `--------------*/ 00341 00342 template <unsigned D, typename G> 00343 bool 00344 operator==(const complex_psite<D, G>& lhs, 00345 const complex_psite<D, G>& rhs) 00346 { 00347 mln_precondition(&lhs.site_set() == &rhs.site_set()); 00348 return lhs.face() == rhs.face(); 00349 } 00350 00351 template <unsigned D, typename G> 00352 bool 00353 operator!=(const complex_psite<D, G>& lhs, 00354 const complex_psite<D, G>& rhs) 00355 { 00356 mln_precondition(&lhs.site_set() == &rhs.site_set()); 00357 return lhs.face() != rhs.face(); 00358 } 00359 00360 template <unsigned D, typename G> 00361 bool 00362 operator< (const complex_psite<D, G>& lhs, 00363 const complex_psite<D, G>& rhs) 00364 { 00365 mln_precondition(&lhs.site_set() == &rhs.site_set()); 00366 return lhs.face() < rhs.face(); 00367 } 00368 00369 00370 /*------------------. 00371 | Pretty-printing. | 00372 `------------------*/ 00373 00374 template <unsigned D, typename G> 00375 inline 00376 std::ostream& 00377 operator<<(std::ostream& ostr, const complex_psite<D, G>& p) 00378 { 00379 return ostr << p.face(); 00380 } 00381 00382 # endif // ! MLN_INCLUDE_ONLY 00383 00384 } // end of mln 00385 00386 #endif // ! MLN_CORE_SITE_SET_COMPLEX_PSITE_HH