Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008, 2009, 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_CORE_FACES_PSITE_HH 00028 # define MLN_CORE_FACES_PSITE_HH 00029 00033 00034 # include <cstdlib> 00035 00036 # include <mln/core/internal/pseudo_site_base.hh> 00037 00038 # include <mln/topo/complex.hh> 00039 00040 // FIXME: Factor complex_psite and faces_psite? 00041 00042 // FIXME: Rename faces_psite as p_faces_psite, and move this file to 00043 // core/site_set. 00044 00045 namespace mln 00046 { 00047 // Forward declaration. 00048 template <unsigned N, unsigned D, typename P> struct p_faces; 00049 00050 00056 template <unsigned N, unsigned D, typename P> 00057 class faces_psite 00058 : public internal::pseudo_site_base_< const P&, 00059 faces_psite<N, D, P> > 00060 { 00061 public: 00062 // This associated type is important to know that this particular 00063 // pseudo site knows the site set it refers to. 00064 typedef p_faces<N, D, P> target; 00065 00068 faces_psite(); 00070 faces_psite(const p_faces<N, D, P>& pf, const topo::n_face<N, D>& face); 00071 faces_psite(const p_faces<N, D, P>& pf, unsigned face_id); 00073 00077 bool is_valid() const; 00079 void invalidate(); 00081 00087 const target& site_set() const; 00088 00090 const target* target_() const; 00092 void change_target(const target& new_target); 00094 00098 const P& subj_(); 00100 00104 topo::n_face<N, D> face() const; 00105 00107 unsigned n() const; 00109 unsigned face_id() const; 00111 00112 private: 00116 void update_(); 00117 // The site corresponding to this psite. 00118 P p_; 00120 00121 /* FIXME: Attributes pf_ and face_ share a common information: the 00122 address of their complex. 00123 00124 This is both a loss of space and time (we must ensure 00125 synchronization), but this design issue is not trivial: we 00126 actually introduced the face handles to pack together the 00127 location information (face_id) with the support (the complex), 00128 to avoid what we did with graphs --- where location (edge id or 00129 vertex id) is separated from the support (the graph). 00130 00131 Think about it, and adjust complex_psite as well. */ 00132 private: 00136 const target* pf_; 00138 topo::n_face<N, D> face_; 00140 }; 00141 00142 00145 /* FIXME: Shouldn't those comparisons be part of a much general 00146 mechanism? */ 00147 00152 template <unsigned N, unsigned D, typename P> 00153 bool 00154 operator==(const faces_psite<N, D, P>& lhs, 00155 const faces_psite<N, D, P>& rhs); 00156 00157 00162 template <unsigned N, unsigned D, typename P> 00163 bool 00164 operator!=(const faces_psite<N, D, P>& lhs, 00165 const faces_psite<N, D, P>& rhs); 00166 00173 template <unsigned N, unsigned D, typename P> 00174 bool 00175 operator< (const faces_psite<N, D, P>& lhs, 00176 const faces_psite<N, D, P>& rhs); 00178 00179 00180 template <unsigned N, unsigned D, typename P> 00181 inline 00182 std::ostream& 00183 operator<<(std::ostream& ostr, const faces_psite<N, D, P>& p); 00184 00185 00186 00187 # ifndef MLN_INCLUDE_ONLY 00188 00189 template <unsigned N, unsigned D, typename P> 00190 inline 00191 faces_psite<N, D, P>::faces_psite() 00192 : pf_(0) 00193 { 00194 // Ensure N is compatible with D. 00195 metal::bool_< N <= D >::check(); 00196 00197 invalidate(); 00198 } 00199 00200 template <unsigned N, unsigned D, typename P> 00201 inline 00202 faces_psite<N, D, P>::faces_psite(const p_faces<N, D, P>& pf, 00203 const topo::n_face<N, D>& face) 00204 : pf_(&pf), 00205 face_(face) 00206 { 00207 // Ensure N is compatible with D. 00208 metal::bool_< N <= D >::check(); 00209 // Check arguments consistency. 00210 // mln_precondition(pf.cplx() == face.cplx()); 00211 00212 update_(); 00213 } 00214 00215 template <unsigned N, unsigned D, typename P> 00216 inline 00217 faces_psite<N, D, P>::faces_psite(const p_faces<N, D, P>& pf, 00218 unsigned face_id) 00219 : pf_(&pf), 00220 face_(pf.cplx(), face_id) 00221 { 00222 // Ensure N is compatible with D. 00223 metal::bool_< N <= D >::check(); 00224 00225 update_(); 00226 } 00227 00228 template <unsigned N, unsigned D, typename P> 00229 inline 00230 bool 00231 faces_psite<N, D, P>::is_valid() const 00232 { 00233 // mln_invariant(!pf_ || pf_.cplx() == face_.cplx()); 00234 return face_.is_valid(); 00235 } 00236 00237 template <unsigned N, unsigned D, typename P> 00238 inline 00239 void 00240 faces_psite<N, D, P>::invalidate() 00241 { 00242 return face_.invalidate(); 00243 } 00244 00245 template <unsigned N, unsigned D, typename P> 00246 inline 00247 const p_faces<N, D, P>& 00248 faces_psite<N, D, P>::site_set() const 00249 { 00250 mln_precondition(target_()); 00251 return *target_(); 00252 } 00253 00254 template <unsigned N, unsigned D, typename P> 00255 inline 00256 const p_faces<N, D, P>* 00257 faces_psite<N, D, P>::target_() const 00258 { 00259 // mln_invariant(!pf_ || pf_.cplx() == face_.cplx()); 00260 return pf_; 00261 } 00262 00263 template <unsigned N, unsigned D, typename P> 00264 inline 00265 void 00266 faces_psite<N, D, P>::change_target(const target& new_target) 00267 { 00268 // Update both pc_ and face_. 00269 pf_ = &new_target; 00270 face_.set_cplx(new_target.cplx()); 00271 invalidate(); 00272 } 00273 00274 // FIXME: Write or extend a test to exercise this method (when the 00275 // handling of P is done, i.e., when update_ is complete). 00276 template <unsigned N, unsigned D, typename P> 00277 inline 00278 const P& 00279 faces_psite<N, D, P>::subj_() 00280 { 00281 // FIXME: Member p_ is not updated correctly yet; do not use this 00282 // method for now. 00283 abort(); 00284 return p_; 00285 } 00286 00287 template <unsigned N, unsigned D, typename P> 00288 inline 00289 topo::n_face<N, D> 00290 faces_psite<N, D, P>::face() const 00291 { 00292 return face_; 00293 } 00294 00295 template <unsigned N, unsigned D, typename P> 00296 inline 00297 unsigned 00298 faces_psite<N, D, P>::n() const 00299 { 00300 return face_.n(); 00301 } 00302 00303 template <unsigned N, unsigned D, typename P> 00304 inline 00305 unsigned 00306 faces_psite<N, D, P>::face_id() const 00307 { 00308 return face_.face_id(); 00309 } 00310 00311 template <unsigned N, unsigned D, typename P> 00312 inline 00313 void 00314 faces_psite<N, D, P>::update_() 00315 { 00316 mln_precondition(is_valid()); 00317 // mln_invariant(!pf_ || pf_.cplx() == face_.cplx()); 00318 // FIXME: Implement (update p_). 00319 } 00320 00321 00322 /*--------------. 00323 | Comparisons. | 00324 `--------------*/ 00325 00326 template <unsigned N, unsigned D, typename P> 00327 bool 00328 operator==(const faces_psite<N, D, P>& lhs, 00329 const faces_psite<N, D, P>& rhs) 00330 { 00331 mln_precondition(&lhs.site_set() == &rhs.site_set()); 00332 return lhs.face() == rhs.face(); 00333 } 00334 00335 template <unsigned N, unsigned D, typename P> 00336 bool 00337 operator!=(const faces_psite<N, D, P>& lhs, 00338 const faces_psite<N, D, P>& rhs) 00339 { 00340 mln_precondition(&lhs.site_set() == &rhs.site_set()); 00341 return lhs.face() != rhs.face(); 00342 } 00343 00344 template <unsigned N, unsigned D, typename P> 00345 bool 00346 operator< (const faces_psite<N, D, P>& lhs, 00347 const faces_psite<N, D, P>& rhs) 00348 { 00349 mln_precondition(&lhs.site_set() == &rhs.site_set()); 00350 return lhs.face() < rhs.face(); 00351 } 00352 00353 00354 /*------------------. 00355 | Pretty-printing. | 00356 `------------------*/ 00357 00358 template <unsigned N, unsigned D, typename P> 00359 inline 00360 std::ostream& 00361 operator<<(std::ostream& ostr, const faces_psite<N, D, P>& p) 00362 { 00363 return ostr << "(dim = " << p.n() << ", id = " << p.face_id() << ')'; 00364 } 00365 00366 # endif // ! MLN_INCLUDE_ONLY 00367 00368 } // end of mln 00369 00370 #endif // ! MLN_CORE_FACES_PSITE_HH