Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2007, 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_IMAGE_GRAPH_WINDOW_PITER_HH 00028 # define MLN_CORE_IMAGE_GRAPH_WINDOW_PITER_HH 00029 00036 00037 # include <mln/core/concept/site_set.hh> 00038 # include <mln/core/concept/window.hh> 00039 # include <mln/core/internal/site_relative_iterator_base.hh> 00040 00041 00042 namespace mln 00043 { 00044 00045 // Forward declaration. 00046 template <typename S, typename I> class p_graph_piter; 00047 00048 00049 namespace internal 00050 { 00051 00054 template <typename C, typename P, typename E> 00055 struct impl_selector 00056 { 00057 void do_start_() 00058 { 00059 internal::force_exact<E>(*this).iter_.start(); 00060 // Nothing else to do. A pointer to the window element's site 00061 // set has been already stored in the constructor. 00062 } 00063 00064 }; 00065 00068 template <typename C, typename E> 00069 struct impl_selector<C,C,E> 00070 { 00071 void do_start_() 00072 { 00073 E& this_ = internal::force_exact<E>(*this); 00074 this_.iter_.start(); 00075 00076 // We need to store a pointer on the site set of the window 00077 // center. 00078 // We cannot do this in the constructor since the center may 00079 // not be initialized. 00080 // Here we suppose that if we start this iterator, the 00081 // potential iterator used as center has been started just 00082 // before calling this method. 00083 // 00084 this_.change_target_site_set(this_.center().site_set()); 00085 } 00086 00087 }; 00088 00089 } // end of namespace mln::internal 00090 00091 00097 // 00098 template <typename S, typename W, typename I> 00099 class graph_window_piter 00100 : public internal::site_relative_iterator_base< W, 00101 graph_window_piter<S,W,I>, 00102 typename W::center_t >, 00103 public internal::impl_selector<typename W::center_t, mln_psite(W), 00104 graph_window_piter<S,W,I> > 00105 { 00106 typedef graph_window_piter<S,W,I> self_; 00107 typedef 00108 internal::site_relative_iterator_base<W,self_,mln_psite(S)> super_; 00109 typedef 00110 internal::impl_selector<typename W::center_t, mln_psite(W), 00111 graph_window_piter<S,W,I> > super_impl_; 00112 00113 00114 public: 00118 typedef mln_result(S::fun_t) P; 00120 typedef typename W::center_t center_t; 00122 typedef typename W::graph_element graph_element; 00124 00127 graph_window_piter(); 00128 00129 00130 // --------------------------------------------------------- 00131 // FIXME: probably ugly to provide constructors usable for 00132 // specific cases only... 00133 // --------------------------------------------------------- 00134 00140 // 00141 template <typename Pref> 00142 graph_window_piter(const Window<W>& win, 00143 const Pref& p_ref); 00144 00152 // 00153 template <typename Pref> 00154 graph_window_piter(const Window<W>& win, 00155 const Site_Set<S>& target_site_set, 00156 const Pref& p_ref); 00158 00161 template <typename Pref> 00162 void init_(const Window<W>& win, const Pref& p_ref); 00163 00164 template <typename Pref> 00165 void init_(const Window<W>& win, 00166 const Site_Set<S>& target_site_set, 00167 const Pref& p_ref); 00169 00173 bool is_valid_() const; 00175 void invalidate_(); 00176 00178 void do_next_(); 00179 00181 template <typename Pref> 00182 void center_at_(const Pref& c); 00183 00185 template <typename S2, typename I2> 00186 void center_at_(const p_graph_piter<S2, I2>& c); 00187 00189 const graph_element& element() const; 00190 00192 mln_psite(W) compute_p_() const; 00193 00198 unsigned id() const; 00200 00204 void change_target_site_set(const S& s); 00208 const S& target_site_set() const; 00209 00210 using super_impl_::do_start_; 00211 00212 friend struct internal::impl_selector<typename W::center_t, mln_psite(W), 00213 graph_window_piter<S,W,I> > ; 00214 00215 private: 00216 I iter_; 00217 const S* s_; 00218 }; 00219 00220 00221 # ifndef MLN_INCLUDE_ONLY 00222 00223 00224 template <typename S, typename W, typename I> 00225 inline 00226 graph_window_piter<S,W,I>::graph_window_piter() 00227 : s_(0) 00228 { 00229 } 00230 00231 00232 template <typename S, typename W, typename I> 00233 template <typename Pref> 00234 inline 00235 graph_window_piter<S,W,I>::graph_window_piter(const Window<W>& win, 00236 const Pref& p_ref) 00237 : s_(0) 00238 { 00239 // Center and neighbor sites have the same type and belong to 00240 // the same site set. 00241 mlc_is(center_t, mln_psite(W))::check(); 00242 init_(win, p_ref); 00243 } 00244 00245 00246 template <typename S, typename W, typename I> 00247 template <typename Pref> 00248 inline 00249 graph_window_piter<S,W,I>::graph_window_piter(const Window<W>& win, 00250 const Site_Set<S>& target_site_set, 00251 const Pref& p_ref) 00252 : s_(0) 00253 { 00254 // Center and neighbors sites do not have the same type and do 00255 // not belong to the same site set. 00256 mlc_is_not(center_t, mln_psite(W))::check(); 00257 init_(win, target_site_set, p_ref); 00258 } 00259 00260 template <typename S, typename W, typename I> 00261 template <typename Pref> 00262 inline 00263 void 00264 graph_window_piter<S,W,I>::init_(const Window<W>& win, 00265 const Pref& p_ref) 00266 { 00267 this->center_at(p_ref); 00268 this->change_target(exact(win)); 00269 00270 mln_postcondition(!this->is_valid()); 00271 } 00272 00273 template <typename S, typename W, typename I> 00274 template <typename Pref> 00275 inline 00276 void 00277 graph_window_piter<S,W,I>::init_(const Window<W>& win, 00278 const Site_Set<S>& target_site_set, 00279 const Pref& p_ref) 00280 { 00281 this->center_at(p_ref); 00282 this->change_target(exact(win)); 00283 change_target_site_set(exact(target_site_set)); 00284 mln_postcondition(!this->is_valid()); 00285 } 00286 00287 00288 template <typename S, typename W, typename I> 00289 inline 00290 bool 00291 graph_window_piter<S,W,I>::is_valid_() const 00292 { 00293 return s_ != 0 && s_->is_valid() && iter_.is_valid(); 00294 } 00295 00296 template <typename S, typename W, typename I> 00297 inline 00298 void 00299 graph_window_piter<S,W,I>::invalidate_() 00300 { 00301 iter_.invalidate(); 00302 } 00303 00304 template <typename S, typename W, typename I> 00305 inline 00306 void 00307 graph_window_piter<S,W,I>::do_next_() 00308 { 00309 iter_.next(); 00310 } 00311 00312 template <typename S, typename W, typename I> 00313 template <typename Pref> 00314 inline 00315 void 00316 graph_window_piter<S, W, I>::center_at_(const Pref& c) 00317 { 00318 iter_.center_at(c.p_hook_()); 00319 } 00320 00321 template <typename S, typename W, typename I> 00322 template <typename S2, typename I2> 00323 inline 00324 void 00325 graph_window_piter<S, W, I>::center_at_(const p_graph_piter<S2, I2>& c) 00326 { 00327 iter_.center_at(c.hook_elt_()); 00328 } 00329 00330 template <typename S, typename W, typename I> 00331 inline 00332 mln_psite(W) 00333 graph_window_piter<S,W,I>::compute_p_() const 00334 { 00335 return mln_psite(S)(target_site_set(), iter_.id()); 00336 } 00337 00338 template <typename S, typename W, typename I> 00339 inline 00340 const typename graph_window_piter<S,W,I>::graph_element& 00341 graph_window_piter<S, W, I>::element() const 00342 { 00343 return iter_; 00344 } 00345 00346 template <typename S, typename W, typename I> 00347 inline 00348 unsigned 00349 graph_window_piter<S, W, I>::id() const 00350 { 00351 return iter_.id(); 00352 } 00353 00354 template <typename S, typename W, typename I> 00355 inline 00356 void 00357 graph_window_piter<S, W, I>::change_target_site_set(const S& s) 00358 { 00359 s_ = & s; 00360 mln_assertion(s_ != 0); 00361 } 00362 00363 template <typename S, typename W, typename I> 00364 inline 00365 const S& 00366 graph_window_piter<S, W, I>::target_site_set() const 00367 { 00368 mln_precondition(s_ != 0); 00369 mln_precondition(s_->is_valid()); 00370 return *s_; 00371 } 00372 00373 00374 # endif // ! MLN_INCLUDE_ONLY 00375 00376 } // end of namespace mln 00377 00378 #endif // ! MLN_CORE_IMAGE_GRAPH_WINDOW_PITER_HH