Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory 00002 // (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_INTERNAL_GRAPH_PSITE_BASE_HH 00028 # define MLN_CORE_INTERNAL_GRAPH_PSITE_BASE_HH 00029 00036 00037 # include <mln/core/internal/pseudo_site_base.hh> 00038 00039 00040 00041 namespace mln 00042 { 00043 00044 namespace internal 00045 { 00046 00047 template <typename S, typename E> 00048 class graph_psite_base : public internal::pseudo_site_base_< const mln_site(S)&, 00049 E > 00050 { 00051 public: 00052 00053 // This associated type is important to know that this particular 00054 // pseudo site knows the site set it refers to. 00055 typedef S target; 00056 00057 // As a Proxy: 00058 const mln_site(S)& subj_(); 00059 00060 typedef typename S::graph_element::id_t id_t; 00061 00065 void change_target(const S& new_target); 00068 void update_id(unsigned elt_id); 00070 00074 const S* target_() const; // Hook to the target. 00075 00077 const S& site_set() const; 00078 00080 const typename S::graph_t& graph() const; 00081 00083 id_t id() const; 00084 00086 00088 bool is_valid() const; 00090 void invalidate(); 00091 00093 operator unsigned () const; 00094 00096 operator typename S::graph_element::id_t () const; 00097 00099 operator const typename S::graph_element&() const; 00100 00102 const typename S::graph_element& element() const; 00103 00105 const typename S::graph_element& p_hook_() const; 00106 00107 protected: 00108 00110 00112 graph_psite_base(); 00115 graph_psite_base(const S& s); 00119 graph_psite_base(const S& , unsigned id); 00121 00122 const S* s_; 00123 mln_site(S) site_; 00124 typename S::graph_element elt_; 00125 }; 00126 00127 00128 /* FIXME: Shouldn't those comparisons be part of a much general 00129 mechanism? */ 00130 00137 template <typename S, typename E> 00138 bool 00139 operator==(const graph_psite_base<S,E>& lhs, const graph_psite_base<S,E>& rhs); 00140 00145 template <typename S, typename E> 00146 bool 00147 operator!=(const graph_psite_base<S,E>& lhs, const graph_psite_base<S,E>& rhs); 00148 00155 template <typename S, typename E> 00156 bool 00157 operator< (const graph_psite_base<S,E>& lhs, const graph_psite_base<S,E>& rhs); 00159 00160 00163 template <typename S, typename P, typename E> 00164 struct subject_impl< const graph_psite_base<S,P>&, E > 00165 { 00166 const S* target_() const; 00167 const S& site_set() const; 00168 const typename S::graph_t& graph() const; 00169 unsigned id() const; 00170 bool is_valid() const; 00171 // operator unsigned() const; 00172 // operator const typename S::graph_element&() const; 00173 const typename S::graph_element& element() const; 00174 const typename S::graph_element& p_hook_() const; 00175 00176 private: 00177 const E& exact_() const; 00178 }; 00179 00180 template <typename S, typename P, typename E> 00181 struct subject_impl< graph_psite_base<S,P>&, E > : 00182 subject_impl< const graph_psite_base<S,P>&, E > 00183 { 00184 void change_target(const S& new_target); 00185 void update_id(unsigned elt_id); 00186 void invalidate(); 00187 00188 private: 00189 E& exact_(); 00190 }; 00192 00193 00194 00195 # ifndef MLN_INCLUDE_ONLY 00196 00197 00198 template <typename S, typename E> 00199 inline 00200 graph_psite_base<S,E>::graph_psite_base() 00201 : s_(0) 00202 { 00203 } 00204 00205 template <typename S, typename E> 00206 inline 00207 graph_psite_base<S,E>::graph_psite_base(const S& s) 00208 { 00209 change_target(s); 00210 } 00211 00212 template <typename S, typename E> 00213 inline 00214 graph_psite_base<S,E>::graph_psite_base(const S& s, unsigned id) 00215 { 00216 change_target(s); 00217 update_id(id); 00218 } 00219 00220 // The lines below are dedicated/local to this file. 00221 template <typename E, typename S, typename G> 00222 inline 00223 void local_change_graph(E& elt_, S& site_, const G& g) 00224 { 00225 (void) site_; 00226 elt_.change_graph(g); 00227 } 00228 template <typename E, typename G> 00229 inline 00230 void local_change_graph(E& elt_, E& site_, const G& g) 00231 { 00232 elt_.change_graph(g); 00233 site_.change_graph(g); 00234 } 00235 // End of local stuff. 00236 00237 template <typename S, typename E> 00238 inline 00239 void 00240 graph_psite_base<S,E>::change_target(const S& new_target) 00241 { 00242 s_ = & new_target; 00243 local_change_graph(elt_, site_, new_target.graph()); 00244 } 00245 00246 template <typename S, typename E> 00247 inline 00248 void 00249 graph_psite_base<S,E>::update_id(unsigned id) 00250 { 00251 mln_precondition(s_ != 0); 00252 elt_.update_id(id); 00253 site_ = s_->function()(elt_.id()); 00254 } 00255 00256 template <typename S, typename E> 00257 inline 00258 const S* 00259 graph_psite_base<S,E>::target_() const 00260 { 00261 return s_; 00262 } 00263 00264 template <typename S, typename E> 00265 inline 00266 const S& 00267 graph_psite_base<S,E>::site_set() const 00268 { 00269 mln_precondition(s_ != 0); 00270 return *s_; 00271 } 00272 00273 template <typename S, typename E> 00274 inline 00275 const typename S::graph_t& 00276 graph_psite_base<S,E>::graph() const 00277 { 00278 mln_precondition(s_ != 0); 00279 return s_->graph(); 00280 } 00281 00282 template <typename S, typename E> 00283 inline 00284 typename graph_psite_base<S,E>::id_t 00285 graph_psite_base<S,E>::id() const 00286 { 00287 return elt_.id(); 00288 } 00289 00290 template <typename S, typename E> 00291 inline 00292 bool 00293 graph_psite_base<S,E>::is_valid() const 00294 { 00295 return s_ != 0 && s_->is_valid() && elt_.is_valid(); 00296 } 00297 00298 template <typename S, typename E> 00299 inline 00300 void 00301 graph_psite_base<S,E>::invalidate() 00302 { 00303 s_ = 0; 00304 elt_.invalidate(); 00305 } 00306 00307 template <typename S, typename E> 00308 inline 00309 const mln_site(S)& 00310 graph_psite_base<S,E>::subj_() 00311 { 00312 /*FIXME: we may like to enable the following precondition, however, we 00313 ** can't do that since neighb_*_niters update the psite target after having 00314 ** taken the adress of the subject. 00315 */ 00316 // mln_precondition(is_valid()); 00317 return site_; 00318 } 00319 00320 template <typename S, typename E> 00321 inline 00322 graph_psite_base<S,E>::operator unsigned () const 00323 { 00324 mln_precondition(is_valid()); 00325 return elt_.id(); 00326 } 00327 00328 template <typename S, typename E> 00329 inline 00330 graph_psite_base<S,E>::operator typename S::graph_element::id_t () const 00331 { 00332 mln_precondition(is_valid()); 00333 return elt_.id(); 00334 } 00335 00336 template <typename S, typename E> 00337 inline 00338 graph_psite_base<S,E>::operator const typename S::graph_element&() const 00339 { 00340 //mln_precondition(is_valid()); 00341 return elt_; 00342 } 00343 00344 template <typename S, typename E> 00345 inline 00346 const typename S::graph_element& 00347 graph_psite_base<S,E>::element() const 00348 { 00349 /*FIXME: we may like to enable the following precondition, however, we 00350 ** can't do that since neighb_*_niters update the psite target after having 00351 ** taken the adress of the subject. 00352 */ 00353 // mln_precondition(is_valid()); 00354 return elt_; 00355 } 00356 00357 template <typename S, typename E> 00358 inline 00359 const typename S::graph_element& 00360 graph_psite_base<S,E>::p_hook_() const 00361 { 00362 return elt_; 00363 } 00364 00365 00366 template <typename S, typename P, typename E> 00367 inline 00368 const E& 00369 subject_impl< const graph_psite_base<S,P>&, E >::exact_() const 00370 { 00371 return internal::force_exact<const E>(*this); 00372 } 00373 00374 template <typename S, typename P, typename E> 00375 inline 00376 const S* 00377 subject_impl< const graph_psite_base<S,P>&, E >::target_() const 00378 { 00379 return exact_().get_subject().target(); 00380 } 00381 00382 template <typename S, typename P, typename E> 00383 inline 00384 const S& 00385 subject_impl< const graph_psite_base<S,P>&, E >::site_set() const 00386 { 00387 return exact_().get_subject().site_set(); 00388 } 00389 00390 00391 template <typename S, typename P, typename E> 00392 inline 00393 const typename S::graph_t& 00394 subject_impl< const graph_psite_base<S,P>&, E >::graph() const 00395 { 00396 return exact_().get_subject().graph(); 00397 } 00398 00399 template <typename S, typename P, typename E> 00400 inline 00401 unsigned 00402 subject_impl< const graph_psite_base<S,P>&, E >::id() const 00403 { 00404 return exact_().get_subject().id(); 00405 }; 00406 00407 template <typename S, typename P, typename E> 00408 inline 00409 bool 00410 subject_impl< const graph_psite_base<S,P>&, E >::is_valid() const 00411 { 00412 return exact_().get_subject().is_valid(); 00413 } 00414 00415 template <typename S, typename P, typename E> 00416 inline 00417 const typename S::graph_element& 00418 subject_impl< const graph_psite_base<S,P>&, E >::element() const 00419 { 00420 return exact_().get_subject().element(); 00421 } 00422 00423 template <typename S, typename P, typename E> 00424 inline 00425 const typename S::graph_element& 00426 subject_impl< const graph_psite_base<S,P>&, E >::p_hook_() const 00427 { 00428 return exact_().get_subject().p_hook_(); 00429 } 00430 00431 00432 template <typename S, typename P, typename E> 00433 inline 00434 E& 00435 subject_impl< graph_psite_base<S,P>&, E >::exact_() 00436 { 00437 return internal::force_exact<E>(*this); 00438 } 00439 00440 template <typename S, typename P, typename E> 00441 inline 00442 void 00443 subject_impl< graph_psite_base<S,P>&, E >::change_target(const S& new_target) 00444 { 00445 exact_().get_subject().change_target(new_target); 00446 } 00447 00448 template <typename S, typename P, typename E> 00449 inline 00450 void 00451 subject_impl< graph_psite_base<S,P>&, E >::update_id(unsigned id) 00452 { 00453 exact_().get_subject().update_id(id); 00454 }; 00455 00456 template <typename S, typename P, typename E> 00457 inline 00458 void 00459 subject_impl< graph_psite_base<S,P>&, E >::invalidate() 00460 { 00461 exact_().get_subject().invalidate(); 00462 } 00463 00464 # endif // ! MLN_INCLUDE_ONLY 00465 00466 } // end of namespace internal 00467 00468 } // end of namespace mln 00469 00470 00471 #endif // ! MLN_CORE_INTERNAL_GRAPH_PSITE_BASE_HH